Ver Fonte

Merge branch 'feature/V8-6993-permettre-la-connexion-au-be-pou' into develop

Olivier Massot há 10 meses atrás
pai
commit
c9c2af309d

+ 10 - 10
doc/be_users.md

@@ -44,10 +44,10 @@ Ce paragraphe présente les droits des be_users sur les pages et contenus du sit
 
 | Page                                               | Show               | Edit content       | Edit page          | Delete             | New                | Code |
 |----------------------------------------------------|--------------------|--------------------|--------------------|--------------------|--------------------|------|
-| Home                                               | ![v](images/v.svg) | ![v](images/v.svg) | ![x](images/x.svg) | ![x](images/x.svg) | ![x](images/x.svg) | *17* |
-| footer/* (mentions légales, contact, plan du site) | ![v](images/v.svg) | ![x](images/x.svg) | ![x](images/x.svg) | ![x](images/x.svg) | ![x](images/x.svg) | *1*  |
-| Menu Présentation (*)                              | ![v](images/v.svg) | ![x](images/x.svg) | ![x](images/x.svg) | ![x](images/x.svg) | ![x](images/x.svg) | *1*  |
-| Autres pages                                       | ![v](images/v.svg) | ![v](images/v.svg) | ![v](images/v.svg) | ![x](images/x.svg) | ![v](images/v.svg) | *27* |
+| Home                                               | ![v](images/v.svg) | ![v](images/v.svg) | ![v](images/v.svg) | ![x](images/x.svg) | ![v](images/v.svg) | *27* |
+| footer/* (mentions légales, contact, plan du site) | ![v](images/v.svg) | ![x](images/x.svg) | ![x](images/x.svg) | ![x](images/x.svg) | ![v](images/v.svg) | *9*  |
+| Menu Présentation (*)                              | ![v](images/v.svg) | ![x](images/x.svg) | ![v](images/v.svg) | ![x](images/x.svg) | ![v](images/v.svg) | *11* |
+| Autres pages                                       | ![v](images/v.svg) | ![v](images/v.svg) | ![v](images/v.svg) | ![v](images/v.svg) | ![v](images/v.svg) | *31* |
 
 ### Licence Standard
 
@@ -64,10 +64,10 @@ Ce paragraphe présente les droits des be_users sur les pages et contenus du sit
 
 | Page                                               | Show               | Edit content       | Edit page          | Delete             | New                | Code |
 |----------------------------------------------------|--------------------|--------------------|--------------------|--------------------|--------------------|------|
-| Home                                               | ![v](images/v.svg) | ![v](images/v.svg) | ![x](images/x.svg) | ![x](images/x.svg) | ![x](images/x.svg) | *17* |
+| Home                                               | ![v](images/v.svg) | ![v](images/v.svg) | ![v](images/v.svg) | ![x](images/x.svg) | ![x](images/x.svg) | *19* |
 | footer/* (mentions légales, contact, plan du site) | ![v](images/v.svg) | ![x](images/x.svg) | ![x](images/x.svg) | ![x](images/x.svg) | ![x](images/x.svg) | *1*  |
 | Menu Présentation (*)                              | ![v](images/v.svg) | ![x](images/x.svg) | ![x](images/x.svg) | ![x](images/x.svg) | ![x](images/x.svg) | *1*  |
-| Autres pages                                       | ![v](images/v.svg) | ![v](images/v.svg) | ![v](images/v.svg) | ![x](images/x.svg) | ![x](images/x.svg) | *19* |
+| Autres pages                                       | ![v](images/v.svg) | ![v](images/v.svg) | ![v](images/v.svg) | ![x](images/x.svg) | ![x](images/x.svg) | *27* |
 
 
 ## Accès aux menus
@@ -77,15 +77,15 @@ Ce paragraphe présente les menus du backend disponibles selon le type de compte
 | Page                                           | Admin Premium      | Editor Premium     |   | Admin Standard     | Editor Standard    |
 |------------------------------------------------|--------------------|--------------------|---|--------------------|--------------------|
 | Web - Page                                     | ![v](images/v.svg) | ![v](images/v.svg) |   | ![v](images/v.svg) | ![v](images/v.svg) |
-| Web - Liste                                    | ![v](images/v.svg) | ![x](images/x.svg) |   | ![x](images/x.svg) | ![x](images/x.svg) |
+| Web - Liste                                    | ![v](images/v.svg) | ![v](images/v.svg) |   | ![v](images/v.svg) | ![v](images/v.svg) |
 | Web - Formulaires                              | ![v](images/v.svg) | ![v](images/v.svg) |   | ![v](images/v.svg) | ![v](images/v.svg) |
 | Web - Corbeille                                | ![x](images/x.svg) | ![x](images/x.svg) |   | ![x](images/x.svg) | ![x](images/x.svg) |
 | Web - Info                                     | ![x](images/x.svg) | ![x](images/x.svg) |   | ![x](images/x.svg) | ![x](images/x.svg) |
-| Web - Personnaliser                            | ![v](images/v.svg) | ![x](images/x.svg) |   | ![v](images/v.svg) | ![x](images/x.svg) |
-| Web - Statistiques                             | ![v](images/v.svg) | ![x](images/x.svg) |   | ![v](images/v.svg) | ![x](images/x.svg) |
+| Web - Personnaliser                            | ![v](images/v.svg) | ![v](images/v.svg) |   | ![v](images/v.svg) | ![v](images/v.svg) |
+| Web - Statistiques                             | ![v](images/v.svg) | ![v](images/v.svg) |   | ![v](images/v.svg) | ![v](images/v.svg) |
 | Web - Gestion des actualités                   | ![v](images/v.svg) | ![v](images/v.svg) |   | ![v](images/v.svg) | ![v](images/v.svg) |
 | Gestionnaire de site - Redirects               | ![x](images/x.svg) | ![x](images/x.svg) |   | ![x](images/x.svg) | ![x](images/x.svg) |
-| Fichier - Fichiers                             | ![v](images/v.svg) | ![x](images/x.svg) |   | ![v](images/v.svg) | ![x](images/x.svg) |
+| Fichier - Fichiers                             | ![v](images/v.svg) | ![v](images/v.svg) |   | ![v](images/v.svg) | ![v](images/v.svg) |
 | Outils Utilisateur - Configuration utilisateur | ![x](images/x.svg) | ![x](images/x.svg) |   | ![x](images/x.svg) | ![x](images/x.svg) |
 | Aide - A propos de...                          | ![x](images/x.svg) | ![x](images/x.svg) |   | ![x](images/x.svg) | ![x](images/x.svg) |
 | Aide -Manuel TYPO3                             | ![x](images/x.svg) | ![x](images/x.svg) |   | ![x](images/x.svg) | ![x](images/x.svg) |

+ 10 - 7
ot_admin/Classes/Controller/SiteController.php

@@ -39,7 +39,7 @@ class SiteController extends ActionController
     // Templates names
     private const TEMPLATE_HOME = "OpenTalent.OtTemplating->home";
     private const TEMPLATE_1COL = "OpenTalent.OtTemplating->1Col";
-    private const TEMPLATE_3COL = "OpenTalent.OtTemplating->home";
+    private const TEMPLATE_3COL = "OpenTalent.OtTemplating->3Col";
     private const TEMPLATE_EVENTS = "OpenTalent.OtTemplating->events";
     private const TEMPLATE_STRUCTURESEVENTS = "OpenTalent.OtTemplating->structuresEvents";
     private const TEMPLATE_STRUCTURES = "OpenTalent.OtTemplating->structures";
@@ -405,7 +405,7 @@ class SiteController extends ActionController
             );
 
             if ($isNetwork) {
-                // > 'Présentation > Les sociétés adhérentes' page
+                // > 'Présentation > Evènements des structures' page
                 $this->insertPage(
                     $websiteUid,
                     $this->createdPagesIndex['/presentation'],
@@ -1743,30 +1743,33 @@ class SiteController extends ActionController
         $pages = $this->otPageRepository->getPageWithSubpages($rootUid);
 
         // To understand how the rights levels are computed:
-        // @see https://ressources.opentalent.fr/display/EX/Droits+des+BE+Users
+        // @see https://gitlab.2iopenservice.com/opentalent/ot_typo3/-/blob/master/doc/be_users.md?ref_type=heads
         foreach ($pages as $page) {
 
             if ($page['ot_page_type'] === OtPageTypeEnum::ROOT) {
 
                 $adminPerms = self::PERM_SHOW + self::PERM_EDIT_CONTENT + self::PERM_EDIT_PAGE;
+                $editorsPerms = self::PERM_SHOW + self::PERM_EDIT_CONTENT + self::PERM_EDIT_PAGE;
                 if ($isPremium)  {
                     $adminPerms += self::PERM_NEW;
+                    $editorsPerms += self::PERM_NEW;
                 }
-                $editorsPerms = self::PERM_SHOW + self::PERM_EDIT_CONTENT;
 
             } else if ($page['ot_page_type'] === OtPageTypeEnum::MANDATORY_NON_EDITABLE) {
                 $adminPerms = self::PERM_SHOW;
+                $editorsPerms = self::PERM_SHOW;
                 if ($isPremium)  {
                     $adminPerms += self::PERM_NEW;
+                    $editorsPerms += self::PERM_NEW;
                 }
-                $editorsPerms = self::PERM_SHOW;
 
             } else if ($page['ot_page_type'] === OtPageTypeEnum::MANDATORY_EDITABLE) {
                 $adminPerms = self::PERM_SHOW;
+                $editorsPerms = self::PERM_SHOW;
                 if ($isPremium)  {
                     $adminPerms += self::PERM_NEW + self::PERM_EDIT_PAGE;
+                    $editorsPerms += self::PERM_NEW + self::PERM_EDIT_PAGE;
                 }
-                $editorsPerms = self::PERM_SHOW;
 
             } else {
                 $adminPerms = self::PERM_SHOW + self::PERM_EDIT_CONTENT + self::PERM_EDIT_PAGE;
@@ -1776,7 +1779,7 @@ class SiteController extends ActionController
 
                 $editorsPerms = self::PERM_SHOW + self::PERM_EDIT_CONTENT + self::PERM_EDIT_PAGE;
                 if ($isPremium)  {
-                    $editorsPerms += self::PERM_NEW;
+                    $editorsPerms += self::PERM_DELETE + self::PERM_NEW;
                 }
             }
 

+ 71 - 27
ot_connect/Classes/Service/OtAuthenticationService.php

@@ -31,6 +31,8 @@ class OtAuthenticationService extends AbstractAuthenticationService
     CONST ISAUTH_URI = 'api/user/isauthenticated';
     CONST LOGOUT_URI = 'logout';
     CONST GROUP_FE_ALL_UID = 18076;
+    CONST GROUP_ADMIN_STANDARD_UID = 1;
+    CONST GROUP_ADMIN_PREMIUM_UID = 3;
 
     // Cookies' domain needs to be the same that the api's cookies, or guzzle will ignore them.
     CONST COOKIE_DOMAIN = 'opentalent.fr';
@@ -118,7 +120,9 @@ class OtAuthenticationService extends AbstractAuthenticationService
         // Does the user already have a session on the Opentalent API?
         $username = $this->getAuthenticatedUsername();
 
-        if ($username != null && $this->authInfo['loginType'] === 'FE' && $this->login['status'] === 'logout') {
+        $isBackend = $this->authInfo['loginType'] === 'BE';
+
+        if ($username != null && !$isBackend && $this->login['status'] === 'logout') {
             // This is a logout request
             $this->logout();
             return false;
@@ -154,8 +158,10 @@ class OtAuthenticationService extends AbstractAuthenticationService
         // Request the latest data for the user and write it in the Typo3 DB
         //   * The shouldUserBeUpdated() method checks if the user was already
         //   generated in the last minutes, to avoid unnecessary operations *
-        if ($this->shouldUserBeUpdated($username)) {
-            $wasUpdated = $this->createOrUpdateUser();
+
+        if ($this->shouldUserBeUpdated($username, $isBackend)) {
+            $wasUpdated = $this->createOrUpdateUser($isBackend);
+
             if (!$wasUpdated) {
                 // An error happened during the update of the user's data
                 // since its data may have changed (credentials, rights, rôles...)
@@ -293,12 +299,12 @@ class OtAuthenticationService extends AbstractAuthenticationService
      * @param string $username
      * @return bool
      */
-    protected function shouldUserBeUpdated(string $username): bool
+    protected function shouldUserBeUpdated(string $username, bool $isBackend = false): bool
     {
-
-        $cnn = $this->connectionPool->getConnectionForTable('fe_users');
-        $q = $cnn->select(['tx_opentalent_generationDate'], 'fe_users', ['username' => $username]);
-        $strGenDate = $q->fetch(3)[0];
+        $table = $isBackend ? 'be_users' : 'fe_users';
+        $cnn = $this->connectionPool->getConnectionForTable($table);
+        $q = $cnn->select(['tx_opentalent_generationDate'], $table, ['username' => $username]);
+        $strGenDate = $q->fetch(3)[0] ?? '1970-01-01 00:00:00';
 
         $genDate = DateTime::createFromFormat("Y-m-d H:i:s", $strGenDate);
         if ($genDate == null) {
@@ -316,8 +322,12 @@ class OtAuthenticationService extends AbstractAuthenticationService
      *
      * @return bool
      */
-    protected function createOrUpdateUser(): bool
+    protected function createOrUpdateUser(bool $isBackend = false): bool
     {
+        $table = $isBackend ? 'be_users' : 'fe_users';
+        $group_table = $isBackend ? 'be_groups' : 'fe_groups';
+        $prefix = $isBackend ? 'BE' : 'FE';
+
         // Get user's data from the API
         $userApiData = $this->getUserData();
 
@@ -327,34 +337,60 @@ class OtAuthenticationService extends AbstractAuthenticationService
             return false;
         }
 
-        $connection = $this->connectionPool->getConnectionForTable('fe_users');
+        $connection = $this->connectionPool->getConnectionForTable($table);
 
         // Since we don't want to store the password in the TYPO3 DB, we store a random string instead
-        $randomStr = (new Random)->generateRandomHexString(20);
+        $randomStr = (new Random)->generateRandomHexString(30);
 
         // Front-end user
-        $fe_row = [
+        $user_row = [
             'username' => $userApiData['username'],
             'password' => $randomStr,
-            'name' => $userApiData['name'],
-            'first_name' => $userApiData['first_name'],
-            'description' => '[Warning: auto-generated record, do not modify] FE User',
+            'description' => "[Warning: auto-generated record, do not modify] $prefix User",
             'deleted' => 0,
             'tx_opentalent_opentalentId' => $userApiData['id'],
             'tx_opentalent_generationDate' => date('Y/m/d H:i:s')
         ];
 
-        $groupsUid = [self::GROUP_FE_ALL_UID];
+        if ($isBackend) {
+            $user_row['lang'] = 'fr';
+            $user_row['options'] = "3";
+            $user_row['TSconfig'] = "options.uploadFieldsInTopOfEB = 1";
+        } else {
+            $user_row['name'] = $userApiData['name'];
+            $user_row['first_name'] = $userApiData['first_name'];
+        }
+
+        $groupsUid = [];
+
+        if (!$isBackend) {
+            $groupsUid[] = self::GROUP_FE_ALL_UID;
+        }
+
+        // Loop over the accesses of the user to list the matching organization groups
         if ($userApiData['accesses']) {
             foreach ($userApiData['accesses'] as $accessData) {
+                if ($isBackend && !$accessData['isEditor'] && !$accessData['admin_access']) {
+                    continue;
+                }
+
+                if ($isBackend && $accessData['admin_access']) {
+                    $adminGroupUid = $accessData['product'] === 'artist_premium' ?
+                        self::GROUP_ADMIN_PREMIUM_UID :
+                        self::GROUP_ADMIN_STANDARD_UID;
+                    if (!in_array($adminGroupUid, $groupsUid)) {
+                        $groupsUid[] = $adminGroupUid;
+                    }
+                }
+
                 $organizationId = $accessData['organizationId'];
 
-                // get the fe_group for this organization
+                // get the group for this organization
                 $groupUid = $connection->fetchOne(
                     "select g.uid
-                     from typo3.fe_groups g
+                     from typo3.$group_table g
                      inner join (select uid, ot_website_uid from typo3.pages where is_siteroot) p 
-                     on g.pid = p.uid
+                     on g." . ($isBackend ? 'db_mountpoints' : 'pid') . " = p.uid
                      inner join typo3.ot_websites w on p.ot_website_uid = w.uid
                      where w.organization_id=:organizationId;",
                     ['organizationId' => $organizationId]
@@ -363,31 +399,39 @@ class OtAuthenticationService extends AbstractAuthenticationService
                 if ($groupUid) {
                     $groupsUid[] = $groupUid;
                 } else {
-                    OtLogger::warning("Warning: no fe_group found for organization " . $organizationId);
+                    OtLogger::warning("Warning: no " . strtolower($prefix) . "_group found for organization " . $organizationId);
                 }
             }
         }
-        $fe_row['usergroup'] = join(',', $groupsUid);
+
+        if ($isBackend && empty($groupsUid)) {
+            throw new \Exception("No BE_group found for user " . $userApiData['username']);
+        }
+
+        $user_row['usergroup'] = join(',', $groupsUid);
 
         // TODO: log a warning if a user with the same opentalentId exists (the user might have changed of username)
         $q = $connection->select(
             ['uid', 'tx_opentalent_opentalentId'],
-            'fe_users',
+            $table,
             ['username' => $userApiData['username']]
         );
         $row = $q->fetch(3);
-        $uid = $row[0];
-        $tx_opentalent_opentalentId = $row[1];
+        $uid = $row[0] ?? null;
+        $tx_opentalent_opentalentId = $row[1] ?? null;
 
         if (!$uid) {
             // No existing user: create
-            $connection->insert('fe_users', $fe_row);
+            $connection->insert($table, $user_row);
         } else {
             // User exists: update
             if (!$tx_opentalent_opentalentId > 0) {
-                OtLogger::warning('WARNING: FE user ' . $userApiData['username'] . ' has been replaced by an auto-generated version.');
+                OtLogger::warning(
+                    "WARNING: $prefix user " . $userApiData['username'] .
+                    ' has been replaced by an auto-generated version.'
+                );
             }
-            $connection->update('fe_users', $fe_row, ['uid' => $uid]);
+            $connection->update($table, $user_row, ['uid' => $uid]);
         }
 
         return true;

+ 1 - 0
ot_core/Classes/Service/OpentalentApiService.php

@@ -82,6 +82,7 @@ class OpentalentApiService
     ): array
     {
         $body = $this->getBody($uri, $params);
+
         $data = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
         if ($data !== null) {
             return json_decode($body, true, 512, JSON_THROW_ON_ERROR);