From a15fc5fd4e96769777dbcba49b18e6535f8f2419 Mon Sep 17 00:00:00 2001 From: xkureck <luckureckova@gmail.com> Date: Wed, 13 Oct 2021 17:08:36 +0200 Subject: [PATCH 1/2] feat(admin): new section - Service account in My profile section * new page on My profile section "Service account" * new section with user type: service in My profile section which should be used by user to manage his service accounts * in admin section pages "service identitites" and "associated users" moved from advanced menu * service identitites renamed to "service accounts" --- .../src/app/admin/admin-routing.module.ts | 38 +++++----- .../admin-user-detail-page.component.html | 2 +- .../admin-user-detail-page.component.ts | 4 ++ .../users-list/users-list.component.html | 4 +- .../users-list/users-list.component.ts | 12 ++-- .../side-menu/side-menu-item.service.ts | 66 ++++++++++++----- .../shared/side-menu/side-menu.component.ts | 2 +- .../user-overview/user-overview.component.ts | 30 ++++++-- ...r-settings-associated-users.component.html | 4 +- ...ser-settings-associated-users.component.ts | 20 +++++- .../user-settings-overview.component.ts | 17 ----- ...service-identity-detail-page.component.css | 0 ...ervice-identity-detail-page.component.html | 34 +++++++++ .../service-identity-detail-page.component.ts | 72 +++++++++++++++++++ .../service-identity-overview.component.css | 0 .../service-identity-overview.component.html | 1 + .../service-identity-overview.component.ts | 30 ++++++++ ...settings-service-identities.component.html | 60 ++++++++-------- ...r-settings-service-identities.component.ts | 27 ++++--- .../src/app/users/users-routing.module.ts | 23 ++++++ apps/admin-gui/src/app/users/users.module.ts | 4 ++ .../application-form-list.component.html | 2 +- apps/admin-gui/src/assets/i18n/en.json | 8 +-- 23 files changed, 344 insertions(+), 116 deletions(-) create mode 100644 apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-detail-page.component.css create mode 100644 apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-detail-page.component.html create mode 100644 apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-detail-page.component.ts create mode 100644 apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-overview/service-identity-overview.component.css create mode 100644 apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-overview/service-identity-overview.component.html create mode 100644 apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-overview/service-identity-overview.component.ts diff --git a/apps/admin-gui/src/app/admin/admin-routing.module.ts b/apps/admin-gui/src/app/admin/admin-routing.module.ts index 92d184e56..3283dfc22 100644 --- a/apps/admin-gui/src/app/admin/admin-routing.module.ts +++ b/apps/admin-gui/src/app/admin/admin-routing.module.ts @@ -158,26 +158,26 @@ const routes: Routes = [ data: {animation: 'UserRolesPage'} }, { - path: 'settings', - component: UserSettingsComponent, - children: [ - { - path: '', - component: UserSettingsOverviewComponent, - data: {animation: 'UserSettingsOverviewPage'} - }, - { - path: 'service-identities', - component: UserSettingsServiceIdentitiesComponent, - data: {animation: 'UserServiceIdentities'} - }, - { - path: 'associated-users', - component: UserSettingsAssociatedUsersComponent, - data: {animation: 'AssociatedUsersPage'} - } - ] + path: 'service-identities', + component: UserSettingsServiceIdentitiesComponent, + data: {animation: 'UserServiceIdentities'} + }, + { + path: 'associated-users', + component: UserSettingsAssociatedUsersComponent, + data: {animation: 'AssociatedUsersPage'} } + // { + // path: 'settings', + // component: UserSettingsComponent, + // children: [ + // { + // path: '', + // component: UserSettingsOverviewComponent, + // data: {animation: 'UserSettingsOverviewPage'} + // } + // ] + // } ] }, { diff --git a/apps/admin-gui/src/app/admin/pages/admin-user-detail-page/admin-user-detail-page.component.html b/apps/admin-gui/src/app/admin/pages/admin-user-detail-page/admin-user-detail-page.component.html index 393429d94..7c2d99921 100644 --- a/apps/admin-gui/src/app/admin/pages/admin-user-detail-page/admin-user-detail-page.component.html +++ b/apps/admin-gui/src/app/admin/pages/admin-user-detail-page/admin-user-detail-page.component.html @@ -6,7 +6,7 @@ <mat-icon matTooltip="{{'ADMIN_USER.ENTITY' | translate}}" [ngStyle]="{'color':'black'}" - svgIcon='perun-user-dark' + [svgIcon]="svgIcon" class="perun-icon perun-icon-detail"> </mat-icon> <div class="page-title-block"> diff --git a/apps/admin-gui/src/app/admin/pages/admin-user-detail-page/admin-user-detail-page.component.ts b/apps/admin-gui/src/app/admin/pages/admin-user-detail-page/admin-user-detail-page.component.ts index fb6b2e83f..879898803 100644 --- a/apps/admin-gui/src/app/admin/pages/admin-user-detail-page/admin-user-detail-page.component.ts +++ b/apps/admin-gui/src/app/admin/pages/admin-user-detail-page/admin-user-detail-page.component.ts @@ -28,6 +28,7 @@ export class AdminUserDetailPageComponent implements OnInit { path: string; regex: string; loading = false; + svgIcon = 'perun-user-dark'; ngOnInit() { this.loading = true; @@ -39,6 +40,9 @@ export class AdminUserDetailPageComponent implements OnInit { this.usersService.getUserById(userId).subscribe(user => { this.user = user; + if(this.user.serviceUser) { + this.svgIcon = 'perun-service-identity'; + } const userItem = this.sideMenuItemService.parseUser(user, this.path, this.regex); this.sideMenuService.setAdminItems([userItem]); diff --git a/apps/admin-gui/src/app/shared/components/users-list/users-list.component.html b/apps/admin-gui/src/app/shared/components/users-list/users-list.component.html index 162157695..ac008eccf 100644 --- a/apps/admin-gui/src/app/shared/components/users-list/users-list.component.html +++ b/apps/admin-gui/src/app/shared/components/users-list/users-list.component.html @@ -76,8 +76,8 @@ <tr *matRowDef="let user; columns: displayedColumns;" [class.cursor-pointer]="!disableRouting" - [perunWebAppsForceRouterLink]="disableRouting ? null : ['/admin/users', user.id]" - [perunWebAppsMiddleClickRouterLink]="disableRouting ? null : ['/admin/users', user.id]" + [perunWebAppsForceRouterLink]="disableRouting ? null : (routeToAdmin ? ['/admin/users', user.id] : ['/myProfile/service-identities', user.id])" + [perunWebAppsMiddleClickRouterLink]="disableRouting ? null : (routeToAdmin ? ['/admin/users', user.id] : ['/myProfile/service-identities', user.id])" class="dark-hover-list-item" mat-row> </tr> diff --git a/apps/admin-gui/src/app/shared/components/users-list/users-list.component.ts b/apps/admin-gui/src/app/shared/components/users-list/users-list.component.ts index 21cb25f2c..d3860c5b4 100644 --- a/apps/admin-gui/src/app/shared/components/users-list/users-list.component.ts +++ b/apps/admin-gui/src/app/shared/components/users-list/users-list.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, Input, OnChanges, ViewChild } from '@angular/core'; +import { Component, Input, OnChanges, ViewChild } from '@angular/core'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import {SelectionModel} from '@angular/cdk/collections'; @@ -17,7 +17,7 @@ import { GuiAuthResolver, TableCheckbox } from '@perun-web-apps/perun/services'; templateUrl: './users-list.component.html', styleUrls: ['./users-list.component.scss'] }) -export class UsersListComponent implements OnChanges, AfterViewInit { +export class UsersListComponent implements OnChanges{ constructor(private authResolver: GuiAuthResolver, private tableCheckbox: TableCheckbox) { } @@ -40,6 +40,9 @@ export class UsersListComponent implements OnChanges, AfterViewInit { displayedColumns: string[] = ['select', 'user', 'id', 'name', 'email', 'logins', 'organization']; + @Input() + routeToAdmin = true; + @Input() disableRouting = false; @@ -118,13 +121,10 @@ export class UsersListComponent implements OnChanges, AfterViewInit { this.dataSource.data = this.users; } - ngAfterViewInit(): void { + ngOnChanges() { if (!this.authResolver.isPerunAdminOrObserver()){ this.displayedColumns = this.displayedColumns.filter(column => column !== 'id'); } - } - - ngOnChanges() { this.setDataSource(); } diff --git a/apps/admin-gui/src/app/shared/side-menu/side-menu-item.service.ts b/apps/admin-gui/src/app/shared/side-menu/side-menu-item.service.ts index 10bb72257..e95761c8f 100644 --- a/apps/admin-gui/src/app/shared/side-menu/side-menu-item.service.ts +++ b/apps/admin-gui/src/app/shared/side-menu/side-menu-item.service.ts @@ -131,8 +131,13 @@ export class SideMenuItemService { }, { label: 'MENU_ITEMS.USER.ROLES', - url: [`myProfile/roles`], - activatedRegex: `myProfile/roles` + url: [`/myProfile/roles`], + activatedRegex: `/myProfile/roles` + }, + { + label: 'MENU_ITEMS.USER.SERVICE_IDENTITIES', + url: [`/myProfile/service-identities`], + activatedRegex: `^/myProfile/service-identities` }, { label: 'MENU_ITEMS.USER.SETTINGS', @@ -374,6 +379,31 @@ export class SideMenuItemService { }; } + parseServiceIdentity(user: User): SideMenuItem { + return { + label: parseFullName(user), + baseLink: [`/myProfile/service-identities/${user.id}`], + backgroundColorCss: this.userBgColor, + textColorCss: this.userTextColor, + links: [ + { + label: 'MENU_ITEMS.USER.OVERVIEW', + url: [`/myProfile/service-identities/${user.id}`], + activatedRegex: '/myProfile/service-identities/\\d+$' + }, + { + label: 'MENU_ITEMS.USER.ASSOCIATED_USERS', + url: [`/myProfile/service-identities/${user.id}/associated-users`], + activatedRegex: '/myProfile/service-identities/\\d+/associated-users' + } + ], + colorClass: 'user-bg-color', + icon: 'perun-service-identity', + activatedClass: 'dark-item-activated', + linksClass: 'dark-item-links' + }; + } + parseService(service: Service): SideMenuItem { return { label: service.name, @@ -639,36 +669,34 @@ export class SideMenuItemService { // Roles links.push({ label: 'MENU_ITEMS.USER.ROLES', - url: [`${path}/roles`], + url: [`${path}/roles`], activatedRegex: `^${path}/roles` }); - - // Settings - links.push({ - label: 'MENU_ITEMS.ADMIN.SETTINGS', - url: [`${path}/settings`], - activatedRegex: `${regex}/settings$`, - children: [], - showChildrenRegex: `${regex}/settings` - }); - // Settings associated users if user is service // Settings service identities if user is person if (user.serviceUser) { - links[links.length - 1].children.push({ + links.push({ label: 'MENU_ITEMS.USER.ASSOCIATED_USERS', - url: [`${path}/settings/associated-users`], - activatedRegex: `^${path}/settings/associated-users` + url: [`${path}/associated-users`], + activatedRegex: `^${path}/associated-users` }); } else { - links[links.length - 1].children.push({ + links.push({ label: 'MENU_ITEMS.USER.SERVICE_IDENTITIES', - url: [`${path}/settings/service-identities`], - activatedRegex: `^${path}/settings/service-identities` + url: [`${path}/service-identities`], + activatedRegex: `^${path}/service-identities` }); } + // Settings + // links.push({ + // label: 'MENU_ITEMS.ADMIN.SETTINGS', + // url: [`${path}/settings`], + // activatedRegex: `${regex}/settings$`, + // children: [], + // showChildrenRegex: `${regex}/settings` + // }); return links; } diff --git a/apps/admin-gui/src/app/shared/side-menu/side-menu.component.ts b/apps/admin-gui/src/app/shared/side-menu/side-menu.component.ts index a5a29892c..fa91eded2 100644 --- a/apps/admin-gui/src/app/shared/side-menu/side-menu.component.ts +++ b/apps/admin-gui/src/app/shared/side-menu/side-menu.component.ts @@ -141,7 +141,7 @@ export class SideMenuComponent implements OnInit { } private setUserItems(items: SideMenuItem[]) { - this.userItemOpened = true; + this.userItemOpened = items.length === 0; this.resetExceptUser(); this.setNewItems(this.userItems, items); } diff --git a/apps/admin-gui/src/app/users/pages/user-detail-page/user-overview/user-overview.component.ts b/apps/admin-gui/src/app/users/pages/user-detail-page/user-overview/user-overview.component.ts index 46314c8ec..5f2b5febc 100644 --- a/apps/admin-gui/src/app/users/pages/user-detail-page/user-overview/user-overview.component.ts +++ b/apps/admin-gui/src/app/users/pages/user-detail-page/user-overview/user-overview.component.ts @@ -29,6 +29,7 @@ export class UserOverviewComponent implements OnInit { navItems: MenuItem[] = []; user: User; + isServiceUser = false; userID: number; path: string; mailDataSource: MatTableDataSource<Attribute>; @@ -41,7 +42,7 @@ export class UserOverviewComponent implements OnInit { if(params['userId'] !== undefined) { this.userService.getUserById(params['userId']).subscribe(user => { this.user = user; - + this.isServiceUser = user.serviceUser; this.initNavItems(); }); } else { @@ -113,13 +114,30 @@ export class UserOverviewComponent implements OnInit { url: `roles`, label: 'MENU_ITEMS.USER.ROLES', style: 'user-btn' - }, - { - cssIcon: 'perun-settings2', - url: `settings`, - label: 'MENU_ITEMS.ADMIN.SETTINGS', + }); + if(this.isServiceUser){ + this.navItems.push({ + cssIcon: 'perun-user-dark', + url:`associated-users`, + label: 'MENU_ITEMS.USER.ASSOCIATED_USERS', style: 'user-btn' }); + } else { + this.navItems.push({ + cssIcon: 'perun-service-identity', + url:`service-identities`, + label: 'MENU_ITEMS.USER.SERVICE_IDENTITIES', + style: 'user-btn' + }); + } + if (!window.location.pathname.startsWith('/admin')) { + this.navItems.push({ + cssIcon: 'perun-settings2', + url: `settings`, + label: 'MENU_ITEMS.ADMIN.SETTINGS', + style: 'user-btn' + }); + } } changeEmail() { diff --git a/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-associated-users/user-settings-associated-users.component.html b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-associated-users/user-settings-associated-users.component.html index 562ab1d5f..1862081be 100644 --- a/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-associated-users/user-settings-associated-users.component.html +++ b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-associated-users/user-settings-associated-users.component.html @@ -24,7 +24,9 @@ *ngIf="!loading" [users]="associatedUsers" [selection]="selection" - [displayedColumns]="displayedColumns"> + [disableRouting]="disableRouting" + [displayedColumns]="displayedColumns" + > </app-users-list> </div> diff --git a/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-associated-users/user-settings-associated-users.component.ts b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-associated-users/user-settings-associated-users.component.ts index 21d897256..99dac9c02 100644 --- a/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-associated-users/user-settings-associated-users.component.ts +++ b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-associated-users/user-settings-associated-users.component.ts @@ -9,6 +9,7 @@ import { SelectionModel } from '@angular/cdk/collections'; import { getDefaultDialogConfig } from '@perun-web-apps/perun/utils'; import { ConnectIdentityDialogComponent } from '../../../../../shared/components/dialogs/connect-identity-dialog/connect-identity-dialog.component'; import { DisconnectIdentityDialogComponent } from '../../../../../shared/components/dialogs/disconnect-identity-dialog/disconnect-identity-dialog.component'; +import { GuiAuthResolver } from '@perun-web-apps/perun/services'; @Component({ selector: 'app-user-settings-associated-users', @@ -20,6 +21,7 @@ export class UserSettingsAssociatedUsersComponent implements OnInit { constructor(private route: ActivatedRoute, private dialog: MatDialog, private router: Router, + public authResolver: GuiAuthResolver, private userManager: UsersManagerService) { } @@ -29,15 +31,19 @@ export class UserSettingsAssociatedUsersComponent implements OnInit { userId: number; tableId = TABLE_USER_ASSOCIATED_USERS; displayedColumns = [ 'select', 'id', 'user', 'name' ]; + addAuth: boolean; + removeAuth: boolean; + disableRouting: boolean; ngOnInit(): void { this.loading = true; - this.route.parent.parent.params + this.route.parent.params .subscribe(params => { this.userId = params["userId"]; this.userManager.getUsersBySpecificUser(this.userId).subscribe(associatedUsers => { this.associatedUsers = associatedUsers; + this.setAuth(); this.loading = false; }); }); @@ -52,6 +58,12 @@ export class UserSettingsAssociatedUsersComponent implements OnInit { }); } + setAuth() { + this.addAuth = this.authResolver.isAuthorized('addSpecificUserOwner_User_User_policy', [{id: this.userId, beanName: 'User'}]); + this.removeAuth = this.authResolver.isAuthorized('removeSpecificUserOwner_User_User_policy', [{id: this.userId, beanName: 'User'}]); + this.disableRouting = !this.authResolver.isPerunAdminOrObserver(); + } + onAdd(){ const config = getDefaultDialogConfig(); config.width = "1250px"; @@ -85,7 +97,11 @@ export class UserSettingsAssociatedUsersComponent implements OnInit { dialogRef.afterClosed().subscribe(result => { if (result) { - this.refreshTable(); + if(!this.authResolver.isAuthorized('getUsersBySpecificUser_User_policy', [{id: this.userId, beanName: 'User'}])) { + this.router.navigate(['/myProfile']); + } else { + this.refreshTable(); + } } }); } diff --git a/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-overview/user-settings-overview.component.ts b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-overview/user-settings-overview.component.ts index 748207c1e..e2d360ea0 100644 --- a/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-overview/user-settings-overview.component.ts +++ b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-overview/user-settings-overview.component.ts @@ -42,7 +42,6 @@ export class UserSettingsOverviewComponent implements OnInit { this.navItems = [ ]; // if at user profile, add user gui config item - // if at admin profile, add service identities if (!window.location.pathname.startsWith('/admin')) { this.navItems.push( { @@ -57,22 +56,6 @@ export class UserSettingsOverviewComponent implements OnInit { label: 'MENU_ITEMS.USER.GUI_CONFIG', style: 'user-btn' }); - } else { - if(this.isServiceUser){ - this.navItems.push({ - cssIcon: 'perun-service-identity', - url:`associated-users`, - label: 'MENU_ITEMS.USER.ASSOCIATED_USERS', - style: 'user-btn' - }); - } else { - this.navItems.push({ - cssIcon: 'perun-service-identity', - url:`service-identities`, - label: 'MENU_ITEMS.USER.SERVICE_IDENTITIES', - style: 'user-btn' - }); - } } } } diff --git a/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-detail-page.component.css b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-detail-page.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-detail-page.component.html b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-detail-page.component.html new file mode 100644 index 000000000..7eb18042c --- /dev/null +++ b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-detail-page.component.html @@ -0,0 +1,34 @@ +<div *ngIf="user !== undefined" class="container-fluid pl-xl-5 pr-xl-5 user-theme"> + <perun-web-apps-back-button> + </perun-web-apps-back-button> + <mat-spinner *ngIf="loading" class="mr-auto ml-auto"></mat-spinner> + <div class="d-flex page-title-headtitle"> + <mat-icon + matTooltip="{{'MENU_ITEMS.USER.ENTITY' | translate}}" + [ngStyle]="{'color':'black'}" + svgIcon='perun-service-identity' + class="perun-icon perun-icon-detail"> + </mat-icon> + <div class="page-title-block"> + <div class="page-title-headline d-flex align-items-center"> + <a [routerLink]="['/myProfile/service-identities', user.id]" class="user-link" queryParamsHandling="merge"> + {{user | userFullName}} + </a> + <span class="text-muted"> + #{{user.id}} + </span> + <button *ngIf="authResolver.isPerunAdmin()" (click)="editUser()" mat-icon-button> + <mat-icon>edit</mat-icon> + </button> + </div> + <div> + {{'ADMIN_USER.UUID' | translate}}: {{user.uuid}} + </div> + <span class="mt-1 entity-info"> + {{'MENU_ITEMS.USER.ENTITY' | translate}}, + {{'MENU_ITEMS.USER.USER_TYPE' | translate}}: {{getUserType()}} + </span> + </div> + </div> + <app-animated-router-outlet></app-animated-router-outlet> +</div> diff --git a/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-detail-page.component.ts b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-detail-page.component.ts new file mode 100644 index 000000000..d8b7113f3 --- /dev/null +++ b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-detail-page.component.ts @@ -0,0 +1,72 @@ +import { Component, OnInit } from '@angular/core'; +import { SideMenuService } from '../../../../../../core/services/common/side-menu.service'; +import { GuiAuthResolver } from '@perun-web-apps/perun/services'; +import { ActivatedRoute } from '@angular/router'; +import { User, UsersManagerService } from '@perun-web-apps/perun/openapi'; +import { SideMenuItemService } from '../../../../../../shared/side-menu/side-menu-item.service'; +import { getDefaultDialogConfig } from '@perun-web-apps/perun/utils'; +import { EditUserDialogComponent } from '../../../../../../shared/components/dialogs/edit-user-dialog/edit-user-dialog.component'; +import { MatDialog } from '@angular/material/dialog'; + +@Component({ + selector: 'app-service-identity-detail-page', + templateUrl: './service-identity-detail-page.component.html', + styleUrls: ['./service-identity-detail-page.component.css'] +}) +export class ServiceIdentityDetailPageComponent implements OnInit { + + constructor( + private sideMenuService: SideMenuService, + private usersService: UsersManagerService, + private sideMenuItemService: SideMenuItemService, + private route: ActivatedRoute, + private dialog: MatDialog, + public authResolver: GuiAuthResolver + ) { + } + + user: User; + loading = false; + + + ngOnInit() { + this.loading = true; + this.route.params.subscribe(params => { + const userId = params['userId']; + + this.usersService.getUserById(userId).subscribe(user => { + this.user = user; + + const userItem = this.sideMenuItemService.parseServiceIdentity(user); + this.sideMenuService.setUserItems([userItem]); + this.loading = false; + }, () => this.loading = false); + }); + } + + getUserType(){ + if (this.user.serviceUser){ + return "Service"; + } + return "Person"; + } + + editUser() { + const config = getDefaultDialogConfig(); + config.width = '450px'; + config.data = { + theme: 'admin-theme', + user: this.user + }; + + const dialogRef = this.dialog.open(EditUserDialogComponent, config); + + dialogRef.afterClosed().subscribe(result => { + if (result) { + this.usersService.getUserById(this.user.id).subscribe(user => { + this.user = user; + }); + } + }); + } +} diff --git a/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-overview/service-identity-overview.component.css b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-overview/service-identity-overview.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-overview/service-identity-overview.component.html b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-overview/service-identity-overview.component.html new file mode 100644 index 000000000..77ae77437 --- /dev/null +++ b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-overview/service-identity-overview.component.html @@ -0,0 +1 @@ +<perun-web-apps-menu-buttons-field [items]="navItems" [size]="'small'"></perun-web-apps-menu-buttons-field> diff --git a/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-overview/service-identity-overview.component.ts b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-overview/service-identity-overview.component.ts new file mode 100644 index 000000000..1c55e7f16 --- /dev/null +++ b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-overview/service-identity-overview.component.ts @@ -0,0 +1,30 @@ +import { Component, OnInit } from '@angular/core'; +import { MenuItem } from '@perun-web-apps/perun/models'; + +@Component({ + selector: 'app-service-identity-overview', + templateUrl: './service-identity-overview.component.html', + styleUrls: ['./service-identity-overview.component.css'] +}) +export class ServiceIdentityOverviewComponent implements OnInit { + + constructor() { } + + navItems: MenuItem[] = []; + + ngOnInit(): void { + this.initNavItems(); + } + + private initNavItems() { + this.navItems = [ + { + cssIcon: 'perun-user', + url: `associated-users`, + label: 'MENU_ITEMS.USER.ASSOCIATED_USERS', + style: 'user-btn' + } + ]; + } + +} diff --git a/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/user-settings-service-identities.component.html b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/user-settings-service-identities.component.html index f87a1c28e..3f1e2a2fd 100644 --- a/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/user-settings-service-identities.component.html +++ b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/user-settings-service-identities.component.html @@ -1,31 +1,33 @@ -<div> - <h1 class="page-subtitle">{{'USER_DETAIL.SETTINGS.SERVICE_IDENTITIES.TITLE' | translate}}</h1> - <perun-web-apps-refresh-button (refresh)="refreshTable()" *ngIf="!loading"></perun-web-apps-refresh-button> - <button - *ngIf="!loading && authResolver.isPerunAdmin()" - (click)="onAdd()" - mat-flat-button - class="mr-2" - color="accent"> - {{'USER_DETAIL.SETTINGS.SERVICE_IDENTITIES.CREATE' | translate}} - </button> - <button - *ngIf="!loading && authResolver.isPerunAdmin()" - (click)="onRemove()" - [disabled]="selection.selected.length === 0" - mat-flat-button - class="mr-2" - color="warn"> - {{'USER_DETAIL.SETTINGS.SERVICE_IDENTITIES.DELETE' | translate}} - </button> - <app-users-list - [tableId]="tableId" - [noUsersFoundLabel]="'USER_DETAIL.SETTINGS.SERVICE_IDENTITIES.NO_IDENTITIES' | translate" - *ngIf="!loading" - [users]="identities" - [selection]="selection" - [displayedColumns]="displayedColumns"> - </app-users-list> -</div> +<h1 class="page-subtitle">{{'USER_DETAIL.SETTINGS.SERVICE_IDENTITIES.TITLE' | translate}}</h1> +<perun-web-apps-refresh-button (refresh)="refreshTable()"></perun-web-apps-refresh-button> +<button + *ngIf="!loading && addIdentity" + (click)="onAdd()" + mat-flat-button + class="mr-2" + color="accent"> + {{'USER_DETAIL.SETTINGS.SERVICE_IDENTITIES.CREATE' | translate}} +</button> +<button + *ngIf="!loading && removeIdentity" + (click)="onRemove()" + [disabled]="selection.selected.length === 0" + mat-flat-button + class="mr-2" + color="warn"> + {{'USER_DETAIL.SETTINGS.SERVICE_IDENTITIES.DELETE' | translate}} +</button> <mat-spinner *ngIf="loading" class="mr-auto ml-auto"></mat-spinner> + +<app-users-list + [tableId]="tableId" + [noUsersFoundLabel]="'USER_DETAIL.SETTINGS.SERVICE_IDENTITIES.NO_IDENTITIES' | translate" + *ngIf="!loading" + [users]="identities" + [selection]="selection" + [routeToAdmin]="routeToAdminSection" + [displayedColumns]="displayedColumns"> +</app-users-list> + + diff --git a/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/user-settings-service-identities.component.ts b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/user-settings-service-identities.component.ts index 606e1fdbc..3ba2d535f 100644 --- a/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/user-settings-service-identities.component.ts +++ b/apps/admin-gui/src/app/users/pages/user-detail-page/user-settings/user-settings-service-identities/user-settings-service-identities.component.ts @@ -7,7 +7,7 @@ import { TABLE_USER_SERVICE_IDENTITIES } from '@perun-web-apps/config/table-conf import { getDefaultDialogConfig } from '@perun-web-apps/perun/utils'; import { ConnectIdentityDialogComponent } from '../../../../../shared/components/dialogs/connect-identity-dialog/connect-identity-dialog.component'; import { DisconnectIdentityDialogComponent } from '../../../../../shared/components/dialogs/disconnect-identity-dialog/disconnect-identity-dialog.component'; -import { GuiAuthResolver } from '@perun-web-apps/perun/services'; +import { GuiAuthResolver, StoreService } from '@perun-web-apps/perun/services'; @Component({ selector: 'app-user-settings-service-identities', @@ -20,7 +20,8 @@ export class UserSettingsServiceIdentitiesComponent implements OnInit { private dialog: MatDialog, private router: Router, private userManager: UsersManagerService, - public authResolver: GuiAuthResolver + public authResolver: GuiAuthResolver, + private store: StoreService, ) { } loading = false; @@ -28,18 +29,23 @@ export class UserSettingsServiceIdentitiesComponent implements OnInit { identities: User[] = []; userId: number; tableId = TABLE_USER_SERVICE_IDENTITIES; - displayedColumns = [ 'select', 'id', 'user', 'name' ]; + displayedColumns = ['select', 'id', 'user', 'name'] + addIdentity: boolean; + removeIdentity: boolean; + routeToAdminSection = true; ngOnInit(): void { this.loading = true; - this.route.parent.parent.params + this.route.parent.params .subscribe(params => { this.userId = params["userId"]; - this.userManager.getSpecificUsersByUser(this.userId).subscribe(identities => { - this.identities = identities; - this.loading = false; - }); + if(this.userId === undefined) { + this.userId = this.store.getPerunPrincipal().userId; + this.routeToAdminSection = false; + } + this.setAuthRights(); + this.refreshTable(); }); } @@ -52,6 +58,11 @@ export class UserSettingsServiceIdentitiesComponent implements OnInit { }); } + setAuthRights() { + this.addIdentity = this.authResolver.isPerunAdmin(); + this.removeIdentity = this.authResolver.isAuthorized('removeSpecificUserOwner_User_User_policy',[{id: this.userId, beanName: 'User'}]); + } + onAdd(){ const config = getDefaultDialogConfig(); config.width = "1250px"; diff --git a/apps/admin-gui/src/app/users/users-routing.module.ts b/apps/admin-gui/src/app/users/users-routing.module.ts index 283b9f8b7..bf295b288 100644 --- a/apps/admin-gui/src/app/users/users-routing.module.ts +++ b/apps/admin-gui/src/app/users/users-routing.module.ts @@ -10,6 +10,10 @@ import { UserSettingsAppConfigurationComponent } from './pages/user-detail-page/ import { UserOverviewComponent } from './pages/user-detail-page/user-overview/user-overview.component'; import { UserProfileComponent } from './components/user-profile/user-profile.component'; import { UserRolesComponent } from './pages/user-detail-page/user-settings/user-roles/user-roles.component'; +import { UserSettingsServiceIdentitiesComponent } from './pages/user-detail-page/user-settings/user-settings-service-identities/user-settings-service-identities.component'; +import { ServiceIdentityDetailPageComponent } from './pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-detail-page.component'; +import { ServiceIdentityOverviewComponent } from './pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-overview/service-identity-overview.component'; +import { UserSettingsAssociatedUsersComponent } from './pages/user-detail-page/user-settings/user-settings-associated-users/user-settings-associated-users.component'; const routes: Routes = [ @@ -42,6 +46,11 @@ const routes: Routes = [ component: UserRolesComponent, data: {animation: 'UserRolesPage'} }, + { + path: 'service-identities', + component: UserSettingsServiceIdentitiesComponent, + data: {animation: 'UserServiceIdentities'} + }, { path: 'settings', component: UserSettingsComponent, @@ -64,6 +73,20 @@ const routes: Routes = [ ] } ] + }, + { + path: 'service-identities/:userId', + component: ServiceIdentityDetailPageComponent, + children: [ + { + path: '', + component: ServiceIdentityOverviewComponent, + }, + { + path: 'associated-users', + component: UserSettingsAssociatedUsersComponent + } + ] } ]; diff --git a/apps/admin-gui/src/app/users/users.module.ts b/apps/admin-gui/src/app/users/users.module.ts index 8d875f138..849f018da 100644 --- a/apps/admin-gui/src/app/users/users.module.ts +++ b/apps/admin-gui/src/app/users/users.module.ts @@ -59,6 +59,8 @@ import { DashboardCardComponent } from './pages/user-detail-page/user-dashboard/ import { DashboardRecentlyViewedButtonFieldComponent } from './pages/user-detail-page/user-dashboard/dashboard-recently-viewed-button-field/dashboard-recently-viewed-button-field.component'; import { UserFacilitiesComponent } from './pages/user-detail-page/user-facilities/user-facilities.component'; import { UserAccountsComponent } from './pages/user-detail-page/user-accounts/user-accounts.component'; +import { ServiceIdentityDetailPageComponent } from './pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-detail-page.component'; +import { ServiceIdentityOverviewComponent } from './pages/user-detail-page/user-settings/user-settings-service-identities/service-identity-detail-page/service-identity-overview/service-identity-overview.component'; @NgModule({ @@ -82,6 +84,8 @@ import { UserAccountsComponent } from './pages/user-detail-page/user-accounts/us DashboardRecentlyViewedButtonFieldComponent, UserFacilitiesComponent, UserAccountsComponent, + ServiceIdentityDetailPageComponent, + ServiceIdentityOverviewComponent ], exports: [ UserDetailPageComponent, diff --git a/apps/admin-gui/src/app/vos/components/application-form-list/application-form-list.component.html b/apps/admin-gui/src/app/vos/components/application-form-list/application-form-list.component.html index 5b8dae893..1120f4722 100644 --- a/apps/admin-gui/src/app/vos/components/application-form-list/application-form-list.component.html +++ b/apps/admin-gui/src/app/vos/components/application-form-list/application-form-list.component.html @@ -1,7 +1,7 @@ <mat-spinner *ngIf="loading" class="ml-auto mr-auto"> </mat-spinner> -<div *ngIf="!loading" class="card mt-2"> +<div *ngIf="this.applicationFormItems.length !== 0 && !loading" class="card mt-2"> <div class="card-body table-theme"> <div class="overflow-auto"> <table #table diff --git a/apps/admin-gui/src/assets/i18n/en.json b/apps/admin-gui/src/assets/i18n/en.json index 1225f8359..62ee24b00 100644 --- a/apps/admin-gui/src/assets/i18n/en.json +++ b/apps/admin-gui/src/assets/i18n/en.json @@ -879,7 +879,7 @@ "TITLE": "User - ", "ROLES": "Roles", "GUI_CONFIG": "Gui configuration", - "SERVICE_IDENTITIES": "Service Identities", + "SERVICE_IDENTITIES": "Service Accounts", "IDENTITIES": "Identities", "PASSWORD_RESET": "Password reset", "FACILITIES": "Facilities", @@ -1976,7 +1976,7 @@ "TITLE": "Create service account", "CREATE": "Create", "CANCEL": "Cancel", - "CREATE_IDENTITY": "Create service identity", + "CREATE_IDENTITY": "Create service account", "NAME": "Account name", "EMAIL": "Email", "NAMESPACE": "Namespace", @@ -2196,10 +2196,10 @@ "SUCCESS_SAVE": "Attributes saved successfully" }, "SERVICE_IDENTITIES": { - "TITLE": "Service identities", + "TITLE": "Service accounts", "CREATE": "Add", "DELETE": "Remove", - "NO_IDENTITIES": "No service identities assigned." + "NO_IDENTITIES": "No service accounts assigned." }, "GUI_CONFIG": { "PREF_TABLE_PAGE_SIZE": "Preferred table page size", -- GitLab From 4d55397923822b93123efaf7876372cc9089a168 Mon Sep 17 00:00:00 2001 From: xkureck <luckureckova@gmail.com> Date: Mon, 18 Oct 2021 16:50:42 +0200 Subject: [PATCH 2/2] feat(admin): new section - Service account in My profile section * fix ng lint problems --- apps/admin-gui/src/app/admin/admin-routing.module.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/admin-gui/src/app/admin/admin-routing.module.ts b/apps/admin-gui/src/app/admin/admin-routing.module.ts index 3283dfc22..ecfec210c 100644 --- a/apps/admin-gui/src/app/admin/admin-routing.module.ts +++ b/apps/admin-gui/src/app/admin/admin-routing.module.ts @@ -19,11 +19,7 @@ import {AdminUserDetailPageComponent} from './pages/admin-user-detail-page/admin import {UserOverviewComponent} from '../users/pages/user-detail-page/user-overview/user-overview.component'; import {UserOrganizationsComponent} from '../users/pages/user-detail-page/user-organizations/user-organizations.component'; import {UserGroupsComponent} from '../users/pages/user-detail-page/user-groups/user-groups.component'; -import {UserSettingsComponent} from '../users/pages/user-detail-page/user-settings/user-settings.component'; import {UserAttributesComponent} from '../users/pages/user-detail-page/user-attributes/user-attributes.component'; -import { - UserSettingsOverviewComponent -} from '../users/pages/user-detail-page/user-settings/user-settings-overview/user-settings-overview.component'; import { AdminExtSourcesComponent } from './pages/admin-page/admin-ext-sources/admin-ext-sources.component'; import { UserRolesComponent } from '../users/pages/user-detail-page/user-settings/user-roles/user-roles.component'; import { UserSettingsServiceIdentitiesComponent } from '../users/pages/user-detail-page/user-settings/user-settings-service-identities/user-settings-service-identities.component'; -- GitLab