Skip to content

Commit deb1778

Browse files
HejdaJakubxflord
authored andcommitted
feat(admin): attribute operation can be globally critical
* In Perun admin Attribute definition section we can now set attribute as globally critical (critical for all objects).
1 parent 58998a1 commit deb1778

File tree

17 files changed

+635
-444
lines changed

17 files changed

+635
-444
lines changed

apps/admin-gui/src/app/shared/components/dialogs/create-attribute-definition-dialog/create-attribute-definition-dialog.component.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@ <h1 mat-dialog-title>{{'DIALOGS.CREATE_ATTRIBUTE_DEFINITION.TITLE' | translate}}
8282

8383
<perun-web-apps-attribute-critical-operations-toggles
8484
(readOperationChanged)="finalReadOperations=$event"
85-
(writeOperationChanged)="finalWriteOperations=$event">
85+
(readGlobalChanged)="finalReadGlobal=$event"
86+
(writeOperationChanged)="finalWriteOperations=$event"
87+
(writeGlobalChanged)="finalWriteGlobal=$event">
8688
</perun-web-apps-attribute-critical-operations-toggles>
8789

8890
<perun-web-apps-attribute-rights-tab-group [collections]="collections">

apps/admin-gui/src/app/shared/components/dialogs/create-attribute-definition-dialog/create-attribute-definition-dialog.component.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ export class CreateAttributeDefinitionDialogComponent {
6666
});
6767
collections: AttributePolicyCollection[] = [];
6868
finalReadOperations: boolean;
69+
finalReadGlobal = false;
6970
finalWriteOperations: boolean;
71+
finalWriteGlobal = false;
7072
attDefCreated: AttributeDefinition;
7173

7274
constructor(
@@ -101,6 +103,8 @@ export class CreateAttributeDefinitionDialogComponent {
101103
this.attributeRightsService.updateAttributeAction(
102104
this.finalReadOperations,
103105
false,
106+
this.finalReadGlobal,
107+
false,
104108
this.attDefCreated.id,
105109
AttributeAction.READ
106110
)
@@ -109,6 +113,8 @@ export class CreateAttributeDefinitionDialogComponent {
109113
this.attributeRightsService.updateAttributeAction(
110114
this.finalWriteOperations,
111115
true, // we want all newly created attributes by default with critical write operations
116+
this.finalWriteGlobal,
117+
false,
112118
this.attDefCreated.id,
113119
AttributeAction.WRITE
114120
)

apps/admin-gui/src/app/shared/components/dialogs/edit-attribute-definition-dialog/edit-attribute-definition-dialog.component.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,13 @@ <h1 mat-dialog-title>{{'DIALOGS.EDIT_ATTRIBUTE_DEFINITION.TITLE' | translate}}</
4747

4848
<perun-web-apps-attribute-critical-operations-toggles
4949
[readOperation]="initReadOperations"
50+
[readGlobal]="initReadGlobal"
5051
[writeOperation]="initWriteOperations"
52+
[writeGlobal]="initWriteGlobal"
5153
(readOperationChanged)="finalReadOperations=$event"
52-
(writeOperationChanged)="finalWriteOperations=$event">
54+
(readGlobalChanged)="finalReadGlobal=$event"
55+
(writeOperationChanged)="finalWriteOperations=$event"
56+
(writeGlobalChanged)="finalWriteGlobal=$event">
5357
</perun-web-apps-attribute-critical-operations-toggles>
5458

5559
<perun-web-apps-attribute-rights-tab-group

apps/admin-gui/src/app/shared/components/dialogs/edit-attribute-definition-dialog/edit-attribute-definition-dialog.component.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,13 @@ export class EditAttributeDefinitionDialogComponent implements OnInit {
3434
showKeys = false;
3535
attDef: AttributeDefinition = this.data.attDef;
3636
initReadOperations: boolean;
37+
initReadGlobal: boolean;
3738
initWriteOperations: boolean;
39+
initWriteGlobal: boolean;
3840
finalReadOperations: boolean;
41+
finalReadGlobal: boolean;
3942
finalWriteOperations: boolean;
43+
finalWriteGlobal: boolean;
4044
attributeControl: UntypedFormGroup = this.formBuilder.group({
4145
name: [this.attDef.displayName, Validators.required],
4246
description: [this.attDef.description, Validators.required],
@@ -64,8 +68,10 @@ export class EditAttributeDefinitionDialogComponent implements OnInit {
6468
this.dialogRef.addPanelClass('mat-dialog-height-transition');
6569
this.attributesManager.getAttributeRules(this.attDef.id).subscribe((attrRights) => {
6670
this.collections$ = new BehaviorSubject(attrRights.attributePolicyCollections);
67-
this.initReadOperations = attrRights.criticalActions.includes('READ');
68-
this.initWriteOperations = attrRights.criticalActions.includes('WRITE');
71+
this.initReadOperations = 'READ' in attrRights.criticalActions;
72+
this.initWriteOperations = 'WRITE' in attrRights.criticalActions;
73+
this.initReadGlobal = attrRights.criticalActions['READ'] || false;
74+
this.initWriteGlobal = attrRights.criticalActions['WRITE'] || false;
6975
this.loading = false;
7076
});
7177
}
@@ -85,6 +91,8 @@ export class EditAttributeDefinitionDialogComponent implements OnInit {
8591
this.attributeRightsService.updateAttributeAction(
8692
this.finalReadOperations,
8793
this.initReadOperations,
94+
this.finalReadGlobal,
95+
this.initReadGlobal,
8896
this.attDef.id,
8997
AttributeAction.READ
9098
)
@@ -93,6 +101,8 @@ export class EditAttributeDefinitionDialogComponent implements OnInit {
93101
this.attributeRightsService.updateAttributeAction(
94102
this.finalWriteOperations,
95103
this.initWriteOperations,
104+
this.finalWriteGlobal,
105+
this.initWriteGlobal,
96106
this.attDef.id,
97107
AttributeAction.WRITE
98108
)
@@ -105,7 +115,10 @@ export class EditAttributeDefinitionDialogComponent implements OnInit {
105115
);
106116
this.dialogRef.close(true);
107117
},
108-
error: () => (this.loading = false),
118+
error: (err) => {
119+
this.loading = false;
120+
console.error(err);
121+
},
109122
});
110123
}
111124

apps/admin-gui/src/assets/i18n/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3330,6 +3330,7 @@
33303330
"ATTRIBUTE_CRITICAL_OPERATIONS_TOGGLE": {
33313331
"READ": "READ operations critical",
33323332
"WRITE": "WRITE operations critical",
3333+
"GLOBAL": "Critical for all objects",
33333334
"INFO": "All operations of the selected type (READ/WRITE) for this attribute will require multi-factor authentication for objects that are marked as critical."
33343335
},
33353336
"DATA_QUOTAS": {
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,37 @@
11
<mat-slide-toggle
2-
class="toggle-font mb-25"
2+
class="toggle-font"
3+
[class.mb-25]="!readOperation"
34
labelPosition="before"
45
data-cy="toggle-read-critical"
56
[(ngModel)]="readOperation"
6-
(toggleChange)="readOperationChanged.emit(!readOperation)">
7+
(toggleChange)="changeReadOperation()">
78
{{'SHARED_LIB.PERUN.COMPONENTS.ATTRIBUTE_CRITICAL_OPERATIONS_TOGGLE.READ' | translate}}
89
</mat-slide-toggle>
9-
<br />
10+
<div *ngIf="readOperation">
11+
<mat-checkbox
12+
[(ngModel)]="readGlobal"
13+
(change)="readGlobalChanged.emit(readGlobal)"
14+
class="ms-2 fst-italic">
15+
{{'SHARED_LIB.PERUN.COMPONENTS.ATTRIBUTE_CRITICAL_OPERATIONS_TOGGLE.GLOBAL' | translate}}
16+
</mat-checkbox>
17+
</div>
18+
<br *ngIf="!readOperation" />
1019
<mat-slide-toggle
11-
class="toggle-font mb-25"
20+
class="toggle-font"
21+
[class.mb-25]="!writeOperation"
1222
labelPosition="before"
1323
[(ngModel)]="writeOperation"
14-
(toggleChange)="writeOperationChanged.emit(!writeOperation)">
24+
(toggleChange)="changeWriteOperation()">
1525
{{'SHARED_LIB.PERUN.COMPONENTS.ATTRIBUTE_CRITICAL_OPERATIONS_TOGGLE.WRITE' | translate}}
1626
</mat-slide-toggle>
27+
<div *ngIf="writeOperation">
28+
<mat-checkbox
29+
[(ngModel)]="writeGlobal"
30+
(change)="writeGlobalChanged.emit(writeGlobal)"
31+
class="ms-2 fst-italic">
32+
{{'SHARED_LIB.PERUN.COMPONENTS.ATTRIBUTE_CRITICAL_OPERATIONS_TOGGLE.GLOBAL' | translate}}
33+
</mat-checkbox>
34+
</div>
1735
<perun-web-apps-alert alert_type="info">
1836
{{'SHARED_LIB.PERUN.COMPONENTS.ATTRIBUTE_CRITICAL_OPERATIONS_TOGGLE.INFO' | translate}}
1937
</perun-web-apps-alert>

libs/perun/components/src/lib/attribute-critical-operations-toggles/attribute-critical-operations-toggles.component.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,29 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
77
})
88
export class AttributeCriticalOperationsTogglesComponent {
99
@Input() readOperation = false;
10+
@Input() readGlobal = false;
1011
@Input() writeOperation = true;
12+
@Input() writeGlobal = false;
1113
@Output() readOperationChanged: EventEmitter<boolean> = new EventEmitter<boolean>();
14+
@Output() readGlobalChanged: EventEmitter<boolean> = new EventEmitter<boolean>();
1215
@Output() writeOperationChanged: EventEmitter<boolean> = new EventEmitter<boolean>();
16+
@Output() writeGlobalChanged: EventEmitter<boolean> = new EventEmitter<boolean>();
17+
18+
changeReadOperation(): void {
19+
this.readOperationChanged.emit(!this.readOperation);
20+
// if the operation is changing from true to false, then we want to change also global criticality to false
21+
if (this.readOperation) {
22+
this.readGlobal = false;
23+
this.readGlobalChanged.emit(this.readGlobal);
24+
}
25+
}
26+
27+
changeWriteOperation(): void {
28+
this.writeOperationChanged.emit(!this.writeOperation);
29+
// if the operation is changing from true to false, then we want to change also global criticality to false
30+
if (this.writeOperation) {
31+
this.writeGlobal = false;
32+
this.writeGlobalChanged.emit(this.writeGlobal);
33+
}
34+
}
1335
}

libs/perun/openapi/src/lib/.openapi-generator/FILES

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ model/ban.ts
5858
model/banOnFacility.ts
5959
model/banOnResource.ts
6060
model/banOnVo.ts
61+
model/blockedLogin.ts
62+
model/blockedLoginsOrderColumn.ts
63+
model/blockedLoginsPageQuery.ts
6164
model/brand.ts
6265
model/candidate.ts
6366
model/category.ts
@@ -144,6 +147,7 @@ model/inputGetMatchResources.ts
144147
model/inputGetMembersByUserAttributes.ts
145148
model/inputGetMessagesPage.ts
146149
model/inputGetPaginatedApplications.ts
150+
model/inputGetPaginatedBlockedLogins.ts
147151
model/inputGetPaginatedGroups.ts
148152
model/inputGetPaginatedMembers.ts
149153
model/inputGetPaginatedSubgroups.ts

libs/perun/openapi/src/lib/api/attributesManager.service.ts

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -746,30 +746,30 @@ export class AttributesManagerService {
746746
}
747747

748748
/**
749-
* Returns all namespaces in which login can be blocked.
749+
* Returns all AttributeDefinitions.
750750
* @param useNon if set to true sends the request to the backend server as 'non' instead of the usual (oauth, krb...).
751751
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
752752
* @param reportProgress flag to report request and response progress.
753753
*/
754-
public getAllNamespaces(
754+
public getAllAttributeDefinitions(
755755
useNon?: boolean,
756756
observe?: 'body',
757757
reportProgress?: boolean,
758758
options?: { httpHeaderAccept?: 'application/json'; context?: HttpContext }
759-
): Observable<Array<string>>;
760-
public getAllNamespaces(
759+
): Observable<Array<AttributeDefinition>>;
760+
public getAllAttributeDefinitions(
761761
useNon?: boolean,
762762
observe?: 'response',
763763
reportProgress?: boolean,
764764
options?: { httpHeaderAccept?: 'application/json'; context?: HttpContext }
765-
): Observable<HttpResponse<Array<string>>>;
766-
public getAllNamespaces(
765+
): Observable<HttpResponse<Array<AttributeDefinition>>>;
766+
public getAllAttributeDefinitions(
767767
useNon?: boolean,
768768
observe?: 'events',
769769
reportProgress?: boolean,
770770
options?: { httpHeaderAccept?: 'application/json'; context?: HttpContext }
771-
): Observable<HttpEvent<Array<string>>>;
772-
public getAllNamespaces(
771+
): Observable<HttpEvent<Array<AttributeDefinition>>>;
772+
public getAllAttributeDefinitions(
773773
useNon: boolean = false,
774774
observe: any = 'body',
775775
reportProgress: boolean = false,
@@ -816,7 +816,7 @@ export class AttributesManagerService {
816816
}
817817
}
818818

819-
let requestUrl = `${this.configuration.basePath}/json/attributesManager/getAllNamespaces`;
819+
let requestUrl = `${this.configuration.basePath}/json/attributesManager/getAttributesDefinition`;
820820
if (useNon) {
821821
// replace the authentication part of url with 'non' authentication
822822
let helperUrl = new URL(requestUrl);
@@ -825,7 +825,7 @@ export class AttributesManagerService {
825825
helperUrl.pathname = path.join('/');
826826
requestUrl = helperUrl.toString();
827827
}
828-
return this.httpClient.get<Array<string>>(requestUrl, {
828+
return this.httpClient.get<Array<AttributeDefinition>>(requestUrl, {
829829
context: localVarHttpContext,
830830
responseType: <any>responseType_,
831831
withCredentials: this.configuration.withCredentials,
@@ -836,30 +836,30 @@ export class AttributesManagerService {
836836
}
837837

838838
/**
839-
* Returns all AttributeDefinitions.
839+
* Returns list of all possible namespaces.
840840
* @param useNon if set to true sends the request to the backend server as 'non' instead of the usual (oauth, krb...).
841841
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
842842
* @param reportProgress flag to report request and response progress.
843843
*/
844-
public getAllAttributeDefinitions(
844+
public getAllNamespaces(
845845
useNon?: boolean,
846846
observe?: 'body',
847847
reportProgress?: boolean,
848848
options?: { httpHeaderAccept?: 'application/json'; context?: HttpContext }
849-
): Observable<Array<AttributeDefinition>>;
850-
public getAllAttributeDefinitions(
849+
): Observable<Array<string>>;
850+
public getAllNamespaces(
851851
useNon?: boolean,
852852
observe?: 'response',
853853
reportProgress?: boolean,
854854
options?: { httpHeaderAccept?: 'application/json'; context?: HttpContext }
855-
): Observable<HttpResponse<Array<AttributeDefinition>>>;
856-
public getAllAttributeDefinitions(
855+
): Observable<HttpResponse<Array<string>>>;
856+
public getAllNamespaces(
857857
useNon?: boolean,
858858
observe?: 'events',
859859
reportProgress?: boolean,
860860
options?: { httpHeaderAccept?: 'application/json'; context?: HttpContext }
861-
): Observable<HttpEvent<Array<AttributeDefinition>>>;
862-
public getAllAttributeDefinitions(
861+
): Observable<HttpEvent<Array<string>>>;
862+
public getAllNamespaces(
863863
useNon: boolean = false,
864864
observe: any = 'body',
865865
reportProgress: boolean = false,
@@ -906,7 +906,7 @@ export class AttributesManagerService {
906906
}
907907
}
908908

909-
let requestUrl = `${this.configuration.basePath}/json/attributesManager/getAttributesDefinition`;
909+
let requestUrl = `${this.configuration.basePath}/json/attributesManager/getAllNamespaces`;
910910
if (useNon) {
911911
// replace the authentication part of url with 'non' authentication
912912
let helperUrl = new URL(requestUrl);
@@ -915,7 +915,7 @@ export class AttributesManagerService {
915915
helperUrl.pathname = path.join('/');
916916
requestUrl = helperUrl.toString();
917917
}
918-
return this.httpClient.get<Array<AttributeDefinition>>(requestUrl, {
918+
return this.httpClient.get<Array<string>>(requestUrl, {
919919
context: localVarHttpContext,
920920
responseType: <any>responseType_,
921921
withCredentials: this.configuration.withCredentials,
@@ -16790,6 +16790,7 @@ export class AttributesManagerService {
1679016790
* @param attributeDefinition id of AttributeDefinition
1679116791
* @param action
1679216792
* @param critical if action should be marked as critical
16793+
* @param global if action should be globally critical (for all objects)
1679316794
* @param useNon if set to true sends the request to the backend server as 'non' instead of the usual (oauth, krb...).
1679416795
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
1679516796
* @param reportProgress flag to report request and response progress.
@@ -16798,6 +16799,7 @@ export class AttributesManagerService {
1679816799
attributeDefinition: number,
1679916800
action: AttributeAction,
1680016801
critical: boolean,
16802+
global?: boolean,
1680116803
useNon?: boolean,
1680216804
observe?: 'body',
1680316805
reportProgress?: boolean,
@@ -16807,6 +16809,7 @@ export class AttributesManagerService {
1680716809
attributeDefinition: number,
1680816810
action: AttributeAction,
1680916811
critical: boolean,
16812+
global?: boolean,
1681016813
useNon?: boolean,
1681116814
observe?: 'response',
1681216815
reportProgress?: boolean,
@@ -16816,6 +16819,7 @@ export class AttributesManagerService {
1681616819
attributeDefinition: number,
1681716820
action: AttributeAction,
1681816821
critical: boolean,
16822+
global?: boolean,
1681916823
useNon?: boolean,
1682016824
observe?: 'events',
1682116825
reportProgress?: boolean,
@@ -16825,6 +16829,7 @@ export class AttributesManagerService {
1682516829
attributeDefinition: number,
1682616830
action: AttributeAction,
1682716831
critical: boolean,
16832+
global?: boolean,
1682816833
useNon: boolean = false,
1682916834
observe: any = 'body',
1683016835
reportProgress: boolean = false,
@@ -16868,6 +16873,13 @@ export class AttributesManagerService {
1686816873
'critical'
1686916874
);
1687016875
}
16876+
if (global !== undefined && global !== null) {
16877+
localVarQueryParameters = this.addToHttpParams(
16878+
localVarQueryParameters,
16879+
<any>global,
16880+
'global'
16881+
);
16882+
}
1687116883

1687216884
let localVarHeaders = this.defaultHeaders;
1687316885

0 commit comments

Comments
 (0)