Skip to content

Commit

Permalink
Renew revoke of ALL assignments (#74)
Browse files Browse the repository at this point in the history
* fix: code smells

* feat: renew revoke all permissions

* fix: code cleanup

* fix: code smells
  • Loading branch information
HenryT-CG authored May 21, 2024
1 parent 45c6c61 commit 392c684
Show file tree
Hide file tree
Showing 14 changed files with 330 additions and 193 deletions.
11 changes: 7 additions & 4 deletions src/app/permission/app-detail/app-detail.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -376,13 +376,16 @@
*ngIf="myPermissions.includes('PERMISSION#EDIT')"
[id]="'app_detail_permission_table_row_' + row + '_edit_action'"
(click)="onDetailPermission($event, rowData)"
[title]="'ACTIONS.EDIT.PERMISSION' | translate"
[title]="
(rowData.mandatory || rowData.operator ? 'ACTIONS.VIEW' : 'ACTIONS.EDIT') + '.PERMISSION'
| translate
"
class="mr-1 my-0 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"
[class.pi-eye]="rowData?.mandatory || rowData?.operator"
[class.pi-pencil]="!(rowData?.mandatory || rowData?.operator)"
[class.pi-eye]="rowData.mandatory || rowData.operator"
[class.pi-pencil]="!(rowData.mandatory || rowData.operator)"
aria-hidden="true"
></span>
</button>
Expand All @@ -403,7 +406,7 @@
*ngIf="myPermissions.includes('PERMISSION#DELETE')"
[id]="'app_detail_permission_table_row_' + row + '_delete_action'"
(click)="onDeletePermission($event, rowData)"
[disabled]="rowData.mandatory"
[disabled]="rowData.mandatory || rowData.operator"
[title]="'ACTIONS.DELETE.PERMISSION' | translate"
class="my-0 p-1 p-button-rounded font-medium p-button-text p-button p-component p-button-icon-only"
>
Expand Down
115 changes: 63 additions & 52 deletions src/app/permission/app-detail/app-detail.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,23 @@ import {
PermissionPageResult,
Permission,
Assignment,
RevokeAssignmentRequest,
CreateAssignmentRequestParams,
GrantRoleAssignmentsRequestParams,
CreateRoleProductAssignmentRequest,
GrantRoleProductAssignmentsRequestParams,
CreateRoleProductsAssignmentRequest,
GrantRoleApplicationAssignmentsRequestParams,
GrantRoleProductsAssignmentsRequestParams,
RevokeRoleAssignmentsRequestParams,
RevokeRoleProductsAssignmentsRequestParams,
RevokeRoleApplicationAssignmentsRequestParams,
DeleteAssignmentRequestParams,
MfeMsAbstract,
Application,
ApplicationAPIService,
AssignmentAPIService,
PermissionAPIService,
RoleAPIService,
WorkspaceAPIService,
WorkspaceDetails
WorkspaceDetails,
ProductDetails
} from 'src/app/shared/generated'
import { dropDownSortItemsByLabel, limitText } from 'src/app/shared/utils'

Expand Down Expand Up @@ -258,18 +260,8 @@ export class AppDetailComponent implements OnInit, OnDestroy {
console.error('getDetailsByWorkspaceName() result:', result)
} else if (result instanceof Object) {
this.currentApp.workspaceDetails = { ...result }
if (this.currentApp.workspaceDetails?.products && this.currentApp.workspaceDetails?.products.length > 0) {
this.currentApp.workspaceDetails?.products.map((product) => {
if (product.mfe)
product.mfe.map((a) => {
this.productApps.push({ appId: a.appId, name: a.appName, productName: product.productName } as App)
})
if (product.ms)
product.ms.map((a) => {
this.productApps.push({ appId: a.appId, name: a.appName, productName: product.productName } as App)
})
})
}
this.currentApp.workspaceDetails?.products?.map((product) => this.fillProductApps(product))
console.log(this.productApps)
this.prepareActionButtons()
this.loadRolesAndPermissions()
} else {
Expand All @@ -278,6 +270,14 @@ export class AppDetailComponent implements OnInit, OnDestroy {
}
})
}
private fillProductApps(product: ProductDetails) {
if (product.mfe) product.mfe.map((app) => this.pushProductApps(product.productName!, app))
if (product.ms) product.ms.map((app) => this.pushProductApps(product.productName!, app))
}
private pushProductApps(productName: string, app: MfeMsAbstract) {
if (this.productApps.filter((aa) => aa.appId === app.appId).length === 0)
this.productApps.push({ appId: app.appId, name: app.appName, productName: productName } as App)
}

/**
* COLUMNS => Roles, ROWS => Permissions
Expand Down Expand Up @@ -560,18 +560,13 @@ export class AppDetailComponent implements OnInit, OnDestroy {
ev.stopPropagation()
this.permissionTable?.clear()
switch (icon.className) {
case 'pi pi-fw pi-sort-alt': // init
icon.className = 'pi pi-fw pi-sort-amount-down'
this.permissionTable?._value.sort(
field === 'appId' ? this.sortPermissionRowByAppIdDesc : this.sortPermissionRowByProductDesc
)
break
case 'pi pi-fw pi-sort-amount-down':
icon.className = 'pi pi-fw pi-sort-amount-up-alt'
this.permissionTable?._value.sort(
field === 'appId' ? this.sortPermissionRowByAppIdAsc : this.sortPermissionRowByProductAsc
)
break
case 'pi pi-fw pi-sort-alt': // init
case 'pi pi-fw pi-sort-amount-up-alt':
icon.className = 'pi pi-fw pi-sort-amount-down'
this.permissionTable?._value.sort(
Expand Down Expand Up @@ -642,7 +637,6 @@ export class AppDetailComponent implements OnInit, OnDestroy {
this.showPermissionDetailDialog = true
}
public onDetailPermission(ev: MouseEvent, perm: PermissionViewRow): void {
console.log('onDetailPermission')
ev.stopPropagation()
this.permission = perm
this.changeMode = this.permission.mandatory || this.permission.operator ? 'VIEW' : 'EDIT'
Expand Down Expand Up @@ -708,45 +702,61 @@ export class AppDetailComponent implements OnInit, OnDestroy {
}
if (this.filterAppValue) {
this.assApi
.grantRoleProductAssignments({
.grantRoleApplicationAssignments({
roleId: role.id,
createRoleProductAssignmentRequest: {
createRoleApplicationAssignmentRequest: {
appId: this.filterAppValue,
productName: this.getProductNameForApp(this.filterAppValue)
} as CreateRoleProductAssignmentRequest
} as GrantRoleProductAssignmentsRequestParams)
}
} as GrantRoleApplicationAssignmentsRequestParams)
.subscribe(response)
} else if (this.filterProductValue) {
this.assApi
.grantRoleProductsAssignments({
roleId: role.id,
createRoleProductsAssignmentRequest: {
productNames: this.prepareProductList()
} as CreateRoleProductsAssignmentRequest
createRoleProductsAssignmentRequest: { productNames: this.prepareProductList() }
} as GrantRoleProductsAssignmentsRequestParams)
.subscribe(response)
} else {
this.assApi.grantRoleAssignments({ roleId: role.id } as GrantRoleAssignmentsRequestParams).subscribe(response)
}
}

// REVOKE ALL depends on what ALL means:
// 1. Value in App filter => remove all assignments of this app to the role
// 2. Value in Product filter => remove all assignments of all Apps of this product to the role
// 3. No filter => remove all assignments of the role
public onRevokeAllPermissions(ev: MouseEvent, role: Role): void {
const pList = this.prepareProductList()
if (pList.length === 0) return // products are required
this.assApi
.revokeAssignments({
revokeAssignmentRequest: { roleId: role.id, productNames: pList } as RevokeAssignmentRequest
})
.subscribe({
next: () => {
this.msgService.success({ summaryKey: 'PERMISSION.ASSIGNMENTS.REVOKE_ALL_SUCCESS' })
this.loadRoleAssignments(false, role.id)
},
error: (err) => {
this.msgService.error({ summaryKey: 'PERMISSION.ASSIGNMENTS.REVOKE_ERROR' })
console.error(err)
}
})
const response: any = {
next: () => {
this.msgService.success({ summaryKey: 'PERMISSION.ASSIGNMENTS.REVOKE_ALL_SUCCESS' })
this.loadRoleAssignments(false, role.id)
},
error: (err: any) => {
this.msgService.error({ summaryKey: 'PERMISSION.ASSIGNMENTS.REVOKE_ERROR' })
console.error(err)
}
}
if (this.filterAppValue) {
this.assApi
.revokeRoleApplicationAssignments({
roleId: role.id,
revokeRoleApplicationAssignmentRequest: {
appId: this.filterAppValue,
productName: this.getProductNameForApp(this.filterAppValue)
}
} as RevokeRoleApplicationAssignmentsRequestParams)
.subscribe(response)
} else if (this.filterProductValue) {
this.assApi
.revokeRoleProductsAssignments({
roleId: role.id,
revokeRoleProductsAssignmentRequest: { productNames: this.prepareProductList() }
} as RevokeRoleProductsAssignmentsRequestParams)
.subscribe(response)
} else {
this.assApi.revokeRoleAssignments({ roleId: role.id } as RevokeRoleAssignmentsRequestParams).subscribe(response)
}
}

// Not perfect: apps are uinique only within the product
Expand All @@ -757,6 +767,7 @@ export class AppDetailComponent implements OnInit, OnDestroy {
}
return pList.length === 1 ? pList[0].productName : undefined
}

private prepareProductList(): string[] {
const pList: string[] = []
// => case 1: Product
Expand All @@ -767,7 +778,7 @@ export class AppDetailComponent implements OnInit, OnDestroy {
// b) all products
else if (this.filterProductItems.length > 1)
this.filterProductItems.map((p) => {
if (p.value) pList.push(p.value!) // ignore empty entry
if (p.value) pList.push(p.value) // ignore empty entry
})
return pList
}
Expand All @@ -789,19 +800,19 @@ export class AppDetailComponent implements OnInit, OnDestroy {
}
private sortPermissionRowByProductAsc(a: PermissionViewRow, b: PermissionViewRow): number {
return (
(a.productName ? a.productName.toUpperCase() : '').localeCompare(
((a.productName ? a.productName.toUpperCase() : '').localeCompare(
b.productName ? b.productName.toUpperCase() : ''
) ||
a.appId?.localeCompare(b!.appId!) ||
a.appId?.localeCompare(b.appId!)) ??
a.key.localeCompare(b.key)
)
}
private sortPermissionRowByProductDesc(bP: PermissionViewRow, aP: PermissionViewRow): number {
return (
(aP.productName ? aP.productName.toUpperCase() : '').localeCompare(
((aP.productName ? aP.productName.toUpperCase() : '').localeCompare(
bP.productName ? bP.productName.toUpperCase() : ''
) ||
aP.appId?.localeCompare(bP!.appId!) ||
aP.appId?.localeCompare(bP.appId!)) ??
aP.key.localeCompare(bP.key)
)
}
Expand Down
16 changes: 8 additions & 8 deletions src/app/permission/app-search/app-search.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { limitText } from 'src/app/shared/utils'
import {
Application,
ApplicationAPIService,
WorkspaceAbstract,
WorkspaceAPIService,
WorkspacePageResult,
ApplicationPageResult
Expand Down Expand Up @@ -116,10 +117,10 @@ export class AppSearchComponent implements OnInit, OnDestroy {
finalize(() => (this.searchInProgress = false))
)
return this.workspaces$.pipe(
map((result) => {
map((result: any) => {
return result.stream
? result.stream
?.map((w) => {
?.map((w: WorkspaceAbstract) => {
return { appId: w.name, appType: 'WORKSPACE', description: w.description } as App
})
.sort(this.sortAppsByAppId)
Expand Down Expand Up @@ -147,28 +148,26 @@ export class AppSearchComponent implements OnInit, OnDestroy {
finalize(() => (this.searchInProgress = false))
)
return this.papps$.pipe(
map((result) => {
map((result: any) => {
if (!result.stream) return []
const productNames: string[] = []
const apps: App[] = []
result.stream?.map((app) => {
result.stream?.map((app: Application) => {
if (!productNames.includes(app.productName ?? '')) {
productNames.push(app.productName ?? '')
apps.push({ ...app, appType: 'PRODUCT' } as App)
}
//}
})
return apps.sort(this.sortAppsByAppId)
})
)
}
public searchApps(): void {
console.log('searchApps: ' + this.appSearchCriteriaGroup.controls['appType'].value)
this.searchInProgress = true
switch (this.appSearchCriteriaGroup.controls['appType'].value) {
case 'ALL':
this.apps$ = combineLatest([this.searchWorkspaces(), this.searchProducts('PRODUCT')]).pipe(
map(([w, a]) => w.concat(a).sort(this.sortAppsByAppId))
map(([w, a]: [App[], App[]]) => w.concat(a).sort(this.sortAppsByAppId))
)
break
case 'WORKSPACE':
Expand Down Expand Up @@ -199,7 +198,7 @@ export class AppSearchComponent implements OnInit, OnDestroy {
'ACTIONS.SEARCH.SORT_DIRECTION_DESC'
])
.pipe(
map((data) => {
map((data: any) => {
this.dataViewControlsTranslations = {
sortDropdownPlaceholder: data['ACTIONS.SEARCH.SORT_BY'],
filterInputPlaceholder: data['ACTIONS.SEARCH.FILTER.LABEL'],
Expand All @@ -218,6 +217,7 @@ export class AppSearchComponent implements OnInit, OnDestroy {
* UI Events
*/
public onAppClick(ev: any, app: App): void {
ev.stopPropagation()
this.router.navigate(['./', app.appType.toLowerCase(), app.appType === 'PRODUCT' ? app.productName : app.appId], {
relativeTo: this.route
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
</label>
</span>
</div>
<div class="flex flex-row justify-content-between align-items-center column-gap-3">
<div class="px-2 flex flex-row justify-content-between align-items-center column-gap-3">
<p-checkbox
type="text"
inputId="permission_detail_operator"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,13 @@ export class PermissionDetailComponent implements OnChanges {
this.formGroup.controls['resource'].patchValue(this.permission.resource)
this.formGroup.controls['action'].patchValue(this.permission.action)
this.formGroup.controls['description'].patchValue(this.permission.description)
this.formGroup.controls['mandatory'].patchValue(this.permission.mandatory ?? false)
this.formGroup.controls['operator'].patchValue(this.permission.operator ?? false)
if (this.changeMode === 'CREATE') {
this.formGroup.controls['mandatory'].patchValue(false)
this.formGroup.controls['operator'].patchValue(false)
} else {
this.formGroup.controls['mandatory'].patchValue(this.permission.mandatory ?? false)
this.formGroup.controls['operator'].patchValue(this.permission.operator ?? false)
}
}
this.formGroup.disable()
if (
Expand Down Expand Up @@ -122,8 +127,6 @@ export class PermissionDetailComponent implements OnChanges {
}
})
} else {
console.info('form valid ' + this.formGroup.valid)
//const roleNameChanged = this.formGroup.controls['name'].value !== this.permission?.name
const permission = {
modificationCount: this.permission?.modificationCount,
appId: this.formGroup.controls['appId'].value,
Expand Down
5 changes: 3 additions & 2 deletions src/app/shared/generated/.openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ model/assignmentSearchCriteria.ts
model/createAssignmentRequest.ts
model/createPermissionRequest.ts
model/createProductAssignmentsRequest.ts
model/createRoleProductAssignmentRequest.ts
model/createRoleApplicationAssignmentRequest.ts
model/createRoleProductsAssignmentRequest.ts
model/createRoleRequest.ts
model/createRolesRequest.ts
Expand All @@ -39,7 +39,8 @@ model/problemDetailParam.ts
model/problemDetailResponse.ts
model/product.ts
model/productDetails.ts
model/revokeAssignmentRequest.ts
model/revokeRoleApplicationAssignmentRequest.ts
model/revokeRoleProductsAssignmentRequest.ts
model/role.ts
model/rolePageResult.ts
model/roleSearchCriteria.ts
Expand Down
Loading

0 comments on commit 392c684

Please sign in to comment.