diff --git a/smp-angular/src/app/guards/authorized-admin.guard.ts b/smp-angular/src/app/guards/authorized-admin.guard.ts index 9e88e047a18401252dfa43ddb4f9a9ab2a119c9f..381154b14f5b1e65e7f00f9dbe2b026608513ca9 100644 --- a/smp-angular/src/app/guards/authorized-admin.guard.ts +++ b/smp-angular/src/app/guards/authorized-admin.guard.ts @@ -18,6 +18,6 @@ export class AuthorizedAdminGuard extends AuthorizedGuard { getAllowedRoles(route: ActivatedRouteSnapshot): Array<Role> { // TODO check if we need the SMP admin in here - return [Role.SYSTEM_ADMINISTRATOR/*, Role.SMP_ADMINISTRATOR*/]; + return [Role.SYSTEM_ADMIN/*, Role.SMP_ADMIN*/]; } } diff --git a/smp-angular/src/app/security/role.model.ts b/smp-angular/src/app/security/role.model.ts index a30436218279dc41882bea02a275284a6341290d..0d959fbdce84c1bb646ba095944dbb39ceeacf90 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_ADMINISTRATOR = 'System Administrator', + SYSTEM_ADMIN = 'System Administrator', /** - * The SMP Administrator role. It is assimilable to the {@link SERVICE_GROUP_ADMINISTRATOR} role for now. + * The SMP Administrator role. It is assimilable to the {@link SERVICE_GROUP_ADMIN} role for now. */ - SMP_ADMINISTRATOR = 'SMP Administrator', + SMP_ADMIN = 'SMP Administrator', /** * The ServiceGroup administrator role */ - SERVICE_GROUP_ADMINISTRATOR = 'ServiceGroup Administrator', + SERVICE_GROUP_ADMIN = 'ServiceGroup Administrator', } diff --git a/smp-angular/src/app/security/security.service.ts b/smp-angular/src/app/security/security.service.ts index b983fd175afce0c35a68fd3b7a1e251394ad7c64..ffa63b454c69ed59a271e41d0137732da7f69848 100644 --- a/smp-angular/src/app/security/security.service.ts +++ b/smp-angular/src/app/security/security.service.ts @@ -82,11 +82,11 @@ export class SecurityService { } isCurrentUserSuperAdmin(): boolean { - return this.isCurrentUserInRole([Role.SYSTEM_ADMINISTRATOR]); + return this.isCurrentUserInRole([Role.SYSTEM_ADMIN]); } isCurrentUserAdmin(): boolean { - return this.isCurrentUserInRole([Role.SYSTEM_ADMINISTRATOR, Role.SMP_ADMINISTRATOR]); + return this.isCurrentUserInRole([Role.SYSTEM_ADMIN, Role.SMP_ADMIN]); } isCurrentUserInRole(roles: Array<Role>): boolean { 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 4a39a063b28f7e6e253add8a707441ab3abe32d9..9f8c0b64d35853ca961e761e1e2c4c3e666a6b63 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 @@ -24,6 +24,8 @@ export class UserDetailsDialogComponent { readonly passwordPattern = '^(?=.*[A-Z])(?=.*[ !#$%&\'()*+,-./:;<=>?@\\[^_`{|}~\\\]"])(?=.*[0-9])(?=.*[a-z]).{8,32}$'; readonly dateFormat: string = 'yyyy-MM-dd HH:mm:ssZ'; + id: number; + editMode: boolean; formTitle: string; userRoles = []; @@ -65,7 +67,9 @@ export class UserDetailsDialogComponent { @Inject(MAT_DIALOG_DATA) public data: any, private fb: FormBuilder) { this.editMode = data.edit; - this.formTitle = this.editMode ? UserDetailsDialogComponent.EDIT_MODE: UserDetailsDialogComponent.NEW_MODE; + this.id = data.row && data.row.id; + + this.formTitle = this.editMode ? UserDetailsDialogComponent.EDIT_MODE: UserDetailsDialogComponent.NEW_MODE; const user: UserRo & { confirmation?: string } = this.editMode ? { @@ -78,14 +82,13 @@ export class UserDetailsDialogComponent { validTo: data.row.validTo, issuer: data.row.issuer, serialNumber: data.row.serialNumber, - } + }, }: { username: '', email: '', password: '', confirmation: '', role: '', - status: SearchTableEntityStatus.NEW, certificate: {}, }; @@ -94,7 +97,7 @@ export class UserDetailsDialogComponent { this.userForm = fb.group({ '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), + 'role': new FormControl({ value: Role[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)), @@ -113,6 +116,7 @@ export class UserDetailsDialogComponent { this.existingRoles = this.editMode ? this.getAllowedRoles(this.userRoles, user.role) : this.userRoles; + console.log(this.userRoles, this.existingRoles); }); } @@ -155,15 +159,22 @@ export class UserDetailsDialogComponent { } get current(): UserRo { - return this.userForm.getRawValue(); + const rawValue = this.userForm.getRawValue(); + + return { + ...rawValue, + id: this.id, + role: Object.keys(Role).find(k => Role[k] === rawValue.role), // ugly hack to find the corresponding enum key as a string + status: this.id ? SearchTableEntityStatus.UPDATED: SearchTableEntityStatus.NEW, + }; } // filters out roles so that the user cannot change from system administrator to the other roles or vice-versa private getAllowedRoles(allRoles, userRole) { - if (userRole === Role.SYSTEM_ADMINISTRATOR) { - return [Role.SYSTEM_ADMINISTRATOR]; + if (userRole === Role.SYSTEM_ADMIN) { + return [Role.SYSTEM_ADMIN]; } else { - return allRoles.filter(role => role !== Role.SYSTEM_ADMINISTRATOR); + return allRoles.filter(role => role !== Role.SYSTEM_ADMIN); } } } diff --git a/smp-angular/src/app/user/user.component.html b/smp-angular/src/app/user/user.component.html index 92c69b96b46a10856a50cb734a39750db60b804a..eb71b56716820e02e441553bb5e367c13aceb875 100644 --- a/smp-angular/src/app/user/user.component.html +++ b/smp-angular/src/app/user/user.component.html @@ -8,6 +8,8 @@ [showSearchPanel]="false" [filter]="filter"> + <ng-template #roleCellTemplate let-value="value" ngx-datatable-cell-template>{{getRoleLabel(value)}}</ng-template> + <ng-template #additionalToolButtons></ng-template> </smp-search-table> diff --git a/smp-angular/src/app/user/user.component.ts b/smp-angular/src/app/user/user.component.ts index 48be157876250bada1117959cc237ae155363ac5..418c56dc3bc0bb2e8ec12e755e476da293b977f9 100644 --- a/smp-angular/src/app/user/user.component.ts +++ b/smp-angular/src/app/user/user.component.ts @@ -4,6 +4,8 @@ import {MatDialog, MatDialogRef} from '@angular/material'; import {AlertService} from '../alert/alert.service'; import {UserController} from './user-controller'; import {HttpClient} from '@angular/common/http'; +import {Role} from "../security/role.model"; +import {UserRo} from "./user-ro.model"; @Component({ templateUrl:'./user.component.html', @@ -11,9 +13,7 @@ import {HttpClient} from '@angular/common/http'; }) export class UserComponent implements OnInit { - @ViewChild('rowMetadataAction') rowMetadataAction: TemplateRef<any> - @ViewChild('rowExtensionAction') rowExtensionAction: TemplateRef<any> - @ViewChild('rowActions') rowActions: TemplateRef<any>; + @ViewChild('roleCellTemplate') roleCellTemplate: TemplateRef<any> columnPicker: ColumnPicker = new ColumnPicker(); userController: UserController; @@ -37,6 +37,7 @@ export class UserComponent implements OnInit { canAutoResize: true }, { + cellTemplate: this.roleCellTemplate, name: 'Role', prop: 'role', canAutoResize: true @@ -51,4 +52,8 @@ export class UserComponent implements OnInit { details(row: any) { this.userController.showDetails(row); } + + getRoleLabel(role: string): Role { + return Role[role]; + } } diff --git a/smp-angular/src/app/user/user.service.ts b/smp-angular/src/app/user/user.service.ts index 59e424de69d20dad854a83f4a0e203de3c2e5e60..aaa14629e2443ce1695996c406df8b67e71adb87 100644 --- a/smp-angular/src/app/user/user.service.ts +++ b/smp-angular/src/app/user/user.service.ts @@ -11,6 +11,6 @@ export class UserService { getUserRoles$() { // return this.http.get('rest/user/userroles'); // TODO create the endpoint - return of({json: () => [Role.SYSTEM_ADMINISTRATOR, Role.SMP_ADMINISTRATOR, Role.SERVICE_GROUP_ADMINISTRATOR]}); + return of({json: () => [Role.SYSTEM_ADMIN, Role.SMP_ADMIN, Role.SERVICE_GROUP_ADMIN]}); } } 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 569447d41d4d543309e944f8323186077f3b4799..210426927d7f2d35caa8bef67ecbffa2789cbb04 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 @@ -1,26 +1,22 @@ package eu.europa.ec.edelivery.smp.ui; - import eu.europa.ec.edelivery.smp.data.ui.CertificateRO; -import eu.europa.ec.edelivery.smp.data.ui.DomainRO; import eu.europa.ec.edelivery.smp.data.ui.ServiceResult; import eu.europa.ec.edelivery.smp.data.ui.UserRO; import eu.europa.ec.edelivery.smp.logging.SMPLogger; import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory; import eu.europa.ec.edelivery.smp.services.ui.UIUserService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; -import javax.annotation.PostConstruct; -import javax.ws.rs.Consumes; -import javax.ws.rs.POST; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.IOException; -import java.io.InputStream; import java.security.cert.CertificateException; import java.util.Arrays; @@ -38,43 +34,31 @@ public class UserResource { @Autowired private UIUserService uiUserService; - @PostConstruct - protected void init() { - - } - - @PutMapping(produces = {"application/json"}) + @GetMapping @ResponseBody - @RequestMapping(method = RequestMethod.GET) public ServiceResult<UserRO> getUsers( @RequestParam(value = "page", defaultValue = "0") int page, @RequestParam(value = "pageSize", defaultValue = "10") int pageSize, @RequestParam(value = "orderBy", required = false) String orderBy, @RequestParam(value = "orderType", defaultValue = "asc", required = false) String orderType, - @RequestParam(value = "user", required = false) String user - ) { - - + @RequestParam(value = "user", required = false) String user) { return uiUserService.getTableList(page,pageSize, orderBy, orderType, null); } @PutMapping(produces = {"application/json"}) - @RequestMapping(method = RequestMethod.PUT) public void updateUserList(@RequestBody(required = true) UserRO[] updateEntities ){ - LOG.info("Update user list, count: {}" + updateEntities.length); + LOG.info("Update user list, count: {}", updateEntities.length); uiUserService.updateUserList(Arrays.asList(updateEntities)); } - - @RequestMapping(path = "certdata", method = RequestMethod.POST) + @PostMapping(path = "certdata") public CertificateRO uploadFile(@RequestBody byte[] data) { LOG.info("Got certificate data: " + data.length); try { return uiUserService.getCertificateData(data); } catch (CertificateException e) { - LOG.error("Error occured while parsing certificate.", e); + LOG.error("Error occurred while parsing certificate.", e); } return null; - } }