Commit b739c1c9 authored by Stephane Bouvry's avatar Stephane Bouvry
Browse files

API en cours

parent 8cc463ba
Loading
Loading
Loading
Loading

dev/api.md

0 → 100644
+8 −0
Original line number Diff line number Diff line
```bash

curl -X GET http://localhost:8888/api/persons -H "X-API-Key: 2p2qFR8UcXGTojOUCuo604ufx6ymyqf3uZ9OSWSQyr9DwA4yH77dkDwBCV1o3njD"


# no access, ok key
curl -X GET http://localhost:8888/api/persons -H "X-API-Key: pNOr3zugygRW2M17YOTtZdiGsrr0rP6OvEY2dWPhjhMLsM6l1knxWiTJzS9GLeBq"
```
 No newline at end of file
+4 −0
Original line number Diff line number Diff line
@@ -10,6 +10,10 @@
                SetHandler "proxy:fcgi://container-name-php:9000"
            </FilesMatch>
    </Directory>

    # But > Forward de "Authorization" > FPM
    SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

    LogLevel debug
    ErrorLog /proc/self/fd/2
</VirtualHost>
 No newline at end of file
+1 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ RUN if [ -n "$HTTP_PROXY" ]; then \

RUN apt update && apt install -y apache2

RUN a2enmod proxy_fcgi setenvif rewrite
RUN a2enmod proxy_fcgi setenvif rewrite headers

EXPOSE 80

+115 −55
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@

namespace Oscar\Controller;

use BjyAuthorize\Exception\UnAuthorizedException;
use Doctrine\DBAL\Driver\PDO\Exception;
use Oscar\Entity\Activity;
use Oscar\Entity\ActivityType;
use Oscar\Entity\Person;
@@ -32,7 +34,15 @@ class ApiController extends AbstractOscarController implements UseOscarUserConte
{
    use UseOscarUserContextServiceTrait, UseOscarConfigurationServiceTrait, UsePersonServiceTrait, UseLoggerServiceTrait, UseOrganizationServiceTrait, UseActivityServiceTrait;

    public function activityTypeAction(){

    const ACCESS_PERSONS_INDEX = 'persons:index';
    const ACCESS_PERSONS_GET = 'persons:item';
    const ACCESS_PERSONS_UPDATE = 'persons:update';
    const ACCESS_PERSONS_NEW = 'persons:new';
    const ACCESS_PERSONS_DELETE = 'persons:delete';

    public function activityTypeAction()
    {
        $out = $this->baseJsonResponse();
        $out['description'] = "Type d'activité configurées dans Oscar";

@@ -42,7 +52,8 @@ class ApiController extends AbstractOscarController implements UseOscarUserConte
        return $this->jsonOutput($out);
    }

    public function activityTypePcruAction(){
    public function activityTypePcruAction()
    {
        $out = $this->baseJsonResponse();
        $out['description'] = "Type d'activité PCRU";

@@ -93,32 +104,73 @@ class ApiController extends AbstractOscarController implements UseOscarUserConte

        $this->getOscarUserContextService()->check(Privileges::DROIT_API_ACCESS);
        $apis = [
            'persons' => "Personnes",
            self::ACCESS_PERSONS_INDEX => "Personnes (liste/recherche)",
            self::ACCESS_PERSONS_GET => "Personnes (fiche/détails)",
            self::ACCESS_PERSONS_NEW => "Personnes (Création)",
            self::ACCESS_PERSONS_UPDATE => "Personnes (Mise à jour)",
            self::ACCESS_PERSONS_DELETE => "Personnes (Suppression)",

            'organizations' => "Organisations",
            'roles' => "Affectations",
            'activities' => "Activités",
        ];
        $urls = [
            'persons' => $this->url()->fromRoute('api/persons'),
            'organizations' => $this->url()->fromRoute('api/organizations'),
        ];

        $formats = $this->getOscarConfigurationService()->getApiFormats([]);

        if ($this->isAjax()) {
            $datas = $this->getOscarConfigurationService()->getEditableConfKey('apiaccess', []);
            $datas = $this->getOscarConfigurationService()->getApiKeys();
            switch ($this->getHttpXMethod()) {
                case "GET" :
                    $displayedDatas = [];
                    foreach ($datas as $key => $data) {
                        $displayedDatas[$key] = [
                            'login' => $data['login'],
                            'apis' => $data['apis'],
                            'pass_show' => $data['pass_show'],
                            'strategies' => $data['strategies'],
                        ];
                    }
                    $output = [
                        'datas' => $datas,
                        'datas' => $displayedDatas,
                    ];
                    return $this->jsonOutput($output);
                    break;

                case "POST" :

                    $testKey = $this->params()->fromPost('test', null);
                    if( $testKey !== null ){
                        try {
                            $infos = $this->getOscarConfigurationService()->getApiInfos($testKey);
                            return $this->jsonOutput($infos);
                        } catch (\Exception $e) {
                            return $this->jsonError($e->getMessage());
                        }

                    }


                    $login = $this->params()->fromPost('login');
                    $pass = $this->params()->fromPost('pass');
                    $apis = $this->params()->fromPost('apis');
                    $strategies = json_decode($this->params()->fromPost('strategies'), JSON_OBJECT_AS_ARRAY);

                    if( array_key_exists($login, $datas) ){
                        $pass_show = $datas[$login]['pass_show'];
                        $hash = $datas[$login]['pass'];
                    } else {
                        $pass_show = substr($pass,0,3)
                            . '...'
                            . substr($pass,strlen($pass)-3);
                        $hash = password_hash($pass, PASSWORD_DEFAULT);
                    }
                    $datas[$login] = [
                        'pass' => $pass,
                        'login' => $login,
                        'pass' => $hash,
                        'pass_show' => $pass_show,
                        'apis' => explode(',', $apis),
                        'strategies' => $strategies
                    ];
@@ -140,7 +192,12 @@ class ApiController extends AbstractOscarController implements UseOscarUserConte

        return [
            'apis' => $apis,
            'formats' => $formats
            'formats' => $formats,
            'params' => [
                'apis' => $apis,
                'formats' => $formats,
                'urls' => $urls,
            ]
        ];
    }

@@ -152,58 +209,27 @@ class ApiController extends AbstractOscarController implements UseOscarUserConte
     */
    protected function checkApiAcces($api)
    {
        if (!isset($_SERVER['PHP_AUTH_USER'])) {
            header('WWW-Authenticate: Basic realm="Oscar');
            header('HTTP/1.0 401 Unauthorized');
            echo "Accès à l'API Oscar limitée";
            exit;
        }
        $ip = $_SERVER['REMOTE_ADDR'];
        $this->getLoggerService()->info("[API OSCAR] access /$api from $ip");
        $authHeader = $this->getRequest()
            ->getHeaders()
            ->get('X-API-Key');

        // Vérification accès
        try {
            $apiaccess = $this->getOscarConfigurationService()->getEditableConfKey('apiaccess');

            if (is_array($apiaccess)) {
                $user = $_SERVER['PHP_AUTH_USER'];
                $pass = $_SERVER['PHP_AUTH_PW'];

                if (!array_key_exists($user, $apiaccess)) {
                    $this->getLoggerService()->error("[API OSCAR] Identifiant inconnnu $user.");
                    throw new OscarException("Accès interdit l'API Oscar");
        if (!$authHeader) {
            $this->getLoggerService()->error("[OSCAR API] Missing X-API-Key header");
            throw new UnAuthorizedException("[OSCAR API] Missing X-API-Key header", 401);
        }

                if ($apiaccess[$user]['pass'] != $pass) {
                    $this->getLoggerService()->error("[API OSCAR] Mot de passe incorrect pour $user.");
                    throw new OscarException("Accès interdit l'API Oscar");
                }

                if (!in_array('persons', $apiaccess[$user]['apis'])) {
                    $this->getLoggerService()->error("[API OSCAR] $user n'a pas accès à l'API $api.");
                    throw new OscarException("Accès interdit l'API Oscar");
                }
            } else {
                $this->getLoggerService()->error("[API OSCAR] L'API oscar n'est pas configurée");
                throw new OscarException("L'accès à l'API Oscar est mal configuré");
            }
        $token = $authHeader->getFieldValue();

            if (array_key_exists("strategies", $apiaccess[$user])) {
                $stategy = $apiaccess[$user]['strategies'];
            } else {
                $stategy = null;
        try {
            $infos = $this->getOscarConfigurationService()->getApiInfos($token);
            if( !in_array($api, $infos['apis']) ) {
                $this->getLoggerService()->error("[OSCAR API] Accès '$api' interdit");
                throw new OscarException("La clef n'autorise pas '$api'");
            }

            return [
                'access' => 'granted',
                'user' => $user,
                'strategies' => $stategy
            ];
        } catch (OscarException $e) {
            throw $e;
            return $infos;
        } catch (\Exception $e) {
            $this->getLoggerService()->error("[OSCAR API] Erreur inconnue : " . $e->getMessage());
            throw new OscarException("Accès interdit l'API Oscar");
            $this->getLoggerService()->error("[OSCAR API] Erreur d'accès : " . $e->getMessage());
            throw new OscarException("[OSCAR API] Accès interdit à l'API Oscar");
        }
    }

@@ -236,9 +262,30 @@ class ApiController extends AbstractOscarController implements UseOscarUserConte
    ///
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    
    public function personsAction()
    {
        try {
            $start = microtime(true);
            $method = $this->getRequest()->getMethod();

            switch ($method) {
                case "GET":
                    $this->checkApiAcces(self::ACCESS_PERSONS_INDEX);
                    break;
                case "POST":
                    throw new Exception("Non fait");
                    break;
                case "PUT":
                    throw new Exception("Non fait");
                    break;
            }
        } catch (\Exception $e) {
            return $this->jsonError($e->getMessage());
        }


        die($method);

        try {
            $granted = $this->checkApiAcces('persons');
@@ -267,9 +314,22 @@ class ApiController extends AbstractOscarController implements UseOscarUserConte

    public function personAction()
    {
        $method = $this->getRequest()->getMethod();
        $this->checkApiAcces(self::ACCESS_PERSONS_GET);
        switch ($method) {
            case "GET":
                $id = $this->params()->fromRoute('id');
                if( $id ){
                    $access = self::ACCESS_PERSONS_GET;
                } else {
                    throw new \Exception("Pas ici");
                }
                break;
        }

        try {
            $start = microtime(true);
            $granted = $this->checkApiAcces('persons');
            $granted = $this->checkApiAcces($access);

            try {
                $config = $this->getOscarConfigurationService()->getConfiguration('api.formats.persons');
+0 −1002

File deleted.

Preview size limit exceeded, changes collapsed.

Loading