Skip to content
Snippets Groups Projects
Verified Commit ed2ae217 authored by Damien's avatar Damien
Browse files

FEAT #8188 Check rest side if user can access route + spinner

parent 2d08b91b
No related branches found
No related tags found
No related merge requests found
......@@ -181,12 +181,13 @@ if (isset($_REQUEST['display'])) {
if (empty($_REQUEST['triggerAngular'])) {
if ($_REQUEST['page'] != 'login' && $_REQUEST['page'] != 'log' && $_REQUEST['page'] != 'logout' && !empty($_SESSION['user']['UserId'])) {
$user = \User\models\UserModel::getByUserId(['userId' => $_SESSION['user']['UserId'], 'select' => ['password_modification_date', 'change_password', 'status']]);
$loggingMethod = \SrcCore\models\CoreConfigModel::getLoggingMethod();
if ($user['status'] == 'ABS') {
header('location: '.$_SESSION['config']['businessappurl'].'index.php?triggerAngular=activateUser');
exit();
}
$loggingMethod = \SrcCore\models\CoreConfigModel::getLoggingMethod();
if (!in_array($loggingMethod['id'], ['sso', 'cas', 'ldap', 'ozwillo'])) {
$passwordRules = \SrcCore\models\PasswordModel::getEnabledRules();
if ($user['change_password'] == 'Y') {
......@@ -362,6 +363,7 @@ if (file_exists($path)) {
$core->insert_page();
}
?>
<div id="loadingContent"></div>
<my-app></my-app>
</div>
<p id="footer">
......
......@@ -18,38 +18,41 @@ declare var angularGlobals: any;
})
export class PasswordModificationComponent implements OnInit {
private _mobileQueryListener: () => void;
mobileQuery: MediaQueryList;
private _mobileQueryListener : () => void;
mobileQuery : MediaQueryList;
dialogRef : MatDialogRef<any>;
config : any = {};
coreUrl: string;
ruleText: string = '';
otherRuleText: string;
lang: any = LANG;
loading: boolean = false;
user: any = {};
hidePassword: Boolean = true;
passLength: any = false;
passwordRules: any = {
minLength: { enabled: false, value: 0 },
complexityUpper: { enabled: false, value: 0 },
complexityNumber: { enabled: false, value: 0 },
complexitySpecial: { enabled: false, value: 0 },
renewal: { enabled: false, value: 0 },
historyLastUse: {enabled:false, value:0},
coreUrl : string;
lang : any = LANG;
loading : boolean = false;
user : any = {};
ruleText : string = '';
otherRuleText : string;
hidePassword : boolean = true;
passLength : any = false;
arrValidator : any[] = [];
validPassword : boolean = false;
matchPassword : boolean = false;
isLinear : boolean = false;
firstFormGroup : FormGroup;
passwordRules : any = {
minLength : { enabled: false, value: 0 },
complexityUpper : { enabled: false, value: 0 },
complexityNumber : { enabled: false, value: 0 },
complexitySpecial : { enabled: false, value: 0 },
renewal : { enabled: false, value: 0 },
historyLastUse : { enabled: false, value: 0 },
};
passwordModel: any = {
currentPassword: "",
newPassword: "",
reNewPassword: "",
passwordModel : any = {
currentPassword : "",
newPassword : "",
reNewPassword : "",
};
arrValidator: any[] = [];
validPassword: Boolean = false;
matchPassword: Boolean = false;
isLinear = false;
firstFormGroup: FormGroup;
constructor(changeDetectorRef: ChangeDetectorRef, media: MediaMatcher, public http: HttpClient, private notify: NotificationService, private _formBuilder: FormBuilder, public dialog: MatDialog) {
$j("link[href='merged_css.php']").remove();
......@@ -59,19 +62,8 @@ export class PasswordModificationComponent implements OnInit {
this.user = angularGlobals.user;
}
regexValidator(regex: RegExp, error: ValidationErrors): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } => {
if (!control.value) {
return null;
}
const valid = regex.test(control.value);
return valid ? null : error;
};
}
prepare() {
$j("link[href='merged_css.php']").remove();
//$j('#header').remove();
$j('#footer').remove();
$j('#inner_content').remove();
$j('#inner_content_contact').parent('div').remove();
......@@ -104,28 +96,20 @@ export class PasswordModificationComponent implements OnInit {
valArr.push(Validators.required);
data.rules.forEach((rule: any) => {
if (rule.label == 'minLength') {
this.passwordRules.minLength.enabled = rule.enabled;
this.passwordRules.minLength.value = rule.value;
if (rule.enabled) {
valArr.push(Validators.minLength(this.passwordRules.minLength.value));
ruleTextArr.push(rule.value + ' ' + this.lang['password' + rule.label]);
}
} else if (rule.label == 'complexityUpper') {
this.passwordRules.complexityUpper.enabled = rule.enabled;
this.passwordRules.complexityUpper.value = rule.value;
if (rule.enabled) {
valArr.push(this.regexValidator(new RegExp('[A-Z]'), { 'complexityUpper': '' }));
ruleTextArr.push(this.lang['password' + rule.label]);
}
} else if (rule.label == 'complexityNumber') {
this.passwordRules.complexityNumber.enabled = rule.enabled;
this.passwordRules.complexityNumber.value = rule.value;
......@@ -133,18 +117,13 @@ export class PasswordModificationComponent implements OnInit {
valArr.push(this.regexValidator(new RegExp('[0-9]'), { 'complexityNumber': '' }));
ruleTextArr.push(this.lang['password' + rule.label]);
}
} else if (rule.label == 'complexitySpecial') {
this.passwordRules.complexitySpecial.enabled = rule.enabled;
this.passwordRules.complexitySpecial.value = rule.value;
if (rule.enabled) {
valArr.push(this.regexValidator(new RegExp('[^A-Za-z0-9]'), { 'complexitySpecial': '' }));
ruleTextArr.push(this.lang['password' + rule.label]);
}
} else if (rule.label == 'renewal') {
this.passwordRules.renewal.enabled = rule.enabled;
this.passwordRules.renewal.value = rule.value;
......@@ -178,18 +157,26 @@ export class PasswordModificationComponent implements OnInit {
'',
Validators.compose([Validators.required])
]
}, {
validator: this.matchValidator
});
validator: this.matchValidator
});
}
matchValidator(group: FormGroup) {
regexValidator(regex: RegExp, error: ValidationErrors): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } => {
if (!control.value) {
return null;
}
const valid = regex.test(control.value);
return valid ? null : error;
};
}
matchValidator(group: FormGroup) {
if (group.controls['newPasswordCtrl'].value == group.controls['retypePasswordCtrl'].value) {
return false;
} else {
group.controls['retypePasswordCtrl'].setErrors({'mismatch': true})
group.controls['retypePasswordCtrl'].setErrors({'mismatch': true});
return {'mismatch': true};
}
}
......@@ -202,21 +189,16 @@ export class PasswordModificationComponent implements OnInit {
}
if (this.firstFormGroup.controls['newPasswordCtrl'].hasError('required')) {
return this.lang.requiredField + ' !';
} else if (this.firstFormGroup.controls['newPasswordCtrl'].hasError('minlength') && this.passwordRules.minLength.enabled) {
return this.passwordRules.minLength.value + ' ' + this.lang.passwordminLength + ' !';
} else if (this.firstFormGroup.controls['newPasswordCtrl'].errors != null && this.firstFormGroup.controls['newPasswordCtrl'].errors.complexityUpper !== undefined && this.passwordRules.complexityUpper.enabled) {
return this.lang.passwordcomplexityUpper + ' !';
} else if (this.firstFormGroup.controls['newPasswordCtrl'].errors != null && this.firstFormGroup.controls['newPasswordCtrl'].errors.complexityNumber !== undefined && this.passwordRules.complexityNumber.enabled) {
return this.lang.passwordcomplexityNumber + ' !';
} else if (this.firstFormGroup.controls['newPasswordCtrl'].errors != null && this.firstFormGroup.controls['newPasswordCtrl'].errors.complexitySpecial !== undefined && this.passwordRules.complexitySpecial.enabled) {
return this.lang.passwordcomplexitySpecial + ' !';
} else {
this.firstFormGroup.controls['newPasswordCtrl'].setErrors(null)
this.firstFormGroup.controls['newPasswordCtrl'].setErrors(null);
this.validPassword = true;
return '';
}
......@@ -227,7 +209,7 @@ export class PasswordModificationComponent implements OnInit {
this.passwordModel.newPassword = this.firstFormGroup.controls['newPasswordCtrl'].value;
this.passwordModel.reNewPassword = this.firstFormGroup.controls['retypePasswordCtrl'].value;
this.http.put(this.coreUrl + "rest/currentUser/password", this.passwordModel)
.subscribe((data: any) => {
.subscribe(() => {
this.config = {data:{state:'END'},disableClose: true};
this.dialogRef = this.dialog.open(InfoChangePasswordModalComponent, this.config);
}, (err: any) => {
......@@ -244,7 +226,8 @@ export class PasswordModificationComponent implements OnInit {
templateUrl: "../../../Views/info-change-password-modal.component.html"
})
export class InfoChangePasswordModalComponent {
lang: any = LANG;
lang : any = LANG;
constructor(public http: HttpClient, @Inject(MAT_DIALOG_DATA) public data: any, public dialogRef: MatDialogRef<InfoChangePasswordModalComponent>) {
}
......
......@@ -8,7 +8,11 @@ function triggerAngular(locationToGo) {
success: function(answer) {
angularGlobals = answer;
$j('#inner_content').html('<i class="fa fa-spinner fa-spin fa-5x" style="margin-left: 50%;margin-top: 16%;font-size: 8em"></i>');
if ($j('#inner_content').length > 0) {
$j('#inner_content').html('<i class="fa fa-spinner fa-spin fa-5x" style="margin-left: 50%;margin-top: 16%;font-size: 8em"></i>');
} else {
$j('#loadingContent').html('<i class="fa fa-spinner fa-spin fa-5x" style="margin-left: 50%;margin-top: 16%;font-size: 8em"></i>');
}
if (!alreadyLoaded) {
var head = document.getElementsByTagName('head')[0];
......@@ -50,20 +54,6 @@ function changeLocationToAngular(locationToGo) {
location.href = locationToGo;
}
function successNotification(message) {
$j('#resultInfo').html(message).removeClass().addClass('alert alert-success alert-dismissible');
$j("#resultInfo").fadeTo(3000, 500).slideUp(500, function() {
$j("#resultInfo").slideUp(500);
});
}
function errorNotification(message) {
$j('#resultInfo').html(message).removeClass().addClass('alert alert-danger alert-dismissible');
$j("#resultInfo").fadeTo(3000, 500).slideUp(500, function() {
$j("#resultInfo").slideUp(500);
});
}
function lockDocument(resId) {
$j.ajax({
url: 'index.php?display=true&dir=actions&page=docLocker',
......
......@@ -34,6 +34,14 @@ $app->add(function (\Slim\Http\Request $request, \Slim\Http\Response $response,
if (!empty($userId)) {
$GLOBALS['userId'] = $userId;
$route = $request->getAttribute('route');
if (!empty($route)) {
$currentRoute = $route->getPattern();
$r = \SrcCore\controllers\AuthenticationController::isRouteAvailable(['userId' => $userId, 'currentRoute' => $currentRoute]);
if (!$r['isRouteAvailable']) {
return $response->withStatus(405)->withJson(['errors' => $r['errors']]);
}
}
$response = $next($request, $response);
return $response;
} else {
......
......@@ -431,6 +431,9 @@ class UserController
}
$user = UserModel::getByUserId(['userId' => $aArgs['userId'], 'select' => ['status']]);
if (empty($user)) {
return $response->withStatus(400)->withJson(['errors' => 'User does not exist']);
}
return $response->withJson(['status' => $user['status']]);
}
......
......@@ -15,6 +15,7 @@
namespace SrcCore\controllers;
use SrcCore\models\AuthenticationModel;
use SrcCore\models\CoreConfigModel;
use SrcCore\models\PasswordModel;
use SrcCore\models\ValidatorModel;
use User\models\UserModel;
......@@ -39,6 +40,42 @@ class AuthenticationController
return $userId;
}
public static function isRouteAvailable(array $aArgs)
{
ValidatorModel::notEmpty($aArgs, ['userId', 'currentRoute']);
ValidatorModel::stringType($aArgs, ['userId', 'currentRoute']);
if ($aArgs['currentRoute'] != '/initialize') {
$user = UserModel::getByUserId(['select' => ['status', 'change_password'], 'userId' => $aArgs['userId']]);
if ($user['status'] == 'ABS' && $aArgs['currentRoute'] != "/users/{id}/status") {
return ['isRouteAvailable' => false, 'errors' => 'User is ABS and must be activated'];
}
if (!in_array($aArgs['currentRoute'], ['/passwordRules', '/currentUser/password'])) {
$loggingMethod = CoreConfigModel::getLoggingMethod();
if (!in_array($loggingMethod['id'], ['sso', 'cas', 'ldap', 'ozwillo'])) {
$passwordRules = PasswordModel::getEnabledRules();
if ($user['change_password'] == 'Y') {
return ['isRouteAvailable' => false, 'errors' => 'User must change his password'];
} elseif (!empty($passwordRules['renewal'])) {
$currentDate = new \DateTime();
$lastModificationDate = new \DateTime($user['password_modification_date']);
$lastModificationDate->add(new \DateInterval("P{$passwordRules['renewal']}D"));
if ($currentDate > $lastModificationDate) {
return ['isRouteAvailable' => false, 'errors' => 'User must change his password'];
}
}
}
}
}
return ['isRouteAvailable' => true];
}
public static function handleFailedAuthentication(array $aArgs)
{
ValidatorModel::notEmpty($aArgs, ['userId']);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment