From 4fa8d75ec7cca0ef1335528cdd2c9dceef0d98f0 Mon Sep 17 00:00:00 2001
From: Damien <damien.burel@maarch.org>
Date: Thu, 3 Dec 2020 10:40:06 +0100
Subject: [PATCH] FEAT #15569 TIME 3:30 WIP OpenAm connection

---
 apps/maarch_entreprise/xml/login_method.xml   |  4 ++
 apps/maarch_entreprise/xml/openAM.json        |  6 +++
 .../controllers/AuthenticationController.php  | 39 +++++++++++++++++++
 src/frontend/app/login/login.component.ts     |  4 +-
 4 files changed, 52 insertions(+), 1 deletion(-)
 create mode 100644 apps/maarch_entreprise/xml/openAM.json

diff --git a/apps/maarch_entreprise/xml/login_method.xml b/apps/maarch_entreprise/xml/login_method.xml
index ffb4de8a061..21cdc151d23 100755
--- a/apps/maarch_entreprise/xml/login_method.xml
+++ b/apps/maarch_entreprise/xml/login_method.xml
@@ -20,4 +20,8 @@
         <ID>keycloak</ID>
         <ENABLED>false</ENABLED>
     </METHOD>
+    <METHOD>
+        <ID>openam</ID>
+        <ENABLED>true</ENABLED>
+    </METHOD>
 </ROOT>
diff --git a/apps/maarch_entreprise/xml/openAM.json b/apps/maarch_entreprise/xml/openAM.json
new file mode 100644
index 00000000000..8bfb3ead15c
--- /dev/null
+++ b/apps/maarch_entreprise/xml/openAM.json
@@ -0,0 +1,6 @@
+{
+    "connectionUrl" : "https://serveur/openam/UI/Login",
+    "attributeUrl"  : "https://serveur/openam/identity/json/attributes",
+    "cookieName"    : "iPlanetDirectoryPro",
+    "attributeName" : "employeeNumber"
+}
diff --git a/src/core/controllers/AuthenticationController.php b/src/core/controllers/AuthenticationController.php
index 3557559a163..9aa0221c39c 100755
--- a/src/core/controllers/AuthenticationController.php
+++ b/src/core/controllers/AuthenticationController.php
@@ -24,6 +24,7 @@ use Slim\Http\Request;
 use Slim\Http\Response;
 use SrcCore\models\AuthenticationModel;
 use SrcCore\models\CoreConfigModel;
+use SrcCore\models\CurlModel;
 use SrcCore\models\PasswordModel;
 use SrcCore\models\ValidatorModel;
 use Stevenmaguire\OAuth2\Client\Provider\Keycloak;
@@ -68,6 +69,9 @@ class AuthenticationController
             $ssoConfiguration = ConfigurationModel::getByPrivilege(['privilege' => 'admin_sso', 'select' => ['value']]);
             $ssoConfiguration = !empty($ssoConfiguration['value']) ? json_decode($ssoConfiguration['value'], true) : null;
             $authUri          = $ssoConfiguration['url'] ?? null;
+        } elseif ($loggingMethod['id'] == 'openam') {
+            $configuration  = CoreConfigModel::getJsonLoaded(['path' => 'apps/maarch_entreprise/xml/openAM.json']);
+            $authUri        = $configuration['connectionUrl'] ?? null;
         }
 
         $return = [
@@ -302,6 +306,15 @@ class AuthenticationController
             if (!AuthenticationController::isUserAuthorized(['login' => $login])) {
                 return $response->withStatus(403)->withJson(['errors' => 'Authentication unauthorized']);
             }
+        } elseif ($loggingMethod['id'] == 'openam') {
+            $authenticated = AuthenticationController::openAMConnection();
+            if (!empty($authenticated['errors'])) {
+                return $response->withStatus(401)->withJson(['errors' => $authenticated['errors']]);
+            }
+            $login = strtolower($authenticated['login']);
+            if (!AuthenticationController::isUserAuthorized(['login' => $login])) {
+                return $response->withStatus(403)->withJson(['errors' => 'Authentication unauthorized']);
+            }
         } else {
             return $response->withStatus(403)->withJson(['errors' => 'Logging method unauthorized']);
         }
@@ -596,6 +609,32 @@ class AuthenticationController
         return ['logoutUrl' => $url];
     }
 
+    private static function openAMConnection()
+    {
+        //TODO OpenAM 13
+        $configuration = CoreConfigModel::getJsonLoaded(['path' => 'apps/maarch_entreprise/xml/openAM.json']);
+
+        if (empty($configuration['attributeUrl']) || empty($configuration['cookieName']) || empty($configuration['attributeName'])) {
+            return ['errors' => 'OpenAM configuration missing'];
+        }
+
+        if (empty($_COOKIE[$configuration['cookieName']])) {
+            return ['errors' => 'Authentication Failed : User cookie is not set'];
+        }
+        $curlResponse = CurlModel::execSimple([
+            'url'           => "{$configuration['attributeUrl']}?subjectid={$_COOKIE[$configuration['cookieName']]}&attributenames={$configuration['attributeName']}",
+            'method'        => 'GET',
+        ]);
+
+        $login = $curlResponse['response']['attributes'][0]['values'][0] ?? null;
+
+        if (empty($login)) {
+            return ['errors' => 'Authentication Failed : login not present in response'];
+        }
+
+        return ['login' => $login];
+    }
+
     public function getRefreshedToken(Request $request, Response $response)
     {
         $queryParams = $request->getQueryParams();
diff --git a/src/frontend/app/login/login.component.ts b/src/frontend/app/login/login.component.ts
index cc54c2945c3..ef65c1f8006 100644
--- a/src/frontend/app/login/login.component.ts
+++ b/src/frontend/app/login/login.component.ts
@@ -102,6 +102,8 @@ export class LoginComponent implements OnInit {
                     this.notify.error(this.translate.instant('lang.accountLocked') + ' ' + this.timeLimit.transform(err.error.date));
                 } else if (this.authService.authMode === 'sso' && err.error.errors === 'Authentication Failed : login not present in header' && !this.functionsService.empty(this.authService.authUri)) {
                     window.location.href = this.authService.authUri;
+                } else if (this.authService.authMode === 'openam' && err.error.errors === 'Authentication Failed : User cookie is not set' && !this.functionsService.empty(this.authService.authUri)) {
+                    window.location.href = this.authService.authUri;
                 } else {
                     this.notify.handleSoftErrors(err);
                 }
@@ -111,7 +113,7 @@ export class LoginComponent implements OnInit {
     }
 
     initConnection() {
-        if (['sso'].indexOf(this.authService.authMode) > -1) {
+        if (['sso', 'openam'].indexOf(this.authService.authMode) > -1) {
             this.loginForm.disable();
             this.loginForm.setValidators(null);
             this.onSubmit();
-- 
GitLab