Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Commit 7d60586b authored by Sebastian-Ion TINCU's avatar Sebastian-Ion TINCU
Browse files

EDELIVERY-3687 SMP UI Add/Edit user

Add missing validators.
Fix bindings for the user's certificate.
parent 3826fa55
No related branches found
No related tags found
No related merge requests found
......@@ -14,3 +14,13 @@
.certificate-valid-from, .certificate-valid-until {
width: 40%;
}
.required-fields {
text-align: right;
font-size: 70%
}
.has-error {
color:red;
font-size: 70%;
}
......@@ -2,26 +2,28 @@
<mat-dialog-content>
<mat-card>
<mat-card-content>
<mat-slide-toggle mat-no-ink class="mat-primary" [checked]="userForm.get('userName')?.value" (change)="onUserToggleChanged($event)">
<mat-slide-toggle mat-no-ink class="mat-primary" [formControl]="userForm.controls['userToggle']" (change)="onUserToggleChanged($event)">
User Details
</mat-slide-toggle>
<div *ngIf="userForm.errors?.userDetailsOrCertificateRequired && (userForm.get('userToggle').dirty || userForm.get('certificateToggle').dirty)" class="has-error">You need to enter at least the details or the certificate for this user</div>
<div class="panel">
<mat-form-field class="username">
<input matInput placeholder="Username" [formControl]="userForm.controls['userName']" maxlength="255" required>
<div *ngIf="userForm.controls['userName'].hasError('required') && userForm.controls['userName'].touched" style="color:red; font-size: 70%">You should type an username</div>
<div *ngIf="userForm.controls['userName'].hasError('required') && userForm.controls['userName'].touched" class="has-error">You should type an username</div>
</mat-form-field>
<mat-form-field class="role">
<mat-select matInput placeholder="Role" class="role" [formControl]="userForm.controls['role']" required>
<mat-option *ngFor="let item of existingRoles" [value]="item">{{item}}</mat-option>
</mat-select>
<div *ngIf="userForm.controls['role'].hasError('required') && userForm.controls['role'].touched" style="color:red; font-size: 70%">You need to choose at least one role for this user</div>
<div *ngIf="userForm.controls['role'].hasError('required') && userForm.controls['role'].touched" class="has-error">You need to choose at least one role for this user</div>
</mat-form-field>
<mat-form-field class="password">
<input matInput placeholder="Password" type="password" [formControl]="userForm.controls['password']" [pattern]="passwordPattern" [required]="!editMode">
<div *ngIf="!editMode && userForm.controls['password'].hasError('required') && userForm.controls['password'].touched" style="color:red; font-size: 70%">You should type a password</div>
<div *ngIf="userForm.controls['password'].dirty && userForm.controls['password'].hasError('pattern') && userForm.controls['password'].touched" style="color:red; font-size: 70%">
<div *ngIf="!editMode && userForm.controls['password'].hasError('required') && userForm.controls['password'].touched" class="has-error">You should type a password</div>
<div *ngIf="userForm.controls['password'].dirty && userForm.controls['password'].hasError('pattern') && userForm.controls['password'].touched" class="has-error">
Password should follow all of these rules:<br>
- Minimum length: 8 characters<br>
- Maximum length: 32 characters<br>
......@@ -34,14 +36,17 @@
<mat-form-field class="password-confirmation">
<input matInput placeholder="Confirmation" type="password" [formControl]="userForm.controls['confirmation']" [required]="!editMode">
<div *ngIf="!editMode && userForm.controls['confirmation'].hasError('required') && userForm.controls['confirmation'].touched" style="color:red; font-size: 70%">You should type a password</div>
<div *ngIf="userForm.errors?.confirmation && userForm.controls['confirmation'].touched" style="color:red; font-size: 70%">Passwords do not match</div>
<div *ngIf="!editMode && userForm.controls['confirmation'].hasError('required') && userForm.controls['confirmation'].touched" class="has-error">You should type a password</div>
<div *ngIf="userForm.errors?.confirmationMatch && userForm.controls['confirmation'].touched" class="has-error">Passwords do not match</div>
</mat-form-field>
</div>
<mat-slide-toggle #certificateToggle mat-no-ink class="mat-primary" [checked]="userForm.get('certificate')?.value">
<mat-slide-toggle mat-no-ink class="mat-primary" [formControl]="userForm.controls['certificateToggle']">
Certificate
</mat-slide-toggle>
<div *ngIf="userForm.errors?.userDetailsOrCertificateRequired && (userForm.get('userToggle').dirty || userForm.get('certificateToggle').dirty)" class="has-error">You need to enter at least the details or the certificate for this user</div>
<div *ngIf="userForm.errors?.certificateDetailsRequired && userForm.get('certificateToggle').touched" class="has-error">All the certificate fields are required so please upload a new certificate</div>
<div class="panel">
<mat-form-field class="certificate-subject">
<input matInput placeholder="Subject Name" [formControl]="userForm.controls['subject']">
......@@ -60,8 +65,8 @@
</mat-form-field>
<label class="custom-file-upload">
<input #fileInput type="file" id="custom-file-upload" accept=".cer" (change)="uploadCertificate()" [disabled]="!certificateToggle.checked">
<button mat-flat-button color="primary" (click)="fileInput.click()" [disabled]="!certificateToggle.checked">Import</button>
<input #fileInput type="file" id="custom-file-upload" accept=".cer" (change)="uploadCertificate()" [disabled]="!userForm.controls['certificateToggle']?.value">
<button mat-flat-button color="primary" (click)="fileInput.click()" [disabled]="!userForm.controls['certificateToggle']?.value">Import</button>
</label>
</div>
</mat-card-content>
......@@ -82,5 +87,5 @@
</td>
</tr>
</table>
<div style="text-align: right; font-size: 70%">* required fields</div>
<div class="required-fields">* required fields</div>
import {Component, Inject, ViewChild} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef, MatSlideToggleChange} from '@angular/material';
import {MAT_DIALOG_DATA, MatDialogRef, MatSlideToggle, MatSlideToggleChange} from '@angular/material';
import {FormBuilder, FormControl, FormGroup, ValidationErrors, ValidatorFn, Validators} from '@angular/forms';
import {UserService} from '../user.service';
import {Role} from '../../security/role.model';
......@@ -30,16 +30,31 @@ export class UserDetailsDialogComponent {
existingRoles = [];
userForm: FormGroup;
userSwitch: boolean;
certificateSwitch: boolean;
@ViewChild('fileInput')
private fileInput;
private passwordConfirmationValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
const userToggle = control.get('userToggle');
const password = control.get('password');
const confirmation = control.get('confirmation');
return password && confirmation && password.value !== confirmation.value ? { confirmation: true } : null;
return userToggle && password && confirmation && userToggle.value && password.value !== confirmation.value ? { confirmationMatch: true } : null;
};
private atLeastOneToggleCheckedValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
const userToggle = control.get('userToggle');
const certificateToggle = control.get('certificateToggle');
return userToggle && certificateToggle && !userToggle.value && !certificateToggle.value ? { userDetailsOrCertificateRequired: true} : null;
};
private certificateValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
const certificateToggle = control.get('certificateToggle');
const subject = control.get('subject');
const validFrom = control.get('validFrom');
const validUntil = control.get('validUntil');
const issuer = control.get('issuer');
const fingerprints = control.get('fingerprints');
return certificateToggle && subject && validFrom && validUntil && issuer && fingerprints
&& certificateToggle.value && !(subject.value && validFrom.value && validUntil.value && issuer.value && fingerprints.value) ? { certificateDetailsRequired: true} : null;
};
constructor(private dialogRef: MatDialogRef<UserDetailsDialogComponent>,
......@@ -57,9 +72,14 @@ export class UserDetailsDialogComponent {
...data.row,
password: '', // ensures the user password is cleared before editing
confirmation: '',
certificate: data.row.certificate || {},
}
: {
certificate: {
subject: data.row.subject,
validFrom: data.row.validFrom,
validUntil: data.row.validUntil,
issuer: data.row.issuer,
fingerprints: data.row.fingerprints,
}
}: {
userName: '',
email: '',
password: '',
......@@ -69,19 +89,23 @@ export class UserDetailsDialogComponent {
certificate: {},
};
const userDetailsToggled: boolean = user && !!user.userName;
this.userForm = fb.group({
'userName': new FormControl({value: user.userName, disabled: this.editMode}, this.editMode ? Validators.nullValidator : null),
'role': new FormControl(user.role, Validators.required),
'password': new FormControl(user.password, [Validators.required, Validators.pattern(this.passwordPattern)]),
'confirmation': new FormControl(user.password, Validators.pattern(this.passwordPattern)),
'subject': new FormControl({ value: user.certificate.subject, disabled: true }),
'validFrom': new FormControl({ value: user.certificate.validFrom, disabled: true }),
'validUntil': new FormControl({ value: user.certificate.validUntil, disabled: true }),
'issuer': new FormControl({ value: user.certificate.issuer, disabled: true }),
'fingerprints': new FormControl({ value: user.certificate.fingerprints, disabled: true }),
'userToggle': new FormControl(userDetailsToggled),
'userName': new FormControl({ value: user.userName, disabled: this.editMode || !userDetailsToggled }, this.editMode ? Validators.nullValidator : null),
'role': new FormControl({ value: user.role, disabled: !userDetailsToggled }, Validators.required),
'password': new FormControl({ value: user.password, disabled: !userDetailsToggled }, [Validators.required, Validators.pattern(this.passwordPattern)]),
'confirmation': new FormControl({ value: user.password, disabled: !userDetailsToggled }, Validators.pattern(this.passwordPattern)),
'certificateToggle': new FormControl(user && user.certificate && !!user.certificate.subject),
'subject': new FormControl({ value: user.certificate.subject, disabled: true }, Validators.required),
'validFrom': new FormControl({ value: user.certificate.validFrom, disabled: true }, Validators.required),
'validUntil': new FormControl({ value: user.certificate.validUntil, disabled: true }, Validators.required),
'issuer': new FormControl({ value: user.certificate.issuer, disabled: true }, Validators.required),
'fingerprints': new FormControl({ value: user.certificate.fingerprints, disabled: true }, Validators.required),
}, {
validator: this.passwordConfirmationValidator
validator: [this.passwordConfirmationValidator, this.atLeastOneToggleCheckedValidator, this.certificateValidator]
});
this.userService.getUserRoles$().subscribe(userRoles => {
......@@ -115,7 +139,7 @@ export class UserDetailsDialogComponent {
'validFrom': this.datePipe.transform(new Date().toString(), this.dateFormat),
'validUntil': this.datePipe.transform(new Date().toString(), this.dateFormat),
'issuer': 'issues',
'fingerprints': 'fingerprints',
'fingerprints': 'fingerprints'
});
// },
// err => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment