Code development platform for open source projects from the European Union institutions :large_blue_circle: EU Login authentication by SMS will be completely phased out by mid-2025. To see alternatives please check here

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

Merge pull request #116 in EDELIVERY/smp from...

Merge pull request #116 in EDELIVERY/smp from feature/EDELIVERY-3687-smp-ui-add-edit-user to development

* commit '663c62a3be135e616aaf52b314aa402b75d60fc2':
  EDELIVERY-3687 SMP UI Add/Edit user
parents fe720c3f cfcfe0eb
No related branches found
No related tags found
No related merge requests found
......@@ -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*/];
}
}
......@@ -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',
}
......@@ -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 {
......
......@@ -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);
}
}
}
......@@ -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>
......@@ -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];
}
}
......@@ -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]});
}
}
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;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment