# Authentification et frontend users

L'extension [OtConnect](/ot_connect) se positionne en amont des services d'authentification Typo3 et utilise l'API Opentalent.
En somme, un utilisateur connecté sur Opentalent.fr le sera aussi sur le ou les autres sous-domaines TYPO3
(correspondant à ses structures et à ses droits)

> **Important**: ce système d'authentification ne concerne pour l'instant que les front-end users

## Fonctionnement de l'authentification TYPO3

### Service d'authentification

Pour authentifier un utilisateur, TYPO3 exécute des services par ordre de priorité, jusqu'à ce qu'un de ces services valident l'identité
de l'utilisateur. Si aucun des services ne valident cette authentification, celle-ci est rejetée.

### Création et enregistrement d'un service d'authentification

Un service d'authentification doit hériter de la classe `TYPO3\CMS\Sv\AbstractAuthenticationService`, et implémenter au moins deux méthodes:

* `getUser` vérifie qu'un utilisateur portant ce nom existe en base et retourne ses informations, ou retourne false en cas d'echec.
* `authUser` vérifie que l'utilisateur est authentifié. La méthode retourne un code indiquant le résultat:
    * 0 signifie que l'authentification a échoué et que le process d'authentif doit s'arrêter là
    * 100 signifie que l'authentification a échoué, mais que les services suivants peuvent essayer à leur tour d'authentifier le user
    * 200 signifie que l'authentification a réussi

De plus, le service doit être enregistré dans `ext_localconf.php` via la méthode `\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addService`.
A cette étape, on peut lui donner des rôles (authentification backend et/ou frontend, par exemple).

> **IMPORTANT** : quelle que soit la méthode d'authentification, les users backend et frontend
>doivent avoir leurs enregistrements dans la base TYPO3 (tables `fe_users` et `be_users`)

### Requêtes d'authentification

Typo3 reconnait une requête d'authentification de la manière suivante :

* La requête a un paramètre `logintype` dont la valeur est `login`: c'est une requête d'authentification Frontend
* La requête a un paramètre `login_status` dont la valeur est `login`: c'est une requête d'authentification Backend

Voilà les formulaires minimaux pour poster une demande d'authentification :

    <-- FrontEnd -->
    <form action="" method="POST" enctype="multipart/form-data" >
        <input type="hidden" name="logintype" value="login" />
        <input type="text" placeholder="Nom d'utilisateur" name="user" required="1" />
        <input type="password" name="pass" placeholder="Mot de passe" required="1" />
        <input type="submit" value="Se connecter" />
    </form>

    <-- BackEnd -->
    <form action="" method="POST" enctype="multipart/form-data" >
        <input type="hidden" name="login_status" value="login" />
        <input type="text" placeholder="Nom d'utilisateur" name="username" required="1" />
        <input type="password" name="password" placeholder="Mot de passe" required="1" />
        <input type="submit" value="Se connecter" />
    </form>

> Côté Frontend, Typo3 attend deux champs dont les attributs 'name' sont 'user' et 'pass'.

### Base de données

Les utilisateurs **Backend** doivent avoir une ligne correspondante dans la table `be_users` de la base TYPO3.
Ils doivent avoir a minima les champs suivants renseignés :

* `username`
* `password`: si le mot de passe n'est pas utilisé pour authentifier l'utilisateur,
  par exemple parce qu'une API l'a déjà authentifié en amont, mettre une random string
* `usergroup`: le user doit appartenir à un groupe existant (cf. `be_groups`), sauf s'il est admin (champs `admin` = 1)

Les utilisateurs **Frontend** doivent avoir une ligne correspondante dans la table `fe_users` de la base TYPO3.
Ils doivent avoir a minima les champs suivants renseignés :

* `username`
* `password` : si le mot de passe n'est pas utilisé pour authentifier l'utilisateur,
  par exemple parce qu'une API l'a déjà authentifié en amont, mettre une random string
* `usergroup` : le user doit appartenir à un groupe existant (cf. `be_groups`)

### Plus d'infos

> [Voir la doc officielle](https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/Authentication/Index.html)


## Fonctionnement de l'extension OtConnect

Un service `OtAuthenticationService` est créé et enregistré avec les caractéristiques suivantes :

* `'subtype' => 'getUserFE,authUserFE,getUserBE,authUserBE'` : le service peut récupérer les infos des users
  et les authentifier, à la fois pour le Frontend (FE) et pour le Backend (BE)
* `'priority' => 80`: la priorité est fixée à 80, ce qui place le service en amont des services Typo3.

Enfin, la variable de configuration `FE_fetchUserIfNoSession` force l'appel à la méthode getUser à chaque affichage d'une page frontEnd si une session n'existe pas déjà.
(sans ça, l'utilisateur doit passer par la page de login même s'il a déjà une session opentalent.fr ouverte)

Voilà les différents scénarios pour un utilisateur nommé Bob.

> Les cas suivants sont donnés pour le Frontend, mais ils sont identiques pour le Backend à deux différences près :
> * Le user doit saisir son login / mdp (pas d'auto-log)
> * Seuls les utilisateurs ayant la propriété `admin_access` à true ont accès au Backend.

| Num. | Cas | Comportement |
| --- | --- | --- |
| 1 | Bob a une session Typo3-FE existante dans son navigateur (cf. cookie `fe_typo_user`) | Le service n'est pas appelé, Bob est déjà connecté |
| 2 | Bob n'a pas de session Typo3 ouverte, mais il a une session ouverte dans son navigateur sur Opentalent.fr (cf. cookies `BEARER` et `SFSESSID`) | Une requête GET `/isauthenticated` est envoyée à l'API Opentalent. En cas de succès, une nouvelle requête est envoyée à l'API pour obtenir les données à jour de l'utilisateur, puis la ligne de Bob est créee ou mise à jour dans la table `fe_users` de la base Typo3 (sauf si cette mise à jour a déjà été faite dans les dernières minutes, voir const USER_UPDATE_DELAY) |
| 3 | Bob n'a ni session Typo3-FE ni session Opentalent.fr ouverte, mais il a envoyé une requête de login valide | Ses données d'authentif sont envoyées à l'API qui lui ouvre une session. La suite se déroule comme pour le cas n°2 |
| 4 | Bob n'a ni session Typo3-FE ni session Opentalent.fr ouverte, mais il a envoyé une requête de login invalide | Ses données d'authentif sont envoyées à l'API qui essaie de lui ouvrir une session et retourne un code d'echec. Le service, constatant qu'il s'agit tout de même d'un compte Opentalent, s'interrompt et refuse l'accès à Bob (qui pleure) |
| 5 | Bob se connecte en utilisant un compte créé dans Typo3 ou via un autre service d'authentification (ce compte n'existe donc pas dans la base Opentalent)  | Ses données d'authentif sont envoyées à l'API qui essaie de lui ouvrir une session et retourne un code d'echec. Le service passe la main aux services Typo3 suivants par ordre de priorité |

