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