feat: impersonation roles (#7442)

* partial work done

* test IAM membership roles

* org membership tests

* console :(, translations and docs

* fix integration test

* fix tests

* add EnableImpersonation to security policy API

* fix integration test timestamp checking

* add security policy tests and fix projections

* add impersonation setting in console

* add security settings to the settings v2 API

* fix typo

* move impersonation to instance

---------

Co-authored-by: Livio Spring <[email protected]>
This commit is contained in:
Tim Möhlmann
2024-02-28 10:21:11 +00:00
committed by GitHub
co-authored by Livio Spring
parent 68af4f59c9
commit 062d153cfe
60 changed files with 1624 additions and 144 deletions
@@ -5,19 +5,22 @@
</div>
<div class="security-wrapper">
<cnsl-info-section [type]="InfoSectionType.ALERT">{{ 'SETTING.SECURITY.DESCRIPTION' | translate }}</cnsl-info-section>
<h3>{{ 'SETTING.SECURITY.IFRAMETITLE' | translate }}</h3>
<mat-checkbox
card-actions
class="security-policy-toggle"
color="primary"
ngDefaultControl
(change)="enabledChanged($event)"
[(ngModel)]="enabled"
(change)="iframeEnabledChanged($event)"
[(ngModel)]="iframeEnabled"
[disabled]="(['iam.policy.write'] | hasRole | async) === false"
>
{{ 'SETTING.SECURITY.IFRAMEENABLED' | translate }}
</mat-checkbox>
<cnsl-info-section [type]="InfoSectionType.ALERT">{{
'SETTING.SECURITY.IFRAMEDESCRIPTION' | translate
}}</cnsl-info-section>
<form class="security-allowed-originsform" (ngSubmit)="add(redInput)">
<cnsl-form-field class="formfield">
@@ -29,14 +32,14 @@
matTooltip="{{ 'ACTIONS.ADD' | translate }}"
type="submit"
mat-icon-button
[disabled]="!enabled || originsControl.invalid || (['iam.policy.write'] | hasRole | async) === false"
[disabled]="!iframeEnabled || originsControl.invalid || (['iam.policy.write'] | hasRole | async) === false"
>
<mat-icon>add</mat-icon>
</button>
</form>
<div class="security-allowed-uris-list">
<div *ngFor="let uri of originsList" class="uri-line" [ngClass]="{ disabled: !enabled }">
<div *ngFor="let uri of originsList" class="uri-line" [ngClass]="{ disabled: !iframeEnabled }">
<span class="uri">{{ uri }}</span>
<span class="fill-space"></span>
@@ -45,6 +48,21 @@
</button>
</div>
</div>
<h3>{{ 'SETTING.SECURITY.IMPERSONATIONTITLE' | translate }}</h3>
<mat-checkbox
card-actions
class="security-policy-toggle"
color="primary"
ngDefaultControl
[(ngModel)]="impersonationEnabled"
[disabled]="(['iam.policy.write'] | hasRole | async) === false"
>
{{ 'SETTING.SECURITY.IMPERSONATIONENABLED' | translate }}
</mat-checkbox>
<cnsl-info-section [type]="InfoSectionType.INFO">{{
'SETTING.SECURITY.IMPERSONATIONDESCRIPTION' | translate
}}</cnsl-info-section>
</div>
<div class="general-btn-container">
@@ -13,7 +13,8 @@ import { InfoSectionType } from '../../info-section/info-section.component';
})
export class SecurityPolicyComponent implements OnInit {
public originsList: string[] = [];
public enabled: boolean = false;
public iframeEnabled: boolean = false;
public impersonationEnabled: boolean = false;
public loading: boolean = false;
public InfoSectionType: any = InfoSectionType;
@@ -32,7 +33,8 @@ export class SecurityPolicyComponent implements OnInit {
private fetchData(): void {
this.service.getSecurityPolicy().then((securityPolicy) => {
if (securityPolicy.policy) {
this.enabled = securityPolicy.policy?.enableIframeEmbedding;
this.impersonationEnabled = securityPolicy.policy?.enableImpersonation;
this.iframeEnabled = securityPolicy.policy?.enableIframeEmbedding;
this.originsList = securityPolicy.policy?.allowedOriginsList;
if (securityPolicy.policy.enableIframeEmbedding) {
this.originsControl.enable();
@@ -46,7 +48,8 @@ export class SecurityPolicyComponent implements OnInit {
private updateData(): Promise<SetDefaultLanguageResponse.AsObject> {
const req = new SetSecurityPolicyRequest();
req.setAllowedOriginsList(this.originsList);
req.setEnableIframeEmbedding(this.enabled);
req.setEnableIframeEmbedding(this.iframeEnabled);
req.setEnableImpersonation(this.impersonationEnabled);
return (this.service as AdminService).setSecurityPolicy(req);
}
@@ -88,7 +91,7 @@ export class SecurityPolicyComponent implements OnInit {
}
}
public enabledChanged(event: MatCheckboxChange) {
public iframeEnabledChanged(event: MatCheckboxChange) {
if (event.checked) {
this.originsControl.enable();
} else {
+12
View File
@@ -87,6 +87,12 @@ export function getMembershipColor(role: string): Color {
case 'IAM_USER_MANAGER':
color = COLORS[8];
break;
case 'IAM_ADMIN_IMPERSONATOR':
color = COLORS[17];
break;
case 'IAM_END_USER_IMPERSONATOR':
color = COLORS[9];
break;
case 'ORG_OWNER':
color = COLORS[16];
@@ -106,6 +112,12 @@ export function getMembershipColor(role: string): Color {
case 'ORG_PROJECT_CREATOR':
color = COLORS[12];
break;
case 'ORG_ADMIN_IMPERSONATOR':
color = COLORS[17];
break;
case 'ORG_END_USER_IMPERSONATOR':
color = COLORS[9];
break;
case 'PROJECT_OWNER':
color = COLORS[9];