From 2d9ffb3483a058bd1e022a9644e6861c4f786ecc Mon Sep 17 00:00:00 2001 From: Alex ORLUC <alex.orluc@maarch.org> Date: Thu, 22 Oct 2020 11:53:31 +0200 Subject: [PATCH] FEAT #13268 TIME 1:50 front admin sso --- .../administration-routing.module.ts | 4 +- .../administration/administration.module.ts | 2 - .../sso/sso-administration.component.html | 43 ++++--- .../sso/sso-administration.component.ts | 110 +++++++++++++----- .../sso-list-administration.component.html | 86 -------------- .../sso-list-administration.component.scss | 7 -- .../sso/sso-list-administration.component.ts | 88 -------------- src/lang/lang-fr.json | 8 +- 8 files changed, 114 insertions(+), 234 deletions(-) delete mode 100644 src/frontend/app/administration/connection/sso/sso-list-administration.component.html delete mode 100644 src/frontend/app/administration/connection/sso/sso-list-administration.component.scss delete mode 100644 src/frontend/app/administration/connection/sso/sso-list-administration.component.ts diff --git a/src/frontend/app/administration/administration-routing.module.ts b/src/frontend/app/administration/administration-routing.module.ts index 5109ac994b5..55a4988ca79 100755 --- a/src/frontend/app/administration/administration-routing.module.ts +++ b/src/frontend/app/administration/administration-routing.module.ts @@ -54,7 +54,6 @@ import { IssuingSiteComponent } from './registered-mail/issuing-site/issuing-sit import { RegisteredMailListComponent } from './registered-mail/registered-mail-list.component'; import { RegisteredMailComponent } from './registered-mail/registered-mail.component'; import { SearchAdministrationComponent } from './search/search-administration.component'; -import { SsoListAdministrationComponent } from './connection/sso/sso-list-administration.component'; import { SsoAdministrationComponent } from './connection/sso/sso-administration.component'; @@ -132,8 +131,7 @@ import { SsoAdministrationComponent } from './connection/sso/sso-administration. { path: 'administration/issuingSites/new', canActivate: [AppGuard], component: IssuingSiteComponent }, { path: 'administration/issuingSites/:id', canActivate: [AppGuard], component: IssuingSiteComponent }, { path: 'administration/search', canActivate: [AppGuard], component: SearchAdministrationComponent }, - { path: 'administration/connections/sso', canActivate: [AppGuard], component: SsoListAdministrationComponent }, - { path: 'administration/connections/sso/:id', canActivate: [AppGuard], component: SsoAdministrationComponent } + { path: 'administration/connections/sso', canActivate: [AppGuard], component: SsoAdministrationComponent }, ]), ], exports: [ diff --git a/src/frontend/app/administration/administration.module.ts b/src/frontend/app/administration/administration.module.ts index dfa472061bb..7972f475719 100755 --- a/src/frontend/app/administration/administration.module.ts +++ b/src/frontend/app/administration/administration.module.ts @@ -75,7 +75,6 @@ import { IssuingSiteListComponent } from './registered-mail/issuing-site/issuing import { IssuingSiteComponent } from './registered-mail/issuing-site/issuing-site.component'; import { RegisteredMailListComponent } from './registered-mail/registered-mail-list.component'; import { SearchAdministrationComponent } from './search/search-administration.component'; -import { SsoListAdministrationComponent } from './connection/sso/sso-list-administration.component'; import { SsoAdministrationComponent } from './connection/sso/sso-administration.component'; @@ -161,7 +160,6 @@ import { SsoAdministrationComponent } from './connection/sso/sso-administration. IssuingSiteComponent, RegisteredMailListComponent, SearchAdministrationComponent, - SsoListAdministrationComponent, SsoAdministrationComponent ], entryComponents: [ diff --git a/src/frontend/app/administration/connection/sso/sso-administration.component.html b/src/frontend/app/administration/connection/sso/sso-administration.component.html index 472a354a3d6..e0bbb86ff50 100644 --- a/src/frontend/app/administration/connection/sso/sso-administration.component.html +++ b/src/frontend/app/administration/connection/sso/sso-administration.component.html @@ -28,26 +28,31 @@ <mat-spinner style="margin:auto;"></mat-spinner> </div> <mat-card *ngIf="!loading" class="card-app-content"> - <mat-form-field appearance="outline"> - <input matInput [placeholder]="'Url SSO'"> - </mat-form-field> - <mat-expansion-panel hideToggle> - <mat-expansion-panel-header> - <mat-panel-title color="primary"> - Interfaçage des en-têtes - </mat-panel-title> - </mat-expansion-panel-header> - <div class="row" style="margin:0px;"> - <div class="col-md-8"> - <mat-form-field *ngFor="let item of mapping"> - <input matInput [(ngModel)]="item.ssoId" [placeholder]="item.maarchId"> - </mat-form-field> - </div> - <div class="col-md-4"> - - </div> + <form style="display: contents;" (ngSubmit)="onSubmit()" #ssoForm="ngForm"> + <mat-form-field appearance="outline"> + <mat-label>{{'lang.ssoUrl' | translate}}</mat-label> + <input matInput name="ssoUrl" [(ngModel)]="sso.url"> + <mat-hint>{{'lang.ssoUrlDesc' | translate}}</mat-hint> + </mat-form-field> + <mat-expansion-panel expanded style="margin-top: 10px;"> + <mat-expansion-panel-header> + <mat-panel-title color="primary"> + {{'lang.mappingHeaders' | translate}} + </mat-panel-title> + </mat-expansion-panel-header> + <mat-form-field *ngFor="let item of sso.mapping;let i=index"> + <input matInput name="input_{{i}}" [(ngModel)]="item.ssoId" + [placeholder]="item.maarchId" required> + <mat-hint>{{item.desc | translate}}</mat-hint> + </mat-form-field> + </mat-expansion-panel> + <div class="text-center" style="padding:10px;"> + <button mat-raised-button [disabled]="!isValid(ssoForm)" + color="primary">{{'lang.validate' | translate}}</button> + <button mat-raised-button type="button" (click)="cancel()" [disabled]="!isValid(ssoForm)" + color="default">{{'lang.cancel' | translate}}</button> </div> - </mat-expansion-panel> + </form> </mat-card> </div> </div> diff --git a/src/frontend/app/administration/connection/sso/sso-administration.component.ts b/src/frontend/app/administration/connection/sso/sso-administration.component.ts index a394cf07f4d..e534e4efa91 100644 --- a/src/frontend/app/administration/connection/sso/sso-administration.component.ts +++ b/src/frontend/app/administration/connection/sso/sso-administration.component.ts @@ -1,11 +1,18 @@ import { HttpClient } from '@angular/common/http'; +import { ThrowStmt } from '@angular/compiler'; import { Component, OnInit, TemplateRef, ViewChild, ViewContainerRef } from '@angular/core'; +import { NgForm } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; import { TranslateService } from '@ngx-translate/core'; +import { ConfirmComponent } from '@plugins/modal/confirm.component'; import { AppService } from '@service/app.service'; +import { AuthService } from '@service/auth.service'; import { HeaderService } from '@service/header.service'; import { NotificationService } from '@service/notification/notification.service'; +import { of } from 'rxjs'; +import { catchError, exhaustMap, filter, tap } from 'rxjs/operators'; import { AdministrationService } from '../../administration.service'; @Component({ @@ -30,33 +37,18 @@ export class SsoAdministrationComponent implements OnInit { } ]; - mapping: any[] = [ - { - maarchId: 'userId', - ssoId: 'id', - separator: null - }, - { - maarchId: 'userName', - ssoId: 'uid', - separator: null - }, - { - maarchId: 'email', - ssoId: 'codeunite', - separator: null - }, - { - maarchId: 'groupId', - ssoId: 'qualification', - separator: ',' - }, - { - maarchId: 'entityId', - ssoId: 'departement_uid', - separator: ',' - }, - ]; + sso = { + url: '', + mapping: [ + { + maarchId: 'userId', + ssoId: 'id', + desc: 'lang.fieldUserIdDescSso' + } + ] + }; + + ssoClone: any; constructor( public translate: TranslateService, @@ -66,6 +58,8 @@ export class SsoAdministrationComponent implements OnInit { private headerService: HeaderService, private viewContainerRef: ViewContainerRef, public adminService: AdministrationService, + public dialog: MatDialog, + private authService: AuthService, ) { } ngOnInit(): void { @@ -75,7 +69,67 @@ export class SsoAdministrationComponent implements OnInit { } getConnection() { - this.loading = false; + this.http.get(`../rest/configurations/admin_sso`).pipe( + tap((data: any) => { + this.sso = data.configuration; + this.ssoClone = JSON.parse(JSON.stringify(this.sso)); + this.loading = false; + }), + catchError((err: any) => { + this.notify.handleSoftErrors(err); + return of(false); + }) + ).subscribe(); + } + + isValid(ssoForm: NgForm) { + return ssoForm.form.valid && JSON.stringify(this.sso) !== JSON.stringify(this.ssoClone); + } + + cancel() { + this.sso = JSON.parse(JSON.stringify(this.ssoClone)); + } + + formatData() { + const objTosend = JSON.parse(JSON.stringify(this.sso)); + + objTosend.mapping = objTosend.mapping.map(((item: any) => { + delete item.desc; + return item; + })); + + return objTosend; + } + + onSubmit() { + this.formatData(); + if (this.authService.authMode !== 'sso') { + const dialogRef = this.dialog.open(ConfirmComponent, { panelClass: 'maarch-modal', autoFocus: false, disableClose: true, data: { title: this.translate.instant('lang.warning') + ' !', msg: this.translate.instant('lang.warningConnectionMsg') } }); + + dialogRef.afterClosed().pipe( + filter((data: string) => data === 'ok'), + exhaustMap(() => this.http.put(`../rest/configurations/admin_sso`, this.formatData())), + tap(() => { + this.notify.success(this.translate.instant('lang.dataUpdated')); + this.ssoClone = JSON.parse(JSON.stringify(this.sso)); + }), + catchError((err: any) => { + this.notify.handleSoftErrors(err); + return of(false); + }) + ).subscribe(); + } else { + this.http.put(`../rest/configurations/admin_sso`, this.formatData()).pipe( + tap(() => { + this.notify.success(this.translate.instant('lang.dataUpdated')); + this.ssoClone = JSON.parse(JSON.stringify(this.sso)); + }), + catchError((err: any) => { + this.notify.handleSoftErrors(err); + return of(false); + }) + ).subscribe(); + } } } diff --git a/src/frontend/app/administration/connection/sso/sso-list-administration.component.html b/src/frontend/app/administration/connection/sso/sso-list-administration.component.html deleted file mode 100644 index 4b4388ffddb..00000000000 --- a/src/frontend/app/administration/connection/sso/sso-list-administration.component.html +++ /dev/null @@ -1,86 +0,0 @@ -<mat-sidenav-container autosize class="maarch-container"> - <ng-template #adminMenuTemplate> - <!--<mat-nav-list> - <h3 mat-subheader>{{'lang.actions' | translate}}</h3> - <a mat-list-item routerLink="/administration/connections/new"> - <mat-icon color="primary" mat-list-icon class="fa fa-plus"></mat-icon> - <p mat-line> - {{'lang.add' | translate}} - </p> - </a> - </mat-nav-list> - <mat-divider></mat-divider>--> - <mat-nav-list> - <a mat-list-item *ngFor="let menu of subMenus" [class.active]="menu.current" [routerLink]="menu.route"> - <mat-icon color="primary" mat-list-icon [class]="menu.icon"></mat-icon> - <p mat-line> - {{menu.label}} - </p> - </a> - </mat-nav-list> - </ng-template> - <mat-sidenav-content> - <div class="bg-head"> - <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> - <div class="bg-head-title-label"> - <header-left></header-left> - </div> - <div class="bg-head-title-tool"> - <header-right></header-right> - </div> - </div> - <div class="bg-head-content" [class.fullContainer]="appService.getViewMode()"> - </div> - </div> - <div class="container" [class.fullContainer]="appService.getViewMode()"> - <div class="container-content"> - <div *ngIf="loading" style="display:flex;height:100%;"> - <mat-spinner style="margin:auto;"></mat-spinner> - </div> - <mat-card *ngIf="!loading" class="card-app-content"> - <div class="row"> - <div class="col-md-6 col-xs-6"> - <mat-form-field> - <input matInput [formControl]="adminService.getFilterField()" placeholder="{{'lang.filterBy' | translate}}"> - </mat-form-field> - </div> - <div class="col-md-6 col-xs-6"> - <mat-paginator #paginator [length]="100" [hidePageSize]="true" [pageSize]="10"> - </mat-paginator> - </div> - </div> - <mat-table #table [dataSource]="adminService.getDataSource()" matSortDisableClear matSort> - <ng-container matColumnDef="id"> - <mat-header-cell *matHeaderCellDef mat-sort-header - [class.hide-for-mobile]="appService.getViewMode()" style="flex:2;">{{'lang.id' | translate}} - </mat-header-cell> - <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()" - style="flex:2;">{{element.id}}</mat-cell> - </ng-container> - <ng-container matColumnDef="label"> - <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:2;">{{'lang.description' | translate}} - </mat-header-cell> - <mat-cell *matCellDef="let element" style="flex:2;"> {{element.label}} </mat-cell> - </ng-container> - <ng-container matColumnDef="actions"> - <mat-header-cell *matHeaderCellDef></mat-header-cell> - <mat-cell *matCellDef="let element" style="justify-content: flex-end;"> - <button mat-icon-button color="warn" matTooltip="{{'lang.delete' | translate}}" - (click)="$event.stopPropagation();delete(element)"> - <mat-icon class="fa fa-trash-alt fa-2x" aria-hidden="true"></mat-icon> - </button> - </mat-cell> - </ng-container> - <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> - <mat-row *matRowDef="let row; columns: displayedColumns;" - routerLink="/administration/connections/sso/{{row.id}}" style="cursor:pointer;" - matTooltip="{{'lang.view' | translate}}"></mat-row> - </mat-table> - <div class="mat-paginator" - style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;"> - {{connections.length}} {{'lang.ssoConnections' | translate}}</div> - </mat-card> - </div> - </div> - </mat-sidenav-content> -</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/connection/sso/sso-list-administration.component.scss b/src/frontend/app/administration/connection/sso/sso-list-administration.component.scss deleted file mode 100644 index 00d1332cb41..00000000000 --- a/src/frontend/app/administration/connection/sso/sso-list-administration.component.scss +++ /dev/null @@ -1,7 +0,0 @@ -@import '../../../../css/vars.scss'; - -.active, .active:hover , .active:active, .active:focus { - color: $primary; - border-left: solid 5px $primary; - background: rgba($primary, 0.14); -} \ No newline at end of file diff --git a/src/frontend/app/administration/connection/sso/sso-list-administration.component.ts b/src/frontend/app/administration/connection/sso/sso-list-administration.component.ts deleted file mode 100644 index a258c3100a9..00000000000 --- a/src/frontend/app/administration/connection/sso/sso-list-administration.component.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { HttpClient } from '@angular/common/http'; -import { Component, OnInit, TemplateRef, ViewChild, ViewContainerRef } from '@angular/core'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import { TranslateService } from '@ngx-translate/core'; -import { AppService } from '@service/app.service'; -import { HeaderService } from '@service/header.service'; -import { NotificationService } from '@service/notification/notification.service'; -import { AdministrationService } from '../../administration.service'; - -@Component({ - selector: 'app-sso-list-administration', - templateUrl: './sso-list-administration.component.html', - styleUrls: ['./sso-list-administration.component.scss'] -}) -export class SsoListAdministrationComponent implements OnInit { - - loading: boolean = true; - - @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; - @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator; - @ViewChild(MatSort, { static: false }) sort: MatSort; - - subMenus: any[] = [ - { - icon: 'fas fa-users-cog', - route: '/administration/sso', - label: this.translate.instant('lang.sso'), - current: true - } - ]; - - displayedColumns = ['id', 'label']; - filterColumns = ['id', 'label']; - - currentConnection = 1; - - connections: any[] = []; - - constructor( - public translate: TranslateService, - public http: HttpClient, - private notify: NotificationService, - public appService: AppService, - private headerService: HeaderService, - private viewContainerRef: ViewContainerRef, - public adminService: AdministrationService, - ) { } - - ngOnInit(): void { - this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); - this.headerService.setHeader(this.translate.instant('lang.administration') + ' ' + this.translate.instant('lang.ssoConnections')); - this.getConnections(); - } - - getConnections() { - // FOR TEST - this.connections = [ - { - id: 1, - label: 'Connexion SSO', - }, - ]; - this.loading = false; - setTimeout(() => { - this.adminService.setDataSource('admin_sso', this.connections, this.sort, this.paginator, this.filterColumns); - }, 0); - - /* this.http.get('../rest/???').pipe( - tap((data: any) => { - this.connections = data; - this.loading = false; - setTimeout(() => { - this.adminService.setDataSource('admin_sso', this.connections, this.sort, this.paginator, this.filterColumns); - }, 0); - }), - catchError((err: any) => { - this.notify.handleSoftErrors(err); - return of(false); - }) - ).subscribe(); */ - } - - delete(elem: any) { - - } - -} diff --git a/src/lang/lang-fr.json b/src/lang/lang-fr.json index 03c8d76df28..225b6bf1d56 100644 --- a/src/lang/lang-fr.json +++ b/src/lang/lang-fr.json @@ -2110,5 +2110,11 @@ "setBindingDocument": "Définir l'engagement d'un document", "freezeRetentionRule": "Geler/dégeler la durée d'utilité courante d'un document", "retentionRuleFrozen": "Durée d'utilité courante gelée", - "bindingMail": "Document engageant" + "bindingMail": "Document engageant", + "warningConnectionMsg": "Vous pouvez rendre l'application <b>indisponible</b> si les informations sont erronées !", + "mappingHeaders": "Interfaçage des en-têtes", + "ssoUrl": "Url du portail SSO", + "ssoUrlDesc": "Permet d'activer le bouton de déconnexion de l'application afin de retourner sur le portail de connexion SSO.", + "warning": "Attention", + "fieldUserIdDescSso": "Permet faire le lien entre l'identifiant utilisateur maarch et l'identifiant SSO" } -- GitLab