From 018ece3bfbae74b32c3fcb630d2f188b23090398 Mon Sep 17 00:00:00 2001 From: Joze RIHTARSIC <joze.rihtarsic@ext.ec.europa.eu> Date: Tue, 23 Oct 2018 10:14:37 +0200 Subject: [PATCH] bugfixes reported by testing team --- smp-angular/src/app/alert/alert.component.css | 1 + smp-angular/src/app/app.component.html | 2 +- smp-angular/src/app/app.component.ts | 10 +- smp-angular/src/app/app.routes.ts | 4 +- .../search-table/search-table.component.html | 4 +- .../search-table/search-table.component.ts | 2 + .../domain-details-dialog.component.html | 2 +- .../src/app/domain/domain.component.html | 1 + .../src/app/domain/domain.component.ts | 7 +- .../src/app/guards/authorized-admin.guard.ts | 6 +- .../src/app/guards/authorized.guard.ts | 4 +- .../src/app/security/authority.model.ts | 19 ++ .../app/security/is-authorized.directive.ts | 4 +- smp-angular/src/app/security/role.model.ts | 6 +- .../src/app/security/security.service.ts | 15 +- smp-angular/src/app/security/user.model.ts | 4 +- ...ervice-group-details-dialog.component.html | 10 +- .../service-group-details-dialog.component.ts | 56 +++-- .../service-group-edit.component.html | 1 + .../service-group-edit.component.ts | 4 +- ...rvice-group-metadata-dialog.component.html | 4 +- ...service-group-metadata-dialog.component.ts | 26 ++- smp-angular/src/app/user/user-controller.ts | 6 +- .../user-details-dialog.component.html | 197 ++++++++++++------ .../user-details-dialog.component.ts | 63 ++++-- smp-angular/src/app/user/user-ro.model.ts | 4 +- smp-angular/src/app/user/user.component.html | 4 +- smp-angular/src/app/user/user.component.ts | 6 +- .../ec/edelivery/smp/data/dao/BaseDao.java | 2 +- .../ec/edelivery/smp/data/dao/DomainDao.java | 23 ++ .../ec/edelivery/smp/data/model/DBDomain.java | 2 +- .../ec/edelivery/smp/data/model/DBUser.java | 8 +- .../ec/edelivery/smp/data/ui/UserRO.java | 21 +- .../services/ui/UIServiceGroupService.java | 2 +- .../smp/services/ui/UIUserService.java | 2 +- .../smp/data/dao/UserDaoIntegrationTest.java | 16 +- .../ui/UIUserServiceIntegrationTest.java | 12 +- .../edelivery/smp/testutil/TestDBUtils.java | 2 +- .../ec/edelivery/smp/auth/SMPAuthority.java | 11 +- .../controllers/ServiceGroupController.java | 10 +- .../ServiceMetadataController.java | 4 +- .../smp/monitor/MonitorResource.java | 2 +- .../smp/ui/AuthenticationResource.java | 3 +- .../ec/edelivery/smp/ui/DomainResource.java | 5 +- .../ec/edelivery/smp/ui/SearchResource.java | 12 +- .../smp/ui/ServiceGroupResource.java | 37 ++-- .../smp/ui/ServiceMetadataResource.java | 4 +- .../ec/edelivery/smp/ui/UserResource.java | 4 +- .../mysql5innodb-4.1.0-SNAPSHOT.ddl | 2 +- .../oracle10g-4.1.0-SNAPSHOT.ddl | 2 +- .../security/SignatureValidatorTest.java | 2 +- .../ServiceGroupControllerTest.java | 2 +- .../smp/monitor/MonitorResourceTest.java | 2 +- .../smp/ui/ServiceGroupResourceTest.java | 37 +++- .../ec/edelivery/smp/ui/UserResourceTest.java | 4 +- .../webapp_integration_test_data.sql | 27 ++- 56 files changed, 477 insertions(+), 255 deletions(-) create mode 100644 smp-angular/src/app/security/authority.model.ts diff --git a/smp-angular/src/app/alert/alert.component.css b/smp-angular/src/app/alert/alert.component.css index da456774d..fa0b48b86 100644 --- a/smp-angular/src/app/alert/alert.component.css +++ b/smp-angular/src/app/alert/alert.component.css @@ -4,6 +4,7 @@ opacity: 1; transition: opacity 0.6s; margin-bottom: 15px; + z-index: 1000; } .alert-error {background-color: #f44336;} diff --git a/smp-angular/src/app/app.component.html b/smp-angular/src/app/app.component.html index 1d81bc9f9..03084d47b 100644 --- a/smp-angular/src/app/app.component.html +++ b/smp-angular/src/app/app.component.html @@ -60,7 +60,7 @@ <div id=".my-content" style="position:absolute; bottom:5px; top:5px; right: 5px; left: 5px"> - <div id="sandwichMenuHolder" style="z-index: 1000"> + <div id="sandwichMenuHolder" style="z-index: 500"> <div id="sandwichMenu"> diff --git a/smp-angular/src/app/app.component.ts b/smp-angular/src/app/app.component.ts index 40aeb809c..2c2f1eb1a 100644 --- a/smp-angular/src/app/app.component.ts +++ b/smp-angular/src/app/app.component.ts @@ -3,9 +3,9 @@ import {SecurityService} from './security/security.service'; import {Router, RouterOutlet} from '@angular/router'; import {SecurityEventService} from './security/security-event.service'; import {Title} from '@angular/platform-browser'; -import {Observable} from 'rxjs'; import {HttpClient, HttpResponse} from '@angular/common/http'; -import {Role} from "./security/role.model"; +import {Authority} from "./security/authority.model"; + @Component({ selector: 'app-root', @@ -55,14 +55,14 @@ export class AppComponent implements OnInit { } isCurrentUserSystemAdmin(): boolean { - return this.securityService.isCurrentUserInRole([Role.SYSTEM_ADMIN]); + return this.securityService.isCurrentUserInRole([Authority.SYSTEM_ADMIN]); } isCurrentUserSMPAdmin(): boolean { - return this.securityService.isCurrentUserInRole([ Role.SMP_ADMIN]); + return this.securityService.isCurrentUserInRole([ Authority.SMP_ADMIN]); } isCurrentUserServiceGroupAdmin(): boolean { - return this.securityService.isCurrentUserInRole([ Role.SERVICE_GROUP_ADMIN]); + return this.securityService.isCurrentUserInRole([ Authority.SERVICE_GROUP_ADMIN]); } get currentUser(): string { diff --git a/smp-angular/src/app/app.routes.ts b/smp-angular/src/app/app.routes.ts index ea81c74b8..a1eaebe8b 100644 --- a/smp-angular/src/app/app.routes.ts +++ b/smp-angular/src/app/app.routes.ts @@ -11,9 +11,9 @@ import {DirtyGuard} from "./common/dirty.guard"; const appRoutes: Routes = [ {path: '', component: ServiceGroupSearchComponent}, {path: 'search', redirectTo: ''}, - {path: 'edit', component: ServiceGroupEditComponent, canActivate: [AuthenticatedGuard], canDeactivate: [DirtyGuard]}, + {path: 'edit', component: ServiceGroupEditComponent, canActivate: [AuthenticatedGuard], canDeactivate: [DirtyGuard]}, {path: 'domain', component: DomainComponent, canActivate: [AuthenticatedGuard], canDeactivate: [DirtyGuard]}, - {path: 'user', component: UserComponent, canActivate: [AuthenticatedGuard], canDeactivate: [DirtyGuard]}, + {path: 'user', component: UserComponent, canActivate: [AuthenticatedGuard], canDeactivate: [DirtyGuard]}, {path: 'login', component: LoginComponent}, {path: '**', redirectTo: ''} ]; diff --git a/smp-angular/src/app/common/search-table/search-table.component.html b/smp-angular/src/app/common/search-table/search-table.component.html index 89fa000b2..653e98ff1 100644 --- a/smp-angular/src/app/common/search-table/search-table.component.html +++ b/smp-angular/src/app/common/search-table/search-table.component.html @@ -106,7 +106,9 @@ <mat-icon>save</mat-icon> <span>Save</span> </button> - <button id="newButton" mat-raised-button (click)="onNewButtonClicked()" [disabled]="loading" color="primary"> + <!-- new button enabled --> + <button id="newButton" mat-raised-button (click)="onNewButtonClicked()" + [disabled]="loading || !allowNewItems" color="primary"> <mat-icon>add</mat-icon> <span>New</span> </button> diff --git a/smp-angular/src/app/common/search-table/search-table.component.ts b/smp-angular/src/app/common/search-table/search-table.component.ts index cadfc4b60..5403d1806 100644 --- a/smp-angular/src/app/common/search-table/search-table.component.ts +++ b/smp-angular/src/app/common/search-table/search-table.component.ts @@ -14,6 +14,7 @@ import {SaveDialogComponent} from '../save-dialog/save-dialog.component'; import {DownloadService} from '../../download/download.service'; import {HttpClient, HttpParams} from '@angular/common/http'; import {ConfirmationDialogComponent} from "../confirmation-dialog/confirmation-dialog.component"; +import {SecurityService} from "../../security/security.service"; @Component({ @@ -43,6 +44,7 @@ export class SearchTableComponent implements OnInit { @Input() showActionButtons: boolean = true; @Input() showSearchPanel: boolean = true; @Input() showIndexColumn: boolean = false; + @Input() allowNewItems: boolean = false; loading = false; diff --git a/smp-angular/src/app/domain/domain-details-dialog/domain-details-dialog.component.html b/smp-angular/src/app/domain/domain-details-dialog/domain-details-dialog.component.html index d20d64954..89af53a72 100644 --- a/smp-angular/src/app/domain/domain-details-dialog/domain-details-dialog.component.html +++ b/smp-angular/src/app/domain/domain-details-dialog/domain-details-dialog.component.html @@ -67,7 +67,7 @@ <table class="buttonsRow"> <tr> <td> - <button mat-raised-button color="primary" [mat-dialog-close]="true" (click)="submitForm()" [disabled]="!domainForm.valid"> + <button mat-raised-button color="primary" (click)="submitForm()" [disabled]="!domainForm.valid"> <mat-icon>check_circle</mat-icon> <span>OK</span> </button> diff --git a/smp-angular/src/app/domain/domain.component.html b/smp-angular/src/app/domain/domain.component.html index ffd7a4c15..0ee884f9d 100644 --- a/smp-angular/src/app/domain/domain.component.html +++ b/smp-angular/src/app/domain/domain.component.html @@ -9,6 +9,7 @@ [searchTableController]="domainController" [showSearchPanel]="false" [filter]="filter" + [allowNewItems]="securityService.isCurrentUserSystemAdmin()" > <ng-template #additionalToolButtons > diff --git a/smp-angular/src/app/domain/domain.component.ts b/smp-angular/src/app/domain/domain.component.ts index 681d1d0b1..90125dc5b 100644 --- a/smp-angular/src/app/domain/domain.component.ts +++ b/smp-angular/src/app/domain/domain.component.ts @@ -8,6 +8,7 @@ import {HttpClient} from '@angular/common/http'; import {SmpConstants} from "../smp.constants"; import {GlobalLookups} from "../common/global-lookups"; import {SearchTableComponent} from "../common/search-table/search-table.component"; +import {SecurityService} from "../security/security.service"; @Component({ moduleId: module.id, @@ -27,7 +28,11 @@ export class DomainComponent implements OnInit { filter: any = {}; - constructor(protected lookups: GlobalLookups, protected http: HttpClient, protected alertService: AlertService, public dialog: MatDialog) { + constructor(public securityService: SecurityService, + protected lookups: GlobalLookups, + protected http: HttpClient, + protected alertService: AlertService, + public dialog: MatDialog) { } ngOnInit() { diff --git a/smp-angular/src/app/guards/authorized-admin.guard.ts b/smp-angular/src/app/guards/authorized-admin.guard.ts index 7c2baac7e..1c8ddfc5b 100644 --- a/smp-angular/src/app/guards/authorized-admin.guard.ts +++ b/smp-angular/src/app/guards/authorized-admin.guard.ts @@ -2,7 +2,7 @@ import {ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router'; import {SecurityService} from '../security/security.service'; import {AuthorizedGuard} from './authorized.guard'; -import {Role} from '../security/role.model'; +import {Authority} from '../security/authority.model'; @Injectable() export class AuthorizedAdminGuard extends AuthorizedGuard { @@ -16,8 +16,8 @@ export class AuthorizedAdminGuard extends AuthorizedGuard { } - getAllowedRoles(route: ActivatedRouteSnapshot): Array<Role> { + getAllowedRoles(route: ActivatedRouteSnapshot): Array<Authority> { // TODO check if we need the SMP admin in here - return [Role.SYSTEM_ADMIN , Role.SMP_ADMIN]; + return [Authority.SYSTEM_ADMIN , Authority.SMP_ADMIN]; } } diff --git a/smp-angular/src/app/guards/authorized.guard.ts b/smp-angular/src/app/guards/authorized.guard.ts index fa877151d..57b320316 100644 --- a/smp-angular/src/app/guards/authorized.guard.ts +++ b/smp-angular/src/app/guards/authorized.guard.ts @@ -2,7 +2,7 @@ import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router'; import {SecurityService} from '../security/security.service'; import {ReplaySubject} from 'rxjs'; -import {Role} from '../security/role.model'; +import {Authority} from "../security/authority.model"; @Injectable() export class AuthorizedGuard implements CanActivate { @@ -25,6 +25,6 @@ export class AuthorizedGuard implements CanActivate { } getAllowedRoles(route: ActivatedRouteSnapshot) { - return route.data["allowedRoles"] as Array<Role>; + return route.data["allowedRoles"] as Array<Authority>; } } diff --git a/smp-angular/src/app/security/authority.model.ts b/smp-angular/src/app/security/authority.model.ts new file mode 100644 index 000000000..96ca6b332 --- /dev/null +++ b/smp-angular/src/app/security/authority.model.ts @@ -0,0 +1,19 @@ +/** + * Note the difference between authority and Role. User with one role could have multiple authorities. + * At the moment role and authorites matches - but this can change in the future. + */ + +export enum Authority { + /** + * The system administrator (a.k.a. the "super admin") role + */ + SYSTEM_ADMIN = 'ROLE_SYSTEM_ADMIN', + /** + * The SMP Administrator role. It is assimilable to the {@link SERVICE_GROUP_ADMINISTRATOR} role for now. + */ + SMP_ADMIN = 'ROLE_SMP_ADMIN', + /** + * The ServiceGroup administrator role + */ + SERVICE_GROUP_ADMIN = 'ROLE_SERVICE_GROUP_ADMIN', +} diff --git a/smp-angular/src/app/security/is-authorized.directive.ts b/smp-angular/src/app/security/is-authorized.directive.ts index d40f816de..7669e8929 100644 --- a/smp-angular/src/app/security/is-authorized.directive.ts +++ b/smp-angular/src/app/security/is-authorized.directive.ts @@ -1,12 +1,12 @@ import {Directive, ElementRef, Input, OnInit} from '@angular/core'; import {SecurityService} from './security.service'; -import {Role} from './role.model'; +import {Authority} from "./authority.model"; @Directive({ selector:'[isAuthorized]' }) export class IsAuthorized implements OnInit { - @Input('isAuthorized') role: Role; + @Input('isAuthorized') role: Authority; constructor(private _elementRef:ElementRef, private securityService:SecurityService) { } diff --git a/smp-angular/src/app/security/role.model.ts b/smp-angular/src/app/security/role.model.ts index 5c8265582..135f827c6 100644 --- a/smp-angular/src/app/security/role.model.ts +++ b/smp-angular/src/app/security/role.model.ts @@ -2,13 +2,13 @@ export enum Role { /** * The system administrator (a.k.a. the "super admin") role */ - SYSTEM_ADMIN = 'ROLE_SYSTEM_ADMIN', + SYSTEM_ADMIN = 'SYSTEM_ADMIN', /** * The SMP Administrator role. It is assimilable to the {@link SERVICE_GROUP_ADMINISTRATOR} role for now. */ - SMP_ADMIN = 'ROLE_SMP_ADMIN', + SMP_ADMIN = 'SMP_ADMIN', /** * The ServiceGroup administrator role */ - SERVICE_GROUP_ADMIN = 'ROLE_SERVICE_GROUP_ADMIN', + SERVICE_GROUP_ADMIN = 'SERVICE_GROUP_ADMIN', } diff --git a/smp-angular/src/app/security/security.service.ts b/smp-angular/src/app/security/security.service.ts index 0876f3f67..d1445baf7 100644 --- a/smp-angular/src/app/security/security.service.ts +++ b/smp-angular/src/app/security/security.service.ts @@ -2,10 +2,9 @@ import {Observable, ReplaySubject} from 'rxjs'; import {User} from './user.model'; import {SecurityEventService} from './security-event.service'; -import {DomainService} from './domain.service'; -import {Role} from './role.model'; import {HttpClient, HttpHeaders} from '@angular/common/http'; import {SmpConstants} from "../smp.constants"; +import {Authority} from "./authority.model"; @Injectable() export class SecurityService { @@ -84,21 +83,21 @@ export class SecurityService { } isCurrentUserSystemAdmin(): boolean { - return this.isCurrentUserInRole([Role.SYSTEM_ADMIN]); + return this.isCurrentUserInRole([Authority.SYSTEM_ADMIN]); } isCurrentUserSMPAdmin(): boolean { - return this.isCurrentUserInRole([ Role.SMP_ADMIN]); + return this.isCurrentUserInRole([ Authority.SMP_ADMIN]); } isCurrentUserServiceGroupAdmin(): boolean { - return this.isCurrentUserInRole([ Role.SERVICE_GROUP_ADMIN]); + return this.isCurrentUserInRole([ Authority.SERVICE_GROUP_ADMIN]); } - isCurrentUserInRole(roles: Array<Role>): boolean { + isCurrentUserInRole(roles: Array<Authority>): boolean { let hasRole = false; const currentUser = this.getCurrentUser(); if (currentUser && currentUser.authorities) { - roles.forEach((role: Role) => { + roles.forEach((role: Authority) => { if (currentUser.authorities.indexOf(role) !== -1) { hasRole = true; } @@ -107,7 +106,7 @@ export class SecurityService { return hasRole; } - isAuthorized(roles: Array<Role>): Observable<boolean> { + isAuthorized(roles: Array<Authority>): Observable<boolean> { let subject = new ReplaySubject<boolean>(); this.isAuthenticated(false).subscribe((isAuthenticated: boolean) => { diff --git a/smp-angular/src/app/security/user.model.ts b/smp-angular/src/app/security/user.model.ts index 085924d91..ad02b6ce7 100644 --- a/smp-angular/src/app/security/user.model.ts +++ b/smp-angular/src/app/security/user.model.ts @@ -1,8 +1,8 @@ -import {Role} from './role.model'; +import {Authority} from "./authority.model"; export interface User { id: number; username: string; - authorities: Array<Role>; + authorities: Array<Authority>; defaultPasswordUsed: boolean; } diff --git a/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.html b/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.html index be002cca5..a81f3ac61 100644 --- a/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.html +++ b/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.html @@ -51,7 +51,9 @@ </div> </mat-panel-description> </mat-expansion-panel-header> - <mat-selection-list #usersSelected [compareWith]="compareTableItemById" + <mat-selection-list #usersSelected + [disabled]="!securityService.isCurrentUserSMPAdmin()" + [compareWith]="compareTableItemById" [formControl]="dialogForm.controls['users']" style="height: 200px; overflow-y: scroll; overflow-x: auto;"> <mat-list-option *ngFor="let user of lookups?.cachedUserList" [value]='user'> @@ -74,7 +76,9 @@ </div> </mat-panel-description> </mat-expansion-panel-header> - <mat-selection-list #domainSelector [compareWith]="compareDomain" + <mat-selection-list #domainSelector + [disabled]="!securityService.isCurrentUserSMPAdmin()" + [compareWith]="compareDomain" [formControl]="dialogForm.controls['serviceGroupDomains']" (selectionChange)="onDomainSelectionChanged($event)" style="height: 200px; overflow-y: scroll; overflow-x: auto;"> @@ -168,7 +172,7 @@ <mat-dialog-actions> <div class="group-action-button"> - <button mat-raised-button color="primary" [mat-dialog-close]="true" (click)="submitForm()" + <button mat-raised-button color="primary" (click)="submitForm()" [disabled]="!dialogForm.valid"> <mat-icon>check_circle</mat-icon> <span>OK</span> diff --git a/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.ts b/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.ts index f28991d83..26ab7a1dc 100644 --- a/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.ts +++ b/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.ts @@ -13,6 +13,7 @@ import {ServiceGroupExtensionRo} from "./service-extension-edit-ro.model"; import {DomainRo} from "../../domain/domain-ro.model"; import {ServiceGroupDomainEditRo} from "../service-group-domain-edit-ro.model"; import {ConfirmationDialogComponent} from "../../common/confirmation-dialog/confirmation-dialog.component"; +import {SecurityService} from "../../security/security.service"; @Component({ selector: 'service-group-details', @@ -29,7 +30,7 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { editMode: boolean; formTitle: string; current: ServiceGroupEditRo & { confirmation?: string }; - showSpinner: boolean = false; + showSpinner: boolean = false; dialogForm: FormGroup; extensionObserver: Observable<ServiceGroupExtensionRo>; @@ -49,7 +50,8 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { } } - constructor(public dialog: MatDialog, + constructor(public securityService: SecurityService, + public dialog: MatDialog, protected http: HttpClient, public dialogRef: MatDialogRef<ServiceGroupDetailsDialogComponent>, private alertService: AlertService, @@ -103,7 +105,7 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { // retrieve xml extension for this service group if (this.current.status !== SearchTableEntityStatus.NEW && !this.current.extension) { // init domains - this.extensionObserver = this.http.get<ServiceGroupExtensionRo>(SmpConstants.REST_SERVICE_GROUP_EXTENSION+'/' + this.current.id); + this.extensionObserver = this.http.get<ServiceGroupExtensionRo>(SmpConstants.REST_SERVICE_GROUP_EXTENSION + '/' + this.current.id); this.extensionObserver.subscribe((res: ServiceGroupExtensionRo) => { this.dialogForm.get('extension').setValue(res.extension); }); @@ -118,8 +120,31 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { submitForm() { - this.checkValidity(this.dialogForm) - this.dialogRef.close(true); + this.checkValidity(this.dialogForm); + + + let request: ServiceGroupExtensionRo = { + serviceGroupId: this.current.id, + extension: this.dialogForm.controls['extension'].value, + } + // + let validationObservable = this.http.post<ServiceGroupExtensionRo>(SmpConstants.REST_SERVICE_GROUP_EXTENSION_VALIDATE, request); + this.showSpinner = true; + validationObservable.toPromise().then((res: ServiceGroupExtensionRo) => { + if (res.errorMessage) { + this.extensionValidationMessage = res.errorMessage; + this.isExtensionValid = false; + this.showSpinner = false; + } else { + this.extensionValidationMessage = "Extension is valid!"; + this.isExtensionValid = true; + this.showSpinner = false; + // we can close the dialog + this.dialogRef.close(true); + } + }); + + } checkValidity(g: FormGroup) { @@ -134,10 +159,6 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { g.get(key).updateValueAndValidity(); }); - this.onExtensionValidate; - - - } @@ -169,7 +190,7 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { let sgd = this.getServiceGroupDomain(domValue.domainCode); // if contains and deselected - delete if (sgd && !opt.selected) { - this.current.serviceMetadata.forEach(metadata=>{ + this.current.serviceMetadata.forEach(metadata => { if (metadata.domainCode === sgd.domainCode) { metadata.status = SearchTableEntityStatus.REMOVED; metadata.deleted = true; @@ -212,11 +233,11 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { }); } - onExtensionValidate() { - let existingXML = this.dialogForm.controls['extension'].value; + public onExtensionValidate() { + let request: ServiceGroupExtensionRo = { serviceGroupId: this.current.id, - extension: existingXML, + extension: this.dialogForm.controls['extension'].value, } // let validationObservable = this.http.post<ServiceGroupExtensionRo>(SmpConstants.REST_SERVICE_GROUP_EXTENSION_VALIDATE, request); @@ -232,6 +253,7 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { this.showSpinner = false; } }); + } onPrettyPrintExtension() { @@ -279,10 +301,10 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { } public getServiceGroupDomain(domainCode: String) { - return this.current.serviceGroupDomains? - this.current.serviceGroupDomains.find(smd => { - return smd.domainCode === domainCode - }):null; + return this.current.serviceGroupDomains ? + this.current.serviceGroupDomains.find(smd => { + return smd.domainCode === domainCode + }) : null; } } diff --git a/smp-angular/src/app/service-group-edit/service-group-edit.component.html b/smp-angular/src/app/service-group-edit/service-group-edit.component.html index 79540ced1..c6a1c3f59 100644 --- a/smp-angular/src/app/service-group-edit/service-group-edit.component.html +++ b/smp-angular/src/app/service-group-edit/service-group-edit.component.html @@ -9,6 +9,7 @@ [searchTableController]="serviceGroupEditController" [tableRowDetailContainer]="tableRowDetailContainer" [additionalRowActionButtons]="additionalRowActionButtons" + [allowNewItems]="securityService.isCurrentUserSMPAdmin()" > <ng-template #rowMetadataAction let-row="row" let-value="value" ngx-datatable-cell-template> diff --git a/smp-angular/src/app/service-group-edit/service-group-edit.component.ts b/smp-angular/src/app/service-group-edit/service-group-edit.component.ts index 6e4d029a3..8eb457e4b 100644 --- a/smp-angular/src/app/service-group-edit/service-group-edit.component.ts +++ b/smp-angular/src/app/service-group-edit/service-group-edit.component.ts @@ -8,6 +8,7 @@ import {SmpConstants} from "../smp.constants"; import {SearchTableEntityStatus} from "../common/search-table/search-table-entity-status.model"; import {SearchTableComponent} from "../common/search-table/search-table.component"; import {GlobalLookups} from "../common/global-lookups"; +import {SecurityService} from "../security/security.service"; @Component({ moduleId: 'edit', @@ -27,7 +28,8 @@ export class ServiceGroupEditComponent implements OnInit { baseUrl: string = SmpConstants.REST_EDIT; contextPath: string = location.pathname.substring(0, location.pathname.length - 3); // remove /ui s - constructor(protected lookups: GlobalLookups, + constructor(public securityService: SecurityService, + protected lookups: GlobalLookups, protected http: HttpClient, protected alertService: AlertService, public dialog: MatDialog, diff --git a/smp-angular/src/app/service-group-edit/service-group-metadata-dialog/service-group-metadata-dialog.component.html b/smp-angular/src/app/service-group-edit/service-group-metadata-dialog/service-group-metadata-dialog.component.html index 7359f01be..db576dbfc 100644 --- a/smp-angular/src/app/service-group-edit/service-group-metadata-dialog/service-group-metadata-dialog.component.html +++ b/smp-angular/src/app/service-group-edit/service-group-metadata-dialog/service-group-metadata-dialog.component.html @@ -27,7 +27,7 @@ </div> <mat-form-field style="width:30%"> - <input matInput placeholder="Document schema" name="documentScheme" id="documentScheme_id" + <input matInput placeholder="Document identifier scheme" name="documentScheme" id="documentScheme_id" [formControl]="dialogForm.controls['documentIdentifierScheme']"> </mat-form-field> <mat-form-field style="width:55%"> @@ -111,7 +111,7 @@ </mat-dialog-content> <mat-dialog-actions> <div class="group-action-button"> - <button mat-raised-button color="primary" [mat-dialog-close]="true" (click)="submitForm()" + <button mat-raised-button color="primary" (click)="submitForm()" [disabled]="!dialogForm.valid"> <mat-icon>check_circle</mat-icon> <span>OK</span> diff --git a/smp-angular/src/app/service-group-edit/service-group-metadata-dialog/service-group-metadata-dialog.component.ts b/smp-angular/src/app/service-group-edit/service-group-metadata-dialog/service-group-metadata-dialog.component.ts index cce601df2..9c947ff4f 100644 --- a/smp-angular/src/app/service-group-edit/service-group-metadata-dialog/service-group-metadata-dialog.component.ts +++ b/smp-angular/src/app/service-group-edit/service-group-metadata-dialog/service-group-metadata-dialog.component.ts @@ -114,8 +114,30 @@ export class ServiceGroupMetadataDialogComponent implements OnInit { } submitForm() { - this.checkValidity(this.dialogForm) - this.dialogRef.close(true); + this.checkValidity(this.dialogForm); + + // before closing check the schema + let request: ServiceMetadataValidationEditRo = { + participantScheme: this.dialogForm.controls['participantScheme'].value, + participantIdentifier: this.dialogForm.controls['participantIdentifier'].value, + documentIdentifierScheme: this.dialogForm.controls['documentIdentifierScheme'].value, + documentIdentifier: this.dialogForm.controls['documentIdentifier'].value, + xmlContent: this.dialogForm.controls['xmlContent'].value, + } + // + let validationObservable = this.http.post<ServiceMetadataValidationEditRo>(SmpConstants.REST_METADATA_VALIDATE, request); + validationObservable.subscribe((res: ServiceMetadataValidationEditRo) => { + if (res.errorMessage) { + this.metadataValidationMessage = res.errorMessage; + this.isMetadataValid = false; + } else { + this.metadataValidationMessage = "ServiceMetada is valid!"; + this.isMetadataValid = true; + // now we can close the dialog + this.dialogRef.close(true); + } + + }); } diff --git a/smp-angular/src/app/user/user-controller.ts b/smp-angular/src/app/user/user-controller.ts index b8a2ad3d8..e144f0682 100644 --- a/smp-angular/src/app/user/user-controller.ts +++ b/smp-angular/src/app/user/user-controller.ts @@ -28,9 +28,11 @@ export class UserController implements SearchTableController { id: null, index: null, username: '', - email: '', + emailAddress: '', role: '', - status: SearchTableEntityStatus.NEW + active: true, + status: SearchTableEntityStatus.NEW, + statusPassword: SearchTableEntityStatus.NEW } } diff --git a/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.html b/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.html index cafe47646..55dc6f555 100644 --- a/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.html +++ b/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.html @@ -1,82 +1,147 @@ +<mat-dialog-content fxFlex="column"> <h2 mat-dialog-title>{{formTitle}}</h2> -<mat-dialog-content> + + <mat-card> - <mat-card-content> - <mat-slide-toggle mat-no-ink class="mat-primary" [formControl]="userForm.controls['userToggle']" (change)="onUserToggleChanged($event)"> - User Details + <mat-card-content > + <mat-slide-toggle style="width:100%" + mat-no-ink class="mat-primary" [formControl]="userForm.controls['active']" + (change)="onUserToggleChanged($event)" id="active_id"> + Active </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" class="has-error">You should type an username</div> - </mat-form-field> + <mat-form-field style="width:100%"> + <mat-select matInput placeholder="Role" class="role" [formControl]="userForm.controls['role']" + id="role_id" 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" + class="has-error">You need to choose at least one role for this user + </div> + </mat-form-field> + <mat-form-field class="emailAddress" style="width:100%"> + <input matInput placeholder="Email address" name="emailAddress" [formControl]="userForm.controls['emailAddress']" + id="emailAddress_id" maxlength="255"> + </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" class="has-error">You need to choose at least one role for this user</div> - </mat-form-field> + </mat-card-content> + </mat-card> + <div fxLayout="row"> + <mat-card fxFlex="40"> + <mat-card-title> + <mat-slide-toggle mat-no-ink class="mat-primary" [formControl]="userForm.controls['userToggle']" + (change)="onUserToggleChanged($event)" id="userDetailsToggle_id"> + User/password authentication + </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> + </mat-card-title> - <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" 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> - - At least one letter in lowercase<br> - - At least one letter in uppercase<br> - - At least one digit<br> - - At least one special character - </div> - </mat-form-field> + <mat-card-content> + <div class="panel" style="height: 100%"> + <mat-form-field class="username"> + <input matInput placeholder="Username" [formControl]="userForm.controls['username']" + id="username_id" maxlength="255" required> + <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="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" 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 *ngIf="editMode" mat-no-ink class="mat-primary" [formControl]="userForm.controls['passwordToggle']" + (change)="onPasswordToggleChanged($event)" id="upasswordToggle_id"> + Change password + </mat-slide-toggle> - <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> + <mat-form-field class="password"> + <input matInput placeholder="Password" type="password" [formControl]="userForm.controls['password']" + [pattern]="passwordPattern" + id="password_id" [required]="!editMode"> + <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> + - At least one letter in lowercase<br> + - At least one letter in uppercase<br> + - At least one digit<br> + - At least one special character + </div> + </mat-form-field> - <div class="panel"> - <mat-form-field class="certificate-subject"> - <input matInput placeholder="Subject Name" [formControl]="userForm.controls['subject']"> - </mat-form-field> - <mat-form-field class="certificate-valid-from"> - <input matInput placeholder="Valid From" [formControl]="userForm.controls['validFrom']"> - </mat-form-field> - <mat-form-field class="certificate-valid-to"> - <input matInput placeholder="Valid To" [formControl]="userForm.controls['validTo']"> - </mat-form-field> - <mat-form-field class="certificate-issuer"> - <input matInput placeholder="Issuer" [formControl]="userForm.controls['issuer']"> - </mat-form-field> - <mat-form-field class="certificate-serial-number"> - <input matInput placeholder="Serial Number" [formControl]="userForm.controls['serialNumber']"> - </mat-form-field> + <mat-form-field class="password-confirmation"> + <input matInput placeholder="Confirmation" type="password" [formControl]="userForm.controls['confirmation']" + id="usernameconfirmation_id" [required]="!editMode"> + <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-card-content> + </mat-card> + <mat-card fxFlex="60"> + <mat-card-title> + <mat-slide-toggle mat-no-ink class="mat-primary" [formControl]="userForm.controls['certificateToggle']" + id="certificateToggle_id"> + Certificate authentication + </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> + </mat-card-title> + <mat-card-content> + <div class="panel"> + <mat-form-field class="certificate-subject"> + <input matInput placeholder="Subject Name" [formControl]="userForm.controls['subject']" id="subject_id"> + </mat-form-field> + <mat-form-field class="certificate-valid-from"> + <input matInput placeholder="Valid From" [formControl]="userForm.controls['validFrom']" id="validFrom_id"> + </mat-form-field> + <mat-form-field class="certificate-valid-to"> + <input matInput placeholder="Valid To" [formControl]="userForm.controls['validTo']" id="validTo_id"> + </mat-form-field> + <mat-form-field class="certificate-issuer"> + <input matInput placeholder="Issuer" [formControl]="userForm.controls['issuer']" id="issuer_id"> + </mat-form-field> + <mat-form-field class="certificate-serial-number"> + <input matInput placeholder="Serial Number" [formControl]="userForm.controls['serialNumber']" + id="servialNumber_id"> + </mat-form-field> + <mat-form-field style="width: 100%;"> + <input matInput placeholder="SMP certificate ID" [formControl]="userForm.controls['certificateId']" + id="certificateId_id"> + </mat-form-field> + + <label class="custom-file-upload"> + <input #fileInput type="file" id="custom-file-upload" accept=".cer,.crt,.pem,.der" + (change)="uploadCertificate($event)" [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> + </mat-card> + </div> - <label class="custom-file-upload"> - <input #fileInput type="file" id="custom-file-upload" accept=".cer" (change)="uploadCertificate($event)" [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> - </mat-card> -</mat-dialog-content> <table class="buttonsRow"> <tr> <td> - <button mat-raised-button color="primary" [mat-dialog-close]="true" (click)="submitForm()" [disabled]="!userForm.valid"> + <button mat-raised-button color="primary" [mat-dialog-close]="true" (click)="submitForm()" + [disabled]="!userForm.valid"> <mat-icon>check_circle</mat-icon> <span>OK</span> </button> @@ -88,4 +153,4 @@ </tr> </table> <div class="required-fields">* required fields</div> - +</mat-dialog-content> diff --git a/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.ts b/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.ts index 28f95f350..d2f7756ec 100644 --- a/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.ts +++ b/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.ts @@ -20,7 +20,7 @@ export class UserDetailsDialogComponent { static readonly NEW_MODE = 'New User'; static readonly EDIT_MODE = 'User Edit'; - // readonly emailPattern = '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'; + readonly emailPattern = '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'; readonly passwordPattern = '^(?=.*[A-Z])(?=.*[ !#$%&\'()*+,-./:;<=>?@\\[^_`{|}~\\\]"])(?=.*[0-9])(?=.*[a-z]).{8,32}$'; readonly dateFormat: string = 'yyyy-MM-dd HH:mm:ssZ'; @@ -29,6 +29,7 @@ export class UserDetailsDialogComponent { userRoles = []; existingRoles = []; userForm: FormGroup; + current: UserRo; @ViewChild('fileInput') private fileInput; @@ -67,7 +68,7 @@ export class UserDetailsDialogComponent { this.editMode = data.edit; this.formTitle = this.editMode ? UserDetailsDialogComponent.EDIT_MODE: UserDetailsDialogComponent.NEW_MODE; - const user: UserRo & { confirmation?: string } = this.editMode + this.current = this.editMode ? { ...data.row, password: '', // ensures the user password is cleared before editing @@ -80,38 +81,51 @@ export class UserDetailsDialogComponent { serialNumber: data.row.serialNumber, } }: { + active: true, username: '', - email: '', + emailAddress: '', password: '', confirmation: '', role: '', status: SearchTableEntityStatus.NEW, + statusPassword: SearchTableEntityStatus.NEW, certificate: {}, }; - const userDetailsToggled: boolean = user && !!user.username; + const userDetailsToggled: boolean = this.current && !!this.current.username; + const passwordToggle: boolean = !this.editMode; + this.userForm = fb.group({ + // common values + 'active': new FormControl({ value: this.current.active},[]), + 'emailAddress': new FormControl({ value:this.current.emailAddress },[ Validators.pattern(this.emailPattern)]), + 'role': new FormControl({ value: this.current.role }, Validators.required), + // username/password authentication '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), - 'validTo': new FormControl({ value: user.certificate.validTo, disabled: true }, Validators.required), - 'issuer': new FormControl({ value: user.certificate.issuer, disabled: true }, Validators.required), - 'serialNumber': new FormControl({ value: user.certificate.serialNumber, disabled: true }, Validators.required), + 'passwordToggle': new FormControl(passwordToggle), + 'username': new FormControl({ value: this.current.username, disabled: this.editMode || !userDetailsToggled }, this.editMode ? Validators.nullValidator : null), + 'password': new FormControl({ value: this.current.password, disabled: !userDetailsToggled && !passwordToggle}, + [Validators.required, Validators.pattern(this.passwordPattern)]), + 'confirmation': new FormControl({ value: this.current.password, disabled: !userDetailsToggled && !passwordToggle}, + Validators.pattern(this.passwordPattern)), + // certificate authentication + 'certificateToggle': new FormControl(this.current && this.current.certificate && !!this.current.certificate.subject), + 'subject': new FormControl({ value: this.current.certificate.subject, disabled: true }, Validators.required), + 'validFrom': new FormControl({ value: this.current.certificate.validFrom, disabled: true }, Validators.required), + 'validTo': new FormControl({ value: this.current.certificate.validTo, disabled: true }, Validators.required), + 'issuer': new FormControl({ value: this.current.certificate.issuer, disabled: true }, Validators.required), + 'serialNumber': new FormControl({ value: this.current.certificate.serialNumber, disabled: true }, Validators.required), + 'certificateId': new FormControl({ value: this.current.certificate.serialNumber, disabled: true }, Validators.required), }, { validator: [this.passwordConfirmationValidator, this.atLeastOneToggleCheckedValidator, this.certificateValidator] }); + this.userService.getUserRoles$().subscribe(userRoles => { this.userRoles = userRoles.json(); this.existingRoles = this.editMode - ? this.getAllowedRoles(this.userRoles, user.role) + ? this.getAllowedRoles(this.userRoles, this.current.role) : this.userRoles; }); } @@ -148,14 +162,23 @@ export class UserDetailsDialogComponent { onUserToggleChanged({checked}: MatSlideToggleChange) { const action = checked ? 'enable' : 'disable'; - this.userForm.get('username')[action](); - this.userForm.get('role')[action](); + this.userForm.get('username')[checked && !this.editMode ? 'enable' : 'disable'](); + //this.userForm.get('role')[action](); + //this.userForm.get('password')[action](); + //this.userForm.get('confirmation')[action](); + } + + onPasswordToggleChanged({checked}: MatSlideToggleChange) { + const action = checked ? 'enable' : 'disable'; this.userForm.get('password')[action](); this.userForm.get('confirmation')[action](); } - get current(): UserRo { - return this.userForm.getRawValue(); + + + getCurrent(): UserRo { + // update data + return this.current; } // filters out roles so that the user cannot change from system administrator to the other roles or vice-versa diff --git a/smp-angular/src/app/user/user-ro.model.ts b/smp-angular/src/app/user/user-ro.model.ts index 1b32a8708..1c6b9ac1b 100644 --- a/smp-angular/src/app/user/user-ro.model.ts +++ b/smp-angular/src/app/user/user-ro.model.ts @@ -3,9 +3,11 @@ import {CertificateRo} from './certificate-ro.model'; export interface UserRo extends SearchTableEntity { username: string; - email: string; + emailAddress: string; password?: string; role: string; + active: boolean; suspended?: boolean; certificate?: CertificateRo; + statusPassword: number; } diff --git a/smp-angular/src/app/user/user.component.html b/smp-angular/src/app/user/user.component.html index 45b4399da..a9fa54d19 100644 --- a/smp-angular/src/app/user/user.component.html +++ b/smp-angular/src/app/user/user.component.html @@ -7,7 +7,9 @@ [additionalToolButtons]="additionalToolButtons" [searchTableController]="userController" [showSearchPanel]="false" - [filter]="filter"> + [filter]="filter" + [allowNewItems]="securityService.isCurrentUserSystemAdmin()" +> <ng-template #additionalToolButtons></ng-template> diff --git a/smp-angular/src/app/user/user.component.ts b/smp-angular/src/app/user/user.component.ts index 96b0ca7be..becea140c 100644 --- a/smp-angular/src/app/user/user.component.ts +++ b/smp-angular/src/app/user/user.component.ts @@ -5,6 +5,7 @@ import {AlertService} from '../alert/alert.service'; import {UserController} from './user-controller'; import {HttpClient} from '@angular/common/http'; import {SearchTableComponent} from "../common/search-table/search-table.component"; +import {SecurityService} from "../security/security.service"; @Component({ templateUrl:'./user.component.html', @@ -21,7 +22,10 @@ export class UserComponent implements OnInit { userController: UserController; filter: any = {}; - constructor(protected http: HttpClient, protected alertService: AlertService, public dialog: MatDialog) { + constructor(public securityService: SecurityService, + protected http: HttpClient, + protected alertService: AlertService, + public dialog: MatDialog) { } ngOnInit() { diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/BaseDao.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/BaseDao.java index e3fc3087b..d5d9f3128 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/BaseDao.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/BaseDao.java @@ -242,7 +242,7 @@ public abstract class BaseDao<E extends BaseEntity> { } else if (searchValue instanceof Long) { lstPredicate.add(cb.equal(getPath(om, fieldName), searchValue)); } else { - LOG.warn("Unknown search value type %s for method %s! Parameter is ignored!", + LOG.info("Unknown search value type {} for method {}! Parameter is ignored!", searchValue, fieldName); } } diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DomainDao.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DomainDao.java index e126fe97f..9f959911e 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DomainDao.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DomainDao.java @@ -15,6 +15,8 @@ package eu.europa.ec.edelivery.smp.data.dao; import eu.europa.ec.edelivery.smp.data.model.DBDomain; import eu.europa.ec.edelivery.smp.exceptions.ErrorCode; +import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException; +import org.apache.commons.lang.StringUtils; import org.springframework.stereotype.Repository; import javax.persistence.NoResultException; @@ -24,6 +26,7 @@ import javax.transaction.Transactional; import java.util.List; import java.util.Optional; +import static eu.europa.ec.edelivery.smp.exceptions.ErrorCode.DOMAIN_NOT_EXISTS; import static eu.europa.ec.edelivery.smp.exceptions.ErrorCode.ILLEGAL_STATE_DOMAIN_MULTIPLE_ENTRY; /** @@ -81,6 +84,26 @@ public class DomainDao extends BaseDao<DBDomain> { } } + /** + * Check if domain for domain code exists. If not SMPRuntimeException with DOMAIN_NOT_EXISTS is thrown. + * If code is null or blank - then null is returned. + * + * @param domainCode + * @return + */ + public DBDomain validateDomainCode(String domainCode){ + DBDomain domain = null; + if (!StringUtils.isBlank(domainCode)) { + Optional<DBDomain> od = getDomainByCode(domainCode); + if (od.isPresent()) { + domain = od.get(); + } else { + throw new SMPRuntimeException(DOMAIN_NOT_EXISTS, domainCode); + } + } + return domain; + } + /** * Removes Entity by given domain code * diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java index 1ad5e40e6..23652e66a 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java @@ -40,7 +40,7 @@ public class DBDomain extends BaseEntity { @Column(name = "DOMAIN_CODE", length = CommonColumnsLengths.MAX_DOMAIN_CODE_LENGTH, nullable = false, unique = true) String domainCode; - @Column(name = "SML_SUBDOMAIN", length = CommonColumnsLengths.MAX_SML_SUBDOMAIN_LENGTH, nullable = false, unique = true) + @Column(name = "SML_SUBDOMAIN", length = CommonColumnsLengths.MAX_SML_SUBDOMAIN_LENGTH, unique = true) String smlSubdomain; @Column(name = "SML_SMP_ID", length = CommonColumnsLengths.MAX_SML_SMP_ID_LENGTH) String smlSmpId; diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBUser.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBUser.java index 272b0dede..3027071e0 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBUser.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBUser.java @@ -40,7 +40,7 @@ public class DBUser extends BaseEntity { @Column(name = "PASSWORD", length = CommonColumnsLengths.MAX_PASSWORD_LENGTH) private String password; @Column(name = "EMAIL", length = CommonColumnsLengths.MAX_PASSWORD_LENGTH) - private String email; + private String emailAddress; @Column(name = "PASSWORD_CHANGED") LocalDateTime passwordChanged; @@ -119,10 +119,10 @@ public class DBUser extends BaseEntity { this.certificate = certificate; } - public String getEmail() { return email; } + public String getEmailAddress() { return emailAddress; } - public void setEmail(String email) { - this.email = email; + public void setEmailAddress(String email) { + this.emailAddress = email; } public LocalDateTime getPasswordChanged() { diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/UserRO.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/UserRO.java index bba178aa3..98928df5b 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/UserRO.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/UserRO.java @@ -1,5 +1,7 @@ package eu.europa.ec.edelivery.smp.data.ui; +import eu.europa.ec.edelivery.smp.data.ui.enums.EntityROStatus; + import java.io.Serializable; import java.time.LocalDateTime; import java.util.List; @@ -16,13 +18,14 @@ public class UserRO extends BaseRO { private static final long serialVersionUID = -4971552086560325302L; private String username; private String password; - private String email; + private String emailAddress; private List<String> authorities; private LocalDateTime passwordChanged; private boolean active = true; private String role; private Long id; private CertificateRO certificateData; + private int statusPassword = EntityROStatus.PERSISTED.getStatusNumber(); public UserRO(){ @@ -52,12 +55,12 @@ public class UserRO extends BaseRO { this.password = password; } - public String getEmail() { - return email; + public String getEmailAddress() { + return emailAddress; } - public void setEmail(String email) { - this.email = email; + public void setEmailAddress(String email) { + this.emailAddress = email; } public LocalDateTime getPasswordChanged() { @@ -98,4 +101,12 @@ public class UserRO extends BaseRO { public void setAuthorities(List<String> authorities) { this.authorities = authorities; } + + public int getStatusPassword() { + return statusPassword; + } + + public void setStatusPassword(int statusPassword) { + this.statusPassword = statusPassword; + } } diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java index 0369a7a58..0c1785d5d 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java @@ -454,7 +454,7 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service userRO.setId(usr.getId()); userRO.setUsername(usr.getUsername()); userRO.setActive(usr.isActive()); - userRO.setEmail(usr.getEmail()); + userRO.setEmailAddress(usr.getEmailAddress()); userRO.setRole(usr.getRole()); serviceGroupRo.getUsers().add(userRO); }); diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java index 697f3e9f2..abdffd9e2 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java @@ -79,7 +79,7 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> { userDao.persistFlushDetach(dbUser); } else if (userRO.getStatus() == EntityROStatus.UPDATED.getStatusNumber()) { DBUser dbUser = userDao.find(userRO.getId()); - dbUser.setEmail(userRO.getEmail()); + dbUser.setEmailAddress(userRO.getEmailAddress()); dbUser.setRole(userRO.getRole()); dbUser.setActive(userRO.isActive()); // check for new password diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/UserDaoIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/UserDaoIntegrationTest.java index 746ba3d83..bc6181fad 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/UserDaoIntegrationTest.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/UserDaoIntegrationTest.java @@ -1,6 +1,5 @@ package eu.europa.ec.edelivery.smp.data.dao; -import eu.europa.ec.edelivery.smp.config.H2JPATestConfiguration; import eu.europa.ec.edelivery.smp.data.model.DBUser; import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException; import eu.europa.ec.edelivery.smp.testutil.TestConstants; @@ -8,12 +7,7 @@ import eu.europa.ec.edelivery.smp.testutil.TestDBUtils; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.jdbc.Sql; -import org.springframework.test.context.jdbc.SqlConfig; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.time.temporal.ChronoUnit; import java.util.Optional; @@ -60,7 +54,7 @@ public class UserDaoIntegrationTest extends AbstractBaseDao{ Optional<DBUser> ou = testInstance.findUserByUsername(TestConstants.USERNAME_1); assertTrue(u!=ou.get()); assertEquals(u, ou.get()); - assertEquals(u.getEmail(), ou.get().getEmail()); + assertEquals(u.getEmailAddress(), ou.get().getEmailAddress()); assertEquals(u.getPassword(), ou.get().getPassword()); assertEquals(u.getRole(), ou.get().getRole()); assertEquals(u.getUsername(), ou.get().getUsername()); @@ -78,7 +72,7 @@ public class UserDaoIntegrationTest extends AbstractBaseDao{ Optional<DBUser> ou = testInstance.findUserByCertificateId(TestConstants.USER_CERT_1); assertTrue(u!=ou.get()); assertEquals(u, ou.get()); - assertEquals(u.getEmail(), ou.get().getEmail()); + assertEquals(u.getEmailAddress(), ou.get().getEmailAddress()); assertEquals(u.getCertificate().getCertificateId(), ou.get().getCertificate().getCertificateId()); assertEquals(u.getCertificate().getValidFrom().truncatedTo(ChronoUnit.MINUTES), ou.get().getCertificate().getValidFrom().truncatedTo(ChronoUnit.MINUTES)); assertEquals(u.getCertificate().getValidTo().truncatedTo(ChronoUnit.MINUTES), ou.get().getCertificate().getValidTo().truncatedTo(ChronoUnit.MINUTES)); @@ -96,7 +90,7 @@ public class UserDaoIntegrationTest extends AbstractBaseDao{ Optional<DBUser> ou = testInstance.findUserByIdentifier(TestConstants.USER_CERT_1); assertTrue(u!=ou.get()); assertEquals(u, ou.get()); - assertEquals(u.getEmail(), ou.get().getEmail()); + assertEquals(u.getEmailAddress(), ou.get().getEmailAddress()); assertEquals(u.getCertificate().getCertificateId(), ou.get().getCertificate().getCertificateId()); // some database timestamp objects does not store miliseconds assertEquals(u.getCertificate().getValidFrom().truncatedTo(ChronoUnit.MINUTES), ou.get().getCertificate().getValidFrom().truncatedTo(ChronoUnit.MINUTES)); @@ -115,7 +109,7 @@ public class UserDaoIntegrationTest extends AbstractBaseDao{ Optional<DBUser> ou = testInstance.findUserByIdentifier(TestConstants.USERNAME_1); assertTrue(u!=ou.get()); assertEquals(u, ou.get()); - assertEquals(u.getEmail(), ou.get().getEmail()); + assertEquals(u.getEmailAddress(), ou.get().getEmailAddress()); } @Test @@ -161,7 +155,7 @@ public class UserDaoIntegrationTest extends AbstractBaseDao{ Optional<DBUser> ou = testInstance.findUserByUsername(TestConstants.USERNAME_1.toUpperCase()); assertTrue(ou.isPresent()); assertEquals(u, ou.get()); - assertEquals(u.getEmail(), ou.get().getEmail()); + assertEquals(u.getEmailAddress(), ou.get().getEmailAddress()); } } \ No newline at end of file diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java index a7d9def81..874d50abb 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java @@ -88,7 +88,7 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest assertNotNull(res); assertNotNull(res.getServiceEntities().get(0).getId()); assertNotNull(res.getServiceEntities().get(0).getUsername()); - assertNotNull(res.getServiceEntities().get(0).getEmail()); + assertNotNull(res.getServiceEntities().get(0).getEmailAddress()); assertNull(res.getServiceEntities().get(0).getPassword()); // Service list must not return passwords assertNotNull(res.getServiceEntities().get(0).getPasswordChanged()); assertNotNull(res.getServiceEntities().get(0).getRole()); @@ -124,7 +124,7 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest UserRO user = new UserRO(); user.setPassword(UUID.randomUUID().toString()); user.setUsername(UUID.randomUUID().toString()); - user.setEmail(UUID.randomUUID().toString()); + user.setEmailAddress(UUID.randomUUID().toString()); user.setRole("ROLE"); user.setStatus(EntityROStatus.NEW.getStatusNumber()); @@ -138,7 +138,7 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest assertEquals(user.getPassword(), oUsr.get().getPassword()); assertEquals(user.getUsername(), oUsr.get().getUsername()); assertEquals(user.getRole(), oUsr.get().getRole()); - assertEquals(user.getEmail(), oUsr.get().getEmail()); + assertEquals(user.getEmailAddress(), oUsr.get().getEmailAddress()); assertNull(oUsr.get().getCertificate()); } @@ -154,7 +154,7 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest UserRO user = new UserRO(); user.setPassword(UUID.randomUUID().toString()); user.setUsername(UUID.randomUUID().toString()); - user.setEmail(UUID.randomUUID().toString()); + user.setEmailAddress(UUID.randomUUID().toString()); user.setRole("ROLE"); CertificateRO cert = new CertificateRO(); cert.setSubject(UUID.randomUUID().toString()); @@ -178,7 +178,7 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest assertEquals(user.getPassword(), oUsr.get().getPassword()); assertEquals(user.getUsername(), oUsr.get().getUsername()); assertEquals(user.getRole(), oUsr.get().getRole()); - assertEquals(user.getEmail(), oUsr.get().getEmail()); + assertEquals(user.getEmailAddress(), oUsr.get().getEmailAddress()); assertNotNull(oUsr.get().getCertificate()); assertEquals(cert.getCertificateId(), cert.getCertificateId()); assertEquals(cert.getSubject(), cert.getSubject()); @@ -200,7 +200,7 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest DBUser user = new DBUser(); user.setPassword(UUID.randomUUID().toString()); user.setUsername(UUID.randomUUID().toString()); - user.setEmail(UUID.randomUUID().toString()); + user.setEmailAddress(UUID.randomUUID().toString()); user.setRole("ROLE"); DBCertificate cert = new DBCertificate(); cert.setSubject(UUID.randomUUID().toString()); diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java index 347d009ca..08b73c004 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java @@ -76,7 +76,7 @@ public class TestDBUtils { DBUser dbuser = new DBUser(); dbuser.setUsername(userName); dbuser.setRole("test"); - dbuser.setEmail("test@test.eu"); + dbuser.setEmailAddress("test@test.eu"); dbuser.setPasswordChanged(LocalDateTime.now()); dbuser.setPassword(UUID.randomUUID().toString()); return dbuser; diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthority.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthority.java index 8a64b60ec..38ac26820 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthority.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthority.java @@ -6,9 +6,14 @@ import org.springframework.security.core.GrantedAuthority; public class SMPAuthority implements GrantedAuthority { // static constants for annotations! - public static final String S_AUTHORITY_SYSTEM_ADMIN = "ROLE_SYSTEM_ADMIN"; - public static final String S_AUTHORITY_SMP_ADMIN = "ROLE_SMP_ADMIN"; - public static final String S_AUTHORITY_SERVICE_GROUP_ADMIN = "ROLE_SERVICE_GROUP_ADMIN"; + public static final String S_AUTHORITY_TOKEN_SYSTEM_ADMIN = "ROLE_SYSTEM_ADMIN"; + public static final String S_AUTHORITY_TOKEN_SMP_ADMIN = "ROLE_SMP_ADMIN"; + public static final String S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN = "ROLE_SERVICE_GROUP_ADMIN"; + + // static constants for verification... + public static final SMPAuthority S_AUTHORITY_SYSTEM_ADMIN = new SMPAuthority(SMPRole.SYSTEM_ADMIN.getCode()); + public static final SMPAuthority S_AUTHORITY_SMP_ADMIN = new SMPAuthority(SMPRole.SMP_ADMIN.getCode()); + public static final SMPAuthority S_AUTHORITY_SERVICE_GROUP = new SMPAuthority(SMPRole.SERVICE_GROUP_ADMIN.getCode()); String role; diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/controllers/ServiceGroupController.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/controllers/ServiceGroupController.java index ce39c2a8f..67ca91528 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/controllers/ServiceGroupController.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/controllers/ServiceGroupController.java @@ -29,24 +29,18 @@ import org.oasis_open.docs.bdxr.ns.smp._2016._05.DocumentIdentifier; import org.oasis_open.docs.bdxr.ns.smp._2016._05.ParticipantIdentifierType; import org.oasis_open.docs.bdxr.ns.smp._2016._05.ServiceGroup; import org.oasis_open.docs.bdxr.ns.smp._2016._05.ServiceMetadataReferenceType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.annotation.Order; -import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.security.access.annotation.Secured; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.core.Context; import java.util.List; import static eu.europa.ec.edelivery.smp.controllers.WebConstans.HTTP_PARAM_DOMAIN; import static eu.europa.ec.edelivery.smp.controllers.WebConstans.HTTP_PARAM_OWNER; import static eu.europa.ec.smp.api.Identifiers.asParticipantId; -import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE; import static org.springframework.http.ResponseEntity.created; import static org.springframework.http.ResponseEntity.ok; @@ -89,7 +83,7 @@ public class ServiceGroupController { @PutMapping - @Secured({SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_SMP_ADMIN}) + @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN}) public ResponseEntity saveServiceGroup(HttpServletRequest httpReq, @PathVariable String serviceGroupId, @RequestHeader(name = HTTP_PARAM_OWNER, required = false) String serviceGroupOwner, @@ -113,7 +107,7 @@ public class ServiceGroupController { } @DeleteMapping - @Secured({SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_SMP_ADMIN}) + @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN}) public void deleteServiceGroup(HttpServletRequest httpReq, @PathVariable String serviceGroupId) { String authentUser = SecurityContextHolder.getContext().getAuthentication().getName(); String host = getRemoteHost(httpReq); diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/controllers/ServiceMetadataController.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/controllers/ServiceMetadataController.java index 9a8c649d9..9a723fd0b 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/controllers/ServiceMetadataController.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/controllers/ServiceMetadataController.java @@ -77,7 +77,7 @@ public class ServiceMetadataController { } @PutMapping - @PreAuthorize("hasAnyAuthority(T(eu.europa.ec.edelivery.smp.auth.SMPAuthority).S_AUTHORITY_SMP_ADMIN) OR" + + @PreAuthorize("hasAnyAuthority(T(eu.europa.ec.edelivery.smp.auth.SMPAuthority).S_AUTHORITY_TOKEN_SMP_ADMIN) OR" + " @serviceGroupService.isServiceGroupOwner(authentication.name, #serviceGroupId)") public ResponseEntity saveServiceMetadata(HttpServletRequest httpReq, @PathVariable String serviceGroupId, @@ -99,7 +99,7 @@ public class ServiceMetadataController { } @DeleteMapping - @PreAuthorize("hasAnyAuthority(T(eu.europa.ec.edelivery.smp.auth.SMPAuthority).S_AUTHORITY_SMP_ADMIN) OR" + + @PreAuthorize("hasAnyAuthority(T(eu.europa.ec.edelivery.smp.auth.SMPAuthority).S_AUTHORITY_TOKEN_SMP_ADMIN) OR" + " @serviceGroupService.isServiceGroupOwner(authentication.name, #serviceGroupId)") public ResponseEntity deleteServiceMetadata(HttpServletRequest httpReq, @PathVariable String serviceGroupId, diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/monitor/MonitorResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/monitor/MonitorResource.java index 034ce4626..b4aa325dd 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/monitor/MonitorResource.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/monitor/MonitorResource.java @@ -60,7 +60,7 @@ public class MonitorResource { @RequestMapping(method = RequestMethod.GET,path = "/is-alive") - @Secured({SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN,SMPAuthority.S_AUTHORITY_SMP_ADMIN}) + @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN,SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN}) public ResponseEntity isAlive() { String user = SecurityContextHolder.getContext().getAuthentication().getName(); diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResource.java index 6eff65bdb..3a80d1972 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResource.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResource.java @@ -15,7 +15,6 @@ import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.User; import org.springframework.security.web.authentication.logout.CookieClearingLogoutHandler; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.transaction.annotation.Transactional; @@ -79,7 +78,7 @@ public class AuthenticationResource { // @PutMapping(produces = {"text/plain"}) @RequestMapping(value = "user", method = RequestMethod.GET) - @Secured({SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_SMP_ADMIN, SMPAuthority.S_AUTHORITY_SERVICE_GROUP_ADMIN}) + @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN}) public UserRO getUser() { // User securityUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); //return securityUser.getUsername(); diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/DomainResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/DomainResource.java index 86aeef9c5..262d6e288 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/DomainResource.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/DomainResource.java @@ -7,15 +7,12 @@ import eu.europa.ec.edelivery.smp.data.ui.ServiceResult; import eu.europa.ec.edelivery.smp.logging.SMPLogger; import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory; import eu.europa.ec.edelivery.smp.services.ui.UIDomainService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.annotation.Secured; import org.springframework.web.bind.annotation.*; import javax.annotation.PostConstruct; import java.util.Arrays; -import java.util.List; /** * @author Joze Rihtarsic @@ -51,7 +48,7 @@ public class DomainResource { @PutMapping(produces = {"application/json"}) @RequestMapping(method = RequestMethod.PUT) - @Secured({SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN}) + @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN}) public void updateDomainList(@RequestBody(required = true) DomainRO [] updateEntities ){ LOG.info("GOT LIST OF DomainRO to UPDATE: " + updateEntities.length); uiDomainService.updateDomainList(Arrays.asList(updateEntities)); diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/SearchResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/SearchResource.java index a6d2f8e30..a89077b36 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/SearchResource.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/SearchResource.java @@ -56,15 +56,9 @@ public class SearchResource { ServiceGroupFilter sgf = new ServiceGroupFilter(); sgf.setParticipantIdentifierLike(participantIdentifier); sgf.setParticipantSchemeLike(participantScheme); - // add domain search paramater - if (!StringUtils.isBlank(domainCode)) { - Optional<DBDomain> od = domainDao.getDomainByCode(domainCode); - if (od.isPresent()) { - sgf.setDomain(od.get()); - } else { - throw new SMPRuntimeException(DOMAIN_NOT_EXISTS, domainCode); - } - } + // add domain search parameter + sgf.setDomain(domainDao.validateDomainCode(domainCode)); + return uiServiceGroupService.getTableList(page, pageSize, orderBy, orderType, sgf); } } diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/ServiceGroupResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/ServiceGroupResource.java index b75a241ed..78357bf54 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/ServiceGroupResource.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/ServiceGroupResource.java @@ -3,6 +3,7 @@ package eu.europa.ec.edelivery.smp.ui; import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationToken; import eu.europa.ec.edelivery.smp.auth.SMPAuthority; +import eu.europa.ec.edelivery.smp.auth.SMPRole; import eu.europa.ec.edelivery.smp.data.dao.DomainDao; import eu.europa.ec.edelivery.smp.data.model.DBDomain; import eu.europa.ec.edelivery.smp.data.model.DBUser; @@ -12,15 +13,13 @@ import eu.europa.ec.edelivery.smp.data.ui.ServiceResult; import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException; import eu.europa.ec.edelivery.smp.logging.SMPLogger; import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory; -import eu.europa.ec.edelivery.smp.logging.SMPMessageCode; -import eu.europa.ec.edelivery.smp.services.ui.UIDomainService; import eu.europa.ec.edelivery.smp.services.ui.UIServiceGroupService; import eu.europa.ec.edelivery.smp.services.ui.filters.ServiceGroupFilter; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.annotation.Secured; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; @@ -55,8 +54,9 @@ public class ServiceGroupResource { @PutMapping(produces = {"application/json"}) @ResponseBody @RequestMapping(method = RequestMethod.GET) - @Secured({SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_SMP_ADMIN, SMPAuthority.S_AUTHORITY_SERVICE_GROUP_ADMIN}) + @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN}) public ServiceResult<ServiceGroupRO> getServiceGroupList( + HttpServletRequest request, @RequestParam(value = "page", defaultValue = "0") int page, @RequestParam(value = "pageSize", defaultValue = "10") int pageSize, @RequestParam(value = "orderBy", required = false) String orderBy, @@ -70,33 +70,26 @@ public class ServiceGroupResource { ServiceGroupFilter sgf = new ServiceGroupFilter(); sgf.setParticipantIdentifierLike(participantIdentifier); sgf.setParticipantSchemeLike(participantScheme); + // add domain search parameter + sgf.setDomain(domainDao.validateDomainCode(domainCode)); // check if logged user is ServiceGroup admin if yes return only his servicegroups Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - if (authentication.getAuthorities().contains(SMPAuthority.S_AUTHORITY_SERVICE_GROUP_ADMIN)){ + + // show all service groups only for SMP Admin + System.out.println("USER authorites: "+ authentication.getAuthorities().size()); + if (!request.isUserInRole(SMPRole.SMP_ADMIN.getCode())){ SMPAuthenticationToken authToken = (SMPAuthenticationToken) authentication; DBUser user = authToken.getUser(); sgf.setOwner(user); } - - // add domain search paramater - if (!StringUtils.isBlank(domainCode)) { - Optional<DBDomain> od = domainDao.getDomainByCode(domainCode); - if (od.isPresent()) { - sgf.setDomain(od.get()); - } else { - throw new SMPRuntimeException(DOMAIN_NOT_EXISTS, domainCode); - } - } - - return uiServiceGroupService.getTableList(page,pageSize, orderBy, orderType, sgf); } @ResponseBody @PutMapping(produces = {"application/json"}) @RequestMapping(method = RequestMethod.GET, path = "{serviceGroupId}") - @Secured({SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_SMP_ADMIN, SMPAuthority.S_AUTHORITY_SERVICE_GROUP_ADMIN}) + @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN}) public ServiceGroupRO getServiceGroupById(@PathVariable Long serviceGroupId) { return uiServiceGroupService.getServiceGroupById(serviceGroupId); } @@ -104,18 +97,18 @@ public class ServiceGroupResource { @ResponseBody @PutMapping(produces = {"application/json"}) @RequestMapping(method = RequestMethod.GET, path = "extension/{serviceGroupId}") - @Secured({SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_SMP_ADMIN, SMPAuthority.S_AUTHORITY_SERVICE_GROUP_ADMIN}) + @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN}) public ServiceGroupExtensionRO getExtensionServiceGroupById(@PathVariable Long serviceGroupId) { return uiServiceGroupService.getServiceGroupExtensionById(serviceGroupId); } @RequestMapping(path = "extension/validate", method = RequestMethod.POST) - @Secured({SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_SMP_ADMIN, SMPAuthority.S_AUTHORITY_SERVICE_GROUP_ADMIN}) + @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN}) public ServiceGroupExtensionRO getExtensionServiceGroupById(@RequestBody(required = true) ServiceGroupExtensionRO sg) { return uiServiceGroupService.validateExtension(sg); } @RequestMapping(path = "extension/format", method = RequestMethod.POST) - @Secured({SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_SMP_ADMIN, SMPAuthority.S_AUTHORITY_SERVICE_GROUP_ADMIN}) + @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN}) public ServiceGroupExtensionRO formatExtension(@RequestBody(required = true) ServiceGroupExtensionRO sg) { return uiServiceGroupService.formatExtension(sg); } @@ -123,7 +116,7 @@ public class ServiceGroupResource { @PutMapping(produces = {"application/json"}) @RequestMapping(method = RequestMethod.PUT) - @Secured({SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_SMP_ADMIN, SMPAuthority.S_AUTHORITY_SERVICE_GROUP_ADMIN}) + @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN}) public void updateDomainList(@RequestBody(required = true) ServiceGroupRO[] updateEntities ){ LOG.info("GOT LIST OF ServiceGroupRO to UPDATE: " + updateEntities.length); uiServiceGroupService.updateServiceGroupList(Arrays.asList(updateEntities)); diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/ServiceMetadataResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/ServiceMetadataResource.java index 1a80b54e6..58ada3b6b 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/ServiceMetadataResource.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/ServiceMetadataResource.java @@ -29,13 +29,13 @@ public class ServiceMetadataResource { @ResponseBody @PutMapping(produces = {"application/json"}) @RequestMapping(method = RequestMethod.GET, path = "{serviceMetadataId}") - @Secured({SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_SMP_ADMIN, SMPAuthority.S_AUTHORITY_SERVICE_GROUP_ADMIN}) + @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN}) public ServiceMetadataRO getServiceGroupById(@PathVariable Long serviceMetadataId) { return uiServiceMetadataService.getServiceMetadataXMLById(serviceMetadataId); } @RequestMapping(path = "validate", method = RequestMethod.POST) - @Secured({SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_SMP_ADMIN, SMPAuthority.S_AUTHORITY_SERVICE_GROUP_ADMIN}) + @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN}) public ServiceMetadataValidationRO validateServiceMetadata(@RequestBody(required = true) ServiceMetadataValidationRO serviceMetadataValidationRO) { return uiServiceMetadataService.validateServiceMetadata(serviceMetadataValidationRO); } diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/UserResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/UserResource.java index 362a5e64e..1f5131a62 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/UserResource.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/UserResource.java @@ -40,7 +40,7 @@ public class UserResource { @ResponseBody @RequestMapping(method = RequestMethod.GET) //update gui to call this when somebody is logged in. - // @Secured({SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_SMP_ADMIN, SMPAuthority.S_AUTHORITY_SERVICE_GROUP_ADMIN}) + // @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN}) public ServiceResult<UserRO> getUsers( @RequestParam(value = "page", defaultValue = "0") int page, @RequestParam(value = "pageSize", defaultValue = "10") int pageSize, @@ -53,7 +53,7 @@ public class UserResource { @PutMapping(produces = {"application/json"}) @RequestMapping(method = RequestMethod.PUT) - @Secured({SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN}) + @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN}) public void updateUserList(@RequestBody(required = true) UserRO[] updateEntities ){ LOG.info("Update user list, count: {}" + updateEntities.length); uiUserService.updateUserList(Arrays.asList(updateEntities)); diff --git a/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb-4.1.0-SNAPSHOT.ddl b/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb-4.1.0-SNAPSHOT.ddl index f9fdc1fe1..4a4cb9e40 100644 --- a/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb-4.1.0-SNAPSHOT.ddl +++ b/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb-4.1.0-SNAPSHOT.ddl @@ -37,7 +37,7 @@ SML_CLIENT_KEY_ALIAS varchar(256) CHARACTER SET utf8 COLLATE utf8_bin, SML_PARTC_IDENT_REGEXP varchar(4000) CHARACTER SET utf8 COLLATE utf8_bin, SML_SMP_ID varchar(256) CHARACTER SET utf8 COLLATE utf8_bin, - SML_SUBDOMAIN varchar(256) CHARACTER SET utf8 COLLATE utf8_bin not null, + SML_SUBDOMAIN varchar(256) CHARACTER SET utf8 COLLATE utf8_bin, primary key (ID) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/smp-webapp/src/main/smp-setup/database-scripts/oracle10g-4.1.0-SNAPSHOT.ddl b/smp-webapp/src/main/smp-setup/database-scripts/oracle10g-4.1.0-SNAPSHOT.ddl index 1d8eda096..81a43ce87 100644 --- a/smp-webapp/src/main/smp-setup/database-scripts/oracle10g-4.1.0-SNAPSHOT.ddl +++ b/smp-webapp/src/main/smp-setup/database-scripts/oracle10g-4.1.0-SNAPSHOT.ddl @@ -43,7 +43,7 @@ create sequence SMP_USER_SEQ start with 1 increment by 50; SML_CLIENT_KEY_ALIAS varchar2(256 char), SML_PARTC_IDENT_REGEXP varchar2(4000 char), SML_SMP_ID varchar2(256 char), - SML_SUBDOMAIN varchar2(256 char) not null, + SML_SUBDOMAIN varchar2(256 char), primary key (ID) ); diff --git a/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SignatureValidatorTest.java b/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SignatureValidatorTest.java index 8b845b20c..14424f7ad 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SignatureValidatorTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SignatureValidatorTest.java @@ -77,7 +77,7 @@ public class SignatureValidatorTest { private static final String C14N_METHOD = CanonicalizationMethod.INCLUSIVE; private static final String PARSER_DISALLOW_DTD_PARSING_FEATURE = "http://apache.org/xml/features/disallow-doctype-decl"; - private static final RequestPostProcessor ADMIN_CREDENTIALS = httpBasic("test_admin", "test123"); + private static final RequestPostProcessor ADMIN_CREDENTIALS = httpBasic("smp_admin", "test123"); @Autowired private WebApplicationContext webAppContext; diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/controllers/ServiceGroupControllerTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/controllers/ServiceGroupControllerTest.java index 186638d9a..0bd193813 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/controllers/ServiceGroupControllerTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/controllers/ServiceGroupControllerTest.java @@ -71,7 +71,7 @@ public class ServiceGroupControllerTest { private static final String OTHER_OWNER_NAME_URL_ENCODED = "CN=utf-8_%C5%BC_SMP,O=EC,C=BE:0000000000000666"; - private static final RequestPostProcessor ADMIN_CREDENTIALS = httpBasic("test_admin", "test123"); + private static final RequestPostProcessor ADMIN_CREDENTIALS = httpBasic("smp_admin", "test123"); @Autowired private WebApplicationContext webAppContext; diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/monitor/MonitorResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/monitor/MonitorResourceTest.java index e85f8aeee..86bd74d90 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/monitor/MonitorResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/monitor/MonitorResourceTest.java @@ -53,7 +53,7 @@ public class MonitorResourceTest { public ExpectedException expectedEx = ExpectedException.none(); private static final String URL = "/monitor/is-alive"; - private static final RequestPostProcessor ADMIN_CREDENTIALS = httpBasic("test_admin", "test123"); + private static final RequestPostProcessor ADMIN_CREDENTIALS = httpBasic("smp_admin", "test123"); @Autowired private WebApplicationContext webAppContext; diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/ServiceGroupResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/ServiceGroupResourceTest.java index e92daebda..ac1a1185e 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/ServiceGroupResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/ServiceGroupResourceTest.java @@ -29,6 +29,7 @@ import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -59,7 +60,8 @@ public class ServiceGroupResourceTest { private WebApplicationContext webAppContext; private MockMvc mvc; - private static final RequestPostProcessor ADMIN_CREDENTIALS = httpBasic("test_admin", "test123"); + private static final RequestPostProcessor SMP_ADMIN_CREDENTIALS = httpBasic("smp_admin", "test123"); + private static final RequestPostProcessor SG_ADMIN_CREDENTIALS = httpBasic("sg_admin", "test123"); @Before public void setup() { mvc = MockMvcBuilders.webAppContextSetup(webAppContext) @@ -76,10 +78,10 @@ public class ServiceGroupResourceTest { } @Test - public void getServiceGroupList() throws Exception { + public void getServiceGroupListForSMPAdmin() throws Exception { // given when MvcResult result = mvc.perform(get(PATH) - .with(ADMIN_CREDENTIALS) + .with(SMP_ADMIN_CREDENTIALS) ).andExpect(status().isOk()).andReturn(); //them @@ -95,7 +97,32 @@ public class ServiceGroupResourceTest { assertNotNull(sgro.getParticipantScheme()); assertNotNull(sgro.getParticipantIdentifier()); assertEquals(1, sgro.getUsers().size()); - assertEquals("test_user_hashed_pass", sgro.getUsers().get(0).getUsername()); + assertNotEquals("smp_admin", sgro.getUsers().get(0).getUsername()); + + }); + } + + @Test + public void getServiceGroupListForServiceGroupAdmin() throws Exception { + // given when + MvcResult result = mvc.perform(get(PATH) + .with(SG_ADMIN_CREDENTIALS) + ).andExpect(status().isOk()).andReturn(); + + //them + ObjectMapper mapper = new ObjectMapper(); + ServiceResult res = mapper.readValue(result.getResponse().getContentAsString(), ServiceResult.class); + + + assertNotNull(res); + assertEquals(1, res.getServiceEntities().size()); + res.getServiceEntities().forEach(sgMap-> { + ServiceGroupRO sgro = mapper.convertValue(sgMap, ServiceGroupRO.class); + assertNotNull(sgro.getId()); + assertNotNull(sgro.getParticipantScheme()); + assertNotNull(sgro.getParticipantIdentifier()); + assertEquals(1, sgro.getUsers().size()); + assertEquals("sg_admin", sgro.getUsers().get(0).getUsername()); }); } @@ -104,7 +131,7 @@ public class ServiceGroupResourceTest { // given when MvcResult result = mvc.perform(get(PATH+"/100000") - .with(ADMIN_CREDENTIALS)). + .with(SMP_ADMIN_CREDENTIALS)). andExpect(status().isOk()).andReturn(); //them diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/UserResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/UserResourceTest.java index 29dba9317..88faf6bb0 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/UserResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/UserResourceTest.java @@ -57,7 +57,7 @@ public class UserResourceTest { private WebApplicationContext webAppContext; private MockMvc mvc; - private static final RequestPostProcessor ADMIN_CREDENTIALS = httpBasic("test_admin", "test123"); + private static final RequestPostProcessor ADMIN_CREDENTIALS = httpBasic("smp_admin", "test123"); @Before public void setup() { mvc = MockMvcBuilders.webAppContextSetup(webAppContext) @@ -85,7 +85,7 @@ public class UserResourceTest { assertNotNull(res); - assertEquals(6, res.getServiceEntities().size()); + assertEquals(9, res.getServiceEntities().size()); res.getServiceEntities().forEach(sgMap-> { UserRO sgro = mapper.convertValue(sgMap, UserRO.class); assertNotNull(sgro.getId()); diff --git a/smp-webapp/src/test/resources/webapp_integration_test_data.sql b/smp-webapp/src/test/resources/webapp_integration_test_data.sql index 4da0acac4..7cc5fb4d2 100644 --- a/smp-webapp/src/test/resources/webapp_integration_test_data.sql +++ b/smp-webapp/src/test/resources/webapp_integration_test_data.sql @@ -8,24 +8,31 @@ -- Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis, -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -insert into SMP_USER (ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (1, 'test_admin', '$2a$06$AXSSUDJlpzzq/gPZb7eIBeb8Mi0.PTKqDjzujZH.bWPwj5.ePEInW', 'SMP_ADMIN', 1,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); -insert into SMP_USER(ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (2, 'test_user_hashed_pass', '$2a$06$AXSSUDJlpzzq/gPZb7eIBeb8Mi0.PTKqDjzujZH.bWPwj5.ePEInW', 'SMP_ADMIN',1,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); -insert into SMP_USER(ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (3, 'test_user_clear_pass', 'test123', 'SMP_ADMIN',1,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); -insert into SMP_USER(ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (4, 'cert1', '', 'SMP_ADMIN', 1,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); -insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (4, 'CN=comon name,O=org,C=BE:0000000000000066', null,null,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); +insert into SMP_USER (ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (1, 'smp_admin', '$2a$06$AXSSUDJlpzzq/gPZb7eIBeb8Mi0.PTKqDjzujZH.bWPwj5.ePEInW', 'SMP_ADMIN', 1,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); +insert into SMP_USER (ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (2, 'sg_admin', '$2a$06$AXSSUDJlpzzq/gPZb7eIBeb8Mi0.PTKqDjzujZH.bWPwj5.ePEInW', 'SERVICE_GROUP_ADMIN', 1,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); +insert into SMP_USER (ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (3, 'sys_admin', '$2a$06$AXSSUDJlpzzq/gPZb7eIBeb8Mi0.PTKqDjzujZH.bWPwj5.ePEInW', 'SMP_ADMIN', 1,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); -insert into SMP_USER(ID, USERNAME, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (5, 'cert2', 'SMP_ADMIN', 1,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); -insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (5, 'CN=EHEALTH_SMP_TEST_BRAZIL,O=European Commission,C=BE:48b681ee8e0dcc08', null,null,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); +insert into SMP_USER(ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (4, 'test_user_hashed_pass', '$2a$06$AXSSUDJlpzzq/gPZb7eIBeb8Mi0.PTKqDjzujZH.bWPwj5.ePEInW', 'SERVICE_GROUP_ADMIN',1,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); +insert into SMP_USER(ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (5, 'test_user_clear_pass', 'test123', 'SERVICE_GROUP_ADMIN',1,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); +insert into SMP_USER(ID, USERNAME, PASSWORD, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (6, 'cert1', '', 'SMP_ADMIN', 1,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); +insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (6, 'CN=comon name,O=org,C=BE:0000000000000066', null,null,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); + +insert into SMP_USER(ID, USERNAME, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (7, 'cert2', 'SMP_ADMIN', 1,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); +insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (7, 'CN=EHEALTH_SMP_TEST_BRAZIL,O=European Commission,C=BE:48b681ee8e0dcc08', null,null,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); + +insert into SMP_USER(ID, USERNAME, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (8, 'Cert3', 'SMP_ADMIN', 1,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); +insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (8, 'CN=utf-8_ż_SMP,O=EC,C=BE:0000000000000666', null,null,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); + +insert into SMP_USER(ID, USERNAME, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (9, 'Cert4', 'SMP_ADMIN', 1,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); +insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (9, 'CN=EHEALTH_SMP_EC,O=European Commission,C=BEf71ee8b11cb3b787', null,null,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); -insert into SMP_USER(ID, USERNAME, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (6, 'Cert2', 'SMP_ADMIN', 1,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); -insert into SMP_CERTIFICATE (ID, CERTIFICATE_ID, VALID_FROM, VALID_TO, CREATED_ON, LAST_UPDATED_ON) values (6, 'CN=utf-8_ż_SMP,O=EC,C=BE:0000000000000666', null,null,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); -- set the ids to higher values - tests are using sequnce which stars from 1 insert into SMP_SERVICE_GROUP(ID, PARTICIPANT_IDENTIFIER, PARTICIPANT_SCHEME, CREATED_ON, LAST_UPDATED_ON) values (100000, 'urn:australia:ncpb', 'ehealth-actorid-qns', CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); insert into SMP_SERVICE_GROUP(ID, PARTICIPANT_IDENTIFIER, PARTICIPANT_SCHEME, CREATED_ON, LAST_UPDATED_ON) values (200000, 'urn:brazil:ncpb', 'ehealth-actorid-qns', CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); -- set ownership -insert into SMP_OWNERSHIP (FK_SG_ID, FK_USER_ID) values (100000, 2); +insert into SMP_OWNERSHIP (FK_SG_ID, FK_USER_ID) values (100000, 4); insert into SMP_OWNERSHIP (FK_SG_ID, FK_USER_ID) values (200000, 2); insert into SMP_DOMAIN (ID, DOMAIN_CODE, SML_SUBDOMAIN, SML_SMP_ID, SIGNATURE_KEY_ALIAS, CREATED_ON, LAST_UPDATED_ON) values (1, 'domain','subdomain', 'CEF-SMP-001','sig-key',CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP()); -- GitLab