Auth Controllers¶
- The Auth controllers allow you to perform basic authentification with:
- login with an account
- account creation
- logout
- controllers with required authentication
Creation¶
In the admin interface (web-tools), activate the Controllers part, and choose create Auth controller:

- Then fill in the form:
- Enter the controller name (BaseAuthController in this case)

The generated controller:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | /**
* Auth Controller BaseAuthController
**/
class BaseAuthController extends \Ubiquity\controllers\auth\AuthController{
protected function onConnect($connected) {
$urlParts=$this->getOriginalURL();
USession::set($this->_getUserSessionKey(), $connected);
if(isset($urlParts)){
Startup::forward(implode("/",$urlParts));
}else{
//TODO
//Forwarding to the default controller/action
}
}
protected function _connect() {
if(URequest::isPost()){
$email=URequest::post($this->_getLoginInputName());
$password=URequest::post($this->_getPasswordInputName());
//TODO
//Loading from the database the user corresponding to the parameters
//Checking user creditentials
//Returning the user
}
return;
}
/**
* {@inheritDoc}
* @see \Ubiquity\controllers\auth\AuthController::isValidUser()
*/
public function _isValidUser($action=null): bool {
return USession::exists($this->_getUserSessionKey());
}
public function _getBaseRoute(): string {
return 'BaseAuthController';
}
}
|
Implementation of the authentification¶
Example of implementation with the administration interface : We will add an authentication check on the admin interface.
Authentication is based on verification of the email/password pair of a model User:

BaseAuthController modification¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | /**
* Auth Controller BaseAuthController
**/
class BaseAuthController extends \Ubiquity\controllers\auth\AuthController{
protected function onConnect($connected) {
$urlParts=$this->getOriginalURL();
USession::set($this->_getUserSessionKey(), $connected);
if(isset($urlParts)){
Startup::forward(implode("/",$urlParts));
}else{
Startup::forward("admin");
}
}
protected function _connect() {
if(URequest::isPost()){
$email=URequest::post($this->_getLoginInputName());
$password=URequest::post($this->_getPasswordInputName());
return DAO::uGetOne(User::class, "email=? and password= ?",false,[$email,$password]);
}
return;
}
/**
* {@inheritDoc}
* @see \Ubiquity\controllers\auth\AuthController::isValidUser()
*/
public function _isValidUser($action=null): bool {
return USession::exists($this->_getUserSessionKey());
}
public function _getBaseRoute(): string {
return 'BaseAuthController';
}
/**
* {@inheritDoc}
* @see \Ubiquity\controllers\auth\AuthController::_getLoginInputName()
*/
public function _getLoginInputName(): string {
return "email";
}
}
|
Admin controller modification¶
Modify the Admin Controller to use BaseAuthController:
1 2 3 4 5 6 | class Admin extends UbiquityMyAdminBaseController{
use WithAuthTrait;
protected function getAuthController(): AuthController {
return $this->_auth ??= new BaseAuthController($this);
}
}
|
Test the administration interface at /admin:

After clicking on login:

If the authentication data entered is invalid:

If the authentication data entered is valid:

Attaching the zone info-user¶
Modify the BaseAuthController controller:
1 2 3 4 5 6 7 8 9 | /**
* Auth Controller BaseAuthController
**/
class BaseAuthController extends \Ubiquity\controllers\auth\AuthController{
...
public function _displayInfoAsString(): bool {
return true;
}
}
|
The _userInfo area is now present on every page of the administration:

It can be displayed in any twig template:
{{ _userInfo | raw }}
Description of the features¶
Customizing templates¶
index.html template¶
The index.html template manages the connection:

Example with the _userInfo area:
Create a new AuthController named PersoAuthController:

Edit the template app/views/PersoAuthController/info.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | {% extends "@framework/auth/info.html" %}
{% block _before %}
<div class="ui tertiary inverted red segment">
{% endblock %}
{% block _userInfo %}
{{ parent() }}
{% endblock %}
{% block _logoutButton %}
{{ parent() }}
{% endblock %}
{% block _logoutCaption %}
{{ parent() }}
{% endblock %}
{% block _loginButton %}
{{ parent() }}
{% endblock %}
{% block _loginCaption %}
{{ parent() }}
{% endblock %}
{% block _after %}
</div>
{% endblock %}
|
Change the AuthController Admin controller:
1 2 3 4 5 6 | class Admin extends UbiquityMyAdminBaseController{
use WithAuthTrait;
protected function getAuthController(): AuthController {
return $this->_auth ??= new PersoAuthController($this);
}
}
|

Customizing messages¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class PersoAuthController extends \controllers\BaseAuth{
...
/**
* {@inheritDoc}
* @see \Ubiquity\controllers\auth\AuthController::badLoginMessage()
*/
protected function badLoginMessage(\Ubiquity\utils\flash\FlashMessage $fMessage) {
$fMessage->setTitle("Erreur d'authentification");
$fMessage->setContent("Login ou mot de passe incorrects !");
$this->_setLoginCaption("Essayer à nouveau");
}
...
}
|
Self-check connection¶
1 2 3 4 5 6 7 8 9 10 11 | class PersoAuthController extends \controllers\BaseAuth{
...
/**
* {@inheritDoc}
* @see \Ubiquity\controllers\auth\AuthController::_checkConnectionTimeout()
*/
public function _checkConnectionTimeout() {
return 10000;
}
...
}
|
Limitation of connection attempts¶
1 2 3 4 5 6 7 8 9 10 11 | class PersoAuthController extends \controllers\BaseAuth{
...
/**
* {@inheritDoc}
* @see \Ubiquity\controllers\auth\AuthController::attemptsNumber()
*/
protected function attemptsNumber(): int {
return 3;
}
...
}
|
Account recovery¶
account recovery is used to reset the account password.
A password reset email is sent, to an email address corresponding to an active account.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class PersoAuthController extends \controllers\BaseAuth{
...
protected function hasAccountRecovery():bool{
return true;
}
protected function _sendEmailAccountRecovery(string $email,string $validationURL,string $expire):bool {
MailerManager::start();
$mail=new AuthAccountRecoveryMail();
$mail->to($connected->getEmail());
$mail->setUrl($validationURL);
$mail->setExpire($expire);
return MailerManager::send($mail);
}
protected function passwordResetAction(string $email,string $newPasswordHash):bool {
//To implement for modifying the user password
}
protected function isValidEmailForRecovery(string $email):bool {
//To implement: return true if a valid account match with this email
}
}
|

Note
By default, the link can only be used on the same machine, within a predetermined period of time (which can be modified by overriding the accountRecoveryDuration
method).
Activation of MFA/2FA¶
Multi-factor authentication can be enabled conditionally, based on the pre-logged-in user’s information.
Note
Phase 2 of the authentication is done in the example below by sending a random code by email.
The AuthMailerClass class is available in the Ubiquity-mailer
package.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class PersoAuthController extends \controllers\BaseAuth{
...
/**
* {@inheritDoc}
* @see \Ubiquity\controllers\auth\AuthController::has2FA()
*/
protected function has2FA($accountValue=null):bool{
return true;
}
protected function _send2FACode(string $code, $connected):void {
MailerManager::start();
$mail=new AuthMailerClass();
$mail->to($connected->getEmail());
$mail->setCode($code);
MailerManager::send($mail);
}
...
}
|

Note
It is possible to customize the creation of the generated code, as well as the prefix used.
The sample below is implemented with robthree/twofactorauth
library.
protected function generate2FACode():string{
$tfa=new TwoFactorAuth();
return $tfa->createSecret();
}
protected function towFACodePrefix():string{
return 'U-';
}
Account creation¶
The activation of the account creation is also optional:

1 2 3 4 5 6 7 | class PersoAuthController extends \controllers\BaseAuth{
...
protected function hasAccountCreation():bool{
return true;
}
...
}
|

In this case, the _create method must be overridden in order to create the account:
protected function _create(string $login, string $password): ?bool {
if(!DAO::exists(User::class,'login= ?',[$login])){
$user=new User();
$user->setLogin($login);
$user->setPassword($password);
URequest::setValuesToObject($user);//for the others params in the POST.
return DAO::insert($user);
}
return false;
}
You can check the validity/availability of the login before validating the account creation form:
protected function newAccountCreationRule(string $accountName): ?bool {
return !DAO::exists(User::class,'login= ?',[$accountName]);
}

A confirmation action (email verification) may be requested from the user:
protected function hasEmailValidation(): bool {
return true;
}
protected function _sendEmailValidation(string $email,string $validationURL,string $expire):void {
MailerManager::start();
$mail=new AuthEmailValidationMail();
$mail->to($connected->getEmail());
$mail->setUrl($validationURL);
$mail->setExpire($expire);
MailerManager::send($mail);
}
Note
It is possible to customize these parts by overriding the associated methods, or by modifying the interfaces in the concerned templates.