mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-01-03 03:26:42 +00:00
user details, Add/remove permissions
This commit is contained in:
parent
65f1d45dc5
commit
0d5f11dfc1
@ -64,11 +64,15 @@ import {ManagementComponent} from "@components/management/management.component";
|
|||||||
import {RoleManagementComponent} from "@components/role-management/role-management.component";
|
import {RoleManagementComponent} from "@components/role-management/role-management.component";
|
||||||
import {RoleDetailComponent} from "@components/role-management/role-detail/role-detail.component";
|
import {RoleDetailComponent} from "@components/role-management/role-detail/role-detail.component";
|
||||||
import {RoleDetailResolver} from "@resolvers/role-detail.resolver";
|
import {RoleDetailResolver} from "@resolvers/role-detail.resolver";
|
||||||
import {PermissionEditorComponent} from "@components/role-management/role-detail/permission-editor/permission-editor.component";
|
|
||||||
import {PermissionResolver} from "@resolvers/permission.resolver";
|
import {PermissionResolver} from "@resolvers/permission.resolver";
|
||||||
import {PermissionsManagementComponent} from "@components/permissions-management/permissions-management.component";
|
|
||||||
import {GroupResolver} from "@resolvers/group.resolver";
|
import {GroupResolver} from "@resolvers/group.resolver";
|
||||||
import {GroupRoleResolver} from "@resolvers/group-role.resolver";
|
import {GroupRoleResolver} from "@resolvers/group-role.resolver";
|
||||||
|
import {PermissionsManagementComponent} from "@components/permissions-management/permissions-management.component";
|
||||||
|
import {UserDetailResolver} from "@resolvers/user-detail.resolver";
|
||||||
|
import {UserGroupsResolver} from "@resolvers/user-groups.resolver";
|
||||||
|
import {UserPermissionsResolver} from "@resolvers/user-permissions.resolver";
|
||||||
|
import {RolePermissionsComponent} from "@components/role-management/role-detail/role-permissions/role-permissions.component";
|
||||||
|
import {UserPermissionsComponent} from "@components/user-management/user-detail/user-permissions/user-permissions.component";
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
@ -93,7 +97,11 @@ const routes: Routes = [
|
|||||||
path: 'server/:server_id/management/users/:user_id',
|
path: 'server/:server_id/management/users/:user_id',
|
||||||
component: UserDetailComponent,
|
component: UserDetailComponent,
|
||||||
canActivate: [LoginGuard],
|
canActivate: [LoginGuard],
|
||||||
resolve: {server: ServerResolve},
|
resolve: {
|
||||||
|
user: UserDetailResolver,
|
||||||
|
groups: UserGroupsResolver,
|
||||||
|
permissions: UserPermissionsResolver,
|
||||||
|
server: ServerResolve},
|
||||||
},
|
},
|
||||||
{path: 'installed-software', component: InstalledSoftwareComponent},
|
{path: 'installed-software', component: InstalledSoftwareComponent},
|
||||||
{path: 'server/:server_id/systemstatus', component: SystemStatusComponent, canActivate: [LoginGuard]},
|
{path: 'server/:server_id/systemstatus', component: SystemStatusComponent, canActivate: [LoginGuard]},
|
||||||
@ -266,7 +274,7 @@ const routes: Routes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'server/:server_id/management/roles/:role_id/permissions',
|
path: 'server/:server_id/management/roles/:role_id/permissions',
|
||||||
component: PermissionEditorComponent,
|
component: RolePermissionsComponent,
|
||||||
resolve: {
|
resolve: {
|
||||||
role: RoleDetailResolver,
|
role: RoleDetailResolver,
|
||||||
server: ServerResolve,
|
server: ServerResolve,
|
||||||
@ -274,10 +282,14 @@ const routes: Routes = [
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'server/:server_id/permission_management',
|
path: 'server/:server_id/management/users/:user_id/permissions',
|
||||||
component: PermissionsManagementComponent,
|
component: UserPermissionsComponent,
|
||||||
canActivate: [LoginGuard],
|
resolve: {
|
||||||
resolve: { server: ServerResolve },
|
user: UserDetailResolver,
|
||||||
|
userPermissions: UserPermissionsResolver,
|
||||||
|
server: ServerResolve,
|
||||||
|
permissions: PermissionResolver
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -300,6 +300,8 @@ import { PermissionEditorValidateDialogComponent } from './components/role-manag
|
|||||||
import { PermissionsManagementComponent } from './components/permissions-management/permissions-management.component';
|
import { PermissionsManagementComponent } from './components/permissions-management/permissions-management.component';
|
||||||
import { PermissionEditLineComponent } from '@components/permissions-management/permission-edit-line/permission-edit-line.component';
|
import { PermissionEditLineComponent } from '@components/permissions-management/permission-edit-line/permission-edit-line.component';
|
||||||
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
|
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
|
||||||
|
import { RolePermissionsComponent } from './components/role-management/role-detail/role-permissions/role-permissions.component';
|
||||||
|
import { UserPermissionsComponent } from './components/user-management/user-detail/user-permissions/user-permissions.component';
|
||||||
import {MatAutocompleteModule} from "@angular/material/autocomplete";
|
import {MatAutocompleteModule} from "@angular/material/autocomplete";
|
||||||
import {PathAutoCompleteComponent} from './components/permissions-management/add-permission-line/path-auto-complete/path-auto-complete.component';
|
import {PathAutoCompleteComponent} from './components/permissions-management/add-permission-line/path-auto-complete/path-auto-complete.component';
|
||||||
import {FilterCompletePipe} from './components/permissions-management/add-permission-line/path-auto-complete/filter-complete.pipe';
|
import {FilterCompletePipe} from './components/permissions-management/add-permission-line/path-auto-complete/filter-complete.pipe';
|
||||||
@ -528,7 +530,9 @@ import {MatFormFieldModule} from "@angular/material/form-field";
|
|||||||
ActionButtonComponent,
|
ActionButtonComponent,
|
||||||
DeletePermissionDialogComponent,
|
DeletePermissionDialogComponent,
|
||||||
PathAutoCompleteComponent,
|
PathAutoCompleteComponent,
|
||||||
FilterCompletePipe
|
FilterCompletePipe,
|
||||||
|
RolePermissionsComponent,
|
||||||
|
UserPermissionsComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
<div class="row align-items-center">
|
<div class="row align-items-center">
|
||||||
<a
|
<a
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
matTooltip="Back to user management"
|
matTooltip="Back to group management"
|
||||||
matTooltipClass="custom-tooltip"
|
matTooltipClass="custom-tooltip"
|
||||||
[routerLink]="['/server', server.id, 'management', 'groups']">
|
[routerLink]="['/server', server.id, 'management', 'groups']">
|
||||||
<mat-icon aria-label="Back to user management">keyboard_arrow_left</mat-icon>
|
<mat-icon aria-label="Back to group management">keyboard_arrow_left</mat-icon>
|
||||||
</a>
|
</a>
|
||||||
<h1 class="col">Groups {{group.name}} details</h1>
|
<h1 class="col">Groups {{group.name}} details</h1>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,18 +1,4 @@
|
|||||||
<div class="header">
|
<div class="header">
|
||||||
<div>
|
|
||||||
<div>
|
|
||||||
<a
|
|
||||||
mat-icon-button
|
|
||||||
matTooltip="Back to role detail"
|
|
||||||
matTooltipClass="custom-tooltip"
|
|
||||||
[routerLink]="['/server', server.id, 'management', 'roles', role.role_id]">
|
|
||||||
<mat-icon aria-label="Back to role detail">keyboard_arrow_left</mat-icon>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Edit {{role.name}} role permissions
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
Allow:
|
Allow:
|
||||||
|
@ -10,16 +10,13 @@
|
|||||||
*
|
*
|
||||||
* Author: Sylvain MATHIEU, Elise LEBEAU
|
* Author: Sylvain MATHIEU, Elise LEBEAU
|
||||||
*/
|
*/
|
||||||
import {Component, OnInit} from '@angular/core';
|
import {Component, Inject, Input, OnInit, Output} from '@angular/core';
|
||||||
import {ActivatedRoute, Router} from "@angular/router";
|
|
||||||
import {Role} from "@models/api/role";
|
import {Role} from "@models/api/role";
|
||||||
import {Server} from "@models/server";
|
import {Server} from "@models/server";
|
||||||
import {Permission} from "@models/api/permission";
|
import {Permission} from "@models/api/permission";
|
||||||
import {MatDialog} from "@angular/material/dialog";
|
import {MatDialog} from "@angular/material/dialog";
|
||||||
import {PermissionEditorValidateDialogComponent} from "@components/role-management/role-detail/permission-editor/permission-editor-validate-dialog/permission-editor-validate-dialog.component";
|
import {PermissionEditorValidateDialogComponent} from "@components/role-management/role-detail/permission-editor/permission-editor-validate-dialog/permission-editor-validate-dialog.component";
|
||||||
import {forkJoin, Observable} from "rxjs";
|
import { EventEmitter } from '@angular/core';
|
||||||
import {RoleService} from "@services/role.service";
|
|
||||||
import {ToasterService} from "@services/toaster.service";
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-permission-editor',
|
selector: 'app-permission-editor',
|
||||||
@ -28,25 +25,18 @@ import {ToasterService} from "@services/toaster.service";
|
|||||||
})
|
})
|
||||||
export class PermissionEditorComponent implements OnInit {
|
export class PermissionEditorComponent implements OnInit {
|
||||||
server: Server;
|
server: Server;
|
||||||
role: Role;
|
|
||||||
private permissions: Permission[];
|
|
||||||
owned: Set<Permission>;
|
owned: Set<Permission>;
|
||||||
available: Set<Permission>;
|
available: Set<Permission>;
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute,
|
@Input() ownedPermissions: Permission[];
|
||||||
private dialog: MatDialog,
|
@Input() availablePermissions: Permission[];
|
||||||
private toastService: ToasterService,
|
@Output() updatedPermissions: EventEmitter<any> = new EventEmitter();
|
||||||
private router: Router,
|
|
||||||
private roleService: RoleService) {
|
|
||||||
this.route.data.subscribe((data: { server: Server, role: Role, permissions: Permission[] }) => {
|
constructor(private dialog: MatDialog) {}
|
||||||
this.server = data.server;
|
|
||||||
this.role = data.role;
|
|
||||||
this.permissions = data.permissions;
|
|
||||||
this.reset();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
this.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
add(permission: Permission) {
|
add(permission: Permission) {
|
||||||
@ -60,9 +50,9 @@ export class PermissionEditorComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
const ownedPermissionId = this.role.permissions.map(p => p.permission_id);
|
const ownedPermissionId = this.ownedPermissions.map(p => p.permission_id);
|
||||||
this.owned = new Set(this.role.permissions);
|
this.owned = new Set(this.ownedPermissions);
|
||||||
this.available = new Set(this.permissions.filter(p => !ownedPermissionId.includes(p.permission_id)));
|
this.available = new Set(this.availablePermissions.filter(p => !ownedPermissionId.includes(p.permission_id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
@ -73,22 +63,7 @@ export class PermissionEditorComponent implements OnInit {
|
|||||||
.afterClosed()
|
.afterClosed()
|
||||||
.subscribe((confirmed: boolean) => {
|
.subscribe((confirmed: boolean) => {
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
const obs: Observable<any>[] = [];
|
this.updatedPermissions.emit({add, remove});
|
||||||
add.forEach((permission: Permission) => {
|
|
||||||
obs.push(this.roleService.addPermission(this.server, this.role, permission));
|
|
||||||
});
|
|
||||||
remove.forEach((permission: Permission) => {
|
|
||||||
obs.push(this.roleService.removePermission(this.server, this.role, permission));
|
|
||||||
});
|
|
||||||
|
|
||||||
forkJoin(obs)
|
|
||||||
.subscribe(() => {
|
|
||||||
this.toastService.success(`permissions updated`);
|
|
||||||
this.router.navigate(['/server', this.server.id, 'management', 'roles', this.role.role_id]);
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
this.toastService.error(error);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -97,7 +72,7 @@ export class PermissionEditorComponent implements OnInit {
|
|||||||
private diff() {
|
private diff() {
|
||||||
const add: Permission[] = [];
|
const add: Permission[] = [];
|
||||||
|
|
||||||
const currentRolePermissionId = this.role.permissions.map(p => p.permission_id);
|
const currentRolePermissionId = this.ownedPermissions.map(p => p.permission_id);
|
||||||
this.owned.forEach((permission: Permission) => {
|
this.owned.forEach((permission: Permission) => {
|
||||||
if (!currentRolePermissionId.includes(permission.permission_id)) {
|
if (!currentRolePermissionId.includes(permission.permission_id)) {
|
||||||
add.push(permission);
|
add.push(permission);
|
||||||
@ -105,7 +80,7 @@ export class PermissionEditorComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const remove: Permission[] = [];
|
const remove: Permission[] = [];
|
||||||
this.role.permissions.forEach((permission: Permission) => {
|
this.ownedPermissions.forEach((permission: Permission) => {
|
||||||
if (!this.owned.has(permission)) {
|
if (!this.owned.has(permission)) {
|
||||||
remove.push(permission);
|
remove.push(permission);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
<div class="header">
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
mat-icon-button
|
||||||
|
matTooltip="Back to role detail"
|
||||||
|
matTooltipClass="custom-tooltip"
|
||||||
|
[routerLink]="['/server', server.id, 'management', 'roles', role.role_id]">
|
||||||
|
<mat-icon aria-label="Back to role detail">keyboard_arrow_left</mat-icon>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Edit {{role.name}} role permissions
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<app-permission-editor [ownedPermissions]="role.permissions" [availablePermissions]="permissions"
|
||||||
|
(updatedPermissions)="updatePermissions($event)"></app-permission-editor>
|
@ -0,0 +1,25 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { RolePermissionsComponent } from './role-permissions.component';
|
||||||
|
|
||||||
|
describe('RolePermissionsComponent', () => {
|
||||||
|
let component: RolePermissionsComponent;
|
||||||
|
let fixture: ComponentFixture<RolePermissionsComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ RolePermissionsComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(RolePermissionsComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,56 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import {ActivatedRoute, Router} from "@angular/router";
|
||||||
|
import {MatDialog} from "@angular/material/dialog";
|
||||||
|
import {ToasterService} from "@services/toaster.service";
|
||||||
|
import {RoleService} from "@services/role.service";
|
||||||
|
import {Server} from "@models/server";
|
||||||
|
import {Role} from "@models/api/role";
|
||||||
|
import {Permission} from "@models/api/permission";
|
||||||
|
import {Observable} from "rxjs/Rx";
|
||||||
|
import {forkJoin} from "rxjs";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-role-permissions',
|
||||||
|
templateUrl: './role-permissions.component.html',
|
||||||
|
styleUrls: ['./role-permissions.component.scss']
|
||||||
|
})
|
||||||
|
export class RolePermissionsComponent implements OnInit {
|
||||||
|
server: Server;
|
||||||
|
role: Role;
|
||||||
|
permissions: Permission[];
|
||||||
|
|
||||||
|
constructor(private route: ActivatedRoute,
|
||||||
|
private dialog: MatDialog,
|
||||||
|
private toastService: ToasterService,
|
||||||
|
private router: Router,
|
||||||
|
private roleService: RoleService) {
|
||||||
|
this.route.data.subscribe((data: { server: Server, role: Role, permissions: Permission[] }) => {
|
||||||
|
this.server = data.server;
|
||||||
|
this.role = data.role;
|
||||||
|
this.permissions = data.permissions;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePermissions(toUpdate) {
|
||||||
|
const {add, remove} = toUpdate;
|
||||||
|
const obs: Observable<any>[] = [];
|
||||||
|
add.forEach((permission: Permission) => {
|
||||||
|
obs.push(this.roleService.addPermission(this.server, this.role, permission));
|
||||||
|
});
|
||||||
|
remove.forEach((permission: Permission) => {
|
||||||
|
obs.push(this.roleService.removePermission(this.server, this.role, permission));
|
||||||
|
});
|
||||||
|
|
||||||
|
forkJoin(obs)
|
||||||
|
.subscribe(() => {
|
||||||
|
this.toastService.success(`permissions updated`);
|
||||||
|
this.router.navigate(['/server', this.server.id, 'management', 'roles', this.role.role_id]);
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
this.toastService.error(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -12,9 +12,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="default-content">
|
<div class="default-content">
|
||||||
<div class="user-edit">
|
<mat-tab-group>
|
||||||
<h1 mat-dialog-title>Update user</h1>
|
<mat-tab label="Details" class="details">
|
||||||
<div *ngIf="user">
|
<div class="user-edit">
|
||||||
<form [formGroup]="editUserForm" class="input-field">
|
<form [formGroup]="editUserForm" class="input-field">
|
||||||
<mat-form-field class="input-field">
|
<mat-form-field class="input-field">
|
||||||
<input matInput type="text" formControlName="username" placeholder="Username"/>
|
<input matInput type="text" formControlName="username" placeholder="Username"/>
|
||||||
@ -54,6 +54,9 @@
|
|||||||
|
|
||||||
|
|
||||||
<mat-checkbox formControlName="is_active">Is active</mat-checkbox>
|
<mat-checkbox formControlName="is_active">Is active</mat-checkbox>
|
||||||
|
<div>
|
||||||
|
<mat-checkbox [checked]="user.is_superadmin" disabled>Is Superadmin</mat-checkbox>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div mat-dialog-actions class="button-div">
|
<div mat-dialog-actions class="button-div">
|
||||||
<button mat-button (click)="onEditClick()" tabindex="2" mat-raised-button color="primary"
|
<button mat-button (click)="onEditClick()" tabindex="2" mat-raised-button color="primary"
|
||||||
@ -62,19 +65,40 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<div>
|
||||||
|
<div>Creation date: {{user.created_at}}</div>
|
||||||
|
<div>Last update Date: {{user.updated_at}}</div>
|
||||||
|
<div>Last login: {{user.last_login}}</div>
|
||||||
|
<div>UUID: {{user.user_id}}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</mat-tab>
|
||||||
|
<mat-tab label="Groups">
|
||||||
|
<div class="user-groups">
|
||||||
|
<ul>
|
||||||
|
<li *ngFor="let group of groups">
|
||||||
|
<a [routerLink]="['/server', server.id, 'management','groups', group.user_group_id]"
|
||||||
|
class="table-link">{{ group.name }}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</mat-tab>
|
||||||
|
<mat-tab label="Permissions">
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
mat-button
|
||||||
|
[routerLink]="['/server', server.id, 'management', 'users', user.user_id, 'permissions']">
|
||||||
|
<mat-icon>edit</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<app-editable-permission
|
||||||
|
[permission]="permission"
|
||||||
|
*ngFor="let permission of permissions">
|
||||||
|
</app-editable-permission>
|
||||||
|
</mat-tab>
|
||||||
|
</mat-tab-group>
|
||||||
|
|
||||||
<div class="user-groups">
|
|
||||||
<h5>Groups</h5>
|
|
||||||
<ul>
|
|
||||||
<li *ngFor="let group of groups">
|
|
||||||
<a [routerLink]="['/server', server.id, 'management','groups', group.user_group_id]"
|
|
||||||
class="table-link">{{ group.name }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -5,12 +5,3 @@
|
|||||||
.button-div {
|
.button-div {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-edit ,
|
|
||||||
.user-groups {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.default-content {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
@ -8,6 +8,8 @@ import {Server} from "@models/server";
|
|||||||
import {userNameAsyncValidator} from "@components/user-management/add-user-dialog/userNameAsyncValidator";
|
import {userNameAsyncValidator} from "@components/user-management/add-user-dialog/userNameAsyncValidator";
|
||||||
import {userEmailAsyncValidator} from "@components/user-management/add-user-dialog/userEmailAsyncValidator";
|
import {userEmailAsyncValidator} from "@components/user-management/add-user-dialog/userEmailAsyncValidator";
|
||||||
import {ActivatedRoute, Router} from "@angular/router";
|
import {ActivatedRoute, Router} from "@angular/router";
|
||||||
|
import {Permission} from "@models/api/permission";
|
||||||
|
import {Role} from "@models/api/role";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-user-detail',
|
selector: 'app-user-detail',
|
||||||
@ -21,6 +23,7 @@ export class UserDetailComponent implements OnInit {
|
|||||||
user: User;
|
user: User;
|
||||||
server: Server;
|
server: Server;
|
||||||
user_id: string;
|
user_id: string;
|
||||||
|
permissions: Permission[];
|
||||||
|
|
||||||
constructor(public userService: UserService,
|
constructor(public userService: UserService,
|
||||||
private toasterService: ToasterService,
|
private toasterService: ToasterService,
|
||||||
@ -33,16 +36,14 @@ export class UserDetailComponent implements OnInit {
|
|||||||
this.server = this.route.snapshot.data['server'];
|
this.server = this.route.snapshot.data['server'];
|
||||||
if (!this.server) this.router.navigate(['/servers']);
|
if (!this.server) this.router.navigate(['/servers']);
|
||||||
|
|
||||||
this.user_id = this.route.snapshot.paramMap.get('user_id');
|
this.route.data.subscribe((d: { server: Server; user: User, groups: Group[], permissions: Permission[]}) => {
|
||||||
this.userService.get(this.server, this.user_id).subscribe((user: User) => {
|
this.user = d.user;
|
||||||
console.log(user)
|
this.user_id = this.user.user_id;
|
||||||
this.user = user;
|
this.groups = d.groups;
|
||||||
this.userService.getGroupsByUserId(this.server, this.user.user_id).subscribe(
|
this.permissions = d.permissions;
|
||||||
(groups: Group[]) => {
|
|
||||||
this.groups = groups;
|
|
||||||
});
|
|
||||||
this.initForm();
|
this.initForm();
|
||||||
})
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initForm() {
|
initForm() {
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
<div class="header">
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
mat-icon-button
|
||||||
|
matTooltip="Back to user detail"
|
||||||
|
matTooltipClass="custom-tooltip"
|
||||||
|
[routerLink]="['/server', server.id, 'management', 'users', user.user_id]">
|
||||||
|
<mat-icon aria-label="Back to user detail">keyboard_arrow_left</mat-icon>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Edit {{user.username}} role permissions
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<app-permission-editor [ownedPermissions]="userPermissions" [availablePermissions]="permissions"
|
||||||
|
(updatedPermissions)="updatePermissions($event)"></app-permission-editor>
|
@ -0,0 +1,25 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { UserPermissionsComponent } from './user-permissions.component';
|
||||||
|
|
||||||
|
describe('UserPermissionsComponent', () => {
|
||||||
|
let component: UserPermissionsComponent;
|
||||||
|
let fixture: ComponentFixture<UserPermissionsComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ UserPermissionsComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(UserPermissionsComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,62 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import {Server} from "@models/server";
|
||||||
|
import {Role} from "@models/api/role";
|
||||||
|
import {Permission} from "@models/api/permission";
|
||||||
|
import {ActivatedRoute, Router} from "@angular/router";
|
||||||
|
import {MatDialog} from "@angular/material/dialog";
|
||||||
|
import {ToasterService} from "@services/toaster.service";
|
||||||
|
import {RoleService} from "@services/role.service";
|
||||||
|
import {forkJoin} from "rxjs";
|
||||||
|
import {Observable} from "rxjs/Rx";
|
||||||
|
import {UserService} from "@services/user.service";
|
||||||
|
import {User} from "@models/users/user";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-user-permissions',
|
||||||
|
templateUrl: './user-permissions.component.html',
|
||||||
|
styleUrls: ['./user-permissions.component.scss']
|
||||||
|
})
|
||||||
|
export class UserPermissionsComponent implements OnInit {
|
||||||
|
|
||||||
|
server: Server;
|
||||||
|
user: User;
|
||||||
|
userPermissions: Permission[];
|
||||||
|
permissions: Permission[];
|
||||||
|
|
||||||
|
constructor(private route: ActivatedRoute,
|
||||||
|
private dialog: MatDialog,
|
||||||
|
private toastService: ToasterService,
|
||||||
|
private router: Router,
|
||||||
|
private userService: UserService) {
|
||||||
|
this.route.data.subscribe((data: { server: Server, user: User, userPermissions: Permission[], permissions: Permission[] }) => {
|
||||||
|
this.server = data.server;
|
||||||
|
this.user = data.user;
|
||||||
|
this.userPermissions = data.userPermissions;
|
||||||
|
this.permissions = data.permissions;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePermissions(toUpdate) {
|
||||||
|
const {add, remove} = toUpdate;
|
||||||
|
const obs: Observable<any>[] = [];
|
||||||
|
add.forEach((permission: Permission) => {
|
||||||
|
obs.push(this.userService.addPermission(this.server, this.user.user_id, permission));
|
||||||
|
});
|
||||||
|
remove.forEach((permission: Permission) => {
|
||||||
|
obs.push(this.userService.removePermission(this.server, this.user.user_id, permission));
|
||||||
|
});
|
||||||
|
|
||||||
|
forkJoin(obs)
|
||||||
|
.subscribe(() => {
|
||||||
|
this.toastService.success(`permissions updated`);
|
||||||
|
this.router.navigate(['/server', this.server.id, 'management', 'users', this.user.user_id]);
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
this.toastService.error(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
16
src/app/resolvers/user-detail.resolver.spec.ts
Normal file
16
src/app/resolvers/user-detail.resolver.spec.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { UserDetailResolver } from './user-detail.resolver';
|
||||||
|
|
||||||
|
describe('UserDetailResolver', () => {
|
||||||
|
let resolver: UserDetailResolver;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
resolver = TestBed.inject(UserDetailResolver);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(resolver).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
36
src/app/resolvers/user-detail.resolver.ts
Normal file
36
src/app/resolvers/user-detail.resolver.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import {
|
||||||
|
Router, Resolve,
|
||||||
|
RouterStateSnapshot,
|
||||||
|
ActivatedRouteSnapshot
|
||||||
|
} from '@angular/router';
|
||||||
|
import {Observable, of, Subscriber} from 'rxjs';
|
||||||
|
import {ServerService} from "@services/server.service";
|
||||||
|
import {UserService} from "@services/user.service";
|
||||||
|
import {User} from "@models/users/user";
|
||||||
|
import {Server} from "@models/server";
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class UserDetailResolver implements Resolve<User> {
|
||||||
|
|
||||||
|
constructor(private serverService: ServerService,
|
||||||
|
private userService: UserService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<User> {
|
||||||
|
return new Observable<User>((subscriber: Subscriber<User>) => {
|
||||||
|
|
||||||
|
const serverId = route.paramMap.get('server_id');
|
||||||
|
const userId = route.paramMap.get('user_id');
|
||||||
|
|
||||||
|
this.serverService.get(+serverId).then((server: Server) => {
|
||||||
|
this.userService.get(server, userId).subscribe((user: User) => {
|
||||||
|
subscriber.next(user);
|
||||||
|
subscriber.complete();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
16
src/app/resolvers/user-groups.resolver.spec.ts
Normal file
16
src/app/resolvers/user-groups.resolver.spec.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { UserGroupsResolver } from './user-groups.resolver';
|
||||||
|
|
||||||
|
describe('UserGroupsResolver', () => {
|
||||||
|
let resolver: UserGroupsResolver;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
resolver = TestBed.inject(UserGroupsResolver);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(resolver).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
36
src/app/resolvers/user-groups.resolver.ts
Normal file
36
src/app/resolvers/user-groups.resolver.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import {
|
||||||
|
Router, Resolve,
|
||||||
|
RouterStateSnapshot,
|
||||||
|
ActivatedRouteSnapshot
|
||||||
|
} from '@angular/router';
|
||||||
|
import {Observable, of, Subscriber} from 'rxjs';
|
||||||
|
import {Group} from "../models/groups/group";
|
||||||
|
import {User} from "../models/users/user";
|
||||||
|
import {Server} from "../models/server";
|
||||||
|
import {ServerService} from "../services/server.service";
|
||||||
|
import {UserService} from "../services/user.service";
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class UserGroupsResolver implements Resolve<Group[]> {
|
||||||
|
constructor(private serverService: ServerService,
|
||||||
|
private userService: UserService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Group[]> {
|
||||||
|
return new Observable<Group[]>((subscriber: Subscriber<Group[]>) => {
|
||||||
|
|
||||||
|
const serverId = route.paramMap.get('server_id');
|
||||||
|
const userId = route.paramMap.get('user_id');
|
||||||
|
|
||||||
|
this.serverService.get(+serverId).then((server: Server) => {
|
||||||
|
this.userService.getGroupsByUserId(server, userId).subscribe((groups: Group[]) => {
|
||||||
|
subscriber.next(groups);
|
||||||
|
subscriber.complete();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
16
src/app/resolvers/user-permissions.resolver.spec.ts
Normal file
16
src/app/resolvers/user-permissions.resolver.spec.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { UserPermissionsResolver } from './user-permissions.resolver';
|
||||||
|
|
||||||
|
describe('UserPermissionsResolver', () => {
|
||||||
|
let resolver: UserPermissionsResolver;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
resolver = TestBed.inject(UserPermissionsResolver);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(resolver).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
36
src/app/resolvers/user-permissions.resolver.ts
Normal file
36
src/app/resolvers/user-permissions.resolver.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import {
|
||||||
|
Router, Resolve,
|
||||||
|
RouterStateSnapshot,
|
||||||
|
ActivatedRouteSnapshot
|
||||||
|
} from '@angular/router';
|
||||||
|
import {Observable, of, Subscriber} from 'rxjs';
|
||||||
|
import {ServerService} from "../services/server.service";
|
||||||
|
import {UserService} from "../services/user.service";
|
||||||
|
import {Server} from "../models/server";
|
||||||
|
import {Permission} from "../models/api/permission";
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class UserPermissionsResolver implements Resolve<Permission[]> {
|
||||||
|
|
||||||
|
constructor(private serverService: ServerService,
|
||||||
|
private userService: UserService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Permission[]> {
|
||||||
|
return new Observable<Permission[]>((subscriber: Subscriber<Permission[]>) => {
|
||||||
|
|
||||||
|
const serverId = route.paramMap.get('server_id');
|
||||||
|
const userId = route.paramMap.get('user_id');
|
||||||
|
|
||||||
|
this.serverService.get(+serverId).then((server: Server) => {
|
||||||
|
this.userService.getPermissionsByUserId(server, userId).subscribe((permissions: Permission[]) => {
|
||||||
|
subscriber.next(permissions);
|
||||||
|
subscriber.complete();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -3,8 +3,8 @@ import {Observable, Subject} from 'rxjs';
|
|||||||
import { Server } from '../models/server';
|
import { Server } from '../models/server';
|
||||||
import { HttpServer } from './http-server.service';
|
import { HttpServer } from './http-server.service';
|
||||||
import { User } from '../models/users/user';
|
import { User } from '../models/users/user';
|
||||||
import {Project} from "@models/project";
|
|
||||||
import {Group} from "@models/groups/group";
|
import {Group} from "@models/groups/group";
|
||||||
|
import {Permission} from "@models/api/permission";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserService {
|
export class UserService {
|
||||||
@ -39,4 +39,16 @@ export class UserService {
|
|||||||
getGroupsByUserId(server: Server, user_id: string) {
|
getGroupsByUserId(server: Server, user_id: string) {
|
||||||
return this.httpServer.get<Group[]>(server, `/users/${user_id}/groups`);
|
return this.httpServer.get<Group[]>(server, `/users/${user_id}/groups`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPermissionsByUserId(server: Server, user_id: string) {
|
||||||
|
return this.httpServer.get<Permission[]>(server, `/users/${user_id}/permissions`);
|
||||||
|
}
|
||||||
|
|
||||||
|
addPermission(server: Server, user_id: string, permission: Permission) {
|
||||||
|
return this.httpServer.put(server, `/users/${user_id}/permissions/${permission.permission_id}`, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
removePermission(server: Server, user_id: string, permission: Permission) {
|
||||||
|
return this.httpServer.delete(server, `/users/${ user_id}/permissions/${permission.permission_id}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user