Commit 6a3923bd authored by Cyril Vazquez's avatar Cyril Vazquez
Browse files

Merge branch 'release/2.5.5' into 'Support/2.5.X'

Release/2.5.5

See merge request !499
parents 8d312fa3 df900de2
Pipeline #8230 failed with stage
# CHANGELOG
## Version 2.5.5
- `Fixed` Rétablissement du changement de mot de passe pour les nouveaux utilisateurs.
- `Added` Ajout de la directive LAABS_SESSION_START dans le fichier vhost par défaut empêchant la création d'une session sur le serveur.
- `Added` Ajout de la directive LAABS_SECURE_COOKIE dans le fichier vhost par défaut permettant d'ajouter l'attribut secure aux cookies dans le cas d'une instance en HTTPS.
- `Fixed` Retrait de certaines données sensibles dans les données retournées par l'application.
- `Added` Ajout de l'attribut "HttpOnly" sur le cookie CSRF.
- `Fixed` Désactivation de l'autocomplete sur les formulaires contenant des mots de passe.
## Version 2.5.4
- `Fixed` Correction faille de sécurité concernant le vol de compte via l'interface de login
......
# Migration 2.5.x vers 2.5.5
## Configuration virtual host
Ajout de 2 directives concernant la sécurité dans le fichier vhost.conf.default :
*LAABS_SESSION_START* --> "Off" par défaut. Permet de ne pas créer de fichier de session inutile sur le serveur.
*LAABS_SECURE_COOKIE* --> désactivé par défaut. Permet d'ajouter l'attribut "secure" sur les cookies dans le cas d'une instance publiée en HTTPS.
# Migration 2.4 vers 2.5
## Présentation et fonctionnalités orientées "archives publiques"
......
......@@ -94,7 +94,9 @@ class laabs
static::preload();
// Start session
\core\Globals\Session::start();
if (isset($_SERVER['LAABS_SESSION_START']) && $_SERVER['LAABS_SESSION_START'] == 'On') {
\core\Globals\Session::start();
}
// Start cache strategies
if (($memcacheServer = \laabs::getMemCacheServer()) && !empty(static::$instance)) {
......@@ -943,7 +945,9 @@ class laabs
$cryptedToken = static::encrypt($jsonToken, static::getCryptKey());
$cookieToken = base64_encode($cryptedToken);
setcookie($cookieName, $cookieToken, $expirationTime, '/', null, false, $httpOnly);
$secure = (isset($_SERVER['LAABS_SECURE_COOKIE']) && $_SERVER['LAABS_SECURE_COOKIE'] == "On");
setcookie($cookieName, $cookieToken, $expirationTime, '/', null, $secure, $httpOnly);
$GLOBALS["TOKEN"][$name] = json_decode($jsonToken);
......
......@@ -32,6 +32,8 @@
SetEnv LAABS_DEPENDENCIES repository;xml;html;localisation;datasource;sdo;json;fileSystem;notification;PDF;csrf;timestamp
SetEnv LAABS_PRESENTATION maarchRM
SetEnv SERVICE_CLIENT_TOKEN service
SetEnv LAABS_SESSION_START Off
#SetEnv LAABS_SECURE_COOKIE On
SetEnv LAABS_CONFIGURATION "../data/maarchRM/conf/configuration.ini"
SetEnv LAABS_LOG "../data/maarchRM/log.txt"
......
......@@ -123,6 +123,26 @@ class userAccount
}
$userAccounts = $this->sdoFactory->find('auth/account', \laabs\implode(" AND ", $queryAssert));
return $this->removeSensibleData($userAccounts);
}
/**
* Remove sensible data from an array of users
*
* @param array $userAccounts Array of user Accounts
*
* @return array Array of userAccounts removed of sensible data
*/
protected function removeSensibleData($userAccounts)
{
foreach ($userAccounts as $key => $user) {
unset($userAccounts[$key]->password);
unset($userAccounts[$key]->replacingUserAccountId);
unset($userAccounts[$key]->salt);
unset($userAccounts[$key]->tokenDate);
unset($userAccounts[$key]->lastIp);
}
return $userAccounts;
}
......
......@@ -184,8 +184,13 @@ class userAuthentication
{
$tempToken = \laabs::getToken('TEMP-AUTH');
if ($this->sdoFactory->exists('auth/account', array('accountName' => $userName))) {
$userAccount = $this->sdoFactory->read('auth/account', array('accountName' => $userName));
} else {
return false;
}
if ($this->sdoFactory->exists('auth/account', array('accountName' => $userName))
&& $userAccount = $this->sdoFactory->read('auth/account', array('accountName' => $userName))
&& !is_null($tempToken)
&& $tempToken->accountId == $userAccount->accountId) {
......
......@@ -128,7 +128,7 @@ class csrf
$responseToken = $this->getLastToken($accountTokens);
\laabs::setToken($this->config["cookieName"], $responseToken, null, false);
\laabs::setToken($this->config["cookieName"], $responseToken, null, true);
}
/**
......
<div class="modal fade" id="disableUserModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Disable user</h4>
</div>
<div class="modal-body">
<p>
You are about to disable this user. Please chose a replacing user to complete this action.
</p>
<input type="text" class="form-control" placeholder="User" id="replacingUser" data-replacinguseraccountid=""/>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" id="cancelDisabling" data-dismiss="modal" title="Close">Cancel</button>
<button type="button" class="btn btn-danger" id="confirmDisabling" data-accountid="[?merge user.accountId ?]" title="Ok">Disabled</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="enableUserModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Enable user</h4>
</div>
<div class="modal-body">
<p>
Are you sure to reactive this user ?
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" id="cancelEnabling" data-dismiss="modal" title="Close">Close</button>
<button type="button" class="btn btn-primary" id="confirmEnabling" data-accountid="[?merge user.accountId ?]" title="Yes">Yes</button>
</div>
</div>
</div>
</div>
<span class="hide" id="no_user_found_text">No user found</span>
<script >
$('#app_maarchRM_main').ready(function(){
// Define data source for person typeahead
var users = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('displayName'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {url: '/user/todisplay', ttl: '0'},
limit: 100
});
users.initialize();
// initialize typeahead
$('#replacingUser').typeahead(
{
hint: true,
highlight: true,
minLength: 3
},
// data source contacts
{
name: 'users',
displayKey: 'displayName',
templates: {
empty: function() {
return "<span class='well well-sm'>"+$('#no_user_found_text').text()+"</span>";
},
suggestion: function(user) {
var display =
"<span>"
+ "<span style='font-family:Helvetica, sans-serif;'>"
+ user.displayName;
display +=
"</span>";
display +=
"</span><br>";
$("#replacingUser").attr('data-replacinguseraccountid', user.accountId);
return display;
}
},
source: function(query, cb) {
users.search(query, function(suggestions) {
cb(suggestions);
});
},
skipCache: true
}
).on('typeahead:selected', function($event, suggestion, source) {
$("#replacingUser").attr('data-replacinguseraccountid', suggestion.userAccountId);
});
})
$('#cancelEnabling').on('click', function(){
$('#enableUser').removeClass('active').find('input').prop('checked', false);
$('#disableUser').addClass('active').find('input').prop('checked', true);
});
$('#confirmDisabling').on('click', function(){
replacingUserId = $("#replacingUser").data('replacinguseraccountid');
userAccountId = $(this).attr('data-accountid');
var parameters = {
replacingUserAccountId :replacingUserId
};
ajax($('#confirmDisabling'), {
url : '/useraccount/'+userAccountId+'/disable',
type : 'PUT',
data : JSON.stringify(parameters),
contentType : 'application/json',
dataType : 'json',
success : function(response) {
var tr = $('#'+userAccountId);
gritter.show(response.message, response.status, response.errors);
$('#disableUserModal').modal('hide');
if ($('#activatedUsers').prop('checked')) {
window.location.reload();
return;
}
tr.find('.userStatus > i').removeClass('fa-check').addClass('fa-ban');
tr.find('.disableUser').css('display', 'none');
tr.find('.enableUser').css('display', '');
},
error : function(response) {
gritter.show(response.responseJSON.message, response.responseJSON.status, response.responseJSON.errors);
}
});
});
$('#cancelDisabling').on('click', function(){
$('#enableUser').addClass('active').find('input').prop('checked', true);
$('#disableUser').removeClass('active').find('input').prop('checked', false);
});
$('#confirmEnabling').on('click', function(){
userAccountId = $(this).attr('data-accountid');
var parameters = {
user : userAccountId
};
$.ajax({
url : '/useraccount/'+userAccountId+'/enable',
type : 'PUT',
contentType : 'application/json',
data : JSON.stringify(parameters),
dataType : 'json',
success : function(response) {
var tr = $('#'+userAccountId);
gritter.show(response.message, response.status, response.errors);
$('#enableUserModal').modal('hide');
tr.find('.userStatus > i').removeClass('fa-ban').addClass('fa-check');
tr.find('.disableUser').css('display', '');
tr.find('.enableUser').css('display', 'none');
},
error : function(response) {
gritter.show(response.responseJSON.message, response.responseJSON.status, response.responseJSON.errors);
}
});
$('#orgUnitConfirmDelete').modal('hide');
});
</script>
\ No newline at end of file
......@@ -38,11 +38,11 @@
</div>
<div class="form-group">
<label>New password</label>
<input type="password" class="form-control" name="newPassword" placeholder="New password">
<input type="password" class="form-control" name="newPassword" placeholder="New password" autocomplete="off">
</div>
<div class="form-group">
<label>Confirm password</label>
<input type="password" class="form-control" name="confirmPassword" placeholder="Confirm password">
<input type="password" class="form-control" name="confirmPassword" placeholder="Confirm password" autocomplete="off">
</div>
<button class="btn btn-success" id="user_newPassword" type="button" data-useraccountid="[?merge user.accountId ?]" title="Ok"><i class="fa fa-check">&nbsp;</i>OK</button>
</div>
......
......@@ -48,11 +48,19 @@ interface auditInterface
*/
public function readEvents($eventType = null, $fromDate = null, $toDate = null, $accountId = null, $event = null, $status = null, $term = null, $wording = null);
/**
/**
* Get event
*
* @uses audit/event/read_eventId_
* @return audit/event/getEvent
*/
public function readEvent_eventId_();
}
\ No newline at end of file
/**
* List all users to display
*
* @uses auth/userAccount/readUserlist
*/
public function readUserTodisplay();
}
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