Skip to content

Commit

Permalink
feat: add IAM roles (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
HenryT-CG authored Jun 6, 2024
1 parent 1b6195e commit 1019c9d
Show file tree
Hide file tree
Showing 12 changed files with 175 additions and 46 deletions.
10 changes: 10 additions & 0 deletions src/_mixins.scss
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,13 @@
}
}
}

@mixin listbox-zebra-rows {
:host ::ng-deep {
.p-listbox:not(.p-disabled) .p-listbox-item:not(.p-highlight):not(.p-disabled) {
&:nth-child(odd) {
background-color: #f8f9fa;
}
}
}
}
8 changes: 4 additions & 4 deletions src/app/permission/app-detail/app-detail.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,9 @@
pbutton
type="button"
*ngIf="myPermissions.includes('ROLE#CREATE') && showRoleTools"
[id]="'app_detail_permission_table_header_add_idm_roles_action'"
(click)="onCreateIDMRoles($event)"
[disabled]="true"
[title]="'ACTIONS.CREATE.IDM_ROLES.TOOLTIP' | translate"
[id]="'app_detail_permission_table_header_add_iam_roles_action'"
(click)="onAddIAMRoles($event)"
[title]="'ACTIONS.CREATE.IAM_ROLES.TOOLTIP' | translate"
class="p-1 p-button-rounded font-medium p-button-text p-button p-component p-button-icon-only"
>
<span class="text-primary font-medium p-button-icon pi pi-bolt" aria-hidden="true"></span>
Expand Down Expand Up @@ -512,6 +511,7 @@
[roles]="roles"
[role]="role"
[changeMode]="changeMode"
[showIamRolesDialog]="showIamRolesDialog"
[displayDetailDialog]="showRoleDetailDialog"
[displayDeleteDialog]="showRoleDeleteDialog"
(dataChanged)="onDetailChanged($event)"
Expand Down
8 changes: 3 additions & 5 deletions src/app/permission/app-detail/app-detail.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,12 +380,10 @@ describe('AppDetailComponent', () => {
/**
* CREATE
*/
it('should do something onCreateIDMRoles', () => {
spyOn(console, 'log')
it('should do something onAddIAMRoles', () => {
component.onAddIAMRoles(new MouseEvent('click'))

component.onCreateIDMRoles(new MouseEvent('click'))

expect(console.log).toHaveBeenCalled()
expect(component.showIamRolesDialog).toBeTrue()
})

it('should return if there are no missing ws roles', () => {
Expand Down
9 changes: 5 additions & 4 deletions src/app/permission/app-detail/app-detail.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ export class AppDetailComponent implements OnInit, OnDestroy {
public missingWorkspaceRoles = false
public showRoleDetailDialog = false
public showRoleDeleteDialog = false
public showIamRolesDialog = false
public showRoleTools = false

constructor(
Expand Down Expand Up @@ -366,10 +367,6 @@ export class AppDetailComponent implements OnInit, OnDestroy {
}
}

public onCreateIDMRoles(ev: MouseEvent) {
console.log('TODO: select IDM roles to take over into permissions')
}

public onCreateWorkspaceRoles(ev: MouseEvent) {
ev.stopPropagation()
if (!this.missingWorkspaceRoles) return
Expand Down Expand Up @@ -624,8 +621,12 @@ export class AppDetailComponent implements OnInit, OnDestroy {
this.showPermissionDeleteDialog = false
this.showRoleDetailDialog = false
this.showRoleDeleteDialog = false
this.showIamRolesDialog = false
if (changed) this.loadData()
}
public onAddIAMRoles(ev: MouseEvent) {
this.showIamRolesDialog = true
}

/****************************************************************************
* PERMISSION
Expand Down
2 changes: 1 addition & 1 deletion src/app/permission/app-search/app-search.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
*ngIf="app.apps"
[id]="'app_search_data_idx_' + idx + '_apps'"
[title]="'APP.APPS' | translate"
class="card-badge-right badge-2-1 p-1 text-primary"
class="card-badge-right badge-2 p-1 text-xs"
>{{ app.apps }}</span
>
<div class="h-2rem md:h-3rem flex flex-column justify-content-between gap-1 lg:gap-2 lg:py-1 text-center">
Expand Down
8 changes: 0 additions & 8 deletions src/app/permission/app-search/app-search.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,6 @@
@include search-criteria-select-button;
@include card-badges;

:host ::ng-deep {
.card-badge-left,
.card-badge-right {
&.badge-2-1 {
top: 32px;
}
}
}
@media screen and (min-width: 768px) {
.md\:h-2-5rem {
height: 2.5rem !important;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,14 @@
[dismissableMask]="true"
[style]="{ 'max-width': '425px' }"
>
<div class="flex column-gap-3 row-gap-1 justify-content-start align-items-center">
<div class="mr-2 flex column-gap-4 row-gap-1 justify-content-start align-items-center">
<div class="pi pi-question-circle text-3xl danger-action-text"></div>
<div>
<div id="permission_delete_button_message">
<div id="permission_delete_message" class="font-bold">
{{ ('ACTIONS.DELETE.MESSAGE.TEXT' | translate).replace('{{ITEM}}', permission?.resource + '#' +
permission?.action) }}
</div>
<div class="mt-2">{{ 'ACTIONS.DELETE.MESSAGE.INFO' | translate }}</div>
<div class="mt-3">{{ 'ACTIONS.DELETE.MESSAGE.INFO' | translate }}</div>
</div>
</div>
<ng-template pTemplate="footer">
Expand Down
61 changes: 57 additions & 4 deletions src/app/permission/role-detail/role-detail.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
[style]="{ width: '400px' }"
>
<form [formGroup]="formGroupRole" errorTailor>
<div class="flex flex-wrap flex-column gap-4 justify-content-between">
<div class="flex flex-wrap flex-column row-gap-4 justify-content-between">
<div class="mt-1">
<span class="p-float-label" controlErrorAnchor>
<input pInputText type="text" class="w-full" id="role_detail_name" formControlName="name" />
Expand Down Expand Up @@ -63,11 +63,13 @@
[dismissableMask]="true"
[style]="{ 'max-width': '425px' }"
>
<div class="flex column-gap-3 row-gap-1 justify-content-start align-items-center">
<div class="mr-2 flex column-gap-4 row-gap-1 justify-content-start align-items-center">
<div class="pi pi-question-circle text-3xl danger-action-text"></div>
<div>
<div>{{ ('ACTIONS.DELETE.MESSAGE.TEXT' | translate).replace('{{ITEM}}', role?.name) }}</div>
<div class="mt-2">{{ 'ACTIONS.DELETE.MESSAGE.INFO' | translate }}</div>
<div id="role_delete_message" class="font-bold">
{{ ('ACTIONS.DELETE.MESSAGE.TEXT' | translate).replace('{{ITEM}}', role?.name) }}
</div>
<div class="mt-3">{{ 'ACTIONS.DELETE.MESSAGE.INFO' | translate }}</div>
</div>
</div>
<ng-template pTemplate="footer">
Expand Down Expand Up @@ -96,3 +98,54 @@
</div>
</ng-template>
</p-dialog>

<!-- SELECT IAM ROLES -->
<p-dialog
[(visible)]="showIamRolesDialog"
[header]="'ROLE.IAM.HEADER' | translate"
(onHide)="onClose()"
[modal]="true"
[closable]="true"
[resizable]="true"
[dismissableMask]="true"
>
<div class="flex flex-column row-gap-2">
<div>{{ 'ROLE.IAM.INFO' | translate }}</div>
<p-listbox
[options]="iamRoles"
[(ngModel)]="selectedIamRoles"
optionLabel="name"
[filter]="true"
[checkbox]="true"
[multiple]="true"
[metaKeySelection]="false"
[showToggleAll]="false"
[listStyle]="{ 'max-height': '300px' }"
/>
</div>
<ng-template pTemplate="footer">
<div class="flex flex-wrap column-gap-2 row-gap-1 justify-content-end">
<button
pButton
type="button"
id="role_select_button_cancel"
class="m-0"
icon="pi pi-times"
iconPos="left"
[label]="'ACTIONS.CANCEL' | translate"
[title]="'ACTIONS.TOOLTIPS.CANCEL' | translate"
(click)="onClose()"
></button>
<button
pButton
type="button"
id="role_select_button_save"
class="m-0"
icon="pi pi-check"
iconPos="left"
[label]="'ROLE.IAM.SAVE' | translate"
(click)="onAddIamRoles()"
></button>
</div>
</ng-template>
</p-dialog>
18 changes: 18 additions & 0 deletions src/app/permission/role-detail/role-detail.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@import '/src/_mixins.scss';

@include listbox-zebra-rows;

:host ::ng-deep {
.p-listbox {
box-shadow: 0 2px 1px -1px rgba(0, 0, 0, 0.2), 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 1px 3px 0 rgba(0, 0, 0, 0.12);
.p-listbox-list-wrapper {
border-radius: var(--border-radius);
.p-listbox-list .p-listbox-item {
padding: 0.5rem 1rem;
.p-checkbox {
margin-right: 1rem;
}
}
}
}
}
41 changes: 39 additions & 2 deletions src/app/permission/role-detail/role-detail.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import { TranslateService } from '@ngx-translate/core'

import { PortalMessageService, UserService } from '@onecx/portal-integration-angular'

import { Role, CreateRoleRequest, UpdateRoleRequest, RoleAPIService } from 'src/app/shared/generated'
import { Role, CreateRoleRequest, IAMRole, UpdateRoleRequest, RoleAPIService } from 'src/app/shared/generated'
import { App, ChangeMode } from 'src/app/permission/app-detail/app-detail.component'

@Component({
selector: 'app-role-detail',
templateUrl: './role-detail.component.html'
templateUrl: './role-detail.component.html',
styleUrls: ['./role-detail.component.scss']
})
export class RoleDetailComponent implements OnChanges {
@Input() currentApp!: App
Expand All @@ -18,10 +19,13 @@ export class RoleDetailComponent implements OnChanges {
@Input() changeMode: ChangeMode = 'VIEW'
@Input() displayDetailDialog = false
@Input() displayDeleteDialog = false
@Input() showIamRolesDialog = false
@Output() dataChanged: EventEmitter<boolean> = new EventEmitter()

public myPermissions = new Array<string>() // permissions of the user
public formGroupRole: FormGroup
public iamRoles!: IAMRole[]
public selectedIamRoles: IAMRole[] | undefined

constructor(
private roleApi: RoleAPIService,
Expand All @@ -44,6 +48,7 @@ export class RoleDetailComponent implements OnChanges {
this.formGroupRole.controls['name'].patchValue(this.role.name)
this.formGroupRole.controls['description'].patchValue(this.role.description)
}
if (this.showIamRolesDialog) this.getIamRoles()
}

public onClose(): void {
Expand Down Expand Up @@ -111,6 +116,9 @@ export class RoleDetailComponent implements OnChanges {
}
}

/**
* Delete a ROLE
*/
public onDeleteConfirmation() {
this.roleApi.deleteRole({ id: this.role?.id ?? '' }).subscribe({
next: () => {
Expand All @@ -123,4 +131,33 @@ export class RoleDetailComponent implements OnChanges {
}
})
}

/**
* Select IAM Roles to be added
*/
public getIamRoles() {
this.roleApi.searchAvailableRoles({ iAMRoleSearchCriteria: { pageSize: 1000 } }).subscribe({
next: (data) => {
this.iamRoles = data.stream ?? []
},
error: (err) => {
console.error(err.error)
}
})
}
public onAddIamRoles() {
console.log('onAddIamRoles', this.selectedIamRoles)
if (this.selectedIamRoles && this.selectedIamRoles.length > 0)
this.roleApi.createRole({ createRolesRequest: { roles: this.selectedIamRoles! } }).subscribe({
next: () => {
this.msgService.success({ summaryKey: 'ACTIONS.CREATE.MESSAGE.ROLE_OK' })
this.dataChanged.emit(true)
},
error: (err) => {
this.msgService.error({ summaryKey: 'ACTIONS.CREATE.MESSAGE.ROLE_NOK' })
console.error(err)
}
})
else this.dataChanged.emit(false)
}
}
22 changes: 16 additions & 6 deletions src/assets/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"PERMISSION.TOOLTIP": "Eine neue Berechtigung erstellen",
"ROLE": "Rolle erstellen",
"ROLE.TOOLTIP": "Eine neue Rolle erstellen",
"IDM_ROLES.TOOLTIP": "IDM Rollen auswählen damit sie hier verwendet werden können",
"IAM_ROLES.TOOLTIP": "IAM Rollen auswählen damit sie hier verwendet werden können",
"WORKSPACE_ROLES.TOOLTIP": "Fehlende Workspace Rollen übernehmen damit sie hier verwendet werden können",
"MESSAGE": {
"APPLICATION_OK": "Die App wurde erfolgreich erstellt",
Expand Down Expand Up @@ -223,7 +223,13 @@
"TOOLTIP": "Liste der Rollen zu denen Berechtigungen erteilt werden können. Wirksam werden Berechtigungen für einen Benutzer erst dann, wenn der Benutzer der Rolle zugeordnet wird.",
"NAME": "Name",
"DESCRIPTION": "Beschreibung",
"MANDATORY": "Diese Rolle ist notwendig für den Betrieb und kann somit nicht bearbeitet oder gelöscht werden."
"MANDATORY": "Diese Rolle ist notwendig für den Betrieb und kann somit nicht bearbeitet oder gelöscht werden.",
"IAM": {
"HEADER": "IAM Rollen auswählen",
"INFO": "Liste der fehlenden IAM Rollen",
"Filter": "Filter",
"SAVE": "Auswahl übernehmen"
}
},
"VALIDATION": {
"HINTS": {
Expand All @@ -242,9 +248,9 @@
}
},
"EXCEPTIONS": {
"HTTP_MISSING_PARAMETER": "Parameter aus der URL konnten nicht abgerufen werden",
"HTTP_MISSING_PARAMETER": "Parameter aus der URL konnten nicht ermittelt werden",
"HTTP_STATUS_0": {
"APP": "Unbekanntes Problem beim Abrufen von Apps/Applikationen - Bitte versuchen sie es noch einmal.",
"APP": "Unbekanntes Problem beim Abrufen von Applikationen - Bitte versuchen sie es noch einmal.",
"ROLES": "Unbekanntes Problem beim Abrufen von Rollen - Bitte versuchen sie es noch einmal.",
"PERMISSIONS": "Unbekanntes Problem beim Abrufen von Berechtigungen - Bitte versuchen sie es noch einmal.",
"ASSIGNMENTS": "Unbekanntes Problem beim Abrufen von Berechtigungen - Bitte versuchen sie es noch einmal.",
Expand All @@ -254,9 +260,13 @@
"ROLES": "Die Rolle konnte nicht verarbeitet werden.",
"PERMISSIONS": "Die Berechtigung konnte nicht verarbeitet werden."
},
"HTTP_STATUS_401": {
"APPS": "Sie haben keine Rechte um Applikationen zu sehen.",
"WORKSPACE": "Sie haben keine Rechte um Workspace Daten zu sehen."
},
"HTTP_STATUS_403": {
"APP": "Sie haben keine Rechte um App/Applikation Daten zu sehen.",
"APPS": "Sie haben keine Rechte um Apps/Applikationen zu sehen.",
"APP": "Sie haben keine Rechte um Applikation Daten zu sehen.",
"APPS": "Sie haben keine Rechte um Applikationen zu sehen.",
"ROLES": "Sie haben keine Rechte um Rollen zu sehen.",
"PERMISSIONS": "Sie haben keine Rechte um Berechtigungen zu sehen.",
"ASSIGNMENTS": "Sie haben keine Rechte um Berechtigungen zu sehen.",
Expand Down
Loading

0 comments on commit 1019c9d

Please sign in to comment.