Commit be28990c authored by Alexandre Goldstein's avatar Alexandre Goldstein
Browse files

Merge branch 'develop' of labs.maarch.org:maarch/maarchRM into develop

parents 06fb1c7d 614b01c2
Pipeline #14029 failed with stages
in 53 seconds
......@@ -142,22 +142,43 @@ abstract class AbstractRequest
*/
protected function getAuthentication()
{
if (isset($_SERVER['PHP_AUTH_USER'])) {
$this->authentication = new basicAuthentication($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
} elseif (isset($_SERVER['PHP_AUTH_DIGEST'])) {
$neededParts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
$data = array();
$keys = implode('|', array_keys($neededParts));
preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $_SERVER['PHP_AUTH_DIGEST'], $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$data[$match[1]] = $match[3] ? $match[3] : $match[4];
unset($neededParts[$match[1]]);
}
$this->authentication = $this->selectAuthentication();
}
$this->authentication = new digestAuthentication($data['username'], $data['nonce'], $data['uri'], $data['response'], $data['qop'], $data['nc'], $data['cnonce']);
}
protected function selectAuthentication()
{
$authModes = \laabs::getAuthModes();
foreach ($authModes as $authMode) {
switch ($authMode) {
case LAABS_BASIC_AUTH:
if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
return new basicAuthentication($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
}
break;
case LAABS_DIGEST_AUTH:
if (isset($_SERVER['PHP_AUTH_DIGEST'])) {
$neededParts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
$data = array();
$keys = implode('|', array_keys($neededParts));
preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $_SERVER['PHP_AUTH_DIGEST'], $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$data[$match[1]] = $match[3] ? $match[3] : $match[4];
unset($neededParts[$match[1]]);
}
return new digestAuthentication($data['username'], $data['nonce'], $data['uri'], $data['response'], $data['qop'], $data['nc'], $data['cnonce']);
}
break;
case LAABS_REMOTE_AUTH:
if (isset($_SERVER['REMOTE_USER']) && isset($_SERVER['AUTH_TYPE'])) {
return new remoteAuthentication($_SERVER['REMOTE_USER'], $_SERVER['AUTH_TYPE']);
}
break;
}
}
}
}
\ No newline at end of file
<?php
namespace core\Request;
/**
* Class to represent app authentication
*/
class remoteAuthentication
extends abstractAuthentication
{
public static $mode = LAABS_REMOTE_AUTH;
public $remoteUser;
public $authType;
public function __construct($remoteUser, $authType)
{
$this->remoteUser = $remoteUser;
$this->authType = $authType;
}
}
\ No newline at end of file
......@@ -137,6 +137,7 @@ const LAABS_BATCH_STATUS_COMPLETED = "Completed";
const LAABS_BASIC_AUTH = "basic";
const LAABS_DIGEST_AUTH = "digest";
const LAABS_APP_AUTH = "app";
const LAABS_REMOTE_AUTH = "remote";
// TOKENS
// Operations
......
......@@ -1392,4 +1392,14 @@ trait laabsAppTrait
}
/**
* Get the auth methods
*
* @return array
*/
public static function getAuthModes()
{
return self::getList('LAABS_AUTH_MODES');
}
}
......@@ -52,4 +52,21 @@
SetEnv LAABS_ERROR_URI recordsManagement/welcome/error
SetEnv LAABS_CRYPT_KEY mySecretKey
### AUTHENTICATION WITH KERBEROS ###
# SetEnv LAABS_AUTH_MODES remote;basic;digest
# <Directory "/var/www/laabs/web">
# <If "'%{HTTP:User-Agent}' !~ m#service(.*)$#">
# AuthType Kerberos
# AuthName "KERBEROS AUTHENTICATION"
# KrbAuthRealms DOMAIN.COM
# KrbServiceName HTTP
# Krb5Keytab /etc/apache2/kerb.keytab
# KrbMethodNegotiate On
# KrbMethodK5Passwd Off
# Require valid-user
# </If>
# </Directory>
</VirtualHost>
......@@ -65,34 +65,102 @@ class userAuthentication
*/
public function login($userName, $password)
{
// Check userAccount exists
$currentDate = \laabs::newTimestamp();
// Check userAccount exists and get it
$userAccount = $this->getUserByName($userName);
$this->checkEnabled($userAccount);
// Check password ans status
$userLogin = $this->checkCredentials($userAccount, $password);
if (isset($this->securityPolicy['sessionTimeout'])) {
$tokenDuration = $this->securityPolicy['sessionTimeout'];
} else {
$tokenDuration = 86400;
}
// Set token
$this->setToken($userLogin, $tokenDuration);
// Require password change
if ($this->securityPolicy['passwordValidity'] && $this->securityPolicy["passwordValidity"] != 0) {
$diff = ($userLogin->lastLogin->getTimestamp() - $userAccount->passwordLastChange->getTimestamp()) / $tokenDuration;
if ($diff > $this->securityPolicy['passwordValidity']) {
throw \laabs::newException('auth/userPasswordChangeRequestException');
}
}
if ($userAccount->passwordChangeRequired == true) {
\laabs::setToken('TEMP-AUTH', $accountToken, $tokenDuration);
\laabs::unsetToken('AUTH');
throw \laabs::newException('auth/userPasswordChangeRequestException');
}
return $userAccount;
}
/**
* Log a remote user
* @param string $userName
*
* @return auth/userAccount
*/
public function logRemoteUser($userName)
{
// Check userAccount exists and get it
$userAccount = $this->getUserByName($userName);
$this->checkEnabled($userAccount);
$userLogin = \laabs::newInstance('auth/userLogin');
$userLogin->accountId = $userAccount->accountId;
$userLogin->lastIp = $_SERVER["REMOTE_ADDR"];
if (isset($this->securityPolicy['sessionTimeout'])) {
$tokenDuration = $this->securityPolicy['sessionTimeout'];
} else {
$tokenDuration = 86400;
}
// Set token
$this->setToken($userLogin, $tokenDuration);
return $userAccount;
}
/**
* Get user from userName
* @param string $userName
*
* @return auth/account
* @throws auth/authenticationException when username not found
*/
public function getUserByName(string $userName)
{
$exists = $this->sdoFactory->exists('auth/account', array('accountName' => $userName));
if (!$exists) {
throw \laabs::newException('auth/authenticationException', 'Username and / or password invalid', 401);
}
$userAccount = $this->sdoFactory->read('auth/account', array('accountName' => $userName));
return $this->sdoFactory->read('auth/account', array('accountName' => $userName));
}
/**
* Check user password and hability to login
* @param object $userAccount
*
* @return object
*/
protected function checkCredentials($userAccount, $password)
{
$currentDate = \laabs::newTimestamp();
// Create user login object
$userLogin = \laabs::newInstance('auth/userLogin');
$userLogin->accountId = $userAccount->accountId;
$userLogin->lastIp = $_SERVER["REMOTE_ADDR"];
// Check enabled
if ($userAccount->enabled != true) {
$e = \laabs::newException(
'auth/authenticationException',
'User %1$s is disabled',
403,
null,
array($userName)
);
throw $e;
}
// Check password
if (!password_verify($password, $userAccount->password) && hash($this->passwordEncryption, $password) != $userAccount->password) {
// Update bad password count
......@@ -119,6 +187,10 @@ class userAuthentication
throw \laabs::newException('auth/authenticationException', 'Username and / or password invalid', 401);
}
if (password_needs_rehash($userAccount->password, PASSWORD_DEFAULT)) {
$userLogin->password = password_hash($password, PASSWORD_DEFAULT);
}
// Check locked
if ($userAccount->locked == true) {
if (!isset($this->securityPolicy['lockDelay']) // No delay while locked
......@@ -137,36 +209,21 @@ class userAuthentication
$userLogin->tokenDate = null;
$userLogin->lastLogin = $currentDate;
if (password_needs_rehash($userAccount->password, PASSWORD_DEFAULT)) {
$userLogin->password = password_hash($password, PASSWORD_DEFAULT);
}
$this->sdoFactory->update($userLogin, 'auth/account');
if (isset($this->securityPolicy['sessionTimeout'])) {
$tokenDuration = $this->securityPolicy['sessionTimeout'];
} else {
$tokenDuration = 86400;
}
return $userLogin;
}
/**
* Sets the auth token
* @param object $userLogin
* @param int $tokenDuration
*/
public function setToken($userLogin, $tokenDuration)
{
$accountToken = new \StdClass();
$accountToken->accountId = $userAccount->accountId;
$accountToken->accountId = $userLogin->accountId;
$userToken = \laabs::setToken('AUTH', $accountToken, $tokenDuration);
if ($this->securityPolicy['passwordValidity'] && $this->securityPolicy["passwordValidity"] != 0) {
$diff = ($currentDate->getTimestamp() - $userAccount->passwordLastChange->getTimestamp()) / $tokenDuration;
if ($diff > $this->securityPolicy['passwordValidity']) {
throw \laabs::newException('auth/userPasswordChangeRequestException');
}
}
if ($userAccount->passwordChangeRequired == true) {
\laabs::setToken('TEMP-AUTH', $accountToken, $tokenDuration);
\laabs::unsetToken('AUTH');
throw \laabs::newException('auth/userPasswordChangeRequestException');
}
return $userAccount;
}
/**
......@@ -230,6 +287,26 @@ class userAuthentication
}
}
/**
* Check if user is enabled
* @param object $userAccount
*
* @return object
*/
protected function checkEnabled($userAccount)
{
if ($userAccount->enabled != true) {
$e = \laabs::newException(
'auth/authenticationException',
'User %1$s is disabled',
403,
null,
array($userName)
);
throw $e;
}
}
/**
* Log out a user
*/
......
......@@ -106,6 +106,21 @@ class authentication
}
break;
case LAABS_REMOTE_AUTH:
try {
$userAuthenticationController = \laabs::newController('auth/userAuthentication');
$this->requestToken = $this->account = $userAuthenticationController->logRemoteUser($requestAuth->remoteUser);
$this->accountId = $this->account->accountId;
\laabs::kernel()->response->code = 307;
\laabs::kernel()->response->setHeader('Location', '/');
\laabs::kernel()->sendResponse();
\laabs::kernel()->end();
} catch (\Exception $e) {
throw $e;
}
break;
/*case LAABS_DIGEST_AUTH:
if ($this->authenticationService->logIn($requestAuth->username, $requestAuth->nonce, $requestAuth->uri, $requestAuth->response, $requestAuth->qop, $requestAuth->nc, $requestAuth->cnonce)) {
$token = $this->encrypt($_SESSION['dependency']['authentication']['credential']);
......
......@@ -1321,10 +1321,10 @@ msgid "Object"
msgstr "Objet"
msgid "Archive added to collection."
msgstr "Archive ajoutée aux favoris."
msgstr "Archive(s) ajoutée(s) aux favoris."
msgid "Archive removed from collection."
msgstr "Archive retirée des favoris."
msgstr "Archive(s) retirée(s) des favoris."
msgid "Remove All Collections"
msgstr "Supprimer tous les favoris"
......
......@@ -6,6 +6,13 @@
</div>
<script>
$('#deleteCollections').on('click', function() {
var collectionLength = $('#archiveList_table').DataTable().rows().count();
if (collectionLength < 1) {
return;
}
ArchivesAction.updateCollection([], true, null, null);
setTimeout(function(){
load('/collection');
}, 200)
});
</script>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment