From 4d4501dea21eca0b503956eff9a7d366b908a64f Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Wed, 8 Mar 2023 14:06:04 +0100 Subject: [PATCH 01/44] init --- .../access-tokens-routing.module.ts | 24 +++++ .../access-tokens/access-tokens.component.ts | 11 +++ .../access-tokens/access-tokens.module.ts | 17 ++++ .../index/index-routing.module.ts | 19 ++++ .../access-tokens/index/index.component.html | 68 ++++++++++++++ .../access-tokens/index/index.component.less | 43 +++++++++ .../access-tokens/index/index.component.ts | 91 +++++++++++++++++++ .../access-tokens/index/index.module.ts | 48 ++++++++++ .../integrations-routing.module.ts | 25 +++++ .../integrations/integrations.component.html | 4 + .../integrations/integrations.component.less | 0 .../integrations/integrations.component.ts | 16 ++++ .../safe/integrations/integrations.module.ts | 20 ++++ .../app/features/safe/safe-routing.module.ts | 15 ++- .../src/app/features/safe/safe.component.ts | 12 +++ 15 files changed, 408 insertions(+), 5 deletions(-) create mode 100644 modules/front-end/src/app/features/safe/integrations/access-tokens/access-tokens-routing.module.ts create mode 100644 modules/front-end/src/app/features/safe/integrations/access-tokens/access-tokens.component.ts create mode 100644 modules/front-end/src/app/features/safe/integrations/access-tokens/access-tokens.module.ts create mode 100644 modules/front-end/src/app/features/safe/integrations/access-tokens/index/index-routing.module.ts create mode 100644 modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html create mode 100644 modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.less create mode 100644 modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts create mode 100644 modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.module.ts create mode 100644 modules/front-end/src/app/features/safe/integrations/integrations-routing.module.ts create mode 100644 modules/front-end/src/app/features/safe/integrations/integrations.component.html create mode 100644 modules/front-end/src/app/features/safe/integrations/integrations.component.less create mode 100644 modules/front-end/src/app/features/safe/integrations/integrations.component.ts create mode 100644 modules/front-end/src/app/features/safe/integrations/integrations.module.ts diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/access-tokens-routing.module.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/access-tokens-routing.module.ts new file mode 100644 index 000000000..fd5157698 --- /dev/null +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/access-tokens-routing.module.ts @@ -0,0 +1,24 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { AccessTokensComponent } from "@features/safe/integrations/access-tokens/access-tokens.component"; + +const routes: Routes = [ + { + path: '', + component: AccessTokensComponent, + children: [ + { + path: '', + loadChildren: () => import("./index/index.module").then(m => m.IndexModule), + } + ] + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], + providers: [ + ] +}) +export class AccessTokensRoutingModule { } diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/access-tokens.component.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/access-tokens.component.ts new file mode 100644 index 000000000..cee7bf4c5 --- /dev/null +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/access-tokens.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'integrations-access-tokens', + template: `` +}) +export class AccessTokensComponent { + constructor( + ) { + } +} diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/access-tokens.module.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/access-tokens.module.ts new file mode 100644 index 000000000..ced67357b --- /dev/null +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/access-tokens.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { AccessTokensRoutingModule } from './access-tokens-routing.module'; +import { CommonModule } from '@angular/common'; +import { AccessTokensComponent } from "@features/safe/integrations/access-tokens/access-tokens.component"; + +@NgModule({ + declarations: [ + AccessTokensComponent + ], + imports: [ + CommonModule, + AccessTokensRoutingModule + ], + providers: [ + ] +}) +export class AccessTokensModule { } diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index-routing.module.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index-routing.module.ts new file mode 100644 index 000000000..4b58b4f28 --- /dev/null +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import {IndexComponent} from "@features/safe/iam/policies/index/index.component"; + + +const routes: Routes = [ + { + path: '', + component: IndexComponent, + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], + providers: [ + ] +}) +export class IndexRoutingModule { } diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html new file mode 100644 index 000000000..a8c709338 --- /dev/null +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html @@ -0,0 +1,68 @@ +
+
+ + + + + + + +
+
+ + + + Name + Type + Description + Resource name (RN) + Actions + + + + + {{ item.name }} + + + {{item.type | policyType}} + + {{ item.description }} + + + {{ resourceName(item) }} + + + Details + + + Remove + + + + + + + + +
+
+ + + diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.less b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.less new file mode 100644 index 000000000..4443a9bbd --- /dev/null +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.less @@ -0,0 +1,43 @@ +@import "variables"; + +.table-content-area { + nz-input-group { + width: 520px; + } + + .copy-icon { + color: #717D8A; + &:hover { + cursor: pointer; + color: @grey70-color; + } + } + + .table-wrapper { + .more-tags-item { + max-width: 150px; + } + + .tag { + max-width: 150px; + } + + .col-rn { + height: 56px; + display: flex; + justify-content: flex-start; + align-items: center; + .rn { + display: inline-block; + max-width: 310px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + } + } +} + + + + diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts new file mode 100644 index 000000000..398df6af4 --- /dev/null +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts @@ -0,0 +1,91 @@ +import { Component, OnInit } from '@angular/core'; +import { copyToClipboard, encodeURIComponentFfc } from '@utils/index'; +import { Subject } from 'rxjs'; +import { debounceTime } from 'rxjs/operators'; +import { Router } from "@angular/router"; +import { NzMessageService } from "ng-zorro-antd/message"; +import { IPagedPolicy, IPolicy, PolicyFilter, policyRn } from "@features/safe/iam/types/policy"; +import { PolicyService } from "@services/policy.service"; + +@Component({ + selector: 'iam-users', + templateUrl: './index.component.html', + styleUrls: ['./index.component.less'] +}) +export class IndexComponent implements OnInit { + + constructor( + private router: Router, + private message: NzMessageService, + private policyService: PolicyService + ) { } + + private search$ = new Subject(); + + isLoading: boolean = true; + filter: PolicyFilter = new PolicyFilter(); + policies: IPagedPolicy = { + items: [], + totalCount: 0 + }; + + ngOnInit(): void { + this.search$.pipe( + debounceTime(300) + ).subscribe(() => { + this.getPolicies(); + }); + + this.search$.next(null); + } + + getPolicies() { + this.isLoading = true; + this.policyService.getList(this.filter).subscribe(policies => { + this.policies = policies; + this.isLoading = false; + }, () => this.isLoading = false); + } + + resourceName(policy: IPolicy) { + return policyRn(policy); + } + + doSearch(resetPage?: boolean) { + if (resetPage) { + this.filter.pageIndex = 1; + } + + this.search$.next(null); + } + + policyDrawerVisible: boolean = false; + showPolicyDrawer(){ + this.policyDrawerVisible = true; + } + policyDrawerClosed(created: any) { + this.policyDrawerVisible = false; + + if (created) { + this.getPolicies(); + } + } + + navigateToDetail(id: string) { + this.router.navigateByUrl(`/iam/policies/${encodeURIComponentFfc(id)}/permission`); + } + + delete(policy: IPolicy) { + this.policyService.delete(policy.id).subscribe(() => { + this.message.success($localize `:@@common.operation-success:Operation succeeded`); + this.policies.items = this.policies.items.filter(it => it.id !== policy.id); + this.policies.totalCount--; + }, () => this.message.error($localize `:@@common.operation-failed:Operation failed`)) + } + + copyText(text: string) { + copyToClipboard(text).then( + () => this.message.success($localize `:@@common.copy-success:Copied`) + ); + } +} diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.module.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.module.ts new file mode 100644 index 000000000..9c0ac2502 --- /dev/null +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.module.ts @@ -0,0 +1,48 @@ +import { NgModule } from '@angular/core'; +import { IndexRoutingModule } from './index-routing.module'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { NzSpinModule } from 'ng-zorro-antd/spin'; +import { NzSelectModule } from 'ng-zorro-antd/select'; +import { NzEmptyModule } from 'ng-zorro-antd/empty'; +import { NzTableModule } from 'ng-zorro-antd/table'; +import { NzButtonModule } from 'ng-zorro-antd/button'; +import { NzIconModule } from 'ng-zorro-antd/icon'; +import { NzInputModule } from 'ng-zorro-antd/input'; +import { NzMessageModule } from 'ng-zorro-antd/message'; + +import { NzDropDownModule } from 'ng-zorro-antd/dropdown'; +import { NzToolTipModule } from 'ng-zorro-antd/tooltip'; +import {IndexComponent} from "@features/safe/integrations/access-tokens/index/index.component"; +import {NzDividerModule} from "ng-zorro-antd/divider"; +import {NzPopconfirmModule} from "ng-zorro-antd/popconfirm"; +import {CoreModule} from "@core/core.module"; + + +@NgModule({ + declarations: [ + IndexComponent + ], + imports: [ + CommonModule, + FormsModule, + NzSpinModule, + NzSelectModule, + NzEmptyModule, + NzTableModule, + NzButtonModule, + NzIconModule, + NzInputModule, + CoreModule, + NzMessageModule, + NzDropDownModule, + NzToolTipModule, + NzDividerModule, + NzPopconfirmModule, + IndexRoutingModule, + CoreModule + ], + providers: [ + ] +}) +export class IndexModule { } diff --git a/modules/front-end/src/app/features/safe/integrations/integrations-routing.module.ts b/modules/front-end/src/app/features/safe/integrations/integrations-routing.module.ts new file mode 100644 index 000000000..6ab0fd0c0 --- /dev/null +++ b/modules/front-end/src/app/features/safe/integrations/integrations-routing.module.ts @@ -0,0 +1,25 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { IntegrationsComponent } from './integrations.component'; + +const routes: Routes = [ + { + path: '', + component: IntegrationsComponent, + children: [ + { + path: 'access-tokens', + loadChildren: () => import("./access-tokens/access-tokens.module").then(m => m.AccessTokensModule), + data: { + breadcrumb: $localize `:@@integrations.routing.access-tokens:Access tokens` + }, + } + ] + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class IntegrationsRoutingModule { } diff --git a/modules/front-end/src/app/features/safe/integrations/integrations.component.html b/modules/front-end/src/app/features/safe/integrations/integrations.component.html new file mode 100644 index 000000000..bf4a1a44d --- /dev/null +++ b/modules/front-end/src/app/features/safe/integrations/integrations.component.html @@ -0,0 +1,4 @@ + + + + diff --git a/modules/front-end/src/app/features/safe/integrations/integrations.component.less b/modules/front-end/src/app/features/safe/integrations/integrations.component.less new file mode 100644 index 000000000..e69de29bb diff --git a/modules/front-end/src/app/features/safe/integrations/integrations.component.ts b/modules/front-end/src/app/features/safe/integrations/integrations.component.ts new file mode 100644 index 000000000..7312b41aa --- /dev/null +++ b/modules/front-end/src/app/features/safe/integrations/integrations.component.ts @@ -0,0 +1,16 @@ +import { Component, OnDestroy } from '@angular/core'; + +@Component({ + selector: 'integrations', + templateUrl: `./integrations.component.html`, + styleUrls: ['./integrations.component.less'] +}) +export class IntegrationsComponent implements OnDestroy { + + constructor( + ) { + } + + ngOnDestroy(): void { + } +} diff --git a/modules/front-end/src/app/features/safe/integrations/integrations.module.ts b/modules/front-end/src/app/features/safe/integrations/integrations.module.ts new file mode 100644 index 000000000..317754930 --- /dev/null +++ b/modules/front-end/src/app/features/safe/integrations/integrations.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { IntegrationsRoutingModule } from './integrations-routing.module'; +import { CommonModule } from '@angular/common'; +import { IntegrationsComponent } from './integrations.component'; +import { NzResultModule } from 'ng-zorro-antd/result'; + +@NgModule({ + declarations: [ + IntegrationsComponent + ], + imports: [ + CommonModule, + NzResultModule, + IntegrationsRoutingModule, + ], + exports: [ + ], + providers: [] +}) +export class IntegrationsModule { } diff --git a/modules/front-end/src/app/features/safe/safe-routing.module.ts b/modules/front-end/src/app/features/safe/safe-routing.module.ts index 3f39ce825..a6f1a1319 100644 --- a/modules/front-end/src/app/features/safe/safe-routing.module.ts +++ b/modules/front-end/src/app/features/safe/safe-routing.module.ts @@ -43,6 +43,13 @@ const routes: Routes = [ breadcrumb: $localize `:@@data-sync:Data sync` }, }, + { + path: 'audit-logs', + loadChildren: () => import("./audit-logs/audit-logs.module").then(m => m.AuditLogsModule), + data: { + breadcrumb: $localize `:@@auditlogs.audit-logs:Audit logs` + }, + }, { path: 'organizations', loadChildren: () => import("./organizations/organizations.module").then(m => m.OrganizationsModule), @@ -56,11 +63,9 @@ const routes: Routes = [ loadChildren: () => import("./iam/iam.module").then(m => m.IAMModule), }, { - path: 'audit-logs', - loadChildren: () => import("./audit-logs/audit-logs.module").then(m => m.AuditLogsModule), - data: { - breadcrumb: $localize `:@@auditlogs.audit-logs:Audit logs` - }, + path: 'integrations', + canActivate: [IAMGuard], + loadChildren: () => import("./integrations/integrations.module").then(m => m.IntegrationsModule), }, { path: '', diff --git a/modules/front-end/src/app/features/safe/safe.component.ts b/modules/front-end/src/app/features/safe/safe.component.ts index 73cc36e59..37cdd89bd 100644 --- a/modules/front-end/src/app/features/safe/safe.component.ts +++ b/modules/front-end/src/app/features/safe/safe.component.ts @@ -109,6 +109,18 @@ export class SafeComponent implements OnInit, OnDestroy { path: '/iam/policies' } ] + }, + { + title: $localize `:@@menu.integrations:Integrations`, + icon: 'block', + path: '/integrations/access-tokens', + children: [ + { + title: $localize `:@@menu.integrations.access-tokens:Access tokens`, + icon: '', + path: '/integrations/access-tokens' + } + ] } ]; } From 0b7c37fc4f9138404f39fc242f8253f2f42bca9e Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Thu, 9 Mar 2023 11:30:21 +0100 Subject: [PATCH 02/44] in progress --- .../safe/integrations/access-tokens/index/index.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html index a8c709338..11902e775 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html @@ -1,7 +1,7 @@
- + From 23091ecb57868c437f7f16d8adce3be279a8eaf4 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Sat, 11 Mar 2023 15:14:25 +0100 Subject: [PATCH 03/44] in progress --- .../access-token-drawer.component.html | 92 +++++++++++ .../access-token-drawer.component.less | 47 ++++++ .../access-token-drawer.component.ts | 149 ++++++++++++++++++ .../components/guide/guide.component.html | 2 +- modules/front-end/src/app/core/core.module.ts | 7 +- .../index/index-routing.module.ts | 2 +- .../access-tokens/index/index.component.html | 4 +- .../access-tokens/index/index.component.ts | 8 +- .../access-tokens/types/access-token.ts | 10 ++ modules/front-end/src/styles-common.less | 9 ++ 10 files changed, 320 insertions(+), 10 deletions(-) create mode 100644 modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html create mode 100644 modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less create mode 100644 modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts create mode 100644 modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html new file mode 100644 index 000000000..f549fbbd4 --- /dev/null +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html @@ -0,0 +1,92 @@ + + +
+ + + Name + + + + + Access token name cannot be empty + This access token name is not available + + + + + + Type + + + + + + + + + + + + + Policies + + + + + + + + {{ policy.name }} + + + + + + + Loading... + + + +
+
+
+ + {{ policy.name }} +
+ +
+
+
+
+
+ + + + + + +
+ diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less new file mode 100644 index 000000000..2e137e412 --- /dev/null +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less @@ -0,0 +1,47 @@ +@import "variables"; + +.selected-policies { + border: 1px solid @grey20-color; + background-color: #ffffff; + padding: 5px 0 1px 6px; + box-sizing: border-box; + border-radius: 8px; + margin-bottom: 12px; + margin-top: 12px; + + .policy { + display: flex; + margin-bottom: 4px; + margin-right: 10px; + + .inner-box { + width: 182px; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + padding: 4px 7px 6px 7px; + background: @grey20-color; + height: 23px; + line-height: 15px; + overflow: hidden; + text-overflow: ellipsis; + cursor: pointer; + white-space: nowrap; + } + + button { + display: flex; + background: @grey20-color; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + height: 23px; + width: 15px; + border: 0; + + i { + width:10px; + height: 10px; + font-size: 10px; + } + } + } +} diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts new file mode 100644 index 000000000..6ce7ad416 --- /dev/null +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts @@ -0,0 +1,149 @@ +import { Component, OnInit, Input, Output, EventEmitter, ViewChild } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { NzMessageService } from 'ng-zorro-antd/message'; +import { debounceTime, distinctUntilChanged, first, map, switchMap } from "rxjs/operators"; +import { PolicyService } from "@services/policy.service"; +import { AccessTokenTypeEnum, IAccessTokenPolicy } from "@features/safe/integrations/access-tokens/types/access-token"; +import { PolicyFilter } from "@features/safe/iam/types/policy"; +import { NzSelectComponent } from "ng-zorro-antd/select"; +import { Subject } from "rxjs"; + +@Component({ + selector: 'access-token-drawer', + templateUrl: './access-token-drawer.component.html', + styleUrls: ['./access-token-drawer.component.less'] +}) +export class AccessTokenDrawerComponent implements OnInit { + + public policyCompareWith: (obj1: IAccessTokenPolicy, obj2: IAccessTokenPolicy) => boolean = (obj1: IAccessTokenPolicy, obj2: IAccessTokenPolicy) => { + if(obj1 && obj2) { + return obj1.id === obj2.id; + } else { + return false; + } + }; + + @Input() visible: boolean = false; + @Output() close: EventEmitter = new EventEmitter(); + + policyDebouncer = new Subject(); + constructor( + private fb: FormBuilder, + private policyService: PolicyService, + private message: NzMessageService + ) { + this.policyDebouncer.pipe( + debounceTime(500), + distinctUntilChanged() + ).subscribe(query => this.searchPolicies(query)); + } + + displayPolicies: boolean = false + + @ViewChild("policyNodeSelector", { static: false }) policySelectNode: NzSelectComponent; + selectedPolicyList: IAccessTokenPolicy[] = []; + policySearchResultList: IAccessTokenPolicy[] = []; + form: FormGroup; + ngOnInit(): void { + this.form = this.fb.group({ + name: ['', [Validators.required], [this.nameAsyncValidator], 'change'], + type: [AccessTokenTypeEnum.Personal, [Validators.required]], + policy: [null, []], + }); + } + + onClose() { + this.form.reset(); + this.close.emit(); + } + + onTypeChange() { + const { type } = this.form.value; + this.displayPolicies = type !== AccessTokenTypeEnum.Personal; + } + + onPolicySelectChange() { + const { policy } = this.form.value; + + if (this.selectedPolicyList.some((sp) => sp.id === policy.id)) { + this.selectedPolicyList = this.selectedPolicyList.filter((sp) => sp.id !== policy.id); + } else { + this.selectedPolicyList = [...this.selectedPolicyList, {...policy}]; + } + + this.policySearchResultList = this.policySearchResultList.map((p) => ({ + ...p, + isSelected: this.selectedPolicyList.some((sp => sp.id === p.id)) + })); + this.policySelectNode.writeValue(undefined); + } + + removePolicy(policy: IAccessTokenPolicy) { + this.selectedPolicyList = this.selectedPolicyList.filter((p) => p.id !== policy.id); + } + + isLoadingPolicies = true; + searchPolicies(query: string = '') { + this.isLoadingPolicies = true; + + this.policyService.getList(new PolicyFilter(query, 1, 50)).subscribe(policies => { + this.policySearchResultList = policies.items.map(p => ({ + ...p, + isSelected: this.selectedPolicyList.some((sp => sp.id === p.id)) + })); + + this.isLoadingPolicies = false; + }, () => this.isLoadingPolicies = false); + } + + nameAsyncValidator = (control: FormControl) => control.valueChanges.pipe( + debounceTime(300), + switchMap(value => this.policyService.isNameUsed(value as string)), + map(isNameUsed => { + switch (isNameUsed) { + case true: + return { error: true, duplicated: true }; + case undefined: + return { error: true, unknown: true }; + default: + return null; + } + }), + first() + ); + + isLoading: boolean = false; + doSubmit() { + if (this.form.invalid) { + for (const i in this.form.controls) { + this.form.controls[i].markAsDirty(); + this.form.controls[i].updateValueAndValidity(); + } + return; + } + + this.isLoading = true; + const {name, description} = this.form.value; + this.policyService.create(name, description).subscribe( + () => { + this.isLoading = false; + this.close.emit(true); + this.message.success($localize `:@@common.operation-success:Operation succeeded`); + this.form.reset(); + }, + _ => { + this.isLoading = false; + } + ) + } + + actionTokenTypeLabel = { + [AccessTokenTypeEnum.Personal]: $localize `:@@integrations.access-token.personal:Personal`, + [AccessTokenTypeEnum.Service]: $localize `:@@integrations.access-token.personal:Service` + } + + actionTokenTypes = [ + AccessTokenTypeEnum.Personal, + AccessTokenTypeEnum.Service + ] +} diff --git a/modules/front-end/src/app/core/components/guide/guide.component.html b/modules/front-end/src/app/core/components/guide/guide.component.html index 43303a2d1..08ca71c46 100644 --- a/modules/front-end/src/app/core/components/guide/guide.component.html +++ b/modules/front-end/src/app/core/components/guide/guide.component.html @@ -59,7 +59,7 @@

How-to guides with demo & SDK

-
- + diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts index 398df6af4..d7670cb68 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts @@ -59,12 +59,12 @@ export class IndexComponent implements OnInit { this.search$.next(null); } - policyDrawerVisible: boolean = false; - showPolicyDrawer(){ - this.policyDrawerVisible = true; + accessTokenDrawerVisible: boolean = false; + openAccessTokenDrawer(){ + this.accessTokenDrawerVisible = true; } policyDrawerClosed(created: any) { - this.policyDrawerVisible = false; + this.accessTokenDrawerVisible = false; if (created) { this.getPolicies(); diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts new file mode 100644 index 000000000..03a68da23 --- /dev/null +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts @@ -0,0 +1,10 @@ +import { IPolicy } from "@features/safe/iam/types/policy"; + +export enum AccessTokenTypeEnum { + Personal = 'personal', + Service = 'service' +} + +export interface IAccessTokenPolicy extends IPolicy { + isSelected: boolean +} diff --git a/modules/front-end/src/styles-common.less b/modules/front-end/src/styles-common.less index a35ef0b61..ba551c4c2 100644 --- a/modules/front-end/src/styles-common.less +++ b/modules/front-end/src/styles-common.less @@ -1089,3 +1089,12 @@ app-root { .ant-input-suffix { pointer-events: unset; } + +.drawer-footer-btn { + display: flex; + justify-content: flex-end; + + button { + border-radius: 30px; + } +} From 6b0edae2b34ff561b766cd7d16bc329b69d4012a Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Sat, 11 Mar 2023 15:46:46 +0100 Subject: [PATCH 04/44] added AccessTokenController --- .../Api/Controllers/AccessTokenController.cs | 20 ++++++++++++++ modules/back-end/src/Api/appsettings.json | 6 ++--- .../AccessTokens/IsAccessTokenNameUsed.cs | 26 +++++++++++++++++++ .../Services/IAccessTokenService.cs | 10 +++++++ .../src/Domain/AccessTokens/AccessToken.cs | 23 ++++++++++++++++ .../Domain/AccessTokens/AccessTokenTypes.cs | 8 ++++++ .../AccessTokens/AccessTokenService.cs | 19 ++++++++++++++ .../src/Infrastructure/ConfigureServices.cs | 2 ++ .../Infrastructure/MongoDb/MongoDbClient.cs | 3 +++ .../access-token-drawer.component.ts | 4 ++- .../app/core/services/access-token.service.ts | 24 +++++++++++++++++ .../access-tokens/types/access-token.ts | 4 +-- 12 files changed, 143 insertions(+), 6 deletions(-) create mode 100644 modules/back-end/src/Api/Controllers/AccessTokenController.cs create mode 100644 modules/back-end/src/Application/AccessTokens/IsAccessTokenNameUsed.cs create mode 100644 modules/back-end/src/Application/Services/IAccessTokenService.cs create mode 100644 modules/back-end/src/Domain/AccessTokens/AccessToken.cs create mode 100644 modules/back-end/src/Domain/AccessTokens/AccessTokenTypes.cs create mode 100644 modules/back-end/src/Infrastructure/AccessTokens/AccessTokenService.cs create mode 100644 modules/front-end/src/app/core/services/access-token.service.ts diff --git a/modules/back-end/src/Api/Controllers/AccessTokenController.cs b/modules/back-end/src/Api/Controllers/AccessTokenController.cs new file mode 100644 index 000000000..e10d45782 --- /dev/null +++ b/modules/back-end/src/Api/Controllers/AccessTokenController.cs @@ -0,0 +1,20 @@ +using Application.AccessTokens; + +namespace Api.Controllers; + +[Route("api/v{version:apiVersion}/organizations/{organizationId:guid}/access-tokens")] +public class AccessTokenController : ApiControllerBase +{ + [HttpGet("is-name-used")] + public async Task> IsNameUsedAsync(Guid organizationId, string name) + { + var request = new IsAccessTokenNameUsed + { + OrganizationId = organizationId, + Name = name + }; + + var isNameUsed = await Mediator.Send(request); + return Ok(isNameUsed); + } +} \ No newline at end of file diff --git a/modules/back-end/src/Api/appsettings.json b/modules/back-end/src/Api/appsettings.json index acb39b6c7..38ba7e844 100644 --- a/modules/back-end/src/Api/appsettings.json +++ b/modules/back-end/src/Api/appsettings.json @@ -11,14 +11,14 @@ "Key": "featbit-identity-key" }, "MongoDb": { - "ConnectionString": "mongodb://admin:password@mongodb:27017", + "ConnectionString": "mongodb://admin:password@localhost:27017", "Database": "featbit" }, "Kafka": { - "BootstrapServers": "kafka:9092" + "BootstrapServers": "localhost:9092" }, "OLAP": { - "ServiceHost": "http://da-server" + "ServiceHost": "http://localhost" }, "AllowedHosts": "*" } diff --git a/modules/back-end/src/Application/AccessTokens/IsAccessTokenNameUsed.cs b/modules/back-end/src/Application/AccessTokens/IsAccessTokenNameUsed.cs new file mode 100644 index 000000000..3dfaf7f46 --- /dev/null +++ b/modules/back-end/src/Application/AccessTokens/IsAccessTokenNameUsed.cs @@ -0,0 +1,26 @@ +namespace Application.AccessTokens; + +public class IsAccessTokenNameUsed : IRequest +{ + public Guid OrganizationId { get; set; } + + public string Name { get; set; } +} + +public class IsAccessTokenNameUsedHandler : IRequestHandler +{ + private readonly IAccessTokenService _service; + + public IsAccessTokenNameUsedHandler(IAccessTokenService service) + { + _service = service; + } + + public async Task Handle(IsAccessTokenNameUsed request, CancellationToken cancellationToken) + { + var isNameUsed = + await _service.AnyAsync(x => x.OrganizationId == request.OrganizationId && x.Name == request.Name); + + return isNameUsed; + } +} \ No newline at end of file diff --git a/modules/back-end/src/Application/Services/IAccessTokenService.cs b/modules/back-end/src/Application/Services/IAccessTokenService.cs new file mode 100644 index 000000000..eb8e19560 --- /dev/null +++ b/modules/back-end/src/Application/Services/IAccessTokenService.cs @@ -0,0 +1,10 @@ +using Application.Bases.Models; +using Application.Policies; +using Domain.AccessTokens; +using Domain.Policies; + +namespace Application.Services; + +public interface IAccessTokenService : IService +{ +} \ No newline at end of file diff --git a/modules/back-end/src/Domain/AccessTokens/AccessToken.cs b/modules/back-end/src/Domain/AccessTokens/AccessToken.cs new file mode 100644 index 000000000..3e3d7a4f6 --- /dev/null +++ b/modules/back-end/src/Domain/AccessTokens/AccessToken.cs @@ -0,0 +1,23 @@ +using Domain.Policies; + +namespace Domain.AccessTokens; + +public class AccessToken : AuditedEntity +{ + public Guid? OrganizationId { get; set; } + + public string Name { get; set; } + + public string Type { get; set; } + + public ICollection Policies { get; set; } + + public AccessToken(Guid organizationId, string name, string type) + { + OrganizationId = organizationId; + Name = name; + + Type = AccessTokenTypes.Personal; + Policies = Array.Empty(); + } +} \ No newline at end of file diff --git a/modules/back-end/src/Domain/AccessTokens/AccessTokenTypes.cs b/modules/back-end/src/Domain/AccessTokens/AccessTokenTypes.cs new file mode 100644 index 000000000..01946ef17 --- /dev/null +++ b/modules/back-end/src/Domain/AccessTokens/AccessTokenTypes.cs @@ -0,0 +1,8 @@ +namespace Domain.Policies; + +public class AccessTokenTypes +{ + public const string Personal = "Personal"; + + public const string Service = "Service"; +} \ No newline at end of file diff --git a/modules/back-end/src/Infrastructure/AccessTokens/AccessTokenService.cs b/modules/back-end/src/Infrastructure/AccessTokens/AccessTokenService.cs new file mode 100644 index 000000000..1c8bbbe4b --- /dev/null +++ b/modules/back-end/src/Infrastructure/AccessTokens/AccessTokenService.cs @@ -0,0 +1,19 @@ +using Application.Bases.Models; +using Application.Policies; +using Domain.AccessTokens; +using Domain.Groups; +using Domain.Members; +using Domain.Organizations; +using Domain.Policies; +using Domain.Users; +using MongoDB.Driver; +using MongoDB.Driver.Linq; + +namespace Infrastructure.AccessTokens; + +public class AccessTokenService : MongoDbService, IAccessTokenService +{ + public AccessTokenService(MongoDbClient mongoDb) : base(mongoDb) + { + } +} \ No newline at end of file diff --git a/modules/back-end/src/Infrastructure/ConfigureServices.cs b/modules/back-end/src/Infrastructure/ConfigureServices.cs index c764cf6bd..7cc4f1552 100644 --- a/modules/back-end/src/Infrastructure/ConfigureServices.cs +++ b/modules/back-end/src/Infrastructure/ConfigureServices.cs @@ -2,6 +2,7 @@ using Domain.Identity; using Domain.Messages; using Domain.Users; +using Infrastructure.AccessTokens; using Infrastructure.AuditLogs; using Infrastructure.DataSync; using Infrastructure.EndUsers; @@ -94,6 +95,7 @@ public static IServiceCollection AddInfrastructureServices( services.AddTransient(); services.AddTransient(); services.AddSingleton(); + services.AddTransient(); return services; } diff --git a/modules/back-end/src/Infrastructure/MongoDb/MongoDbClient.cs b/modules/back-end/src/Infrastructure/MongoDb/MongoDbClient.cs index ae3334333..bd6cc7634 100644 --- a/modules/back-end/src/Infrastructure/MongoDb/MongoDbClient.cs +++ b/modules/back-end/src/Infrastructure/MongoDb/MongoDbClient.cs @@ -1,3 +1,4 @@ +using Domain.AccessTokens; using Domain.AuditLogs; using Domain.EndUsers; using Domain.ExperimentMetrics; @@ -59,6 +60,8 @@ public MongoDbClient(IOptions options) { typeof(Experiment), "Experiments" }, { typeof(ExperimentMetric), "ExperimentMetrics" }, + + { typeof(AccessToken), "AccessTokens" }, }; public IMongoCollection CollectionOf() diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts index 6ce7ad416..d0d1b2d4d 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts @@ -7,6 +7,7 @@ import { AccessTokenTypeEnum, IAccessTokenPolicy } from "@features/safe/integrat import { PolicyFilter } from "@features/safe/iam/types/policy"; import { NzSelectComponent } from "ng-zorro-antd/select"; import { Subject } from "rxjs"; +import { AccessTokenService } from "@services/access-token.service"; @Component({ selector: 'access-token-drawer', @@ -30,6 +31,7 @@ export class AccessTokenDrawerComponent implements OnInit { constructor( private fb: FormBuilder, private policyService: PolicyService, + private accessTokenService: AccessTokenService, private message: NzMessageService ) { this.policyDebouncer.pipe( @@ -98,7 +100,7 @@ export class AccessTokenDrawerComponent implements OnInit { nameAsyncValidator = (control: FormControl) => control.valueChanges.pipe( debounceTime(300), - switchMap(value => this.policyService.isNameUsed(value as string)), + switchMap(value => this.accessTokenService.isNameUsed(value as string)), map(isNameUsed => { switch (isNameUsed) { case true: diff --git a/modules/front-end/src/app/core/services/access-token.service.ts b/modules/front-end/src/app/core/services/access-token.service.ts new file mode 100644 index 000000000..e055bd73b --- /dev/null +++ b/modules/front-end/src/app/core/services/access-token.service.ts @@ -0,0 +1,24 @@ +import { Injectable } from "@angular/core"; +import { HttpClient } from "@angular/common/http"; +import { getCurrentOrganization } from "@utils/project-env"; +import { environment } from "src/environments/environment"; +import { Observable, of } from "rxjs"; +import { catchError } from "rxjs/operators"; + +@Injectable({ + providedIn: 'root' +}) +export class AccessTokenService { + constructor(private http: HttpClient) { } + + get baseUrl() { + const organizationId = getCurrentOrganization().id; + return `${environment.url}/api/v1/organizations/${organizationId}/access-tokens`; + } + + isNameUsed(name: string) { + const url = `${this.baseUrl}/is-name-used?name=${name}`; + + return this.http.get(url).pipe(catchError(() => of(undefined))); + } +} diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts index 03a68da23..73f96d437 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts @@ -1,8 +1,8 @@ import { IPolicy } from "@features/safe/iam/types/policy"; export enum AccessTokenTypeEnum { - Personal = 'personal', - Service = 'service' + Personal = 'Personal', + Service = 'Service' } export interface IAccessTokenPolicy extends IPolicy { From 669330e10d3c88861a992bd24512ba89d471e634 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Sat, 11 Mar 2023 17:53:43 +0100 Subject: [PATCH 05/44] in progress --- .../Api/Controllers/AccessTokenController.cs | 9 +++ .../Application/AccessTokens/AccessTokenVm.cs | 14 +++++ .../AccessTokens/CreateAccessToken.cs | 63 +++++++++++++++++++ .../Application/AccessTokens/MapperProfile.cs | 13 ++++ .../src/Application/Bases/ErrorCodes.cs | 4 ++ .../src/Application/Policies/MapperProfile.cs | 1 + .../src/Domain/AccessTokens/AccessToken.cs | 4 +- .../Domain/AccessTokens/AccessTokenTypes.cs | 7 +++ .../access-token-drawer.component.html | 7 ++- .../access-token-drawer.component.less | 4 ++ .../access-token-drawer.component.ts | 57 ++++++++++++----- .../request-response.interceptor.ts | 2 +- .../app/core/services/access-token.service.ts | 6 ++ .../access-tokens/types/access-token.ts | 7 +++ modules/front-end/src/variables.less | 1 + 15 files changed, 180 insertions(+), 19 deletions(-) create mode 100644 modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs create mode 100644 modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs create mode 100644 modules/back-end/src/Application/AccessTokens/MapperProfile.cs diff --git a/modules/back-end/src/Api/Controllers/AccessTokenController.cs b/modules/back-end/src/Api/Controllers/AccessTokenController.cs index e10d45782..a4830e05b 100644 --- a/modules/back-end/src/Api/Controllers/AccessTokenController.cs +++ b/modules/back-end/src/Api/Controllers/AccessTokenController.cs @@ -17,4 +17,13 @@ public async Task> IsNameUsedAsync(Guid organizationId, string var isNameUsed = await Mediator.Send(request); return Ok(isNameUsed); } + + [HttpPost] + public async Task> CreateAsync(Guid organizationId, CreateAccessToken request) + { + request.OrganizationId = organizationId; + + var policy = await Mediator.Send(request); + return Ok(policy); + } } \ No newline at end of file diff --git a/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs b/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs new file mode 100644 index 000000000..3b4033812 --- /dev/null +++ b/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs @@ -0,0 +1,14 @@ +using Domain.Policies; + +namespace Application.AccessTokens; + +public class AccessTokenVm +{ + public string Id { get; set; } + + public string Name { get; set; } + + public string Type { get; set; } + + public IEnumerable PolicyIds { get; set; } +} \ No newline at end of file diff --git a/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs b/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs new file mode 100644 index 000000000..0724e5b72 --- /dev/null +++ b/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs @@ -0,0 +1,63 @@ +using Application.Bases; +using Application.Policies; +using Domain.AccessTokens; +using Domain.Policies; + +namespace Application.AccessTokens; + +public class CreateAccessToken : IRequest +{ + public Guid OrganizationId { get; set; } + + public string Name { get; set; } + + public string Type { get; set; } + + public IEnumerable PolicyIds { get; set; } +} + +public class CreateAccessTokenValidator : AbstractValidator +{ + public CreateAccessTokenValidator() + { + RuleFor(x => x.Name) + .NotEmpty().WithErrorCode(ErrorCodes.NameIsRequired); + + RuleFor(x => x.Type) + .Must(AccessTokenTypes.IsDefined).WithErrorCode(ErrorCodes.InvalidAccessTokenType); + + RuleFor(x => x.PolicyIds) + .Must(PolicyIds => PolicyIds.Any()) + .Unless(x => x.Type == AccessTokenTypes.Personal) + .WithErrorCode(ErrorCodes.ServiceAccessTokenMustDefinePolicies); + } +} + +public class CreateAccessTokenHandler : IRequestHandler +{ + private readonly IPolicyService _policyService; + private readonly IAccessTokenService _service; + private readonly IMapper _mapper; + + public CreateAccessTokenHandler(IAccessTokenService service, IPolicyService policyService, IMapper mapper) + { + _service = service; + _policyService = policyService; + _mapper = mapper; + } + + public async Task Handle(CreateAccessToken request, CancellationToken cancellationToken) + { + var policies = Enumerable.Empty(); + if (request.Type == AccessTokenTypes.Service) + { + policies = await _policyService.FindManyAsync((x) => request.PolicyIds.Contains(x.Id)); + } + + var accessToken = new AccessToken(request.OrganizationId, request.Name, request.Type, policies); + + await _service.AddOneAsync(accessToken); + + return _mapper.Map(accessToken); + } +} \ No newline at end of file diff --git a/modules/back-end/src/Application/AccessTokens/MapperProfile.cs b/modules/back-end/src/Application/AccessTokens/MapperProfile.cs new file mode 100644 index 000000000..db401ba40 --- /dev/null +++ b/modules/back-end/src/Application/AccessTokens/MapperProfile.cs @@ -0,0 +1,13 @@ +using Application.Bases.Models; +using Domain.AccessTokens; + +namespace Application.AccessTokens; + +public class MapperProfile : Profile +{ + public MapperProfile() + { + CreateMap(); + CreateMap, PagedResult>(); + } +} \ No newline at end of file diff --git a/modules/back-end/src/Application/Bases/ErrorCodes.cs b/modules/back-end/src/Application/Bases/ErrorCodes.cs index 8a968cbf9..581e2af2d 100644 --- a/modules/back-end/src/Application/Bases/ErrorCodes.cs +++ b/modules/back-end/src/Application/Bases/ErrorCodes.cs @@ -65,4 +65,8 @@ public static class ErrorCodes public const string EventTypeIsRequired = nameof(EventTypeIsRequired); public const string EventNameIsRequired = nameof(EventNameIsRequired); public const string MetricIsBeingUsedByExperiment = nameof(MetricIsBeingUsedByExperiment); + + // access tokens + public const string InvalidAccessTokenType = nameof(InvalidAccessTokenType); + public const string ServiceAccessTokenMustDefinePolicies = nameof(ServiceAccessTokenMustDefinePolicies); } \ No newline at end of file diff --git a/modules/back-end/src/Application/Policies/MapperProfile.cs b/modules/back-end/src/Application/Policies/MapperProfile.cs index 45e35bd19..6febbe829 100644 --- a/modules/back-end/src/Application/Policies/MapperProfile.cs +++ b/modules/back-end/src/Application/Policies/MapperProfile.cs @@ -8,6 +8,7 @@ public class MapperProfile : Profile public MapperProfile() { CreateMap(); + CreateMap, IEnumerable>(); CreateMap, PagedResult>(); } } \ No newline at end of file diff --git a/modules/back-end/src/Domain/AccessTokens/AccessToken.cs b/modules/back-end/src/Domain/AccessTokens/AccessToken.cs index 3e3d7a4f6..6ab06a94e 100644 --- a/modules/back-end/src/Domain/AccessTokens/AccessToken.cs +++ b/modules/back-end/src/Domain/AccessTokens/AccessToken.cs @@ -12,12 +12,12 @@ public class AccessToken : AuditedEntity public ICollection Policies { get; set; } - public AccessToken(Guid organizationId, string name, string type) + public AccessToken(Guid organizationId, string name, string type, IEnumerable policies) { OrganizationId = organizationId; Name = name; Type = AccessTokenTypes.Personal; - Policies = Array.Empty(); + Policies = policies.ToArray(); } } \ No newline at end of file diff --git a/modules/back-end/src/Domain/AccessTokens/AccessTokenTypes.cs b/modules/back-end/src/Domain/AccessTokens/AccessTokenTypes.cs index 01946ef17..45a2da628 100644 --- a/modules/back-end/src/Domain/AccessTokens/AccessTokenTypes.cs +++ b/modules/back-end/src/Domain/AccessTokens/AccessTokenTypes.cs @@ -5,4 +5,11 @@ public class AccessTokenTypes public const string Personal = "Personal"; public const string Service = "Service"; + + public static readonly string[] All = { Personal, Service }; + + public static bool IsDefined(string type) + { + return All.Contains(type); + } } \ No newline at end of file diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html index f549fbbd4..52d2bdf02 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html @@ -40,9 +40,9 @@ - + Policies - +
+ +
Policies are mandatory for service type access tokens
+ diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less index 2e137e412..75b92cc95 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less @@ -1,5 +1,9 @@ @import "variables"; +.error-message { + color: @red60-color; +} + .selected-policies { border: 1px solid @grey20-color; background-color: #ffffff; diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts index d0d1b2d4d..e7133085c 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts @@ -40,7 +40,7 @@ export class AccessTokenDrawerComponent implements OnInit { ).subscribe(query => this.searchPolicies(query)); } - displayPolicies: boolean = false + isServiceAccessToken: boolean = false @ViewChild("policyNodeSelector", { static: false }) policySelectNode: NzSelectComponent; selectedPolicyList: IAccessTokenPolicy[] = []; @@ -50,7 +50,7 @@ export class AccessTokenDrawerComponent implements OnInit { this.form = this.fb.group({ name: ['', [Validators.required], [this.nameAsyncValidator], 'change'], type: [AccessTokenTypeEnum.Personal, [Validators.required]], - policy: [null, []], + policy: [null, []] }); } @@ -61,7 +61,7 @@ export class AccessTokenDrawerComponent implements OnInit { onTypeChange() { const { type } = this.form.value; - this.displayPolicies = type !== AccessTokenTypeEnum.Personal; + this.isServiceAccessToken = type === AccessTokenTypeEnum.Service; } onPolicySelectChange() { @@ -78,10 +78,12 @@ export class AccessTokenDrawerComponent implements OnInit { isSelected: this.selectedPolicyList.some((sp => sp.id === p.id)) })); this.policySelectNode.writeValue(undefined); + this.validatePoliciesControl(); } removePolicy(policy: IAccessTokenPolicy) { this.selectedPolicyList = this.selectedPolicyList.filter((p) => p.id !== policy.id); + this.validatePoliciesControl(); } isLoadingPolicies = true; @@ -115,27 +117,54 @@ export class AccessTokenDrawerComponent implements OnInit { ); isLoading: boolean = false; + isPolicyIdsValid = true; + + validatePoliciesControl() { + const policyControl = this.form.get('policy'); + if (this.isServiceAccessToken && this.selectedPolicyList.length === 0) { + policyControl.setValidators(Validators.required); + policyControl.setErrors({required: true}); + this.isPolicyIdsValid = false; + } else { + policyControl.clearValidators(); + policyControl.markAsPristine(); + this.isPolicyIdsValid = true; + } + } doSubmit() { + // we validate name and type only here if (this.form.invalid) { for (const i in this.form.controls) { this.form.controls[i].markAsDirty(); this.form.controls[i].updateValueAndValidity(); } + } + + // validate policies + this.validatePoliciesControl(); + + if (this.form.invalid || !this.isPolicyIdsValid) { return; } this.isLoading = true; - const {name, description} = this.form.value; - this.policyService.create(name, description).subscribe( - () => { - this.isLoading = false; - this.close.emit(true); - this.message.success($localize `:@@common.operation-success:Operation succeeded`); - this.form.reset(); - }, - _ => { - this.isLoading = false; - } + const { name, type } = this.form.value; + const policies = this.isServiceAccessToken ? this.selectedPolicyList.map(p => p.id) : []; + + this.accessTokenService.create(name, type, policies).subscribe({ + next: () => { + this.isLoading = false; + this.close.emit(true); + this.message.success($localize `:@@common.operation-success:Operation succeeded`); + this.form.reset(); + }, + error: (e) => { + this.isLoading = false; + if (e.errors[0] === 'ServiceAccessTokenMustDefinePolicies') { + this.message.error($localize `:@@integrations.access-token.service-access-token-must-define-policies:Policies are mandatory for service type access tokens`); + } + } + } ) } diff --git a/modules/front-end/src/app/core/interceptors/request-response.interceptor.ts b/modules/front-end/src/app/core/interceptors/request-response.interceptor.ts index 50574a049..0c2b02bd5 100644 --- a/modules/front-end/src/app/core/interceptors/request-response.interceptor.ts +++ b/modules/front-end/src/app/core/interceptors/request-response.interceptor.ts @@ -48,7 +48,7 @@ export class RequestResponseInterceptor implements HttpInterceptor { } this.showErrorMsg(errorResponse); - throw errorResponse; + throw errorResponse.error; }) ); } diff --git a/modules/front-end/src/app/core/services/access-token.service.ts b/modules/front-end/src/app/core/services/access-token.service.ts index e055bd73b..24fd8db1b 100644 --- a/modules/front-end/src/app/core/services/access-token.service.ts +++ b/modules/front-end/src/app/core/services/access-token.service.ts @@ -4,6 +4,8 @@ import { getCurrentOrganization } from "@utils/project-env"; import { environment } from "src/environments/environment"; import { Observable, of } from "rxjs"; import { catchError } from "rxjs/operators"; +import { IPolicy } from "@features/safe/iam/types/policy"; +import { IAccessToken } from "@features/safe/integrations/access-tokens/types/access-token"; @Injectable({ providedIn: 'root' @@ -21,4 +23,8 @@ export class AccessTokenService { return this.http.get(url).pipe(catchError(() => of(undefined))); } + + create(name: string, type: string, policyIds: string[] = []): Observable { + return this.http.post(this.baseUrl, { name, type, policyIds }); + } } diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts index 73f96d437..47e2b21ed 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts @@ -1,5 +1,12 @@ import { IPolicy } from "@features/safe/iam/types/policy"; +export interface IAccessToken { + id: string; + type: string; + name: string; + policies: IPolicy[], +} + export enum AccessTokenTypeEnum { Personal = 'Personal', Service = 'Service' diff --git a/modules/front-end/src/variables.less b/modules/front-end/src/variables.less index b94360801..36529c079 100644 --- a/modules/front-end/src/variables.less +++ b/modules/front-end/src/variables.less @@ -29,6 +29,7 @@ @red10-color: #FFE8D7; @red40-color: #FF886B; @red50-color: #FF513A; +@red60-color: #ff4d4f; @yellow10-color: #FFF9CF; @yellow55-color: #faad14; From b6f3f4306c23de47543e8295458e3faaf93f1e7a Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Sat, 11 Mar 2023 21:46:55 +0100 Subject: [PATCH 06/44] in progress --- .../Api/Controllers/AccessTokenController.cs | 21 ++++- .../AccessTokens/AccessTokenFilter.cs | 10 +++ .../Application/AccessTokens/AccessTokenVm.cs | 10 ++- .../AccessTokens/CreateAccessToken.cs | 6 +- .../AccessTokens/GetAccessTokenList.cs | 40 ++++++++++ .../Services/IAccessTokenService.cs | 4 +- .../Application/Services/IMemberService.cs | 1 + .../src/Domain/AccessTokens/AccessToken.cs | 16 +++- .../Domain/AccessTokens/AccessTokenStatus.cs | 15 ++++ .../Domain/AccessTokens/AccessTokenTypes.cs | 2 +- .../AccessTokens/AccessTokenService.cs | 34 ++++++++ .../Infrastructure/Members/MemberService.cs | 13 +++ .../access-token-drawer.component.html | 2 +- .../access-token-drawer.component.ts | 5 -- modules/front-end/src/app/core/core.module.ts | 6 ++ .../core/pipes/access-token-status.pipe.ts | 19 +++++ .../app/core/pipes/access-token-type.pipe.ts | 16 ++++ .../app/core/services/access-token.service.ts | 28 ++++++- .../experimentation.component.less | 2 +- .../policy-editor.component.less | 2 +- .../iam/groups/index/index.component.less | 2 +- .../iam/policies/index/index.component.less | 2 +- .../safe/iam/team/index/index.component.less | 2 +- .../access-tokens/index/index.component.html | 67 ++++++++++++---- .../access-tokens/index/index.component.less | 4 +- .../access-tokens/index/index.component.ts | 80 ++++++++++++++----- .../access-tokens/types/access-token.ts | 33 ++++++++ 27 files changed, 379 insertions(+), 63 deletions(-) create mode 100644 modules/back-end/src/Application/AccessTokens/AccessTokenFilter.cs create mode 100644 modules/back-end/src/Application/AccessTokens/GetAccessTokenList.cs create mode 100644 modules/back-end/src/Domain/AccessTokens/AccessTokenStatus.cs create mode 100644 modules/front-end/src/app/core/pipes/access-token-status.pipe.ts create mode 100644 modules/front-end/src/app/core/pipes/access-token-type.pipe.ts diff --git a/modules/back-end/src/Api/Controllers/AccessTokenController.cs b/modules/back-end/src/Api/Controllers/AccessTokenController.cs index a4830e05b..4cd80aef7 100644 --- a/modules/back-end/src/Api/Controllers/AccessTokenController.cs +++ b/modules/back-end/src/Api/Controllers/AccessTokenController.cs @@ -1,10 +1,26 @@ using Application.AccessTokens; +using Application.Bases.Models; namespace Api.Controllers; [Route("api/v{version:apiVersion}/organizations/{organizationId:guid}/access-tokens")] public class AccessTokenController : ApiControllerBase { + [HttpGet] + public async Task>> GetListAsync( + Guid organizationId, + [FromQuery] AccessTokenFilter filter) + { + var request = new GetAccessTokenList + { + OrganizationId = organizationId, + Filter = filter + }; + + var accessTokens = await Mediator.Send(request); + return Ok(accessTokens); + } + [HttpGet("is-name-used")] public async Task> IsNameUsedAsync(Guid organizationId, string name) { @@ -22,8 +38,9 @@ public async Task> IsNameUsedAsync(Guid organizationId, string public async Task> CreateAsync(Guid organizationId, CreateAccessToken request) { request.OrganizationId = organizationId; + request.CreatorId = CurrentUser.Id; - var policy = await Mediator.Send(request); - return Ok(policy); + var accessToken = await Mediator.Send(request); + return Ok(accessToken); } } \ No newline at end of file diff --git a/modules/back-end/src/Application/AccessTokens/AccessTokenFilter.cs b/modules/back-end/src/Application/AccessTokens/AccessTokenFilter.cs new file mode 100644 index 000000000..8505a5da1 --- /dev/null +++ b/modules/back-end/src/Application/AccessTokens/AccessTokenFilter.cs @@ -0,0 +1,10 @@ +using Application.Bases.Models; + +namespace Application.AccessTokens; + +public class AccessTokenFilter : PagedRequest +{ + public string Name { get; set; } + public Guid? CreatorId { get; set; } + public string Type { get; set; } +} \ No newline at end of file diff --git a/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs b/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs index 3b4033812..f81633442 100644 --- a/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs +++ b/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs @@ -1,14 +1,20 @@ +using Application.Members; using Domain.Policies; namespace Application.AccessTokens; public class AccessTokenVm { - public string Id { get; set; } + public Guid Id { get; set; } public string Name { get; set; } public string Type { get; set; } + + public string Status { get; set; } + public MemberVm Creator { get; set; } - public IEnumerable PolicyIds { get; set; } + public IEnumerable Policies { get; set; } + + public DateTime? LastUsedAt { get; set; } } \ No newline at end of file diff --git a/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs b/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs index 0724e5b72..ff2ba8af6 100644 --- a/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs +++ b/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs @@ -12,7 +12,9 @@ public class CreateAccessToken : IRequest public string Name { get; set; } public string Type { get; set; } - + + public Guid CreatorId { get; set; } + public IEnumerable PolicyIds { get; set; } } @@ -54,7 +56,7 @@ public async Task Handle(CreateAccessToken request, CancellationT policies = await _policyService.FindManyAsync((x) => request.PolicyIds.Contains(x.Id)); } - var accessToken = new AccessToken(request.OrganizationId, request.Name, request.Type, policies); + var accessToken = new AccessToken(request.OrganizationId, request.CreatorId, request.Name, request.Type, policies); await _service.AddOneAsync(accessToken); diff --git a/modules/back-end/src/Application/AccessTokens/GetAccessTokenList.cs b/modules/back-end/src/Application/AccessTokens/GetAccessTokenList.cs new file mode 100644 index 000000000..2d43e64ef --- /dev/null +++ b/modules/back-end/src/Application/AccessTokens/GetAccessTokenList.cs @@ -0,0 +1,40 @@ +using Application.Bases.Models; +using Application.Members; + +namespace Application.AccessTokens; + +public class GetAccessTokenList : IRequest> +{ + public Guid OrganizationId { get; set; } + + public AccessTokenFilter Filter { get; set; } +} + +public class GetAccessTokenListHandler : IRequestHandler> +{ + private readonly IMemberService _memberService; + private readonly IAccessTokenService _service; + private readonly IMapper _mapper; + + public GetAccessTokenListHandler(IAccessTokenService service, IMemberService memberService, IMapper mapper) + { + _service = service; + _memberService = memberService; + _mapper = mapper; + } + + public async Task> Handle(GetAccessTokenList request, CancellationToken cancellationToken) + { + var accessTokens = await _service.GetListAsync(request.OrganizationId, request.Filter); + var creatorIds = accessTokens.Items.Select(x => x.CreatorId); + var creators = await _memberService.GetListByIds(creatorIds); + var accessTokenVms = _mapper.Map>(accessTokens); + foreach (var accessTokenItem in accessTokens.Items) + { + var accessTokenVm = accessTokenVms.Items.First(x => x.Id == accessTokenItem.Id); + accessTokenVm.Creator = _mapper.Map(creators.First(x => x.Id == accessTokenItem.CreatorId)); + } + + return accessTokenVms; + } +} \ No newline at end of file diff --git a/modules/back-end/src/Application/Services/IAccessTokenService.cs b/modules/back-end/src/Application/Services/IAccessTokenService.cs index eb8e19560..1eac619e8 100644 --- a/modules/back-end/src/Application/Services/IAccessTokenService.cs +++ b/modules/back-end/src/Application/Services/IAccessTokenService.cs @@ -1,10 +1,10 @@ +using Application.AccessTokens; using Application.Bases.Models; -using Application.Policies; using Domain.AccessTokens; -using Domain.Policies; namespace Application.Services; public interface IAccessTokenService : IService { + Task> GetListAsync(Guid organizationId, AccessTokenFilter filter); } \ No newline at end of file diff --git a/modules/back-end/src/Application/Services/IMemberService.cs b/modules/back-end/src/Application/Services/IMemberService.cs index a83520627..a529dd72c 100644 --- a/modules/back-end/src/Application/Services/IMemberService.cs +++ b/modules/back-end/src/Application/Services/IMemberService.cs @@ -8,6 +8,7 @@ namespace Application.Services; public interface IMemberService { Task GetAsync(Guid organizationId, Guid memberId); + Task> GetListByIds(IEnumerable ids); Task DeleteAsync(Guid organizationId, Guid memberId); diff --git a/modules/back-end/src/Domain/AccessTokens/AccessToken.cs b/modules/back-end/src/Domain/AccessTokens/AccessToken.cs index 6ab06a94e..ed4e7832c 100644 --- a/modules/back-end/src/Domain/AccessTokens/AccessToken.cs +++ b/modules/back-end/src/Domain/AccessTokens/AccessToken.cs @@ -9,15 +9,27 @@ public class AccessToken : AuditedEntity public string Name { get; set; } public string Type { get; set; } + public string Status { get; set; } + + public Guid CreatorId { get; set; } public ICollection Policies { get; set; } + + public DateTime? LastUsedAt { get; set; } - public AccessToken(Guid organizationId, string name, string type, IEnumerable policies) + public AccessToken(Guid organizationId, Guid creatorId, string name, string type, IEnumerable policies) { OrganizationId = organizationId; + CreatorId = creatorId; Name = name; - + + Status = AccessTokenStatus.Active; Type = AccessTokenTypes.Personal; Policies = policies.ToArray(); } + + public void RefreshLastUsedAt() + { + LastUsedAt = DateTime.UtcNow; + } } \ No newline at end of file diff --git a/modules/back-end/src/Domain/AccessTokens/AccessTokenStatus.cs b/modules/back-end/src/Domain/AccessTokens/AccessTokenStatus.cs new file mode 100644 index 000000000..8c8922473 --- /dev/null +++ b/modules/back-end/src/Domain/AccessTokens/AccessTokenStatus.cs @@ -0,0 +1,15 @@ +namespace Domain.AccessTokens; + +public class AccessTokenStatus +{ + public const string Active = "Active"; + + public const string Inactive = "Inactive"; + + public static readonly string[] All = { Active, Inactive }; + + public static bool IsDefined(string type) + { + return All.Contains(type); + } +} \ No newline at end of file diff --git a/modules/back-end/src/Domain/AccessTokens/AccessTokenTypes.cs b/modules/back-end/src/Domain/AccessTokens/AccessTokenTypes.cs index 45a2da628..5422dfd12 100644 --- a/modules/back-end/src/Domain/AccessTokens/AccessTokenTypes.cs +++ b/modules/back-end/src/Domain/AccessTokens/AccessTokenTypes.cs @@ -1,4 +1,4 @@ -namespace Domain.Policies; +namespace Domain.AccessTokens; public class AccessTokenTypes { diff --git a/modules/back-end/src/Infrastructure/AccessTokens/AccessTokenService.cs b/modules/back-end/src/Infrastructure/AccessTokens/AccessTokenService.cs index 1c8bbbe4b..601bc5240 100644 --- a/modules/back-end/src/Infrastructure/AccessTokens/AccessTokenService.cs +++ b/modules/back-end/src/Infrastructure/AccessTokens/AccessTokenService.cs @@ -1,3 +1,4 @@ +using Application.AccessTokens; using Application.Bases.Models; using Application.Policies; using Domain.AccessTokens; @@ -16,4 +17,37 @@ public class AccessTokenService : MongoDbService, IAccessTokenServi public AccessTokenService(MongoDbClient mongoDb) : base(mongoDb) { } + + public async Task> GetListAsync(Guid organizationId, AccessTokenFilter filter) + { + var query = MongoDb.QueryableOf() + .Where(x => x.OrganizationId == organizationId); + + var name = filter.Name; + if (!string.IsNullOrWhiteSpace(name)) + { + query = query.Where(x => x.Name.Contains(name, StringComparison.CurrentCultureIgnoreCase)); + } + + var type = filter.Type; + if (!string.IsNullOrWhiteSpace(type)) + { + query = query.Where(x => x.Type == type); + } + + var creatorId = filter.CreatorId; + if (!string.IsNullOrWhiteSpace(type)) + { + query = query.Where(x => x.CreatorId == creatorId); + } + + var totalCount = await query.CountAsync(); + var items = await query + .Skip(filter.PageIndex * filter.PageSize) + .OrderByDescending(x => x.CreatedAt) + .Take(filter.PageSize) + .ToListAsync(); + + return new PagedResult(totalCount, items); + } } \ No newline at end of file diff --git a/modules/back-end/src/Infrastructure/Members/MemberService.cs b/modules/back-end/src/Infrastructure/Members/MemberService.cs index cebf68233..ee7f627f1 100644 --- a/modules/back-end/src/Infrastructure/Members/MemberService.cs +++ b/modules/back-end/src/Infrastructure/Members/MemberService.cs @@ -66,6 +66,19 @@ await _mongoDb.CollectionOf() .DeleteManyAsync(x => x.OrganizationId == organizationId && x.MemberId == memberId); } + public async Task> GetListByIds(IEnumerable ids) + { + var query = _mongoDb.QueryableOf() + .Where(x => ids.Contains(x.Id)); + + return await query.Select(x => new Member + { + Id = x.Id, + Email = x.Email, + Name = x.Name, + }).ToListAsync();; + } + public async Task> GetListAsync(Guid organizationId, MemberFilter filter) { var users = _mongoDb.QueryableOf(); diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html index 52d2bdf02..5326732ae 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html @@ -32,7 +32,7 @@ + [nzLabel]="at | accessTokenType"> diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts index e7133085c..37edc31d6 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts @@ -168,11 +168,6 @@ export class AccessTokenDrawerComponent implements OnInit { ) } - actionTokenTypeLabel = { - [AccessTokenTypeEnum.Personal]: $localize `:@@integrations.access-token.personal:Personal`, - [AccessTokenTypeEnum.Service]: $localize `:@@integrations.access-token.personal:Service` - } - actionTokenTypes = [ AccessTokenTypeEnum.Personal, AccessTokenTypeEnum.Service diff --git a/modules/front-end/src/app/core/core.module.ts b/modules/front-end/src/app/core/core.module.ts index 4d098281b..d049483d8 100644 --- a/modules/front-end/src/app/core/core.module.ts +++ b/modules/front-end/src/app/core/core.module.ts @@ -80,6 +80,8 @@ import { ChangeReviewComponent } from "@core/components/change-review/change-rev import { NzBreadCrumbModule } from "ng-zorro-antd/breadcrumb"; import { NzInputNumberModule } from "ng-zorro-antd/input-number"; import { AccessTokenDrawerComponent } from "@core/components/access-token-drawer/access-token-drawer.component"; +import { AccessTokenTypePipe } from "@core/pipes/access-token-type.pipe"; +import { AccessTokenStatusPipe } from "@core/pipes/access-token-status.pipe"; @NgModule({ declarations: [ @@ -87,6 +89,8 @@ import { AccessTokenDrawerComponent } from "@core/components/access-token-drawer PercentagePipe, SafeHtmlPipe, PolicyTypePipe, + AccessTokenTypePipe, + AccessTokenStatusPipe, TranslationPipe, RuleVariationValuePipe, PermissionCheckDirective, @@ -172,6 +176,8 @@ import { AccessTokenDrawerComponent } from "@core/components/access-token-drawer PercentagePipe, SafeHtmlPipe, PolicyTypePipe, + AccessTokenTypePipe, + AccessTokenStatusPipe, TranslationPipe, RuleVariationValuePipe, PermissionCheckDirective, diff --git a/modules/front-end/src/app/core/pipes/access-token-status.pipe.ts b/modules/front-end/src/app/core/pipes/access-token-status.pipe.ts new file mode 100644 index 000000000..057c8bfe1 --- /dev/null +++ b/modules/front-end/src/app/core/pipes/access-token-status.pipe.ts @@ -0,0 +1,19 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import { + AccessTokenStatusEnum, + AccessTokenTypeEnum +} from "@features/safe/integrations/access-tokens/types/access-token"; + +@Pipe({ + name: 'accessTokenStatus' +}) +export class AccessTokenStatusPipe implements PipeTransform { + typeDict = { + [AccessTokenStatusEnum.Active]: $localize `:@@integrations.access-token.active:Active`, + [AccessTokenStatusEnum.Inactive]: $localize `:@@integrations.access-token.inactive:Inactive` + } + + transform(value: string): string { + return this.typeDict[value] || ''; + } +} diff --git a/modules/front-end/src/app/core/pipes/access-token-type.pipe.ts b/modules/front-end/src/app/core/pipes/access-token-type.pipe.ts new file mode 100644 index 000000000..6a3f6e7fc --- /dev/null +++ b/modules/front-end/src/app/core/pipes/access-token-type.pipe.ts @@ -0,0 +1,16 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import { AccessTokenTypeEnum } from "@features/safe/integrations/access-tokens/types/access-token"; + +@Pipe({ + name: 'accessTokenType' +}) +export class AccessTokenTypePipe implements PipeTransform { + typeDict = { + [AccessTokenTypeEnum.Personal]: $localize `:@@integrations.access-token.personal:Personal`, + [AccessTokenTypeEnum.Service]: $localize `:@@integrations.access-token.personal:Service` + } + + transform(value: string): string { + return this.typeDict[value] || ''; + } +} diff --git a/modules/front-end/src/app/core/services/access-token.service.ts b/modules/front-end/src/app/core/services/access-token.service.ts index 24fd8db1b..6dbafb7fc 100644 --- a/modules/front-end/src/app/core/services/access-token.service.ts +++ b/modules/front-end/src/app/core/services/access-token.service.ts @@ -1,11 +1,14 @@ import { Injectable } from "@angular/core"; -import { HttpClient } from "@angular/common/http"; +import { HttpClient, HttpParams } from "@angular/common/http"; import { getCurrentOrganization } from "@utils/project-env"; import { environment } from "src/environments/environment"; import { Observable, of } from "rxjs"; import { catchError } from "rxjs/operators"; -import { IPolicy } from "@features/safe/iam/types/policy"; -import { IAccessToken } from "@features/safe/integrations/access-tokens/types/access-token"; +import { + AccessTokenFilter, + IAccessToken, + IPagedAccessToken +} from "@features/safe/integrations/access-tokens/types/access-token"; @Injectable({ providedIn: 'root' @@ -18,6 +21,21 @@ export class AccessTokenService { return `${environment.url}/api/v1/organizations/${organizationId}/access-tokens`; } + getList(filter: AccessTokenFilter = new AccessTokenFilter()): Observable { + const queryParam = { + name: filter.name ?? '', + type: filter.type ?? '', + creatorId: filter.creatorId ?? '', + pageIndex: filter.pageIndex - 1, + pageSize: filter.pageSize, + }; + + return this.http.get( + this.baseUrl, + {params: new HttpParams({fromObject: queryParam})} + ); + } + isNameUsed(name: string) { const url = `${this.baseUrl}/is-name-used?name=${name}`; @@ -27,4 +45,8 @@ export class AccessTokenService { create(name: string, type: string, policyIds: string[] = []): Observable { return this.http.post(this.baseUrl, { name, type, policyIds }); } + + delete(id: string): Observable { + return this.http.delete(`${this.baseUrl}/${id}`); + } } diff --git a/modules/front-end/src/app/features/safe/feature-flags/details/experimentation/experimentation.component.less b/modules/front-end/src/app/features/safe/feature-flags/details/experimentation/experimentation.component.less index 616fbd5b2..5bf414121 100644 --- a/modules/front-end/src/app/features/safe/feature-flags/details/experimentation/experimentation.component.less +++ b/modules/front-end/src/app/features/safe/feature-flags/details/experimentation/experimentation.component.less @@ -171,7 +171,7 @@ } .empty-experiment { margin-top: 20px; - background-color: #717D8A; + background-color: @grey50-color; height: 200px; padding-top: 90px; text-align: center; diff --git a/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.less b/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.less index 7dd4ff5db..e1f33bef5 100644 --- a/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.less +++ b/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.less @@ -25,7 +25,7 @@ cursor: pointer; margin-left: 12px; font-size: 20px; - color: #717d8a; + color: @grey50-color; } } .statements-wrapper { diff --git a/modules/front-end/src/app/features/safe/iam/groups/index/index.component.less b/modules/front-end/src/app/features/safe/iam/groups/index/index.component.less index 4443a9bbd..f665f341d 100644 --- a/modules/front-end/src/app/features/safe/iam/groups/index/index.component.less +++ b/modules/front-end/src/app/features/safe/iam/groups/index/index.component.less @@ -6,7 +6,7 @@ } .copy-icon { - color: #717D8A; + color: @grey50-color; &:hover { cursor: pointer; color: @grey70-color; diff --git a/modules/front-end/src/app/features/safe/iam/policies/index/index.component.less b/modules/front-end/src/app/features/safe/iam/policies/index/index.component.less index 4443a9bbd..f665f341d 100644 --- a/modules/front-end/src/app/features/safe/iam/policies/index/index.component.less +++ b/modules/front-end/src/app/features/safe/iam/policies/index/index.component.less @@ -6,7 +6,7 @@ } .copy-icon { - color: #717D8A; + color: @grey50-color; &:hover { cursor: pointer; color: @grey70-color; diff --git a/modules/front-end/src/app/features/safe/iam/team/index/index.component.less b/modules/front-end/src/app/features/safe/iam/team/index/index.component.less index 4443a9bbd..f665f341d 100644 --- a/modules/front-end/src/app/features/safe/iam/team/index/index.component.less +++ b/modules/front-end/src/app/features/safe/iam/team/index/index.component.less @@ -6,7 +6,7 @@ } .copy-icon { - color: #717D8A; + color: @grey50-color; &:hover { cursor: pointer; color: @grey70-color; diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html index c07d0fb99..69330577a 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html @@ -1,11 +1,36 @@
- + + + + + + + + + Loading... + + + + + +
- + diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts index 7fedd3f03..6f4276522 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts @@ -89,10 +89,6 @@ export class IndexComponent implements OnInit { }); } - resourceName(policy: IPolicy) { - return policyRn(policy); - } - doSearch(resetPage?: boolean) { if (resetPage) { this.filter.pageIndex = 1; @@ -105,7 +101,7 @@ export class IndexComponent implements OnInit { openAccessTokenDrawer(){ this.accessTokenDrawerVisible = true; } - policyDrawerClosed(created: any) { + accessTokenDrawerClosed(created: any) { this.accessTokenDrawerVisible = false; if (created) { @@ -114,16 +110,23 @@ export class IndexComponent implements OnInit { } delete(accessToken: IAccessToken) { - this.accessTokenService.delete(accessToken.id).subscribe(() => { - this.message.success($localize `:@@common.operation-success:Operation succeeded`); - this.accessTokens.items = this.accessTokens.items.filter(it => it.id !== accessToken.id); - this.accessTokens.totalCount--; - }, () => this.message.error($localize `:@@common.operation-failed:Operation failed`)) + this.accessTokenService.delete(accessToken.id).subscribe({ + next:() => { + this.message.success($localize `:@@common.operation-success:Operation succeeded`); + this.accessTokens.items = this.accessTokens.items.filter(it => it.id !== accessToken.id); + this.accessTokens.totalCount--; + }, + error: () => this.message.error($localize `:@@common.operation-failed:Operation failed`) + }) } - copyText(text: string) { - copyToClipboard(text).then( - () => this.message.success($localize `:@@common.copy-success:Copied`) - ); + toggleStatus(accessToken: IAccessToken) { + this.accessTokenService.toggleStatus(accessToken.id).subscribe({ + next:() => { + this.message.success($localize `:@@common.operation-success:Operation succeeded`); + accessToken.status = accessToken.status === this.AccessTokenStatusActive ? this.AccessTokenStatusInactive : this.AccessTokenStatusActive; + }, + error: () => this.message.error($localize `:@@common.operation-failed:Operation failed`) + }) } } From b238dcfa2af9ab126ddedc385d0a3fa71621d23d Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Sat, 11 Mar 2023 22:12:28 +0100 Subject: [PATCH 08/44] in progress --- .../access-tokens/index/index.component.html | 63 ++++++++++--------- .../access-tokens/index/index.component.less | 8 +++ 2 files changed, 41 insertions(+), 30 deletions(-) diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html index 17707e0ce..920fa296f 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html @@ -1,36 +1,39 @@
- - - - - - - - - +
+ + + + + + + + + + + + + + Loading... - - - - Loading... - - - - - - + + + + + +
+
- +
diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts index 37edc31d6..cb9c03ad3 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts @@ -3,11 +3,17 @@ import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms' import { NzMessageService } from 'ng-zorro-antd/message'; import { debounceTime, distinctUntilChanged, first, map, switchMap } from "rxjs/operators"; import { PolicyService } from "@services/policy.service"; -import { AccessTokenTypeEnum, IAccessTokenPolicy } from "@features/safe/integrations/access-tokens/types/access-token"; +import { + AccessTokenTypeEnum, + IAccessToken, + IAccessTokenPolicy +} from "@features/safe/integrations/access-tokens/types/access-token"; import { PolicyFilter } from "@features/safe/iam/types/policy"; import { NzSelectComponent } from "ng-zorro-antd/select"; import { Subject } from "rxjs"; import { AccessTokenService } from "@services/access-token.service"; +import { CustomEventSuccessCriteria, CustomEventTrackOption, IMetric } from "@features/safe/experiments/types"; +import { uuidv4 } from "@utils/index"; @Component({ selector: 'access-token-drawer', @@ -17,17 +23,34 @@ import { AccessTokenService } from "@services/access-token.service"; export class AccessTokenDrawerComponent implements OnInit { public policyCompareWith: (obj1: IAccessTokenPolicy, obj2: IAccessTokenPolicy) => boolean = (obj1: IAccessTokenPolicy, obj2: IAccessTokenPolicy) => { - if(obj1 && obj2) { + if (obj1 && obj2) { return obj1.id === obj2.id; } else { return false; } }; + private _accessToken: IAccessToken; + isEditing: boolean = false; + + @Input() + set accessToken(accessToken: IAccessToken) { + this.isEditing = accessToken && !!accessToken.id; + if (accessToken) { + this.selectedPolicyList = accessToken.policies.map((p) => ({...p, isSelected: true})); + this.isServiceAccessToken = accessToken.type === AccessTokenTypeEnum.Service; + this.patchForm(accessToken); + } else { + this.resetForm(); + } + this._accessToken = accessToken; + } + @Input() visible: boolean = false; - @Output() close: EventEmitter = new EventEmitter(); + @Output() close: EventEmitter = new EventEmitter(); policyDebouncer = new Subject(); + constructor( private fb: FormBuilder, private policyService: PolicyService, @@ -42,10 +65,11 @@ export class AccessTokenDrawerComponent implements OnInit { isServiceAccessToken: boolean = false - @ViewChild("policyNodeSelector", { static: false }) policySelectNode: NzSelectComponent; + @ViewChild("policyNodeSelector", {static: false}) policySelectNode: NzSelectComponent; selectedPolicyList: IAccessTokenPolicy[] = []; policySearchResultList: IAccessTokenPolicy[] = []; form: FormGroup; + ngOnInit(): void { this.form = this.fb.group({ name: ['', [Validators.required], [this.nameAsyncValidator], 'change'], @@ -54,18 +78,38 @@ export class AccessTokenDrawerComponent implements OnInit { }); } + get accessToken() { + return this._accessToken; + } + + resetForm() { + this.form && this.form.reset(); + } + + patchForm(accessToken: Partial) { + this.form.patchValue({ + name: accessToken.name, + type: accessToken.type, + policy: {}, + }); + } + onClose() { - this.form.reset(); + this.reset(); this.close.emit(); } + private reset() { + this.form.reset(); + } + onTypeChange() { - const { type } = this.form.value; + const {type} = this.form.value; this.isServiceAccessToken = type === AccessTokenTypeEnum.Service; } onPolicySelectChange() { - const { policy } = this.form.value; + const {policy} = this.form.value; if (this.selectedPolicyList.some((sp) => sp.id === policy.id)) { this.selectedPolicyList = this.selectedPolicyList.filter((sp) => sp.id !== policy.id); @@ -87,6 +131,7 @@ export class AccessTokenDrawerComponent implements OnInit { } isLoadingPolicies = true; + searchPolicies(query: string = '') { this.isLoadingPolicies = true; @@ -106,9 +151,9 @@ export class AccessTokenDrawerComponent implements OnInit { map(isNameUsed => { switch (isNameUsed) { case true: - return { error: true, duplicated: true }; + return {error: true, duplicated: true}; case undefined: - return { error: true, unknown: true }; + return {error: true, unknown: true}; default: return null; } @@ -131,6 +176,7 @@ export class AccessTokenDrawerComponent implements OnInit { this.isPolicyIdsValid = true; } } + doSubmit() { // we validate name and type only here if (this.form.invalid) { @@ -148,24 +194,40 @@ export class AccessTokenDrawerComponent implements OnInit { } this.isLoading = true; - const { name, type } = this.form.value; - const policies = this.isServiceAccessToken ? this.selectedPolicyList.map(p => p.id) : []; - - this.accessTokenService.create(name, type, policies).subscribe({ - next: () => { - this.isLoading = false; - this.close.emit(true); - this.message.success($localize `:@@common.operation-success:Operation succeeded`); - this.form.reset(); - }, - error: (e) => { - this.isLoading = false; - if (e.errors[0] === 'ServiceAccessTokenMustDefinePolicies') { - this.message.error($localize `:@@integrations.access-token.service-access-token-must-define-policies:Policies are mandatory for service type access tokens`); + const {name, type} = this.form.value; + + if (this.isEditing) { + this.accessTokenService.update(this.accessToken.id, name).subscribe({ + next: res => { + this.isLoading = false; + this.close.emit({ isEditing: true, id: this.accessToken.id, name: name}); + this.message.success($localize`:@@common.operation-success:Operation succeeded`); + }, + error: _ => { + this.message.error($localize`:@@common.operation-failed-try-again:Operation failed, please try again`); + this.isLoading = false; + } + } + ); + } else { + const policies = this.isServiceAccessToken ? this.selectedPolicyList.map(p => p.id) : []; + + this.accessTokenService.create(name, type, policies).subscribe({ + next: () => { + this.isLoading = false; + this.close.emit({ isEditing: false }); + this.message.success($localize`:@@common.operation-success:Operation succeeded`); + this.reset(); + }, + error: (e) => { + this.isLoading = false; + if (e.errors[0] === 'ServiceAccessTokenMustDefinePolicies') { + this.message.error($localize`:@@integrations.access-token.service-access-token-must-define-policies:Policies are mandatory for service type access tokens`); + } } } + ) } - ) } actionTokenTypes = [ diff --git a/modules/front-end/src/app/core/services/access-token.service.ts b/modules/front-end/src/app/core/services/access-token.service.ts index f2f2d35b1..29c301eb3 100644 --- a/modules/front-end/src/app/core/services/access-token.service.ts +++ b/modules/front-end/src/app/core/services/access-token.service.ts @@ -9,6 +9,7 @@ import { IAccessToken, IPagedAccessToken } from "@features/safe/integrations/access-tokens/types/access-token"; +import { IMetric } from "@features/safe/experiments/types"; @Injectable({ providedIn: 'root' @@ -53,4 +54,9 @@ export class AccessTokenService { toggleStatus(id: string): Observable { return this.http.put(`${this.baseUrl}/${id}/toggle`, {}); } + + update(id: string, name: string): Observable { + const url = this.baseUrl; + return this.http.put(url + `/${id}`, { name }); + } } diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html index 920fa296f..7f18224df 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html @@ -34,7 +34,7 @@ - @@ -75,7 +75,7 @@ {{ item.status | accessTokenStatus }} {{ item.lastUsedAt | date: 'YYYY-MM-dd HH:mm'}} - Edit + Edit @@ -104,5 +104,5 @@ - + diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts index 6f4276522..de1a67260 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts @@ -7,7 +7,7 @@ import { NzMessageService } from "ng-zorro-antd/message"; import { IPagedPolicy, IPolicy, PolicyFilter, policyRn } from "@features/safe/iam/types/policy"; import { PolicyService } from "@services/policy.service"; import { - AccessTokenFilter, AccessTokenStatusEnum, + AccessTokenFilter, AccessTokenStatusEnum, AccessTokenTypeEnum, IAccessToken, IPagedAccessToken } from "@features/safe/integrations/access-tokens/types/access-token"; @@ -98,17 +98,36 @@ export class IndexComponent implements OnInit { } accessTokenDrawerVisible: boolean = false; - openAccessTokenDrawer(){ + private openAccessTokenDrawer(){ this.accessTokenDrawerVisible = true; } - accessTokenDrawerClosed(created: any) { + + accessTokenDrawerClosed(data: any) { //{ isEditing: boolean, id: string, name: string } this.accessTokenDrawerVisible = false; - if (created) { + if (!data) { + return; + } + + if (!data.isEditing) { this.getAccessTokens(); + } else { + this.accessTokens.items = this.accessTokens.items.map((ac) => { + if (ac.id === data.id) { + return { ...ac, name: data.name }; + } + + return ac; + }) } } + currentAccessToken: IAccessToken; + creatOrEdit(accessToken: IAccessToken = { name: null, type: AccessTokenTypeEnum.Personal, policies: []}) { + this.currentAccessToken = accessToken; + this.openAccessTokenDrawer(); + } + delete(accessToken: IAccessToken) { this.accessTokenService.delete(accessToken.id).subscribe({ next:() => { diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts index 1852d30fc..bf1e89c7a 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts @@ -2,13 +2,13 @@ import { IPolicy } from "@features/safe/iam/types/policy"; import { IMember } from "@features/safe/iam/types/member"; export interface IAccessToken { - id: string; + id?: string; type: string; - creator: IMember; - status: string; + creator?: IMember; + status?: string; name: string; - policies: IPolicy[], - lastUsedAt: string + policies?: IPolicy[], + lastUsedAt?: string } export enum AccessTokenTypeEnum { From 660feaad10dc4c8de3492738553e10b859823149 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Sun, 12 Mar 2023 01:55:18 +0100 Subject: [PATCH 10/44] added translations --- modules/front-end/src/locale/messages.xlf | 1594 +++++++++-------- modules/front-end/src/locale/messages.zh.xlf | 1617 ++++++++++-------- 2 files changed, 1840 insertions(+), 1371 deletions(-) diff --git a/modules/front-end/src/locale/messages.xlf b/modules/front-end/src/locale/messages.xlf index af77bba42..543335c4f 100644 --- a/modules/front-end/src/locale/messages.xlf +++ b/modules/front-end/src/locale/messages.xlf @@ -2,6 +2,721 @@ + + Add access token + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 7 + + + + Name + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 15 + + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 17 + + + src/app/core/components/env-drawer/env-drawer.component.html + 22 + + + src/app/core/components/env-drawer/env-drawer.component.html + 24 + + + src/app/core/components/group-drawer/group-drawer.component.html + 14 + + + src/app/core/components/group-drawer/group-drawer.component.html + 16 + + + src/app/core/components/metric-drawer/metric-drawer.component.html + 12 + + + src/app/core/components/metric-drawer/metric-drawer.component.html + 14 + + + src/app/core/components/organization-drawer/organization-drawer.component.html + 13 + + + src/app/core/components/organization-drawer/organization-drawer.component.html + 15 + + + src/app/core/components/policy-drawer/policy-drawer.component.html + 14 + + + src/app/core/components/policy-drawer/policy-drawer.component.html + 16 + + + src/app/core/components/project-drawer/project-drawer.component.html + 23 + + + src/app/core/components/project-drawer/project-drawer.component.html + 25 + + + src/app/core/components/props-drawer/props-drawer.component.html + 39 + + + src/app/core/components/props-drawer/props-drawer.component.html + 74 + + + src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.html + 37,38 + + + src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.html + 85,86 + + + src/app/features/safe/data-sync/remote-sync/remote-sync.component.html + 25 + + + src/app/features/safe/end-users/details/details.component.html + 16 + + + src/app/features/safe/feature-flags/details/insights/insights.component.html + 56 + + + src/app/features/safe/feature-flags/details/setting/setting.component.html + 31 + + + src/app/features/safe/feature-flags/index/index.component.html + 70 + + + src/app/features/safe/feature-flags/index/index.component.html + 185 + + + src/app/features/safe/iam/groups/details/setting/setting.component.html + 10 + + + src/app/features/safe/iam/groups/details/setting/setting.component.html + 17 + + + src/app/features/safe/iam/groups/details/team/team.component.html + 27 + + + src/app/features/safe/iam/groups/index/index.component.html + 29 + + + src/app/features/safe/iam/policies/details/groups/groups.component.html + 27 + + + src/app/features/safe/iam/policies/details/setting/setting.component.html + 10 + + + src/app/features/safe/iam/policies/details/setting/setting.component.html + 17 + + + src/app/features/safe/iam/policies/details/team/team.component.html + 28 + + + src/app/features/safe/iam/policies/index/index.component.html + 29 + + + src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.html + 30 + + + src/app/features/safe/iam/team/details/groups/groups.component.html + 27 + + + src/app/features/safe/iam/team/details/inherited-policies/inherited-policies.component.html + 23 + + + src/app/features/safe/iam/team/details/setting/setting.component.html + 10 + + + src/app/features/safe/iam/team/index/index.component.html + 29 + + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 57 + + + src/app/features/safe/organizations/profile/profile.component.html + 4 + + + src/app/features/safe/organizations/profile/profile.component.html + 7 + + + src/app/features/safe/organizations/project/project.component.html + 120 + + + src/app/features/safe/segments/details/setting/setting.component.html + 15 + + + src/app/features/safe/segments/index/index.component.html + 35 + + + src/app/features/safe/segments/index/index.component.html + 82 + + + + Validating... + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 16 + + + src/app/core/components/group-drawer/group-drawer.component.html + 15 + + + src/app/core/components/policy-drawer/policy-drawer.component.html + 15 + + + src/app/features/safe/feature-flags/index/index.component.html + 203 + + + src/app/features/safe/segments/index/index.component.html + 83 + + + + Access token name cannot be empty + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 20 + + + + This access token name is not available + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 21 + + + + Type + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 27 + + + src/app/features/safe/data-sync/remote-sync/remote-sync.component.html + 26 + + + src/app/features/safe/iam/policies/details/setting/setting.component.html + 33 + + + src/app/features/safe/iam/policies/index/index.component.html + 30 + + + src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.html + 31 + + + src/app/features/safe/iam/team/details/inherited-policies/inherited-policies.component.html + 25 + + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 58 + + + + Policies + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 45 + + + src/app/features/safe/iam/groups/details/details.component.html + 13 + + + + Select policies + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 50 + + + + Loading... + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 68 + + + src/app/core/components/audit-logs/audit-logs.component.html + 26 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 36 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 66 + + + src/app/core/components/member-drawer/member-drawer.component.html + 38 + + + src/app/core/components/member-drawer/member-drawer.component.html + 55 + + + src/app/core/components/metric-drawer/metric-drawer.component.html + 43 + + + src/app/core/components/target-user/target-user.component.html + 44 + + + src/app/features/safe/end-users/index/index.component.html + 25 + + + src/app/features/safe/end-users/index/index.component.html + 60 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html + 138 + + + src/app/features/safe/feature-flags/details/insights/insights.component.html + 18 + + + src/app/features/safe/feature-flags/details/setting/setting.component.html + 136,137 + + + src/app/features/safe/feature-flags/index/index.component.html + 26 + + + src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html + 38 + + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 28 + + + + Policies are mandatory for service type access tokens + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 82 + + + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 225 + + + + Save + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 92 + + + src/app/core/components/change-review/change-review.component.html + 43 + + + src/app/core/components/env-drawer/env-drawer.component.html + 35 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 91 + + + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 202 + + + src/app/core/components/group-drawer/group-drawer.component.html + 32 + + + src/app/core/components/header/header.component.html + 80,81 + + + src/app/core/components/member-drawer/member-drawer.component.html + 61 + + + src/app/core/components/metric-drawer/metric-drawer.component.html + 121 + + + src/app/core/components/organization-drawer/organization-drawer.component.html + 18 + + + src/app/core/components/policy-drawer/policy-drawer.component.html + 32 + + + src/app/core/components/project-drawer/project-drawer.component.html + 29 + + + src/app/core/components/props-drawer/props-drawer.component.html + 90 + + + src/app/core/components/target-user/target-user.component.html + 69 + + + src/app/features/safe/feature-flags/details/setting/setting.component.html + 164,166 + + + src/app/features/safe/feature-flags/index/index.component.html + 224 + + + src/app/features/safe/iam/components/policy-editor/policy-editor.component.html + 9 + + + src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html + 76 + + + src/app/features/safe/segments/index/index.component.html + 104 + + + + Operation succeeded + + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 204 + + + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 219 + + + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts + 193 + + + src/app/core/components/group-drawer/group-drawer.component.ts + 68 + + + src/app/core/components/member-drawer/member-drawer.component.ts + 121 + + + src/app/core/components/metric-drawer/metric-drawer.component.ts + 241 + + + src/app/core/components/metric-drawer/metric-drawer.component.ts + 258 + + + src/app/core/components/policy-drawer/policy-drawer.component.ts + 68 + + + src/app/core/components/props-drawer/props-drawer.component.ts + 93 + + + src/app/core/components/props-drawer/props-drawer.component.ts + 116 + + + src/app/core/components/props-drawer/props-drawer.component.ts + 134 + + + src/app/features/safe/experiments/metrics/metrics.component.ts + 85 + + + src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts + 59 + + + src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts + 77 + + + src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts + 86 + + + src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts + 97 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 84 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 95 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 190 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 322 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 333 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 341 + + + src/app/features/safe/feature-flags/index/index.component.ts + 336 + + + src/app/features/safe/feature-flags/index/index.component.ts + 349 + + + src/app/features/safe/feature-flags/index/index.component.ts + 359 + + + src/app/features/safe/iam/groups/details/policies/policies.component.ts + 74 + + + src/app/features/safe/iam/groups/details/policies/policies.component.ts + 88 + + + src/app/features/safe/iam/groups/details/setting/setting.component.ts + 42 + + + src/app/features/safe/iam/groups/details/setting/setting.component.ts + 69 + + + src/app/features/safe/iam/groups/details/team/team.component.ts + 73 + + + src/app/features/safe/iam/groups/details/team/team.component.ts + 87 + + + src/app/features/safe/iam/groups/index/index.component.ts + 84 + + + src/app/features/safe/iam/policies/details/groups/groups.component.ts + 76 + + + src/app/features/safe/iam/policies/details/groups/groups.component.ts + 90 + + + src/app/features/safe/iam/policies/details/permission/permission.component.ts + 40 + + + src/app/features/safe/iam/policies/details/setting/setting.component.ts + 46 + + + src/app/features/safe/iam/policies/details/setting/setting.component.ts + 53 + + + src/app/features/safe/iam/policies/details/team/team.component.ts + 76 + + + src/app/features/safe/iam/policies/details/team/team.component.ts + 90 + + + src/app/features/safe/iam/policies/index/index.component.ts + 80 + + + src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.ts + 75 + + + src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.ts + 89 + + + src/app/features/safe/iam/team/details/groups/groups.component.ts + 81 + + + src/app/features/safe/iam/team/details/groups/groups.component.ts + 95 + + + src/app/features/safe/iam/team/details/setting/setting.component.ts + 51 + + + src/app/features/safe/iam/team/index/index.component.ts + 72 + + + src/app/features/safe/integrations/access-tokens/index/index.component.ts + 134 + + + src/app/features/safe/integrations/access-tokens/index/index.component.ts + 145 + + + src/app/features/safe/segments/details/setting/setting.component.ts + 60 + + + src/app/features/safe/segments/details/targeting/targeting.component.ts + 136 + + + src/app/features/safe/segments/index/index.component.ts + 41 + + + src/app/features/safe/segments/index/index.component.ts + 63 + + + src/app/features/safe/segments/index/index.component.ts + 76 + + + + Operation failed, please try again + + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 207 + + + src/app/core/components/metric-drawer/metric-drawer.component.ts + 244 + + + src/app/core/components/target-user/target-user.component.ts + 127 + + + src/app/core/components/target-user/target-user.component.ts + 159 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts + 213 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts + 229 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts + 296 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts + 309 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 274 + + + src/app/features/safe/feature-flags/details/targeting/targeting.component.ts + 109 + + + src/app/features/safe/feature-flags/index/index.component.ts + 339 + + + src/app/features/safe/onboarding/steps/steps.component.ts + 63 + + + src/app/features/safe/organizations/project/project.component.ts + 253 + + + src/app/features/safe/organizations/project/project.component.ts + 287 + + + src/app/features/safe/organizations/project/project.component.ts + 303 + + + src/app/features/safe/segments/index/index.component.ts + 79 + + created @@ -53,75 +768,16 @@ Filter by name, comment - - src/app/core/components/audit-logs/audit-logs.component.html - 6 - - - - Filter by team member - - src/app/core/components/audit-logs/audit-logs.component.html - 20 - - - - Loading... - - src/app/core/components/audit-logs/audit-logs.component.html - 26 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 36 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 66 - - - src/app/core/components/member-drawer/member-drawer.component.html - 38 - - - src/app/core/components/member-drawer/member-drawer.component.html - 55 - - - src/app/core/components/metric-drawer/metric-drawer.component.html - 43 - - - src/app/core/components/target-user/target-user.component.html - 44 - - - src/app/features/safe/end-users/index/index.component.html - 25 - - - src/app/features/safe/end-users/index/index.component.html - 60 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 138 - - - src/app/features/safe/feature-flags/details/insights/insights.component.html - 18 - - - src/app/features/safe/feature-flags/details/setting/setting.component.html - 136,137 - - - src/app/features/safe/feature-flags/index/index.component.html - 26 + + src/app/core/components/audit-logs/audit-logs.component.html + 6 + + + Filter by team member - src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html - 38 + src/app/core/components/audit-logs/audit-logs.component.html + 20 @@ -328,296 +984,50 @@ Cancel src/app/core/components/change-review/change-review.component.html - 41 - - - src/app/core/components/header/header.component.html - 79,80 - - - src/app/core/components/props-drawer/props-drawer.component.html - 103 - - - src/app/core/components/target-user/target-user.component.html - 68 - - - src/app/features/safe/feature-flags/details/setting/setting.component.html - 162,163 - - - src/app/features/safe/feature-flags/index/index.component.html - 223 - - - src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html - 75 - - - src/app/features/safe/segments/index/index.component.html - 102 - - - src/app/features/safe/segments/index/index.component.html - 141 - - - - Save - - src/app/core/components/change-review/change-review.component.html - 43 - - - src/app/core/components/env-drawer/env-drawer.component.html - 35 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 91 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 202 - - - src/app/core/components/group-drawer/group-drawer.component.html - 32 - - - src/app/core/components/header/header.component.html - 80,81 - - - src/app/core/components/member-drawer/member-drawer.component.html - 61 - - - src/app/core/components/metric-drawer/metric-drawer.component.html - 121 - - - src/app/core/components/organization-drawer/organization-drawer.component.html - 18 - - - src/app/core/components/policy-drawer/policy-drawer.component.html - 32 - - - src/app/core/components/project-drawer/project-drawer.component.html - 29 - - - src/app/core/components/props-drawer/props-drawer.component.html - 90 - - - src/app/core/components/target-user/target-user.component.html - 69 - - - src/app/features/safe/feature-flags/details/setting/setting.component.html - 164,166 - - - src/app/features/safe/feature-flags/index/index.component.html - 224 - - - src/app/features/safe/iam/components/policy-editor/policy-editor.component.html - 9 - - - src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html - 76 - - - src/app/features/safe/segments/index/index.component.html - 104 - - - - Permission will become invalid if you change the name - - src/app/core/components/env-drawer/env-drawer.component.html - 15 - - - src/app/core/components/project-drawer/project-drawer.component.html - 16 - - - - Name - - src/app/core/components/env-drawer/env-drawer.component.html - 22 - - - src/app/core/components/env-drawer/env-drawer.component.html - 24 - - - src/app/core/components/group-drawer/group-drawer.component.html - 14 - - - src/app/core/components/group-drawer/group-drawer.component.html - 16 - - - src/app/core/components/metric-drawer/metric-drawer.component.html - 12 - - - src/app/core/components/metric-drawer/metric-drawer.component.html - 14 - - - src/app/core/components/organization-drawer/organization-drawer.component.html - 13 - - - src/app/core/components/organization-drawer/organization-drawer.component.html - 15 - - - src/app/core/components/policy-drawer/policy-drawer.component.html - 14 - - - src/app/core/components/policy-drawer/policy-drawer.component.html - 16 - - - src/app/core/components/project-drawer/project-drawer.component.html - 23 - - - src/app/core/components/project-drawer/project-drawer.component.html - 25 - - - src/app/core/components/props-drawer/props-drawer.component.html - 39 - - - src/app/core/components/props-drawer/props-drawer.component.html - 74 - - - src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.html - 37,38 - - - src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.html - 85,86 - - - src/app/features/safe/data-sync/remote-sync/remote-sync.component.html - 25 - - - src/app/features/safe/end-users/details/details.component.html - 16 - - - src/app/features/safe/feature-flags/details/insights/insights.component.html - 56 - - - src/app/features/safe/feature-flags/details/setting/setting.component.html - 31 - - - src/app/features/safe/feature-flags/index/index.component.html - 70 - - - src/app/features/safe/feature-flags/index/index.component.html - 185 - - - src/app/features/safe/iam/groups/details/setting/setting.component.html - 10 - - - src/app/features/safe/iam/groups/details/setting/setting.component.html - 17 - - - src/app/features/safe/iam/groups/details/team/team.component.html - 27 - - - src/app/features/safe/iam/groups/index/index.component.html - 29 - - - src/app/features/safe/iam/policies/details/groups/groups.component.html - 27 - - - src/app/features/safe/iam/policies/details/setting/setting.component.html - 10 - - - src/app/features/safe/iam/policies/details/setting/setting.component.html - 17 - - - src/app/features/safe/iam/policies/details/team/team.component.html - 28 - - - src/app/features/safe/iam/policies/index/index.component.html - 29 + 41 - src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.html - 30 + src/app/core/components/header/header.component.html + 79,80 - src/app/features/safe/iam/team/details/groups/groups.component.html - 27 + src/app/core/components/props-drawer/props-drawer.component.html + 103 - src/app/features/safe/iam/team/details/inherited-policies/inherited-policies.component.html - 23 + src/app/core/components/target-user/target-user.component.html + 68 - src/app/features/safe/iam/team/details/setting/setting.component.html - 10 + src/app/features/safe/feature-flags/details/setting/setting.component.html + 162,163 - src/app/features/safe/iam/team/index/index.component.html - 29 + src/app/features/safe/feature-flags/index/index.component.html + 223 - src/app/features/safe/organizations/profile/profile.component.html - 4 + src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html + 75 - src/app/features/safe/organizations/profile/profile.component.html - 7 + src/app/features/safe/segments/index/index.component.html + 102 - src/app/features/safe/organizations/project/project.component.html - 120 + src/app/features/safe/segments/index/index.component.html + 141 + + + Permission will become invalid if you change the name - src/app/features/safe/segments/details/setting/setting.component.html + src/app/core/components/env-drawer/env-drawer.component.html 15 - src/app/features/safe/segments/index/index.component.html - 35 - - - src/app/features/safe/segments/index/index.component.html - 82 + src/app/core/components/project-drawer/project-drawer.component.html + 16 @@ -816,263 +1226,64 @@ 127 - - serve - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 64 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 148 - - - - Percentage of users dispatched to experiment - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 68 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 94 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 152 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 178 - - - - Compared to all users matching this rule - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 68 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 94 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 152 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 178 - - - - Default rule - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 88 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 172 - - - - Operation succeeded - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts - 193 - - - src/app/core/components/group-drawer/group-drawer.component.ts - 68 - - - src/app/core/components/member-drawer/member-drawer.component.ts - 121 - - - src/app/core/components/metric-drawer/metric-drawer.component.ts - 241 - - - src/app/core/components/metric-drawer/metric-drawer.component.ts - 258 - - - src/app/core/components/policy-drawer/policy-drawer.component.ts - 68 - - - src/app/core/components/props-drawer/props-drawer.component.ts - 93 - - - src/app/core/components/props-drawer/props-drawer.component.ts - 116 - - - src/app/core/components/props-drawer/props-drawer.component.ts - 134 - - - src/app/features/safe/experiments/metrics/metrics.component.ts - 85 - - - src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 59 - - - src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 77 - - - src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 86 - - - src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 97 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 84 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 95 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 190 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 322 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 333 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 341 - - - src/app/features/safe/feature-flags/index/index.component.ts - 336 - - - src/app/features/safe/feature-flags/index/index.component.ts - 349 - - - src/app/features/safe/feature-flags/index/index.component.ts - 359 - - - src/app/features/safe/iam/groups/details/policies/policies.component.ts - 74 - - - src/app/features/safe/iam/groups/details/policies/policies.component.ts - 88 - - - src/app/features/safe/iam/groups/details/setting/setting.component.ts - 42 - - - src/app/features/safe/iam/groups/details/setting/setting.component.ts - 69 - - - src/app/features/safe/iam/groups/details/team/team.component.ts - 73 - - - src/app/features/safe/iam/groups/details/team/team.component.ts - 87 - - - src/app/features/safe/iam/groups/index/index.component.ts - 84 - - - src/app/features/safe/iam/policies/details/groups/groups.component.ts - 76 - - - src/app/features/safe/iam/policies/details/groups/groups.component.ts - 90 - - - src/app/features/safe/iam/policies/details/permission/permission.component.ts - 40 - - - src/app/features/safe/iam/policies/details/setting/setting.component.ts - 46 - - - src/app/features/safe/iam/policies/details/setting/setting.component.ts - 53 - - - src/app/features/safe/iam/policies/details/team/team.component.ts - 76 - - - src/app/features/safe/iam/policies/details/team/team.component.ts - 90 - + + serve - src/app/features/safe/iam/policies/index/index.component.ts - 80 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 64 - src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.ts - 75 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 148 + + + Percentage of users dispatched to experiment - src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.ts - 89 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 68 - src/app/features/safe/iam/team/details/groups/groups.component.ts - 81 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 94 - src/app/features/safe/iam/team/details/groups/groups.component.ts - 95 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 152 - src/app/features/safe/iam/team/details/setting/setting.component.ts - 51 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 178 + + + Compared to all users matching this rule - src/app/features/safe/iam/team/index/index.component.ts - 72 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 68 - src/app/features/safe/segments/details/setting/setting.component.ts - 60 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 94 - src/app/features/safe/segments/details/targeting/targeting.component.ts - 136 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 152 - src/app/features/safe/segments/index/index.component.ts - 41 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 178 + + + Default rule - src/app/features/safe/segments/index/index.component.ts - 63 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 88 - src/app/features/safe/segments/index/index.component.ts - 76 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 172 @@ -1193,6 +1404,14 @@ src/app/features/safe/iam/team/index/index.component.ts 75 + + src/app/features/safe/integrations/access-tokens/index/index.component.ts + 138 + + + src/app/features/safe/integrations/access-tokens/index/index.component.ts + 148 + src/app/features/safe/segments/details/targeting/targeting.component.ts 142 @@ -1455,25 +1674,6 @@ 7 - - Validating... - - src/app/core/components/group-drawer/group-drawer.component.html - 15 - - - src/app/core/components/policy-drawer/policy-drawer.component.html - 15 - - - src/app/features/safe/feature-flags/index/index.component.html - 203 - - - src/app/features/safe/segments/index/index.component.html - 83 - - Group name cannot be empty @@ -2079,69 +2279,6 @@ 116 - - Operation failed, please try again - - src/app/core/components/metric-drawer/metric-drawer.component.ts - 244 - - - src/app/core/components/target-user/target-user.component.ts - 127 - - - src/app/core/components/target-user/target-user.component.ts - 159 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts - 213 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts - 229 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts - 296 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts - 309 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 274 - - - src/app/features/safe/feature-flags/details/targeting/targeting.component.ts - 109 - - - src/app/features/safe/feature-flags/index/index.component.ts - 339 - - - src/app/features/safe/onboarding/steps/steps.component.ts - 63 - - - src/app/features/safe/organizations/project/project.component.ts - 253 - - - src/app/features/safe/organizations/project/project.component.ts - 287 - - - src/app/features/safe/organizations/project/project.component.ts - 303 - - - src/app/features/safe/segments/index/index.component.ts - 79 - - Create organization @@ -2291,6 +2428,10 @@ src/app/features/safe/iam/team/details/groups/groups.component.html 54 + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 39 + src/app/features/safe/organizations/organization/organization.component.html 29 @@ -2396,6 +2537,10 @@ src/app/features/safe/iam/team/index/index.component.html 34 + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 62 + src/app/features/safe/segments/index/index.component.html 37 @@ -2473,6 +2618,10 @@ src/app/features/safe/iam/team/index/index.component.html 68 + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 91 + src/app/features/safe/organizations/project/project.component.html 72 @@ -2556,6 +2705,10 @@ src/app/features/safe/iam/team/index/index.component.html 72 + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 95 + src/app/features/safe/organizations/project/project.component.html 75 @@ -2886,6 +3039,31 @@ 158,160 + + Active + + src/app/core/pipes/access-token-status.pipe.ts + 12 + + + + Inactive + + src/app/core/pipes/access-token-status.pipe.ts + 13 + + + + Personal + + src/app/core/pipes/access-token-type.pipe.ts + 9 + + + src/app/core/pipes/access-token-type.pipe.ts + 10 + + System Managed @@ -2998,7 +3176,7 @@ src/app/features/safe/safe-routing.module.ts - 62 + 50 src/app/features/safe/safe.component.ts @@ -3136,29 +3314,6 @@ 51 - - Type - - src/app/features/safe/data-sync/remote-sync/remote-sync.component.html - 26 - - - src/app/features/safe/iam/policies/details/setting/setting.component.html - 33 - - - src/app/features/safe/iam/policies/index/index.component.html - 30 - - - src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.html - 31 - - - src/app/features/safe/iam/team/details/inherited-policies/inherited-policies.component.html - 25 - - URL @@ -3376,6 +3531,10 @@ src/app/features/safe/experiments/metrics/metrics.component.html 72 + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 78 + Loading failed, please try again @@ -4432,6 +4591,10 @@ src/app/features/safe/feature-flags/index/index.component.html 75 + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 60 + Tags @@ -5038,13 +5201,6 @@ 13 - - Policies - - src/app/features/safe/iam/groups/details/details.component.html - 13 - - Filter by policy name @@ -5421,6 +5577,62 @@ 51 + + Filter by name + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 5 + + + + Select creator + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 12 + + + + Filter by type + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 31 + + + + Creator + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 59 + + + + Last used + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 61 + + + + Activate + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 82 + + + + Deactivate + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 87 + + + + Access tokens + + src/app/features/safe/integrations/integrations-routing.module.ts + 14 + + We've created a project for @@ -5850,7 +6062,7 @@ Organization src/app/features/safe/safe-routing.module.ts - 50 + 57 @@ -5923,6 +6135,20 @@ 107,106 + + Integrations + + src/app/features/safe/safe.component.ts + 114,113 + + + + Access tokens + + src/app/features/safe/safe.component.ts + 119,118 + + This segment is not used by any feature flag diff --git a/modules/front-end/src/locale/messages.zh.xlf b/modules/front-end/src/locale/messages.zh.xlf index f914a5f86..d35e115c3 100644 --- a/modules/front-end/src/locale/messages.zh.xlf +++ b/modules/front-end/src/locale/messages.zh.xlf @@ -1,7 +1,734 @@ - - + + + Add access token + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 7 + + 添加访问密钥 + + + Name + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 15 + + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 17 + + + src/app/core/components/env-drawer/env-drawer.component.html + 22 + + + src/app/core/components/env-drawer/env-drawer.component.html + 24 + + + src/app/core/components/group-drawer/group-drawer.component.html + 14 + + + src/app/core/components/group-drawer/group-drawer.component.html + 16 + + + src/app/core/components/metric-drawer/metric-drawer.component.html + 12 + + + src/app/core/components/metric-drawer/metric-drawer.component.html + 14 + + + src/app/core/components/organization-drawer/organization-drawer.component.html + 13 + + + src/app/core/components/organization-drawer/organization-drawer.component.html + 15 + + + src/app/core/components/policy-drawer/policy-drawer.component.html + 14 + + + src/app/core/components/policy-drawer/policy-drawer.component.html + 16 + + + src/app/core/components/project-drawer/project-drawer.component.html + 23 + + + src/app/core/components/project-drawer/project-drawer.component.html + 25 + + + src/app/core/components/props-drawer/props-drawer.component.html + 39 + + + src/app/core/components/props-drawer/props-drawer.component.html + 74 + + + src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.html + 37,38 + + + src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.html + 85,86 + + + src/app/features/safe/data-sync/remote-sync/remote-sync.component.html + 25 + + + src/app/features/safe/end-users/details/details.component.html + 16 + + + src/app/features/safe/feature-flags/details/insights/insights.component.html + 56 + + + src/app/features/safe/feature-flags/details/setting/setting.component.html + 31 + + + src/app/features/safe/feature-flags/index/index.component.html + 70 + + + src/app/features/safe/feature-flags/index/index.component.html + 185 + + + src/app/features/safe/iam/groups/details/setting/setting.component.html + 10 + + + src/app/features/safe/iam/groups/details/setting/setting.component.html + 17 + + + src/app/features/safe/iam/groups/details/team/team.component.html + 27 + + + src/app/features/safe/iam/groups/index/index.component.html + 29 + + + src/app/features/safe/iam/policies/details/groups/groups.component.html + 27 + + + src/app/features/safe/iam/policies/details/setting/setting.component.html + 10 + + + src/app/features/safe/iam/policies/details/setting/setting.component.html + 17 + + + src/app/features/safe/iam/policies/details/team/team.component.html + 28 + + + src/app/features/safe/iam/policies/index/index.component.html + 29 + + + src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.html + 30 + + + src/app/features/safe/iam/team/details/groups/groups.component.html + 27 + + + src/app/features/safe/iam/team/details/inherited-policies/inherited-policies.component.html + 23 + + + src/app/features/safe/iam/team/details/setting/setting.component.html + 10 + + + src/app/features/safe/iam/team/index/index.component.html + 29 + + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 57 + + + src/app/features/safe/organizations/profile/profile.component.html + 4 + + + src/app/features/safe/organizations/profile/profile.component.html + 7 + + + src/app/features/safe/organizations/project/project.component.html + 120 + + + src/app/features/safe/segments/details/setting/setting.component.html + 15 + + + src/app/features/safe/segments/index/index.component.html + 35 + + + src/app/features/safe/segments/index/index.component.html + 82 + + 名称 + + + Validating... + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 16 + + + src/app/core/components/group-drawer/group-drawer.component.html + 15 + + + src/app/core/components/policy-drawer/policy-drawer.component.html + 15 + + + src/app/features/safe/feature-flags/index/index.component.html + 203 + + + src/app/features/safe/segments/index/index.component.html + 83 + + 校验中... + + + Access token name cannot be empty + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 20 + + 访问密钥名称不能为空 + + + This access token name is not available + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 21 + + 该名称已被使用 + + + Type + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 27 + + + src/app/features/safe/data-sync/remote-sync/remote-sync.component.html + 26 + + + src/app/features/safe/iam/policies/details/setting/setting.component.html + 33 + + + src/app/features/safe/iam/policies/index/index.component.html + 30 + + + src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.html + 31 + + + src/app/features/safe/iam/team/details/inherited-policies/inherited-policies.component.html + 25 + + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 58 + + 类型 + + + Policies + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 45 + + + src/app/features/safe/iam/groups/details/details.component.html + 13 + + 策略 + + + Select policies + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 50 + + 选择策略 + + + Loading... + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 68 + + + src/app/core/components/audit-logs/audit-logs.component.html + 26 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 36 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 66 + + + src/app/core/components/member-drawer/member-drawer.component.html + 38 + + + src/app/core/components/member-drawer/member-drawer.component.html + 55 + + + src/app/core/components/metric-drawer/metric-drawer.component.html + 43 + + + src/app/core/components/target-user/target-user.component.html + 44 + + + src/app/features/safe/end-users/index/index.component.html + 25 + + + src/app/features/safe/end-users/index/index.component.html + 60 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html + 138 + + + src/app/features/safe/feature-flags/details/insights/insights.component.html + 18 + + + src/app/features/safe/feature-flags/details/setting/setting.component.html + 136,137 + + + src/app/features/safe/feature-flags/index/index.component.html + 26 + + + src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html + 38 + + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 28 + + 数据加载中... + + + Policies are mandatory for service type access tokens + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 82 + + + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 225 + + 策略不能为空 + + + Save + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 92 + + + src/app/core/components/change-review/change-review.component.html + 43 + + + src/app/core/components/env-drawer/env-drawer.component.html + 35 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 91 + + + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 202 + + + src/app/core/components/group-drawer/group-drawer.component.html + 32 + + + src/app/core/components/header/header.component.html + 80,81 + + + src/app/core/components/member-drawer/member-drawer.component.html + 61 + + + src/app/core/components/metric-drawer/metric-drawer.component.html + 121 + + + src/app/core/components/organization-drawer/organization-drawer.component.html + 18 + + + src/app/core/components/policy-drawer/policy-drawer.component.html + 32 + + + src/app/core/components/project-drawer/project-drawer.component.html + 29 + + + src/app/core/components/props-drawer/props-drawer.component.html + 90 + + + src/app/core/components/target-user/target-user.component.html + 69 + + + src/app/features/safe/feature-flags/details/setting/setting.component.html + 164,166 + + + src/app/features/safe/feature-flags/index/index.component.html + 224 + + + src/app/features/safe/iam/components/policy-editor/policy-editor.component.html + 9 + + + src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html + 76 + + + src/app/features/safe/segments/index/index.component.html + 104 + + 保存 + + + Operation succeeded + + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 204 + + + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 219 + + + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts + 193 + + + src/app/core/components/group-drawer/group-drawer.component.ts + 68 + + + src/app/core/components/member-drawer/member-drawer.component.ts + 121 + + + src/app/core/components/metric-drawer/metric-drawer.component.ts + 241 + + + src/app/core/components/metric-drawer/metric-drawer.component.ts + 258 + + + src/app/core/components/policy-drawer/policy-drawer.component.ts + 68 + + + src/app/core/components/props-drawer/props-drawer.component.ts + 93 + + + src/app/core/components/props-drawer/props-drawer.component.ts + 116 + + + src/app/core/components/props-drawer/props-drawer.component.ts + 134 + + + src/app/features/safe/experiments/metrics/metrics.component.ts + 85 + + + src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts + 59 + + + src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts + 77 + + + src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts + 86 + + + src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts + 97 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 84 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 95 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 190 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 322 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 333 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 341 + + + src/app/features/safe/feature-flags/index/index.component.ts + 336 + + + src/app/features/safe/feature-flags/index/index.component.ts + 349 + + + src/app/features/safe/feature-flags/index/index.component.ts + 359 + + + src/app/features/safe/iam/groups/details/policies/policies.component.ts + 74 + + + src/app/features/safe/iam/groups/details/policies/policies.component.ts + 88 + + + src/app/features/safe/iam/groups/details/setting/setting.component.ts + 42 + + + src/app/features/safe/iam/groups/details/setting/setting.component.ts + 69 + + + src/app/features/safe/iam/groups/details/team/team.component.ts + 73 + + + src/app/features/safe/iam/groups/details/team/team.component.ts + 87 + + + src/app/features/safe/iam/groups/index/index.component.ts + 84 + + + src/app/features/safe/iam/policies/details/groups/groups.component.ts + 76 + + + src/app/features/safe/iam/policies/details/groups/groups.component.ts + 90 + + + src/app/features/safe/iam/policies/details/permission/permission.component.ts + 40 + + + src/app/features/safe/iam/policies/details/setting/setting.component.ts + 46 + + + src/app/features/safe/iam/policies/details/setting/setting.component.ts + 53 + + + src/app/features/safe/iam/policies/details/team/team.component.ts + 76 + + + src/app/features/safe/iam/policies/details/team/team.component.ts + 90 + + + src/app/features/safe/iam/policies/index/index.component.ts + 80 + + + src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.ts + 75 + + + src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.ts + 89 + + + src/app/features/safe/iam/team/details/groups/groups.component.ts + 81 + + + src/app/features/safe/iam/team/details/groups/groups.component.ts + 95 + + + src/app/features/safe/iam/team/details/setting/setting.component.ts + 51 + + + src/app/features/safe/iam/team/index/index.component.ts + 72 + + + src/app/features/safe/integrations/access-tokens/index/index.component.ts + 134 + + + src/app/features/safe/integrations/access-tokens/index/index.component.ts + 145 + + + src/app/features/safe/segments/details/setting/setting.component.ts + 60 + + + src/app/features/safe/segments/details/targeting/targeting.component.ts + 136 + + + src/app/features/safe/segments/index/index.component.ts + 41 + + + src/app/features/safe/segments/index/index.component.ts + 63 + + + src/app/features/safe/segments/index/index.component.ts + 76 + + 操作成功 + + + Operation failed, please try again + + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 207 + + + src/app/core/components/metric-drawer/metric-drawer.component.ts + 244 + + + src/app/core/components/target-user/target-user.component.ts + 127 + + + src/app/core/components/target-user/target-user.component.ts + 159 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts + 213 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts + 229 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts + 296 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts + 309 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 274 + + + src/app/features/safe/feature-flags/details/targeting/targeting.component.ts + 109 + + + src/app/features/safe/feature-flags/index/index.component.ts + 339 + + + src/app/features/safe/onboarding/steps/steps.component.ts + 63 + + + src/app/features/safe/organizations/project/project.component.ts + 253 + + + src/app/features/safe/organizations/project/project.component.ts + 287 + + + src/app/features/safe/organizations/project/project.component.ts + 303 + + + src/app/features/safe/segments/index/index.component.ts + 79 + + 操作失败,请重试 + created @@ -69,70 +796,10 @@ Filter by team member - src/app/core/components/audit-logs/audit-logs.component.html - 20 - - 按团队成员查找 - - - Loading... - - src/app/core/components/audit-logs/audit-logs.component.html - 26 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 36 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 66 - - - src/app/core/components/member-drawer/member-drawer.component.html - 38 - - - src/app/core/components/member-drawer/member-drawer.component.html - 55 - - - src/app/core/components/metric-drawer/metric-drawer.component.html - 43 - - - src/app/core/components/target-user/target-user.component.html - 44 - - - src/app/features/safe/end-users/index/index.component.html - 25 - - - src/app/features/safe/end-users/index/index.component.html - 60 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 138 - - - src/app/features/safe/feature-flags/details/insights/insights.component.html - 18 - - - src/app/features/safe/feature-flags/details/setting/setting.component.html - 136,137 - - - src/app/features/safe/feature-flags/index/index.component.html - 26 - - - src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html - 38 + src/app/core/components/audit-logs/audit-logs.component.html + 20 - 数据加载中... + 按团队成员查找 Filter by type @@ -365,298 +1032,50 @@ 41 - src/app/core/components/header/header.component.html - 79,80 - - - src/app/core/components/props-drawer/props-drawer.component.html - 103 - - - src/app/core/components/target-user/target-user.component.html - 68 - - - src/app/features/safe/feature-flags/details/setting/setting.component.html - 162,163 - - - src/app/features/safe/feature-flags/index/index.component.html - 223 - - - src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html - 75 - - - src/app/features/safe/segments/index/index.component.html - 102 - - - src/app/features/safe/segments/index/index.component.html - 141 - - 取消 - - - Save - - src/app/core/components/change-review/change-review.component.html - 43 - - - src/app/core/components/env-drawer/env-drawer.component.html - 35 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 91 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 202 - - - src/app/core/components/group-drawer/group-drawer.component.html - 32 - - - src/app/core/components/header/header.component.html - 80,81 - - - src/app/core/components/member-drawer/member-drawer.component.html - 61 - - - src/app/core/components/metric-drawer/metric-drawer.component.html - 121 - - - src/app/core/components/organization-drawer/organization-drawer.component.html - 18 - - - src/app/core/components/policy-drawer/policy-drawer.component.html - 32 - - - src/app/core/components/project-drawer/project-drawer.component.html - 29 - - - src/app/core/components/props-drawer/props-drawer.component.html - 90 - - - src/app/core/components/target-user/target-user.component.html - 69 - - - src/app/features/safe/feature-flags/details/setting/setting.component.html - 164,166 - - - src/app/features/safe/feature-flags/index/index.component.html - 224 - - - src/app/features/safe/iam/components/policy-editor/policy-editor.component.html - 9 - - - src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html - 76 - - - src/app/features/safe/segments/index/index.component.html - 104 - - 保存 - - - Permission will become invalid if you change the name - - src/app/core/components/env-drawer/env-drawer.component.html - 15 - - - src/app/core/components/project-drawer/project-drawer.component.html - 16 - - 修改名称后对其设置的权限将会失效 - - - Name - - src/app/core/components/env-drawer/env-drawer.component.html - 22 - - - src/app/core/components/env-drawer/env-drawer.component.html - 24 - - - src/app/core/components/group-drawer/group-drawer.component.html - 14 - - - src/app/core/components/group-drawer/group-drawer.component.html - 16 - - - src/app/core/components/metric-drawer/metric-drawer.component.html - 12 - - - src/app/core/components/metric-drawer/metric-drawer.component.html - 14 - - - src/app/core/components/organization-drawer/organization-drawer.component.html - 13 - - - src/app/core/components/organization-drawer/organization-drawer.component.html - 15 - - - src/app/core/components/policy-drawer/policy-drawer.component.html - 14 - - - src/app/core/components/policy-drawer/policy-drawer.component.html - 16 - - - src/app/core/components/project-drawer/project-drawer.component.html - 23 - - - src/app/core/components/project-drawer/project-drawer.component.html - 25 - - - src/app/core/components/props-drawer/props-drawer.component.html - 39 - - - src/app/core/components/props-drawer/props-drawer.component.html - 74 - - - src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.html - 37,38 - - - src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.html - 85,86 - - - src/app/features/safe/data-sync/remote-sync/remote-sync.component.html - 25 - - - src/app/features/safe/end-users/details/details.component.html - 16 - - - src/app/features/safe/feature-flags/details/insights/insights.component.html - 56 - - - src/app/features/safe/feature-flags/details/setting/setting.component.html - 31 - - - src/app/features/safe/feature-flags/index/index.component.html - 70 - - - src/app/features/safe/feature-flags/index/index.component.html - 185 - - - src/app/features/safe/iam/groups/details/setting/setting.component.html - 10 - - - src/app/features/safe/iam/groups/details/setting/setting.component.html - 17 - - - src/app/features/safe/iam/groups/details/team/team.component.html - 27 - - - src/app/features/safe/iam/groups/index/index.component.html - 29 - - - src/app/features/safe/iam/policies/details/groups/groups.component.html - 27 - - - src/app/features/safe/iam/policies/details/setting/setting.component.html - 10 - - - src/app/features/safe/iam/policies/details/setting/setting.component.html - 17 - - - src/app/features/safe/iam/policies/details/team/team.component.html - 28 - - - src/app/features/safe/iam/policies/index/index.component.html - 29 - - - src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.html - 30 - - - src/app/features/safe/iam/team/details/groups/groups.component.html - 27 + src/app/core/components/header/header.component.html + 79,80 - src/app/features/safe/iam/team/details/inherited-policies/inherited-policies.component.html - 23 + src/app/core/components/props-drawer/props-drawer.component.html + 103 - src/app/features/safe/iam/team/details/setting/setting.component.html - 10 + src/app/core/components/target-user/target-user.component.html + 68 - src/app/features/safe/iam/team/index/index.component.html - 29 + src/app/features/safe/feature-flags/details/setting/setting.component.html + 162,163 - src/app/features/safe/organizations/profile/profile.component.html - 4 + src/app/features/safe/feature-flags/index/index.component.html + 223 - src/app/features/safe/organizations/profile/profile.component.html - 7 + src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html + 75 - src/app/features/safe/organizations/project/project.component.html - 120 + src/app/features/safe/segments/index/index.component.html + 102 - src/app/features/safe/segments/details/setting/setting.component.html - 15 + src/app/features/safe/segments/index/index.component.html + 141 + 取消 + + + Permission will become invalid if you change the name - src/app/features/safe/segments/index/index.component.html - 35 + src/app/core/components/env-drawer/env-drawer.component.html + 15 - src/app/features/safe/segments/index/index.component.html - 82 + src/app/core/components/project-drawer/project-drawer.component.html + 16 - 名称 + 修改名称后对其设置的权限将会失效 Environment name is mandatory! @@ -886,257 +1305,57 @@ 返回 - - Percentage of users dispatched to experiment - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 68 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 94 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 152 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 178 - - 分流入实验的用户所占百分比 - - - Compared to all users matching this rule - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 68 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 94 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 152 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 178 - - 相对于匹配到该规则的总用户数 - - - Default rule - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 88 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 172 - - 默认规则 - - - Operation succeeded - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts - 193 - - - src/app/core/components/group-drawer/group-drawer.component.ts - 68 - - - src/app/core/components/member-drawer/member-drawer.component.ts - 121 - - - src/app/core/components/metric-drawer/metric-drawer.component.ts - 241 - - - src/app/core/components/metric-drawer/metric-drawer.component.ts - 258 - - - src/app/core/components/policy-drawer/policy-drawer.component.ts - 68 - - - src/app/core/components/props-drawer/props-drawer.component.ts - 93 - - - src/app/core/components/props-drawer/props-drawer.component.ts - 116 - - - src/app/core/components/props-drawer/props-drawer.component.ts - 134 - - - src/app/features/safe/experiments/metrics/metrics.component.ts - 85 - - - src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 59 - - - src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 77 - - - src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 86 - - - src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 97 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 84 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 95 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 190 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 322 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 333 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 341 - - - src/app/features/safe/feature-flags/index/index.component.ts - 336 - - - src/app/features/safe/feature-flags/index/index.component.ts - 349 - - - src/app/features/safe/feature-flags/index/index.component.ts - 359 - - - src/app/features/safe/iam/groups/details/policies/policies.component.ts - 74 - - - src/app/features/safe/iam/groups/details/policies/policies.component.ts - 88 - - - src/app/features/safe/iam/groups/details/setting/setting.component.ts - 42 - - - src/app/features/safe/iam/groups/details/setting/setting.component.ts - 69 - - - src/app/features/safe/iam/groups/details/team/team.component.ts - 73 - - - src/app/features/safe/iam/groups/details/team/team.component.ts - 87 - - - src/app/features/safe/iam/groups/index/index.component.ts - 84 - - - src/app/features/safe/iam/policies/details/groups/groups.component.ts - 76 - - - src/app/features/safe/iam/policies/details/groups/groups.component.ts - 90 - - - src/app/features/safe/iam/policies/details/permission/permission.component.ts - 40 - - - src/app/features/safe/iam/policies/details/setting/setting.component.ts - 46 - - - src/app/features/safe/iam/policies/details/setting/setting.component.ts - 53 - - - src/app/features/safe/iam/policies/details/team/team.component.ts - 76 - - - src/app/features/safe/iam/policies/details/team/team.component.ts - 90 - - - src/app/features/safe/iam/policies/index/index.component.ts - 80 - - - src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.ts - 75 - + + Percentage of users dispatched to experiment - src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.ts - 89 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 68 - src/app/features/safe/iam/team/details/groups/groups.component.ts - 81 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 94 - src/app/features/safe/iam/team/details/groups/groups.component.ts - 95 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 152 - src/app/features/safe/iam/team/details/setting/setting.component.ts - 51 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 178 + 分流入实验的用户所占百分比 + + + Compared to all users matching this rule - src/app/features/safe/iam/team/index/index.component.ts - 72 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 68 - src/app/features/safe/segments/details/setting/setting.component.ts - 60 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 94 - src/app/features/safe/segments/details/targeting/targeting.component.ts - 136 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 152 - src/app/features/safe/segments/index/index.component.ts - 41 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 178 + 相对于匹配到该规则的总用户数 + + + Default rule - src/app/features/safe/segments/index/index.component.ts - 63 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 88 - src/app/features/safe/segments/index/index.component.ts - 76 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 172 - 操作成功 + 默认规则 Operation failed @@ -1256,6 +1475,14 @@ src/app/features/safe/iam/team/index/index.component.ts 75 + + src/app/features/safe/integrations/access-tokens/index/index.component.ts + 138 + + + src/app/features/safe/integrations/access-tokens/index/index.component.ts + 148 + src/app/features/safe/segments/details/targeting/targeting.component.ts 142 @@ -1554,26 +1781,6 @@ 添加组 - - Validating... - - src/app/core/components/group-drawer/group-drawer.component.html - 15 - - - src/app/core/components/policy-drawer/policy-drawer.component.html - 15 - - - src/app/features/safe/feature-flags/index/index.component.html - 203 - - - src/app/features/safe/segments/index/index.component.html - 83 - - 校验中... - Group name cannot be empty @@ -2234,70 +2441,6 @@ 低于基准值 - - Operation failed, please try again - - src/app/core/components/metric-drawer/metric-drawer.component.ts - 244 - - - src/app/core/components/target-user/target-user.component.ts - 127 - - - src/app/core/components/target-user/target-user.component.ts - 159 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts - 213 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts - 229 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts - 296 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts - 309 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 274 - - - src/app/features/safe/feature-flags/details/targeting/targeting.component.ts - 109 - - - src/app/features/safe/feature-flags/index/index.component.ts - 339 - - - src/app/features/safe/onboarding/steps/steps.component.ts - 63 - - - src/app/features/safe/organizations/project/project.component.ts - 253 - - - src/app/features/safe/organizations/project/project.component.ts - 287 - - - src/app/features/safe/organizations/project/project.component.ts - 303 - - - src/app/features/safe/segments/index/index.component.ts - 79 - - 操作失败,请重试 - Create organization @@ -2460,6 +2603,10 @@ src/app/features/safe/iam/team/details/groups/groups.component.html 54 + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 39 + src/app/features/safe/organizations/organization/organization.component.html 29 @@ -2568,6 +2715,10 @@ src/app/features/safe/iam/team/index/index.component.html 34 + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 62 + src/app/features/safe/segments/index/index.component.html 37 @@ -2648,6 +2799,10 @@ src/app/features/safe/iam/team/index/index.component.html 68 + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 91 + src/app/features/safe/organizations/project/project.component.html 72 @@ -2732,6 +2887,10 @@ src/app/features/safe/iam/team/index/index.component.html 72 + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 95 + src/app/features/safe/organizations/project/project.component.html 75 @@ -3093,6 +3252,34 @@ 格式化 + + Active + + src/app/core/pipes/access-token-status.pipe.ts + 12 + + Active + + + Inactive + + src/app/core/pipes/access-token-status.pipe.ts + 13 + + Inactive + + + Personal + + src/app/core/pipes/access-token-type.pipe.ts + 9 + + + src/app/core/pipes/access-token-type.pipe.ts + 10 + + Personal + System Managed @@ -3217,7 +3404,7 @@ src/app/features/safe/safe-routing.module.ts - 62 + 50 src/app/features/safe/safe.component.ts @@ -3373,30 +3560,6 @@ 添加 - - Type - - src/app/features/safe/data-sync/remote-sync/remote-sync.component.html - 26 - - - src/app/features/safe/iam/policies/details/setting/setting.component.html - 33 - - - src/app/features/safe/iam/policies/index/index.component.html - 30 - - - src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.html - 31 - - - src/app/features/safe/iam/team/details/inherited-policies/inherited-policies.component.html - 25 - - 类型 - URL @@ -3639,6 +3802,10 @@ src/app/features/safe/experiments/metrics/metrics.component.html 72 + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 78 + 编辑 @@ -4824,6 +4991,10 @@ src/app/features/safe/feature-flags/index/index.component.html 75 + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 60 + 状态 @@ -5501,14 +5672,6 @@ 团队 - - Policies - - src/app/features/safe/iam/groups/details/details.component.html - 13 - - 策略 - Filter by policy name @@ -5933,6 +6096,70 @@ + + Filter by name + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 5 + + 按名称查找 + + + Select creator + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 12 + + 选择创建者 + + + Filter by type + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 31 + + 按类型查找 + + + Creator + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 59 + + 创建者 + + + Last used + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 61 + + 上一次使用 + + + Activate + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 82 + + 激活 + + + Deactivate + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 87 + + 停用 + + + Access tokens + + src/app/features/safe/integrations/integrations-routing.module.ts + 14 + + 访问密钥 + We've created a project for @@ -6422,7 +6649,7 @@ Organization src/app/features/safe/safe-routing.module.ts - 50 + 57 组织机构 @@ -6506,6 +6733,22 @@ 策略 + + Integrations + + src/app/features/safe/safe.component.ts + 114,113 + + 服务集成 + + + Access tokens + + src/app/features/safe/safe.component.ts + 119,118 + + 访问密钥 + This segment is not used by any feature flag From e9525bfaa9b17b6f39b3609c962e8216b0d609a5 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Sun, 12 Mar 2023 02:13:34 +0100 Subject: [PATCH 11/44] in progress --- .../access-token-drawer.component.html | 5 +--- .../access-token-drawer.component.ts | 30 ++++++++----------- .../app/core/services/permissions.service.ts | 2 ++ 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html index 55b6a9e46..0651a4350 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html @@ -54,7 +54,7 @@ (ngModelChange)="onPolicySelectChange()" (nzOnSearch)="policyDebouncer.next($event)"> - + @@ -64,9 +64,6 @@ - - Loading... -
diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts index cb9c03ad3..6a25d85bd 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts @@ -1,19 +1,17 @@ import { Component, OnInit, Input, Output, EventEmitter, ViewChild } from '@angular/core'; import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { NzMessageService } from 'ng-zorro-antd/message'; -import { debounceTime, distinctUntilChanged, first, map, switchMap } from "rxjs/operators"; +import { debounceTime, first, map, switchMap } from "rxjs/operators"; import { PolicyService } from "@services/policy.service"; import { AccessTokenTypeEnum, IAccessToken, IAccessTokenPolicy } from "@features/safe/integrations/access-tokens/types/access-token"; -import { PolicyFilter } from "@features/safe/iam/types/policy"; import { NzSelectComponent } from "ng-zorro-antd/select"; import { Subject } from "rxjs"; import { AccessTokenService } from "@services/access-token.service"; -import { CustomEventSuccessCriteria, CustomEventTrackOption, IMetric } from "@features/safe/experiments/types"; -import { uuidv4 } from "@utils/index"; +import { PermissionsService } from "@services/permissions.service"; @Component({ selector: 'access-token-drawer', @@ -54,12 +52,12 @@ export class AccessTokenDrawerComponent implements OnInit { constructor( private fb: FormBuilder, private policyService: PolicyService, + private permissionsService: PermissionsService, private accessTokenService: AccessTokenService, private message: NzMessageService ) { this.policyDebouncer.pipe( - debounceTime(500), - distinctUntilChanged() + debounceTime(100), ).subscribe(query => this.searchPolicies(query)); } @@ -130,19 +128,15 @@ export class AccessTokenDrawerComponent implements OnInit { this.validatePoliciesControl(); } - isLoadingPolicies = true; - searchPolicies(query: string = '') { - this.isLoadingPolicies = true; - - this.policyService.getList(new PolicyFilter(query, 1, 50)).subscribe(policies => { - this.policySearchResultList = policies.items.map(p => ({ - ...p, - isSelected: this.selectedPolicyList.some((sp => sp.id === p.id)) - })); - - this.isLoadingPolicies = false; - }, () => this.isLoadingPolicies = false); + const regex = new RegExp(query,'ig') + this.policySearchResultList = this.permissionsService.policies + .filter((policy) => query === '' || policy.name.match(regex)) + .map((policy) => ({ + ...policy, + isSelected: this.selectedPolicyList.some((sp => sp.id === policy.id)) + }) + ); } nameAsyncValidator = (control: FormControl) => control.valueChanges.pipe( diff --git a/modules/front-end/src/app/core/services/permissions.service.ts b/modules/front-end/src/app/core/services/permissions.service.ts index a74e7383c..80720cd8e 100644 --- a/modules/front-end/src/app/core/services/permissions.service.ts +++ b/modules/front-end/src/app/core/services/permissions.service.ts @@ -8,6 +8,7 @@ import {EffectEnum, ResourceTypeEnum} from "@features/safe/iam/components/policy providedIn: 'root' }) export class PermissionsService { + policies: IPolicy[]; private permissions: IPolicyStatement[]; genericDenyMessage: string = $localize `:@@permissions.need-permissions-to-operate:You don't have permissions to take this action, please contact the admin to grant you the necessary permissions`; @@ -17,6 +18,7 @@ export class PermissionsService { async fetchPolicies(memberId: string) { const policies = await lastValueFrom(this.memberSvc.getAllPolicies(memberId)); + this.policies = [...policies]; this.permissions = policies.flatMap(p => p.statements); } From da2a2b9b5a0066f3cd8c284216074f673adfd2f4 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Sun, 12 Mar 2023 02:32:43 +0100 Subject: [PATCH 12/44] in progress --- .../docker-entrypoint-initdb.d/init.js | 21 +++++++++++++++++++ .../actions-selector.component.html | 2 +- .../iam/components/policy-editor/types.ts | 15 +++++++++++++ .../front-end/src/app/shared/permissions.ts | 7 ++++++- 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/infra/mongodb/docker-entrypoint-initdb.d/init.js b/infra/mongodb/docker-entrypoint-initdb.d/init.js index 3579f200b..80089bf73 100644 --- a/infra/mongodb/docker-entrypoint-initdb.d/init.js +++ b/infra/mongodb/docker-entrypoint-initdb.d/init.js @@ -108,6 +108,17 @@ db.Policies.insertOne( actions: ["UpdateOrgName"], resources: ["account"] }, + { + _id: getUUIDString(), + resourceType: "general", + effect: "allow", + actions: [ + "CreateServiceAccessTokens", + "CreatePersonalAccessTokens", + "ListAccessTokens" + ], + resources: ["account"] + }, { _id: getUUIDString(), resourceType: "general", @@ -151,6 +162,16 @@ db.Policies.insertOne( "ListEnvs" ], resources: ["project"] + }, + { + _id: getUUIDString(), + resourceType: "general", + effect: "allow", + actions: [ + "CreatePersonalAccessTokens", + "ListAccessTokens" + ], + resources: ["account"] } ], createdAt: new Date(), diff --git a/modules/front-end/src/app/features/safe/iam/components/policy-editor/actions-selector/actions-selector.component.html b/modules/front-end/src/app/features/safe/iam/components/policy-editor/actions-selector/actions-selector.component.html index fb83f65e5..6b98472f4 100644 --- a/modules/front-end/src/app/features/safe/iam/components/policy-editor/actions-selector/actions-selector.component.html +++ b/modules/front-end/src/app/features/safe/iam/components/policy-editor/actions-selector/actions-selector.component.html @@ -7,7 +7,7 @@
-
+
{{act.displayName}} ({{act.name}})
diff --git a/modules/front-end/src/app/features/safe/iam/components/policy-editor/types.ts b/modules/front-end/src/app/features/safe/iam/components/policy-editor/types.ts index 6c04d785b..74e01065b 100644 --- a/modules/front-end/src/app/features/safe/iam/components/policy-editor/types.ts +++ b/modules/front-end/src/app/features/safe/iam/components/policy-editor/types.ts @@ -126,6 +126,21 @@ export const resourceActionsDict: {[key: string]: IamPolicyAction[]} = { name: permissionActions.UpdateOrgName, displayName: $localize`:@@iam.action.update-org-name:Update org name` }, + { + id: uuidv4(), + name: permissionActions.ListAccessTokens, + displayName: $localize`:@@iam.action.list-access-tokens:List access tokens` + }, + { + id: uuidv4(), + name: permissionActions.CreateServiceAccessTokens, + displayName: $localize`:@@iam.action.create-service-access-tokens:Create service access tokens` + }, + { + id: uuidv4(), + name: permissionActions.CreatePersonalAccessTokens, + displayName: $localize`:@@iam.action.create-personal-access-tokens:Create personal access tokens` + }, ], [`${ResourceTypeEnum.General},iam`]: [ { diff --git a/modules/front-end/src/app/shared/permissions.ts b/modules/front-end/src/app/shared/permissions.ts index 29d294877..1b8472d63 100644 --- a/modules/front-end/src/app/shared/permissions.ts +++ b/modules/front-end/src/app/shared/permissions.ts @@ -26,5 +26,10 @@ export const permissionActions = { UpdateOrgName: 'UpdateOrgName', // iam - CanManageIAM: 'CanManageIAM' + CanManageIAM: 'CanManageIAM', + + // access tokens + ListAccessTokens: 'ListAccessTokens', + CreateServiceAccessTokens: 'CreateServiceAccessTokens', + CreatePersonalAccessTokens: 'CreatePersonalAccessTokens', } From 1f299f94d92cfcc1846d3ffab117ab979441a564 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Sun, 12 Mar 2023 02:57:45 +0100 Subject: [PATCH 13/44] in progress --- .../src/app/core/guards/accessTokens.guard.ts | 33 +++ .../app/core/pipes/access-token-type.pipe.ts | 2 +- .../access-tokens/index/index.component.html | 10 +- .../access-tokens/index/index.component.less | 24 +- .../integrations-routing.module.ts | 2 + .../app/features/safe/safe-routing.module.ts | 1 - modules/front-end/src/locale/messages.xlf | 234 +++++++++-------- modules/front-end/src/locale/messages.zh.xlf | 242 ++++++++++-------- 8 files changed, 308 insertions(+), 240 deletions(-) create mode 100644 modules/front-end/src/app/core/guards/accessTokens.guard.ts diff --git a/modules/front-end/src/app/core/guards/accessTokens.guard.ts b/modules/front-end/src/app/core/guards/accessTokens.guard.ts new file mode 100644 index 000000000..223754ed0 --- /dev/null +++ b/modules/front-end/src/app/core/guards/accessTokens.guard.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@angular/core'; +import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router'; +import {PermissionsService} from "@services/permissions.service"; +import {generalResourceRNPattern, permissionActions} from "@shared/permissions"; +import {NzMessageService} from "ng-zorro-antd/message"; + +@Injectable({ + providedIn: 'root' +}) +export class AccessTokensGuard implements CanActivate { + + constructor( + private router: Router, + private message: NzMessageService, + private permissionsService: PermissionsService + ) { } + + async canActivate( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot): Promise { + return await this.checkPermission(state.url); + } + + async checkPermission(url: string): Promise { + const canListAccessTokens = !!this.permissionsService.canTakeAction(generalResourceRNPattern.account, permissionActions.ListAccessTokens); + + if (!canListAccessTokens) { + this.message.warning(this.permissionsService.genericDenyMessage); + } + + return canListAccessTokens; + } +} diff --git a/modules/front-end/src/app/core/pipes/access-token-type.pipe.ts b/modules/front-end/src/app/core/pipes/access-token-type.pipe.ts index 6a3f6e7fc..3e1fc1b65 100644 --- a/modules/front-end/src/app/core/pipes/access-token-type.pipe.ts +++ b/modules/front-end/src/app/core/pipes/access-token-type.pipe.ts @@ -7,7 +7,7 @@ import { AccessTokenTypeEnum } from "@features/safe/integrations/access-tokens/t export class AccessTokenTypePipe implements PipeTransform { typeDict = { [AccessTokenTypeEnum.Personal]: $localize `:@@integrations.access-token.personal:Personal`, - [AccessTokenTypeEnum.Service]: $localize `:@@integrations.access-token.personal:Service` + [AccessTokenTypeEnum.Service]: $localize `:@@integrations.access-token.service:Service` } transform(value: string): string { diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html index 7f18224df..4f8711b58 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html @@ -72,7 +72,15 @@ {{ item.creator.name }} ({{ item.creator.email }}) {{ item.creator.email }} - {{ item.status | accessTokenStatus }} + + + + + + + + {{ item.status | accessTokenStatus }} + {{ item.lastUsedAt | date: 'YYYY-MM-dd HH:mm'}} Edit diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.less b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.less index 7ca329a39..112bb4460 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.less +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.less @@ -21,27 +21,9 @@ } } - .table-wrapper { - .more-tags-item { - max-width: 150px; - } - - .tag { - max-width: 150px; - } - - .col-rn { - height: 56px; - display: flex; - justify-content: flex-start; - align-items: center; - .rn { - display: inline-block; - max-width: 310px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } + .status { + &.status-Active { + color: @green70-color; } } } diff --git a/modules/front-end/src/app/features/safe/integrations/integrations-routing.module.ts b/modules/front-end/src/app/features/safe/integrations/integrations-routing.module.ts index 6ab0fd0c0..5fb59285d 100644 --- a/modules/front-end/src/app/features/safe/integrations/integrations-routing.module.ts +++ b/modules/front-end/src/app/features/safe/integrations/integrations-routing.module.ts @@ -1,6 +1,7 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { IntegrationsComponent } from './integrations.component'; +import { AccessTokensGuard } from "@core/guards/accessTokens.guard"; const routes: Routes = [ { @@ -9,6 +10,7 @@ const routes: Routes = [ children: [ { path: 'access-tokens', + canActivate: [AccessTokensGuard], loadChildren: () => import("./access-tokens/access-tokens.module").then(m => m.AccessTokensModule), data: { breadcrumb: $localize `:@@integrations.routing.access-tokens:Access tokens` diff --git a/modules/front-end/src/app/features/safe/safe-routing.module.ts b/modules/front-end/src/app/features/safe/safe-routing.module.ts index a6f1a1319..eb870bfed 100644 --- a/modules/front-end/src/app/features/safe/safe-routing.module.ts +++ b/modules/front-end/src/app/features/safe/safe-routing.module.ts @@ -64,7 +64,6 @@ const routes: Routes = [ }, { path: 'integrations', - canActivate: [IAMGuard], loadChildren: () => import("./integrations/integrations.module").then(m => m.IntegrationsModule), }, { diff --git a/modules/front-end/src/locale/messages.xlf b/modules/front-end/src/locale/messages.xlf index 543335c4f..300c95477 100644 --- a/modules/front-end/src/locale/messages.xlf +++ b/modules/front-end/src/locale/messages.xlf @@ -278,89 +278,22 @@ 50 - - Loading... - - src/app/core/components/access-token-drawer/access-token-drawer.component.html - 68 - - - src/app/core/components/audit-logs/audit-logs.component.html - 26 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 36 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 66 - - - src/app/core/components/member-drawer/member-drawer.component.html - 38 - - - src/app/core/components/member-drawer/member-drawer.component.html - 55 - - - src/app/core/components/metric-drawer/metric-drawer.component.html - 43 - - - src/app/core/components/target-user/target-user.component.html - 44 - - - src/app/features/safe/end-users/index/index.component.html - 25 - - - src/app/features/safe/end-users/index/index.component.html - 60 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 138 - - - src/app/features/safe/feature-flags/details/insights/insights.component.html - 18 - - - src/app/features/safe/feature-flags/details/setting/setting.component.html - 136,137 - - - src/app/features/safe/feature-flags/index/index.component.html - 26 - - - src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html - 38 - - - src/app/features/safe/integrations/access-tokens/index/index.component.html - 28 - - Policies are mandatory for service type access tokens src/app/core/components/access-token-drawer/access-token-drawer.component.html - 82 + 79 src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 225 + 219 Save src/app/core/components/access-token-drawer/access-token-drawer.component.html - 92 + 89 src/app/core/components/change-review/change-review.component.html @@ -439,11 +372,11 @@ Operation succeeded src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 204 + 198 src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 219 + 213 src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts @@ -654,7 +587,7 @@ Operation failed, please try again src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 207 + 201 src/app/core/components/metric-drawer/metric-drawer.component.ts @@ -780,6 +713,69 @@ 20 + + Loading... + + src/app/core/components/audit-logs/audit-logs.component.html + 26 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 36 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 66 + + + src/app/core/components/member-drawer/member-drawer.component.html + 38 + + + src/app/core/components/member-drawer/member-drawer.component.html + 55 + + + src/app/core/components/metric-drawer/metric-drawer.component.html + 43 + + + src/app/core/components/target-user/target-user.component.html + 44 + + + src/app/features/safe/end-users/index/index.component.html + 25 + + + src/app/features/safe/end-users/index/index.component.html + 60 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html + 138 + + + src/app/features/safe/feature-flags/details/insights/insights.component.html + 18 + + + src/app/features/safe/feature-flags/details/setting/setting.component.html + 136,137 + + + src/app/features/safe/feature-flags/index/index.component.html + 26 + + + src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html + 38 + + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 28 + + Filter by type @@ -2620,7 +2616,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 91 + 99 src/app/features/safe/organizations/project/project.component.html @@ -2707,7 +2703,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 95 + 103 src/app/features/safe/organizations/project/project.component.html @@ -3059,6 +3055,9 @@ src/app/core/pipes/access-token-type.pipe.ts 9 + + + Service src/app/core/pipes/access-token-type.pipe.ts 10 @@ -3082,7 +3081,7 @@ You don't have permissions to take this action, please contact the admin to grant you the necessary permissions src/app/core/services/permissions.service.ts - 13 + 14 @@ -3533,7 +3532,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 78 + 86 @@ -5017,151 +5016,172 @@ 127 + + List access tokens + + src/app/features/safe/iam/components/policy-editor/types.ts + 132 + + + + Create service access tokens + + src/app/features/safe/iam/components/policy-editor/types.ts + 137 + + + + Create personal access tokens + + src/app/features/safe/iam/components/policy-editor/types.ts + 142 + + IAM src/app/features/safe/iam/components/policy-editor/types.ts - 134 + 149 List projects src/app/features/safe/iam/components/policy-editor/types.ts - 141 + 156 Create projects src/app/features/safe/iam/components/policy-editor/types.ts - 146 + 161 Delete projects src/app/features/safe/iam/components/policy-editor/types.ts - 151 + 166 src/app/features/safe/iam/components/policy-editor/types.ts - 208 + 223 Update project settings src/app/features/safe/iam/components/policy-editor/types.ts - 156 + 171 src/app/features/safe/iam/components/policy-editor/types.ts - 213 + 228 List environments src/app/features/safe/iam/components/policy-editor/types.ts - 161 + 176 src/app/features/safe/iam/components/policy-editor/types.ts - 218 + 233 Create environment src/app/features/safe/iam/components/policy-editor/types.ts - 166 + 181 src/app/features/safe/iam/components/policy-editor/types.ts - 223 + 238 Access environments src/app/features/safe/iam/components/policy-editor/types.ts - 171 + 186 src/app/features/safe/iam/components/policy-editor/types.ts - 203 + 218 src/app/features/safe/iam/components/policy-editor/types.ts - 245 + 260 Delete environments src/app/features/safe/iam/components/policy-editor/types.ts - 176 + 191 src/app/features/safe/iam/components/policy-editor/types.ts - 250 + 265 Update environment settings src/app/features/safe/iam/components/policy-editor/types.ts - 181 + 196 src/app/features/safe/iam/components/policy-editor/types.ts - 255 + 270 Delete environment secret src/app/features/safe/iam/components/policy-editor/types.ts - 186 + 201 src/app/features/safe/iam/components/policy-editor/types.ts - 228 + 243 src/app/features/safe/iam/components/policy-editor/types.ts - 260 + 275 Create environment secret src/app/features/safe/iam/components/policy-editor/types.ts - 191 + 206 src/app/features/safe/iam/components/policy-editor/types.ts - 233 + 248 src/app/features/safe/iam/components/policy-editor/types.ts - 265 + 280 Update environment secret src/app/features/safe/iam/components/policy-editor/types.ts - 196 + 211 src/app/features/safe/iam/components/policy-editor/types.ts - 238 + 253 src/app/features/safe/iam/components/policy-editor/types.ts - 270 + 285 @@ -5616,21 +5636,21 @@ Activate src/app/features/safe/integrations/access-tokens/index/index.component.html - 82 + 90 Deactivate src/app/features/safe/integrations/access-tokens/index/index.component.html - 87 + 95 Access tokens src/app/features/safe/integrations/integrations-routing.module.ts - 14 + 16 diff --git a/modules/front-end/src/locale/messages.zh.xlf b/modules/front-end/src/locale/messages.zh.xlf index d35e115c3..9f55d0634 100644 --- a/modules/front-end/src/locale/messages.zh.xlf +++ b/modules/front-end/src/locale/messages.zh.xlf @@ -285,83 +285,15 @@ 选择策略 - - Loading... - - src/app/core/components/access-token-drawer/access-token-drawer.component.html - 68 - - - src/app/core/components/audit-logs/audit-logs.component.html - 26 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 36 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 66 - - - src/app/core/components/member-drawer/member-drawer.component.html - 38 - - - src/app/core/components/member-drawer/member-drawer.component.html - 55 - - - src/app/core/components/metric-drawer/metric-drawer.component.html - 43 - - - src/app/core/components/target-user/target-user.component.html - 44 - - - src/app/features/safe/end-users/index/index.component.html - 25 - - - src/app/features/safe/end-users/index/index.component.html - 60 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 138 - - - src/app/features/safe/feature-flags/details/insights/insights.component.html - 18 - - - src/app/features/safe/feature-flags/details/setting/setting.component.html - 136,137 - - - src/app/features/safe/feature-flags/index/index.component.html - 26 - - - src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html - 38 - - - src/app/features/safe/integrations/access-tokens/index/index.component.html - 28 - - 数据加载中... - Policies are mandatory for service type access tokens src/app/core/components/access-token-drawer/access-token-drawer.component.html - 82 + 79 src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 225 + 219 策略不能为空 @@ -369,7 +301,7 @@ Save src/app/core/components/access-token-drawer/access-token-drawer.component.html - 92 + 89 src/app/core/components/change-review/change-review.component.html @@ -449,11 +381,11 @@ Operation succeeded src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 204 + 198 src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 219 + 213 src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts @@ -665,7 +597,7 @@ Operation failed, please try again src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 207 + 201 src/app/core/components/metric-drawer/metric-drawer.component.ts @@ -801,6 +733,70 @@ 按团队成员查找 + + Loading... + + src/app/core/components/audit-logs/audit-logs.component.html + 26 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 36 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 66 + + + src/app/core/components/member-drawer/member-drawer.component.html + 38 + + + src/app/core/components/member-drawer/member-drawer.component.html + 55 + + + src/app/core/components/metric-drawer/metric-drawer.component.html + 43 + + + src/app/core/components/target-user/target-user.component.html + 44 + + + src/app/features/safe/end-users/index/index.component.html + 25 + + + src/app/features/safe/end-users/index/index.component.html + 60 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html + 138 + + + src/app/features/safe/feature-flags/details/insights/insights.component.html + 18 + + + src/app/features/safe/feature-flags/details/setting/setting.component.html + 136,137 + + + src/app/features/safe/feature-flags/index/index.component.html + 26 + + + src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html + 38 + + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 28 + + 数据加载中... + Filter by type @@ -2801,7 +2797,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 91 + 99 src/app/features/safe/organizations/project/project.component.html @@ -2889,7 +2885,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 95 + 103 src/app/features/safe/organizations/project/project.component.html @@ -3274,11 +3270,15 @@ src/app/core/pipes/access-token-type.pipe.ts 9 + Personal + + + Service src/app/core/pipes/access-token-type.pipe.ts 10 - Personal + Service System Managed @@ -3300,7 +3300,7 @@ You don't have permissions to take this action, please contact the admin to grant you the necessary permissions src/app/core/services/permissions.service.ts - 13 + 14 您未被授权进行该操作, 请联系账户管理员添加相关权限 @@ -3804,7 +3804,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 78 + 86 编辑 @@ -5472,11 +5472,35 @@ 修改机构名称 + + List access tokens + + src/app/features/safe/iam/components/policy-editor/types.ts + 132 + + 查看访问策略列表 + + + Create service access tokens + + src/app/features/safe/iam/components/policy-editor/types.ts + 137 + + 创建 Service 访问策略 + + + Create personal access tokens + + src/app/features/safe/iam/components/policy-editor/types.ts + 142 + + 创建 Personal 访问策略 + IAM src/app/features/safe/iam/components/policy-editor/types.ts - 134 + 149 权限管理 @@ -5484,7 +5508,7 @@ List projects src/app/features/safe/iam/components/policy-editor/types.ts - 141 + 156 查看项目列表 @@ -5492,7 +5516,7 @@ Create projects src/app/features/safe/iam/components/policy-editor/types.ts - 146 + 161 创建项目 @@ -5500,11 +5524,11 @@ Delete projects src/app/features/safe/iam/components/policy-editor/types.ts - 151 + 166 src/app/features/safe/iam/components/policy-editor/types.ts - 208 + 223 删除项目 @@ -5512,11 +5536,11 @@ Update project settings src/app/features/safe/iam/components/policy-editor/types.ts - 156 + 171 src/app/features/safe/iam/components/policy-editor/types.ts - 213 + 228 修改项目设置 @@ -5524,11 +5548,11 @@ List environments src/app/features/safe/iam/components/policy-editor/types.ts - 161 + 176 src/app/features/safe/iam/components/policy-editor/types.ts - 218 + 233 查看环境列表 @@ -5536,11 +5560,11 @@ Create environment src/app/features/safe/iam/components/policy-editor/types.ts - 166 + 181 src/app/features/safe/iam/components/policy-editor/types.ts - 223 + 238 创建环境 @@ -5548,15 +5572,15 @@ Access environments src/app/features/safe/iam/components/policy-editor/types.ts - 171 + 186 src/app/features/safe/iam/components/policy-editor/types.ts - 203 + 218 src/app/features/safe/iam/components/policy-editor/types.ts - 245 + 260 进入环境 @@ -5564,11 +5588,11 @@ Delete environments src/app/features/safe/iam/components/policy-editor/types.ts - 176 + 191 src/app/features/safe/iam/components/policy-editor/types.ts - 250 + 265 删除环境 @@ -5576,11 +5600,11 @@ Update environment settings src/app/features/safe/iam/components/policy-editor/types.ts - 181 + 196 src/app/features/safe/iam/components/policy-editor/types.ts - 255 + 270 修改环境设置 @@ -5588,15 +5612,15 @@ Delete environment secret src/app/features/safe/iam/components/policy-editor/types.ts - 186 + 201 src/app/features/safe/iam/components/policy-editor/types.ts - 228 + 243 src/app/features/safe/iam/components/policy-editor/types.ts - 260 + 275 删除环境秘钥 @@ -5604,15 +5628,15 @@ Create environment secret src/app/features/safe/iam/components/policy-editor/types.ts - 191 + 206 src/app/features/safe/iam/components/policy-editor/types.ts - 233 + 248 src/app/features/safe/iam/components/policy-editor/types.ts - 265 + 280 创建环境秘钥 @@ -5620,15 +5644,15 @@ Update environment secret src/app/features/safe/iam/components/policy-editor/types.ts - 196 + 211 src/app/features/safe/iam/components/policy-editor/types.ts - 238 + 253 src/app/features/safe/iam/components/policy-editor/types.ts - 270 + 285 修改环境秘钥 @@ -6140,7 +6164,7 @@ Activate src/app/features/safe/integrations/access-tokens/index/index.component.html - 82 + 90 激活 @@ -6148,7 +6172,7 @@ Deactivate src/app/features/safe/integrations/access-tokens/index/index.component.html - 87 + 95 停用 @@ -6156,7 +6180,7 @@ Access tokens src/app/features/safe/integrations/integrations-routing.module.ts - 14 + 16 访问密钥 From 76fcb95028484c49663a53bb6ed27639bc9a678c Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Sun, 12 Mar 2023 03:38:46 +0100 Subject: [PATCH 14/44] in progress --- .../src/Domain/AccessTokens/AccessToken.cs | 2 +- .../AccessTokens/AccessTokenService.cs | 4 +- .../access-token-drawer.component.html | 5 +- .../access-token-drawer.component.ts | 49 ++++- .../access-tokens/index/index.component.html | 38 ++-- .../access-tokens/index/index.component.ts | 11 ++ modules/front-end/src/locale/messages.xlf | 178 +++++++++-------- modules/front-end/src/locale/messages.zh.xlf | 182 +++++++++--------- 8 files changed, 266 insertions(+), 203 deletions(-) diff --git a/modules/back-end/src/Domain/AccessTokens/AccessToken.cs b/modules/back-end/src/Domain/AccessTokens/AccessToken.cs index 553a699f5..d1c03f8f4 100644 --- a/modules/back-end/src/Domain/AccessTokens/AccessToken.cs +++ b/modules/back-end/src/Domain/AccessTokens/AccessToken.cs @@ -24,7 +24,7 @@ public AccessToken(Guid organizationId, Guid creatorId, string name, string type Name = name; Status = AccessTokenStatus.Active; - Type = AccessTokenTypes.Personal; + Type = type; Policies = policies.ToArray(); } diff --git a/modules/back-end/src/Infrastructure/AccessTokens/AccessTokenService.cs b/modules/back-end/src/Infrastructure/AccessTokens/AccessTokenService.cs index aed6b62bf..3546711c5 100644 --- a/modules/back-end/src/Infrastructure/AccessTokens/AccessTokenService.cs +++ b/modules/back-end/src/Infrastructure/AccessTokens/AccessTokenService.cs @@ -30,9 +30,9 @@ public async Task> GetListAsync(Guid organizationId, Ac } var creatorId = filter.CreatorId; - if (!string.IsNullOrWhiteSpace(type)) + if (creatorId.HasValue) { - query = query.Where(x => x.CreatorId == creatorId); + query = query.Where(x => x.CreatorId == creatorId.Value); } var totalCount = await query.CountAsync(); diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html index 0651a4350..55b6a9e46 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html @@ -54,7 +54,7 @@ (ngModelChange)="onPolicySelectChange()" (nzOnSearch)="policyDebouncer.next($event)"> - + @@ -64,6 +64,9 @@ + + Loading... +
diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts index 6a25d85bd..0aed41c66 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts @@ -12,6 +12,8 @@ import { NzSelectComponent } from "ng-zorro-antd/select"; import { Subject } from "rxjs"; import { AccessTokenService } from "@services/access-token.service"; import { PermissionsService } from "@services/permissions.service"; +import { generalResourceRNPattern, permissionActions } from "@shared/permissions"; +import { PolicyFilter } from "@features/safe/iam/types/policy"; @Component({ selector: 'access-token-drawer', @@ -49,6 +51,8 @@ export class AccessTokenDrawerComponent implements OnInit { policyDebouncer = new Subject(); + canTakeActionOnPersonalAccessToken = false; + canTakeActionOnServiceAccessToken = false; constructor( private fb: FormBuilder, private policyService: PolicyService, @@ -59,6 +63,9 @@ export class AccessTokenDrawerComponent implements OnInit { this.policyDebouncer.pipe( debounceTime(100), ).subscribe(query => this.searchPolicies(query)); + + this.canTakeActionOnPersonalAccessToken = this.permissionsService.canTakeAction(generalResourceRNPattern.account, permissionActions.CreatePersonalAccessTokens); + this.canTakeActionOnServiceAccessToken = this.permissionsService.canTakeAction(generalResourceRNPattern.account, permissionActions.CreateServiceAccessTokens); } isServiceAccessToken: boolean = false @@ -128,15 +135,34 @@ export class AccessTokenDrawerComponent implements OnInit { this.validatePoliciesControl(); } + isLoadingPolicies = false; searchPolicies(query: string = '') { - const regex = new RegExp(query,'ig') - this.policySearchResultList = this.permissionsService.policies - .filter((policy) => query === '' || policy.name.match(regex)) - .map((policy) => ({ - ...policy, - isSelected: this.selectedPolicyList.some((sp => sp.id === policy.id)) - }) - ); + const hasOwnerPolicy = this.permissionsService.policies.some((policy) => policy.name === 'Owner' && policy.type === 'SysManaged'); + + if (hasOwnerPolicy) { + this.isLoadingPolicies = true; + + this.policyService.getList(new PolicyFilter(query, 1, 50)).subscribe({ + next: policies => { + this.policySearchResultList = policies.items.map(p => ({ + ...p, + isSelected: this.selectedPolicyList.some((sp => sp.id === p.id)) + })); + + this.isLoadingPolicies = false; + }, error: () => this.isLoadingPolicies = false + }); + } else { + const regex = new RegExp(query,'ig'); + this.policySearchResultList = this.permissionsService.policies + .filter((policy) => query === '' || policy.name.match(regex)) + .map((policy) => ({ + ...policy, + isSelected: this.selectedPolicyList.some((sp => sp.id === policy.id)) + }) + ); + } + } nameAsyncValidator = (control: FormControl) => control.valueChanges.pipe( @@ -187,9 +213,14 @@ export class AccessTokenDrawerComponent implements OnInit { return; } - this.isLoading = true; const {name, type} = this.form.value; + if ((type === AccessTokenTypeEnum.Personal && !this.canTakeActionOnPersonalAccessToken) || (type === AccessTokenTypeEnum.Service && !this.canTakeActionOnServiceAccessToken)) { + this.message.warning($localize `:@@permissions.need-permissions-to-operate:You don't have permissions to take this action, please contact the admin to grant you the necessary permissions`); + return; + } + + this.isLoading = true; if (this.isEditing) { this.accessTokenService.update(this.accessToken.id, name).subscribe({ next: res => { diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html index 4f8711b58..f728ef06f 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html @@ -29,12 +29,12 @@ - - + +
- @@ -83,25 +83,27 @@ {{ item.lastUsedAt | date: 'YYYY-MM-dd HH:mm'}} - Edit + + Edit - - - Activate - + + + Activate + + + + + Deactivate + - - Deactivate + + Remove + - - - - Remove - diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts index de1a67260..c2fde6ca6 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts @@ -15,6 +15,8 @@ import { AccessTokenService } from "@services/access-token.service"; import { IOrganization } from "@shared/types"; import { CURRENT_ORGANIZATION } from "@utils/localstorage-keys"; import { TeamService } from "@services/team.service"; +import { PermissionsService } from "@services/permissions.service"; +import { generalResourceRNPattern, permissionActions } from "@shared/permissions"; @Component({ selector: 'access-tokens', @@ -26,10 +28,16 @@ export class IndexComponent implements OnInit { AccessTokenStatusActive = AccessTokenStatusEnum.Active; AccessTokenStatusInactive = AccessTokenStatusEnum.Inactive; + AccessTokenTypePersonal = AccessTokenTypeEnum.Personal; + AccessTokenTypeService = AccessTokenTypeEnum.Service; + + canTakeActionOnPersonalAccessToken = false; + canTakeActionOnServiceAccessToken = false; constructor( private router: Router, private message: NzMessageService, private teamService: TeamService, + private permissionsService: PermissionsService, private accessTokenService: AccessTokenService ) { const currentAccount: IOrganization = JSON.parse(localStorage.getItem(CURRENT_ORGANIZATION())); @@ -47,6 +55,9 @@ export class IndexComponent implements OnInit { } }); }); + + this.canTakeActionOnPersonalAccessToken = this.permissionsService.canTakeAction(generalResourceRNPattern.account, permissionActions.CreatePersonalAccessTokens); + this.canTakeActionOnServiceAccessToken = this.permissionsService.canTakeAction(generalResourceRNPattern.account, permissionActions.CreateServiceAccessTokens); } private search$ = new Subject(); diff --git a/modules/front-end/src/locale/messages.xlf b/modules/front-end/src/locale/messages.xlf index 300c95477..cfa59764d 100644 --- a/modules/front-end/src/locale/messages.xlf +++ b/modules/front-end/src/locale/messages.xlf @@ -278,22 +278,89 @@ 50 + + Loading... + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 68 + + + src/app/core/components/audit-logs/audit-logs.component.html + 26 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 36 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 66 + + + src/app/core/components/member-drawer/member-drawer.component.html + 38 + + + src/app/core/components/member-drawer/member-drawer.component.html + 55 + + + src/app/core/components/metric-drawer/metric-drawer.component.html + 43 + + + src/app/core/components/target-user/target-user.component.html + 44 + + + src/app/features/safe/end-users/index/index.component.html + 25 + + + src/app/features/safe/end-users/index/index.component.html + 60 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html + 138 + + + src/app/features/safe/feature-flags/details/insights/insights.component.html + 18 + + + src/app/features/safe/feature-flags/details/setting/setting.component.html + 136,137 + + + src/app/features/safe/feature-flags/index/index.component.html + 26 + + + src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html + 38 + + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 28 + + Policies are mandatory for service type access tokens src/app/core/components/access-token-drawer/access-token-drawer.component.html - 79 + 82 src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 219 + 250 Save src/app/core/components/access-token-drawer/access-token-drawer.component.html - 89 + 92 src/app/core/components/change-review/change-review.component.html @@ -368,15 +435,26 @@ 104 + + You don't have permissions to take this action, please contact the admin to grant you the necessary permissions + + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 219 + + + src/app/core/services/permissions.service.ts + 14 + + Operation succeeded src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 198 + 229 src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 213 + 244 src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts @@ -556,11 +634,11 @@ src/app/features/safe/integrations/access-tokens/index/index.component.ts - 134 + 145 src/app/features/safe/integrations/access-tokens/index/index.component.ts - 145 + 156 src/app/features/safe/segments/details/setting/setting.component.ts @@ -587,7 +665,7 @@ Operation failed, please try again src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 201 + 232 src/app/core/components/metric-drawer/metric-drawer.component.ts @@ -713,69 +791,6 @@ 20 - - Loading... - - src/app/core/components/audit-logs/audit-logs.component.html - 26 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 36 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 66 - - - src/app/core/components/member-drawer/member-drawer.component.html - 38 - - - src/app/core/components/member-drawer/member-drawer.component.html - 55 - - - src/app/core/components/metric-drawer/metric-drawer.component.html - 43 - - - src/app/core/components/target-user/target-user.component.html - 44 - - - src/app/features/safe/end-users/index/index.component.html - 25 - - - src/app/features/safe/end-users/index/index.component.html - 60 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 138 - - - src/app/features/safe/feature-flags/details/insights/insights.component.html - 18 - - - src/app/features/safe/feature-flags/details/setting/setting.component.html - 136,137 - - - src/app/features/safe/feature-flags/index/index.component.html - 26 - - - src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html - 38 - - - src/app/features/safe/integrations/access-tokens/index/index.component.html - 28 - - Filter by type @@ -1402,11 +1417,11 @@ src/app/features/safe/integrations/access-tokens/index/index.component.ts - 138 + 149 src/app/features/safe/integrations/access-tokens/index/index.component.ts - 148 + 159 src/app/features/safe/segments/details/targeting/targeting.component.ts @@ -2616,7 +2631,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 99 + 100 src/app/features/safe/organizations/project/project.component.html @@ -2703,7 +2718,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 103 + 104 src/app/features/safe/organizations/project/project.component.html @@ -3077,13 +3092,6 @@ 9 - - You don't have permissions to take this action, please contact the admin to grant you the necessary permissions - - src/app/core/services/permissions.service.ts - 14 - - Login @@ -3532,7 +3540,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 86 + 87 @@ -5636,14 +5644,14 @@ Activate src/app/features/safe/integrations/access-tokens/index/index.component.html - 90 + 91 Deactivate src/app/features/safe/integrations/access-tokens/index/index.component.html - 95 + 96 diff --git a/modules/front-end/src/locale/messages.zh.xlf b/modules/front-end/src/locale/messages.zh.xlf index 9f55d0634..6dc7844cf 100644 --- a/modules/front-end/src/locale/messages.zh.xlf +++ b/modules/front-end/src/locale/messages.zh.xlf @@ -285,15 +285,83 @@ 选择策略 + + Loading... + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 68 + + + src/app/core/components/audit-logs/audit-logs.component.html + 26 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 36 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 66 + + + src/app/core/components/member-drawer/member-drawer.component.html + 38 + + + src/app/core/components/member-drawer/member-drawer.component.html + 55 + + + src/app/core/components/metric-drawer/metric-drawer.component.html + 43 + + + src/app/core/components/target-user/target-user.component.html + 44 + + + src/app/features/safe/end-users/index/index.component.html + 25 + + + src/app/features/safe/end-users/index/index.component.html + 60 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html + 138 + + + src/app/features/safe/feature-flags/details/insights/insights.component.html + 18 + + + src/app/features/safe/feature-flags/details/setting/setting.component.html + 136,137 + + + src/app/features/safe/feature-flags/index/index.component.html + 26 + + + src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html + 38 + + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 28 + + 数据加载中... + Policies are mandatory for service type access tokens src/app/core/components/access-token-drawer/access-token-drawer.component.html - 79 + 82 src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 219 + 250 策略不能为空 @@ -301,7 +369,7 @@ Save src/app/core/components/access-token-drawer/access-token-drawer.component.html - 89 + 92 src/app/core/components/change-review/change-review.component.html @@ -377,15 +445,27 @@ 保存 + + You don't have permissions to take this action, please contact the admin to grant you the necessary permissions + + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 219 + + + src/app/core/services/permissions.service.ts + 14 + + 您未被授权进行该操作, 请联系账户管理员添加相关权限 + Operation succeeded src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 198 + 229 src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 213 + 244 src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts @@ -565,11 +645,11 @@ src/app/features/safe/integrations/access-tokens/index/index.component.ts - 134 + 145 src/app/features/safe/integrations/access-tokens/index/index.component.ts - 145 + 156 src/app/features/safe/segments/details/setting/setting.component.ts @@ -597,7 +677,7 @@ Operation failed, please try again src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 201 + 232 src/app/core/components/metric-drawer/metric-drawer.component.ts @@ -733,70 +813,6 @@ 按团队成员查找 - - Loading... - - src/app/core/components/audit-logs/audit-logs.component.html - 26 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 36 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 66 - - - src/app/core/components/member-drawer/member-drawer.component.html - 38 - - - src/app/core/components/member-drawer/member-drawer.component.html - 55 - - - src/app/core/components/metric-drawer/metric-drawer.component.html - 43 - - - src/app/core/components/target-user/target-user.component.html - 44 - - - src/app/features/safe/end-users/index/index.component.html - 25 - - - src/app/features/safe/end-users/index/index.component.html - 60 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 138 - - - src/app/features/safe/feature-flags/details/insights/insights.component.html - 18 - - - src/app/features/safe/feature-flags/details/setting/setting.component.html - 136,137 - - - src/app/features/safe/feature-flags/index/index.component.html - 26 - - - src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html - 38 - - - src/app/features/safe/integrations/access-tokens/index/index.component.html - 28 - - 数据加载中... - Filter by type @@ -1473,11 +1489,11 @@ src/app/features/safe/integrations/access-tokens/index/index.component.ts - 138 + 149 src/app/features/safe/integrations/access-tokens/index/index.component.ts - 148 + 159 src/app/features/safe/segments/details/targeting/targeting.component.ts @@ -2797,7 +2813,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 99 + 100 src/app/features/safe/organizations/project/project.component.html @@ -2885,7 +2901,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 103 + 104 src/app/features/safe/organizations/project/project.component.html @@ -3296,14 +3312,6 @@ 客户托管 - - You don't have permissions to take this action, please contact the admin to grant you the necessary permissions - - src/app/core/services/permissions.service.ts - 14 - - 您未被授权进行该操作, 请联系账户管理员添加相关权限 - Login @@ -3804,7 +3812,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 86 + 87 编辑 @@ -6164,7 +6172,7 @@ Activate src/app/features/safe/integrations/access-tokens/index/index.component.html - 90 + 91 激活 @@ -6172,7 +6180,7 @@ Deactivate src/app/features/safe/integrations/access-tokens/index/index.component.html - 95 + 96 停用 From 010fac9b0509ca377fbbd68ba56bf70808e06719 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Sun, 12 Mar 2023 03:41:38 +0100 Subject: [PATCH 15/44] in progress --- modules/front-end/src/app/core/guards/accessTokens.guard.ts | 1 + modules/front-end/src/app/core/guards/iam.guard.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/modules/front-end/src/app/core/guards/accessTokens.guard.ts b/modules/front-end/src/app/core/guards/accessTokens.guard.ts index 223754ed0..c11c0c1b6 100644 --- a/modules/front-end/src/app/core/guards/accessTokens.guard.ts +++ b/modules/front-end/src/app/core/guards/accessTokens.guard.ts @@ -26,6 +26,7 @@ export class AccessTokensGuard implements CanActivate { if (!canListAccessTokens) { this.message.warning(this.permissionsService.genericDenyMessage); + return this.router.parseUrl('/'); } return canListAccessTokens; diff --git a/modules/front-end/src/app/core/guards/iam.guard.ts b/modules/front-end/src/app/core/guards/iam.guard.ts index 715d36169..9539775fb 100644 --- a/modules/front-end/src/app/core/guards/iam.guard.ts +++ b/modules/front-end/src/app/core/guards/iam.guard.ts @@ -26,6 +26,7 @@ export class IAMGuard implements CanActivate { if (!canManageIAM) { this.message.warning(this.permissionsService.genericDenyMessage); + return this.router.parseUrl('/'); } return canManageIAM; From 7a04461605d528873aea5fbb6d6d883d853b9d62 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Sun, 12 Mar 2023 03:46:23 +0100 Subject: [PATCH 16/44] in progress --- .../access-token-drawer.component.ts | 8 ++++++++ modules/front-end/src/locale/messages.xlf | 10 +++++----- modules/front-end/src/locale/messages.zh.xlf | 10 +++++----- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts index 0aed41c66..e44577fc2 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts @@ -99,6 +99,12 @@ export class AccessTokenDrawerComponent implements OnInit { }); } + resetPolicy() { + this.form.patchValue({ + policy: {}, + }); + } + onClose() { this.reset(); this.close.emit(); @@ -111,6 +117,8 @@ export class AccessTokenDrawerComponent implements OnInit { onTypeChange() { const {type} = this.form.value; this.isServiceAccessToken = type === AccessTokenTypeEnum.Service; + this.selectedPolicyList = []; + this.resetPolicy(); } onPolicySelectChange() { diff --git a/modules/front-end/src/locale/messages.xlf b/modules/front-end/src/locale/messages.xlf index cfa59764d..034b5b882 100644 --- a/modules/front-end/src/locale/messages.xlf +++ b/modules/front-end/src/locale/messages.xlf @@ -353,7 +353,7 @@ src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 250 + 258 @@ -439,7 +439,7 @@ You don't have permissions to take this action, please contact the admin to grant you the necessary permissions src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 219 + 227 src/app/core/services/permissions.service.ts @@ -450,11 +450,11 @@ Operation succeeded src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 229 + 237 src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 244 + 252 src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts @@ -665,7 +665,7 @@ Operation failed, please try again src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 232 + 240 src/app/core/components/metric-drawer/metric-drawer.component.ts diff --git a/modules/front-end/src/locale/messages.zh.xlf b/modules/front-end/src/locale/messages.zh.xlf index 6dc7844cf..1e04534d9 100644 --- a/modules/front-end/src/locale/messages.zh.xlf +++ b/modules/front-end/src/locale/messages.zh.xlf @@ -361,7 +361,7 @@ src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 250 + 258 策略不能为空 @@ -449,7 +449,7 @@ You don't have permissions to take this action, please contact the admin to grant you the necessary permissions src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 219 + 227 src/app/core/services/permissions.service.ts @@ -461,11 +461,11 @@ Operation succeeded src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 229 + 237 src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 244 + 252 src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts @@ -677,7 +677,7 @@ Operation failed, please try again src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 232 + 240 src/app/core/components/metric-drawer/metric-drawer.component.ts From cf38cbc941c5acce738a2053c1d3b9438c6d95c3 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Sun, 12 Mar 2023 03:47:49 +0100 Subject: [PATCH 17/44] Update init.js --- infra/mongodb/docker-entrypoint-initdb.d/init.js | 1 + 1 file changed, 1 insertion(+) diff --git a/infra/mongodb/docker-entrypoint-initdb.d/init.js b/infra/mongodb/docker-entrypoint-initdb.d/init.js index 80089bf73..51008e60a 100644 --- a/infra/mongodb/docker-entrypoint-initdb.d/init.js +++ b/infra/mongodb/docker-entrypoint-initdb.d/init.js @@ -168,6 +168,7 @@ db.Policies.insertOne( resourceType: "general", effect: "allow", actions: [ + "CreateServiceAccessTokens", "CreatePersonalAccessTokens", "ListAccessTokens" ], From 484b06e18d0fa4775071a7c8d9cb454167ff58ca Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Sun, 12 Mar 2023 03:49:20 +0100 Subject: [PATCH 18/44] fix --- .../back-end/src/Api/Controllers/AccessTokenController.cs | 4 ++-- modules/back-end/src/Api/appsettings.json | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/back-end/src/Api/Controllers/AccessTokenController.cs b/modules/back-end/src/Api/Controllers/AccessTokenController.cs index b7146d98f..35104be3d 100644 --- a/modules/back-end/src/Api/Controllers/AccessTokenController.cs +++ b/modules/back-end/src/Api/Controllers/AccessTokenController.cs @@ -74,8 +74,8 @@ public async Task> UpdateAsync(Guid id, UpdateAccessT { request.Id = id; - var metricVm = await Mediator.Send(request); + var accessTokenVm = await Mediator.Send(request); - return Ok(metricVm); + return Ok(accessTokenVm); } } \ No newline at end of file diff --git a/modules/back-end/src/Api/appsettings.json b/modules/back-end/src/Api/appsettings.json index 38ba7e844..acb39b6c7 100644 --- a/modules/back-end/src/Api/appsettings.json +++ b/modules/back-end/src/Api/appsettings.json @@ -11,14 +11,14 @@ "Key": "featbit-identity-key" }, "MongoDb": { - "ConnectionString": "mongodb://admin:password@localhost:27017", + "ConnectionString": "mongodb://admin:password@mongodb:27017", "Database": "featbit" }, "Kafka": { - "BootstrapServers": "localhost:9092" + "BootstrapServers": "kafka:9092" }, "OLAP": { - "ServiceHost": "http://localhost" + "ServiceHost": "http://da-server" }, "AllowedHosts": "*" } From ab7906e8a10652f5d4aaf9022432efe1beb11330 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Sun, 12 Mar 2023 03:55:58 +0100 Subject: [PATCH 19/44] in progress --- modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs | 1 + .../back-end/src/Application/AccessTokens/DeleteAccessToken.cs | 2 +- .../src/Application/AccessTokens/ToggleAccessTokenStatus.cs | 2 +- modules/back-end/src/Application/Policies/MapperProfile.cs | 1 - 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs b/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs index f81633442..427add870 100644 --- a/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs +++ b/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs @@ -12,6 +12,7 @@ public class AccessTokenVm public string Type { get; set; } public string Status { get; set; } + public MemberVm Creator { get; set; } public IEnumerable Policies { get; set; } diff --git a/modules/back-end/src/Application/AccessTokens/DeleteAccessToken.cs b/modules/back-end/src/Application/AccessTokens/DeleteAccessToken.cs index 3d4a8f07b..808d27cb9 100644 --- a/modules/back-end/src/Application/AccessTokens/DeleteAccessToken.cs +++ b/modules/back-end/src/Application/AccessTokens/DeleteAccessToken.cs @@ -1,4 +1,4 @@ -namespace Application.Policies; +namespace Application.AccessTokens; public class DeleteAccessToken : IRequest { diff --git a/modules/back-end/src/Application/AccessTokens/ToggleAccessTokenStatus.cs b/modules/back-end/src/Application/AccessTokens/ToggleAccessTokenStatus.cs index db85cd5d8..1c135c909 100644 --- a/modules/back-end/src/Application/AccessTokens/ToggleAccessTokenStatus.cs +++ b/modules/back-end/src/Application/AccessTokens/ToggleAccessTokenStatus.cs @@ -1,7 +1,7 @@ using Application.Users; using Domain.AuditLogs; -namespace Application.FeatureFlags; +namespace Application.AccessTokens; public class ToggleAccessTokenStatus : IRequest { diff --git a/modules/back-end/src/Application/Policies/MapperProfile.cs b/modules/back-end/src/Application/Policies/MapperProfile.cs index 6febbe829..45e35bd19 100644 --- a/modules/back-end/src/Application/Policies/MapperProfile.cs +++ b/modules/back-end/src/Application/Policies/MapperProfile.cs @@ -8,7 +8,6 @@ public class MapperProfile : Profile public MapperProfile() { CreateMap(); - CreateMap, IEnumerable>(); CreateMap, PagedResult>(); } } \ No newline at end of file From a97f23c15fc029e084310b2631db98060a48b3e0 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Sun, 12 Mar 2023 11:15:38 +0100 Subject: [PATCH 20/44] in progress --- .../Application/AccessTokens/AccessTokenVm.cs | 2 +- .../AccessTokens/GetAccessTokenList.cs | 1 + .../src/Domain/AccessTokens/AccessToken.cs | 21 +- .../access-token-drawer.component.html | 30 ++ .../access-token-drawer.component.less | 19 ++ .../access-token-drawer.component.ts | 21 +- .../change-review.component.less | 4 +- .../expt-rules-drawer.component.less | 4 +- .../flag-triggers.component.html | 4 +- .../flag-triggers.component.less | 10 +- .../flag-triggers/flag-triggers.component.ts | 7 + .../experimentation.component.html | 4 +- .../experimentation.component.less | 2 +- .../details/setting/setting.component.less | 4 +- .../feature-flags/index/index.component.less | 2 +- .../access-tokens/index/index.component.html | 59 ++-- .../access-tokens/index/index.component.ts | 4 +- .../access-tokens/types/access-token.ts | 1 + .../safe/segments/index/index.component.less | 4 +- modules/front-end/src/locale/messages.xlf | 265 ++++++++++------- modules/front-end/src/locale/messages.zh.xlf | 272 ++++++++++-------- modules/front-end/src/styles-common.less | 8 + modules/front-end/src/variables.less | 1 + 23 files changed, 480 insertions(+), 269 deletions(-) diff --git a/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs b/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs index 427add870..e4660e40f 100644 --- a/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs +++ b/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs @@ -12,7 +12,7 @@ public class AccessTokenVm public string Type { get; set; } public string Status { get; set; } - + public string Token { get; set; } public MemberVm Creator { get; set; } public IEnumerable Policies { get; set; } diff --git a/modules/back-end/src/Application/AccessTokens/GetAccessTokenList.cs b/modules/back-end/src/Application/AccessTokens/GetAccessTokenList.cs index 2d43e64ef..6c815fe88 100644 --- a/modules/back-end/src/Application/AccessTokens/GetAccessTokenList.cs +++ b/modules/back-end/src/Application/AccessTokens/GetAccessTokenList.cs @@ -33,6 +33,7 @@ public async Task> Handle(GetAccessTokenList request, { var accessTokenVm = accessTokenVms.Items.First(x => x.Id == accessTokenItem.Id); accessTokenVm.Creator = _mapper.Map(creators.First(x => x.Id == accessTokenItem.CreatorId)); + accessTokenVm.Token = accessTokenVm.Token[..15] + "**************"; } return accessTokenVms; diff --git a/modules/back-end/src/Domain/AccessTokens/AccessToken.cs b/modules/back-end/src/Domain/AccessTokens/AccessToken.cs index d1c03f8f4..4b9a5b9f8 100644 --- a/modules/back-end/src/Domain/AccessTokens/AccessToken.cs +++ b/modules/back-end/src/Domain/AccessTokens/AccessToken.cs @@ -1,3 +1,4 @@ +using System.Text; using Domain.Policies; namespace Domain.AccessTokens; @@ -10,13 +11,29 @@ public class AccessToken : AuditedEntity public string Type { get; set; } public string Status { get; set; } - + public string Token { get; set; } public Guid CreatorId { get; set; } public ICollection Policies { get; set; } public DateTime? LastUsedAt { get; set; } + private string NewToken() + { + // timestamp in millis, length is 13 + var reversedTimestamp = + new string(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString().Reverse().ToArray()); + + // header length is (13 + 2) * 4/3 = 20, we trim '=' character, so got 18 chars + var header = Convert.ToBase64String(Encoding.UTF8.GetBytes(reversedTimestamp)).TrimEnd('='); + + // 22 chars + var guid = GuidHelper.Encode(Guid.NewGuid()); + + // 4 + 18 + 22 = 44 chars + return $"api-{header}{guid}"; + } + public AccessToken(Guid organizationId, Guid creatorId, string name, string type, IEnumerable policies) { OrganizationId = organizationId; @@ -26,6 +43,8 @@ public AccessToken(Guid organizationId, Guid creatorId, string name, string type Status = AccessTokenStatus.Active; Type = type; Policies = policies.ToArray(); + + Token = NewToken(); } public void RefreshLastUsedAt() diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html index 55b6a9e46..2a2403bdc 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html @@ -94,3 +94,33 @@ + + +
+ + +
+
{{tokenName}}:
+
+ {{tokenValue}} + +
+
+
+
+ + + +
+ diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less index 75b92cc95..ea11d5fcc 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less @@ -4,6 +4,25 @@ color: @red60-color; } +#confirm-modal-ok { + color: @white; + + &:hover, &:focus { + color: @white; + border-color: #61d4aa; + background: #61d4aa; + } +} + +.token-wrapper { + margin: 32px 0; + display: flex; + justify-content: center; + align-items: center; + gap: 8px; + font-size: 15px; +} + .selected-policies { border: 1px solid @grey20-color; background-color: #ffffff; diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts index e44577fc2..4eeecc425 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts @@ -14,6 +14,9 @@ import { AccessTokenService } from "@services/access-token.service"; import { PermissionsService } from "@services/permissions.service"; import { generalResourceRNPattern, permissionActions } from "@shared/permissions"; import { PolicyFilter } from "@features/safe/iam/types/policy"; +import { IFeatureFlag } from "@features/safe/feature-flags/types/details"; +import { NzModalService } from "ng-zorro-antd/modal"; +import { copyToClipboard } from "@utils/index"; @Component({ selector: 'access-token-drawer', @@ -58,6 +61,7 @@ export class AccessTokenDrawerComponent implements OnInit { private policyService: PolicyService, private permissionsService: PermissionsService, private accessTokenService: AccessTokenService, + private modal: NzModalService, private message: NzMessageService ) { this.policyDebouncer.pipe( @@ -205,6 +209,9 @@ export class AccessTokenDrawerComponent implements OnInit { } } + tokenName = ''; + tokenValue = ''; + isCreationConfirmModalVisible = false; doSubmit() { // we validate name and type only here if (this.form.invalid) { @@ -227,13 +234,12 @@ export class AccessTokenDrawerComponent implements OnInit { this.message.warning($localize `:@@permissions.need-permissions-to-operate:You don't have permissions to take this action, please contact the admin to grant you the necessary permissions`); return; } - this.isLoading = true; if (this.isEditing) { this.accessTokenService.update(this.accessToken.id, name).subscribe({ next: res => { this.isLoading = false; - this.close.emit({ isEditing: true, id: this.accessToken.id, name: name}); + this.close.emit({ isEditing: true, id: this.accessToken.id, name: name }); this.message.success($localize`:@@common.operation-success:Operation succeeded`); }, error: _ => { @@ -246,11 +252,14 @@ export class AccessTokenDrawerComponent implements OnInit { const policies = this.isServiceAccessToken ? this.selectedPolicyList.map(p => p.id) : []; this.accessTokenService.create(name, type, policies).subscribe({ - next: () => { + next: ({id, name, token}) => { this.isLoading = false; this.close.emit({ isEditing: false }); this.message.success($localize`:@@common.operation-success:Operation succeeded`); this.reset(); + this.tokenName = name; + this.tokenValue = token; + this.isCreationConfirmModalVisible = true; }, error: (e) => { this.isLoading = false; @@ -263,6 +272,12 @@ export class AccessTokenDrawerComponent implements OnInit { } } + copyText(event, text: string) { + copyToClipboard(text).then( + () => this.message.success($localize `:@@common.copy-success:Copied`) + ); + } + actionTokenTypes = [ AccessTokenTypeEnum.Personal, AccessTokenTypeEnum.Service diff --git a/modules/front-end/src/app/core/components/change-review/change-review.component.less b/modules/front-end/src/app/core/components/change-review/change-review.component.less index 96efddd29..1e41b1728 100644 --- a/modules/front-end/src/app/core/components/change-review/change-review.component.less +++ b/modules/front-end/src/app/core/components/change-review/change-review.component.less @@ -28,14 +28,14 @@ padding: 10px; border: 1px solid #d2d2d2; margin: 12px 0; - border-left: 3px solid #ff912b; + border-left: 3px solid @yellow5-color; border-radius: 10px; .warning { display: flex; .warning-icon { - color: #ff912b; + color: @yellow5-color; } .warning-content { diff --git a/modules/front-end/src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.less b/modules/front-end/src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.less index 9962bfc4e..a895ccfa8 100644 --- a/modules/front-end/src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.less +++ b/modules/front-end/src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.less @@ -9,14 +9,14 @@ padding: 10px; border: 1px solid #d2d2d2; margin-bottom: 15px; - border-left: 3px solid #ff912b; + border-left: 3px solid @yellow5-color; border-radius: 10px; .warning { display: flex; .warning-icon { - color: #ff912b; + color: @yellow5-color; } .warning-content { padding-left: 5px; diff --git a/modules/front-end/src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.html b/modules/front-end/src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.html index ff356544f..9a9278b3f 100644 --- a/modules/front-end/src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.html +++ b/modules/front-end/src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.html @@ -38,8 +38,8 @@
{{trigger.description}}
- {{getTriggerUrl(trigger.token)}} - {{getTriggerUrl(trigger.token)}} + {{getTriggerUrl(trigger.token)}} +
diff --git a/modules/front-end/src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.less b/modules/front-end/src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.less index f07696382..b02d4d7b5 100644 --- a/modules/front-end/src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.less +++ b/modules/front-end/src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.less @@ -179,6 +179,14 @@ .trigger-url{ color: rgba(0, 0, 0, 0.85); + + .copy-icon { + font-size: 13px; + + &:hover { + color: @green60-color; + } + } } .warning { @@ -188,7 +196,7 @@ margin-top: 5px; .warning-icon { - color: #ff912b; + color: @yellow5-color; } } } diff --git a/modules/front-end/src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts b/modules/front-end/src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts index 2a317179a..7d883c90e 100644 --- a/modules/front-end/src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts +++ b/modules/front-end/src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts @@ -4,6 +4,7 @@ import { FlagTriggerService } from '@services/flag-trigger.service'; import { FlagTriggerActionEnum, FlagTriggerTypeEnum, IFlagTrigger } from '../../types/flag-triggers'; import {IFeatureFlag} from "@features/safe/feature-flags/types/details"; import {FeatureFlagService} from "@services/feature-flag.service"; +import { copyToClipboard } from "@utils/index"; @Component({ selector: 'flag-triggers', @@ -104,6 +105,12 @@ export class FlagTriggersComponent implements OnInit { return this.flagTriggerService.getTriggerUrl(token); } + copyText(event, text: string) { + copyToClipboard(text).then( + () => this.message.success($localize `:@@common.copy-success:Copied`) + ); + } + flagTriggerTypeLabel = { [FlagTriggerTypeEnum.FeatureFlagGeneral]: 'General' } diff --git a/modules/front-end/src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html b/modules/front-end/src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html index a60f984e2..225e0a0ea 100644 --- a/modules/front-end/src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html +++ b/modules/front-end/src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html @@ -58,7 +58,7 @@

Refresh

- +
    @@ -68,7 +68,6 @@

    nzPopconfirmTitle="This would remove all data of this experiment, it cannot be reverted, are you sure to remove it?" nzPopconfirmPlacement="bottomRight" [nzPopconfirmOverlayStyle]="{minWidth: '240px'}" - style="width: 100%;display: flex;justify-content: center;" (nzOnConfirm)="onDeleteExptDataClick(experiment)"> Remove data @@ -78,7 +77,6 @@

    nzPopconfirmTitle="This would remove the experiment and all data, it cannot be reverted, are you sure to remove it?" nzPopconfirmPlacement="bottomRight" [nzPopconfirmOverlayStyle]="{minWidth: '240px'}" - style="width: 100%;display: flex;justify-content: center;" (nzOnConfirm)="onDeleteExptClick(experiment)"> Remove experiment diff --git a/modules/front-end/src/app/features/safe/feature-flags/details/experimentation/experimentation.component.less b/modules/front-end/src/app/features/safe/feature-flags/details/experimentation/experimentation.component.less index 5bf414121..83d81a4fe 100644 --- a/modules/front-end/src/app/features/safe/feature-flags/details/experimentation/experimentation.component.less +++ b/modules/front-end/src/app/features/safe/feature-flags/details/experimentation/experimentation.component.less @@ -111,7 +111,7 @@ display: flex; .warning-icon { - color: #ff912b; + color: @yellow5-color; } .warning-content { padding-left: 5px; diff --git a/modules/front-end/src/app/features/safe/feature-flags/details/setting/setting.component.less b/modules/front-end/src/app/features/safe/feature-flags/details/setting/setting.component.less index 49042c946..e7996626d 100644 --- a/modules/front-end/src/app/features/safe/feature-flags/details/setting/setting.component.less +++ b/modules/front-end/src/app/features/safe/feature-flags/details/setting/setting.component.less @@ -362,14 +362,14 @@ font-weight: 500; padding: 10px; border: 1px solid #d2d2d2; - border-left: 3px solid #ff912b; + border-left: 3px solid @yellow5-color; border-radius: 10px; .warning { display: flex; .warning-icon { - color: #ff912b; + color: @yellow5-color; } .warning-content { padding-left: 5px; diff --git a/modules/front-end/src/app/features/safe/feature-flags/index/index.component.less b/modules/front-end/src/app/features/safe/feature-flags/index/index.component.less index 8d595eae6..92ee3c71d 100644 --- a/modules/front-end/src/app/features/safe/feature-flags/index/index.component.less +++ b/modules/front-end/src/app/features/safe/feature-flags/index/index.component.less @@ -35,7 +35,7 @@ section.body-container { } .copy-icon { - margin-right: 4px; + margin-left: 0px; &:hover { cursor: pointer; diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html index f728ef06f..ba877cbee 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html @@ -56,9 +56,10 @@ Name Type - Creator + Created by Status Last used + Access token Actions @@ -82,33 +83,47 @@ {{ item.status | accessTokenStatus }} {{ item.lastUsedAt | date: 'YYYY-MM-dd HH:mm'}} - + {{ item.token }} + - Edit - - - - Activate - - - - - Deactivate - - - - - Remove - + + +
      +
    • + Edit +
    • +
    • + Activate +
    • +
    • + Deactivate +
    • +
    • + Remove +
    • +
    +
    - +

diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts index c2fde6ca6..2ee9a321e 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts @@ -1,11 +1,8 @@ import { Component, OnInit } from '@angular/core'; -import { copyToClipboard, encodeURIComponentFfc } from '@utils/index'; import { BehaviorSubject, Subject } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import { Router } from "@angular/router"; import { NzMessageService } from "ng-zorro-antd/message"; -import { IPagedPolicy, IPolicy, PolicyFilter, policyRn } from "@features/safe/iam/types/policy"; -import { PolicyService } from "@services/policy.service"; import { AccessTokenFilter, AccessTokenStatusEnum, AccessTokenTypeEnum, IAccessToken, @@ -94,6 +91,7 @@ export class IndexComponent implements OnInit { this.accessTokenService.getList(this.filter).subscribe({ next: (accessTokens) => { this.accessTokens = accessTokens; + this.isLoading = false; }, error:() => this.isLoading = false diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts index bf1e89c7a..bcfba7446 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts @@ -6,6 +6,7 @@ export interface IAccessToken { type: string; creator?: IMember; status?: string; + token?: string; name: string; policies?: IPolicy[], lastUsedAt?: string diff --git a/modules/front-end/src/app/features/safe/segments/index/index.component.less b/modules/front-end/src/app/features/safe/segments/index/index.component.less index 9009d83cc..263f71898 100644 --- a/modules/front-end/src/app/features/safe/segments/index/index.component.less +++ b/modules/front-end/src/app/features/safe/segments/index/index.component.less @@ -12,14 +12,14 @@ section.body-container { padding: 10px; border: 1px solid #d2d2d2; margin: 15px 0; - border-left: 3px solid #ff912b; + border-left: 3px solid @yellow5-color; border-radius: 10px; .warning { display: flex; .warning-icon { - color: #ff912b; + color: @yellow5-color; } .warning-content { diff --git a/modules/front-end/src/locale/messages.xlf b/modules/front-end/src/locale/messages.xlf index 034b5b882..a37a40ac2 100644 --- a/modules/front-end/src/locale/messages.xlf +++ b/modules/front-end/src/locale/messages.xlf @@ -322,7 +322,7 @@ src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 138 + 136 src/app/features/safe/feature-flags/details/insights/insights.component.html @@ -353,7 +353,7 @@ src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 258 + 267 @@ -435,11 +435,32 @@ 104 + + Access token created + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 100 + + + + Copy and save this token now, the token value will be masked once you leave the page. + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 108 + + + + OK + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 123 + + You don't have permissions to take this action, please contact the admin to grant you the necessary permissions src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 227 + 234 src/app/core/services/permissions.service.ts @@ -450,11 +471,11 @@ Operation succeeded src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 237 + 243 src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 252 + 258 src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts @@ -498,19 +519,19 @@ src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 59 + 60 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 77 + 78 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 86 + 87 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 97 + 98 src/app/features/safe/feature-flags/details/setting/setting.component.ts @@ -634,11 +655,11 @@ src/app/features/safe/integrations/access-tokens/index/index.component.ts - 145 + 143 src/app/features/safe/integrations/access-tokens/index/index.component.ts - 156 + 154 src/app/features/safe/segments/details/setting/setting.component.ts @@ -665,7 +686,7 @@ Operation failed, please try again src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 240 + 246 src/app/core/components/metric-drawer/metric-drawer.component.ts @@ -728,6 +749,69 @@ 79 + + Copied + + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 277 + + + src/app/core/components/header/header.component.ts + 151 + + + src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.ts + 60 + + + src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts + 110 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 42 + + + src/app/features/safe/feature-flags/index/index.component.ts + 204 + + + src/app/features/safe/feature-flags/index/index.component.ts + 373 + + + src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts + 140 + + + src/app/features/safe/iam/groups/details/setting/setting.component.ts + 80 + + + src/app/features/safe/iam/groups/index/index.component.ts + 78 + + + src/app/features/safe/iam/policies/details/setting/setting.component.ts + 80 + + + src/app/features/safe/iam/policies/index/index.component.ts + 88 + + + src/app/features/safe/iam/team/details/setting/setting.component.ts + 58 + + + src/app/features/safe/iam/team/index/index.component.ts + 92 + + + src/app/features/safe/organizations/project/project.component.ts + 181 + + created @@ -958,7 +1042,7 @@ src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 160 + 158 @@ -1150,23 +1234,23 @@ src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 36 + 37 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 64 + 65 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 79 + 80 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 88 + 89 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 99 + 100 @@ -1417,11 +1501,11 @@ src/app/features/safe/integrations/access-tokens/index/index.component.ts - 149 + 147 src/app/features/safe/integrations/access-tokens/index/index.component.ts - 159 + 157 src/app/features/safe/segments/details/targeting/targeting.component.ts @@ -1950,61 +2034,6 @@ 53 - - Copied - - src/app/core/components/header/header.component.ts - 151 - - - src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.ts - 60 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 42 - - - src/app/features/safe/feature-flags/index/index.component.ts - 204 - - - src/app/features/safe/feature-flags/index/index.component.ts - 373 - - - src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 140 - - - src/app/features/safe/iam/groups/details/setting/setting.component.ts - 80 - - - src/app/features/safe/iam/groups/index/index.component.ts - 78 - - - src/app/features/safe/iam/policies/details/setting/setting.component.ts - 80 - - - src/app/features/safe/iam/policies/index/index.component.ts - 88 - - - src/app/features/safe/iam/team/details/setting/setting.component.ts - 58 - - - src/app/features/safe/iam/team/index/index.component.ts - 92 - - - src/app/features/safe/organizations/project/project.component.ts - 181 - - Add team member @@ -2182,7 +2211,7 @@ src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 153 + 151 src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts @@ -2550,7 +2579,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 62 + 63 src/app/features/safe/segments/index/index.component.html @@ -2629,10 +2658,6 @@ src/app/features/safe/iam/team/index/index.component.html 68 - - src/app/features/safe/integrations/access-tokens/index/index.component.html - 100 - src/app/features/safe/organizations/project/project.component.html 72 @@ -2718,7 +2743,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 104 + 118 src/app/features/safe/organizations/project/project.component.html @@ -2943,7 +2968,7 @@ src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 150 + 148 src/app/features/safe/feature-flags/details/insights/insights.component.html @@ -3540,7 +3565,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 87 + 94 @@ -3918,91 +3943,91 @@ Remove data src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 73 + 72 This would remove the experiment and all data, it cannot be reverted, are you sure to remove it? src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 78 + 77 Remove experiment src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 83 + 81 Restart src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 96 + 94 Pause src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 100 + 98 Period src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 105 + 103 Need more data to confirm the results of the experiment src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 119 + 117 The difference is not significant compared to the baseline src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 123 + 121 Winner src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 127 + 125 Start src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 135 + 133 Conversion / Users src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 152 + 150 Total events src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 156 + 154 Average src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 157 + 155 src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts @@ -4017,67 +4042,67 @@ Confidence interval src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 159 + 157 P-Value src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 162 + 160 The result is significant if P value is less than α(0.05) src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 166 + 164 Data is not available yet src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 179 + 177 Baseline src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 187 + 185 src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 217 + 215 Winner src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 195 + 193 It's not significant compared to baseline src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 198 + 196 Hide chart src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 273 + 271 Show chart src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 274 + 272 @@ -5626,8 +5651,8 @@ 31 - - Creator + + Created by src/app/features/safe/integrations/access-tokens/index/index.component.html 59 @@ -5640,18 +5665,36 @@ 61 + + Access token + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 62 + + Activate src/app/features/safe/integrations/access-tokens/index/index.component.html - 91 + 97 + + + + Deactivate this access token? You can't use an inactive access token to make API calls but you can activate it again later. + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 102 + + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 113 Deactivate src/app/features/safe/integrations/access-tokens/index/index.component.html - 96 + 107 diff --git a/modules/front-end/src/locale/messages.zh.xlf b/modules/front-end/src/locale/messages.zh.xlf index 1e04534d9..b1d6263a3 100644 --- a/modules/front-end/src/locale/messages.zh.xlf +++ b/modules/front-end/src/locale/messages.zh.xlf @@ -329,7 +329,7 @@ src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 138 + 136 src/app/features/safe/feature-flags/details/insights/insights.component.html @@ -361,7 +361,7 @@ src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 258 + 267 策略不能为空 @@ -445,11 +445,35 @@ 保存 + + Access token created + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 100 + + 成功创建访问秘钥 + + + Copy and save this token now, the token value will be masked once you leave the page. + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 108 + + 请复制并保存 Token,一旦离开该页面后,该 Token 将会被隐藏。 + + + OK + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 123 + + OK + You don't have permissions to take this action, please contact the admin to grant you the necessary permissions src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 227 + 234 src/app/core/services/permissions.service.ts @@ -461,11 +485,11 @@ Operation succeeded src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 237 + 243 src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 252 + 258 src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts @@ -509,19 +533,19 @@ src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 59 + 60 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 77 + 78 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 86 + 87 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 97 + 98 src/app/features/safe/feature-flags/details/setting/setting.component.ts @@ -645,11 +669,11 @@ src/app/features/safe/integrations/access-tokens/index/index.component.ts - 145 + 143 src/app/features/safe/integrations/access-tokens/index/index.component.ts - 156 + 154 src/app/features/safe/segments/details/setting/setting.component.ts @@ -677,7 +701,7 @@ Operation failed, please try again src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 240 + 246 src/app/core/components/metric-drawer/metric-drawer.component.ts @@ -741,6 +765,70 @@ 操作失败,请重试 + + Copied + + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 277 + + + src/app/core/components/header/header.component.ts + 151 + + + src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.ts + 60 + + + src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts + 110 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 42 + + + src/app/features/safe/feature-flags/index/index.component.ts + 204 + + + src/app/features/safe/feature-flags/index/index.component.ts + 373 + + + src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts + 140 + + + src/app/features/safe/iam/groups/details/setting/setting.component.ts + 80 + + + src/app/features/safe/iam/groups/index/index.component.ts + 78 + + + src/app/features/safe/iam/policies/details/setting/setting.component.ts + 80 + + + src/app/features/safe/iam/policies/index/index.component.ts + 88 + + + src/app/features/safe/iam/team/details/setting/setting.component.ts + 58 + + + src/app/features/safe/iam/team/index/index.component.ts + 92 + + + src/app/features/safe/organizations/project/project.component.ts + 181 + + 复制成功 + created @@ -1001,7 +1089,7 @@ src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 160 + 158 变化 @@ -1209,23 +1297,23 @@ src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 36 + 37 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 64 + 65 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 79 + 80 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 88 + 89 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 99 + 100 发生错误,请重试 @@ -1489,11 +1577,11 @@ src/app/features/safe/integrations/access-tokens/index/index.component.ts - 149 + 147 src/app/features/safe/integrations/access-tokens/index/index.component.ts - 159 + 157 src/app/features/safe/segments/details/targeting/targeting.component.ts @@ -2081,62 +2169,6 @@ 您没有查看项目环境列表的权限, 请联系账户管理员添加相关权限 - - Copied - - src/app/core/components/header/header.component.ts - 151 - - - src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.ts - 60 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 42 - - - src/app/features/safe/feature-flags/index/index.component.ts - 204 - - - src/app/features/safe/feature-flags/index/index.component.ts - 373 - - - src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 140 - - - src/app/features/safe/iam/groups/details/setting/setting.component.ts - 80 - - - src/app/features/safe/iam/groups/index/index.component.ts - 78 - - - src/app/features/safe/iam/policies/details/setting/setting.component.ts - 80 - - - src/app/features/safe/iam/policies/index/index.component.ts - 88 - - - src/app/features/safe/iam/team/details/setting/setting.component.ts - 58 - - - src/app/features/safe/iam/team/index/index.component.ts - 92 - - - src/app/features/safe/organizations/project/project.component.ts - 181 - - 复制成功 - Add team member @@ -2333,7 +2365,7 @@ src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 153 + 151 src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts @@ -2729,7 +2761,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 62 + 63 src/app/features/safe/segments/index/index.component.html @@ -2811,10 +2843,6 @@ src/app/features/safe/iam/team/index/index.component.html 68 - - src/app/features/safe/integrations/access-tokens/index/index.component.html - 100 - src/app/features/safe/organizations/project/project.component.html 72 @@ -2901,7 +2929,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 104 + 118 src/app/features/safe/organizations/project/project.component.html @@ -3152,7 +3180,7 @@ src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 150 + 148 src/app/features/safe/feature-flags/details/insights/insights.component.html @@ -3812,7 +3840,7 @@ src/app/features/safe/integrations/access-tokens/index/index.component.html - 87 + 94 编辑 @@ -4233,7 +4261,7 @@ Remove data src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 73 + 72 删除数据 @@ -4241,7 +4269,7 @@ This would remove the experiment and all data, it cannot be reverted, are you sure to remove it? src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 78 + 77 确定删除吗? 将会删除该实验及其相关数据,删除后不可恢复。 @@ -4249,7 +4277,7 @@ Remove experiment src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 83 + 81 删除实验 @@ -4257,7 +4285,7 @@ Restart src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 96 + 94 重新开始 @@ -4265,7 +4293,7 @@ Pause src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 100 + 98 暂停 @@ -4273,7 +4301,7 @@ Period src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 105 + 103 时间区间 @@ -4281,7 +4309,7 @@ Need more data to confirm the results of the experiment src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 119 + 117 需要更多的实验数据才能在统计学上确认表格中的结论 @@ -4289,7 +4317,7 @@ The difference is not significant compared to the baseline src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 123 + 121 该特性相对于基准特性,统计学上差异效果不显著 @@ -4297,7 +4325,7 @@ Winner src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 127 + 125 胜出 @@ -4305,7 +4333,7 @@ Start src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 135 + 133 开始实验 @@ -4313,7 +4341,7 @@ Conversion / Users src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 152 + 150 转化数 / 用户数 @@ -4321,7 +4349,7 @@ Total events src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 156 + 154 总事件数 @@ -4329,7 +4357,7 @@ Average src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 157 + 155 src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts @@ -4345,7 +4373,7 @@ Confidence interval src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 159 + 157 置信区间 @@ -4353,7 +4381,7 @@ P-Value src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 162 + 160 P-值 @@ -4361,7 +4389,7 @@ The result is significant if P value is less than α(0.05) src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 166 + 164 P值小于α(0.05)表示实验结果显著 @@ -4369,7 +4397,7 @@ Data is not available yet src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 179 + 177 暂时没有实验数据 @@ -4377,11 +4405,11 @@ Baseline src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 187 + 185 src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 217 + 215 基准特性 @@ -4389,7 +4417,7 @@ Winner src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 195 + 193 胜出 @@ -4397,7 +4425,7 @@ It's not significant compared to baseline src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 198 + 196 该特性相对于基准特性,统计学上差异效果不显著 @@ -4405,7 +4433,7 @@ Hide chart src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 273 + 271 收起图表 @@ -4413,7 +4441,7 @@ Show chart src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 274 + 272 查看图表 @@ -6152,8 +6180,8 @@ 按类型查找 - - Creator + + Created by src/app/features/safe/integrations/access-tokens/index/index.component.html 59 @@ -6168,19 +6196,39 @@ 上一次使用 + + Access token + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 62 + + 访问秘钥 + Activate src/app/features/safe/integrations/access-tokens/index/index.component.html - 91 + 97 激活 + + Deactivate this access token? You can't use an inactive access token to make API calls but you can activate it again later. + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 102 + + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 113 + + 停用访问密钥?您不能使用非活动密钥来进行 API 调用,但您可以在以后重新将其激活。 + Deactivate src/app/features/safe/integrations/access-tokens/index/index.component.html - 96 + 107 停用 diff --git a/modules/front-end/src/styles-common.less b/modules/front-end/src/styles-common.less index ba551c4c2..ce6ed3641 100644 --- a/modules/front-end/src/styles-common.less +++ b/modules/front-end/src/styles-common.less @@ -1098,3 +1098,11 @@ app-root { border-radius: 30px; } } + +.copy-icon { + cursor: pointer; + margin: 0 4px; + &:hover { + color: @green60-color; + } +} diff --git a/modules/front-end/src/variables.less b/modules/front-end/src/variables.less index 36529c079..c3057f029 100644 --- a/modules/front-end/src/variables.less +++ b/modules/front-end/src/variables.less @@ -31,6 +31,7 @@ @red50-color: #FF513A; @red60-color: #ff4d4f; +@yellow5-color: #ff912b; @yellow10-color: #FFF9CF; @yellow55-color: #faad14; From ea917971282686eab9c2fc5c8da0d6ffa2635bf8 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Mon, 13 Mar 2023 11:25:44 +0100 Subject: [PATCH 21/44] refactor --- .../docker-entrypoint-initdb.d/init.js | 8 +- .../project-drawer.component.ts | 2 +- .../app/core/services/permissions.service.ts | 2 +- .../src/app/core/services/resource.service.ts | 2 +- .../actions-selector.component.ts | 2 +- .../policy-editor/policy-editor.component.ts | 2 +- .../resources-selector.component.ts | 3 +- .../project/project.component.ts | 2 +- .../types.ts => shared/policy.ts} | 130 +++++++++++++----- 9 files changed, 106 insertions(+), 47 deletions(-) rename modules/front-end/src/app/{features/safe/iam/components/policy-editor/types.ts => shared/policy.ts} (62%) diff --git a/infra/mongodb/docker-entrypoint-initdb.d/init.js b/infra/mongodb/docker-entrypoint-initdb.d/init.js index 51008e60a..7cfc935d1 100644 --- a/infra/mongodb/docker-entrypoint-initdb.d/init.js +++ b/infra/mongodb/docker-entrypoint-initdb.d/init.js @@ -101,18 +101,12 @@ db.Policies.insertOne( actions: ["CanManageIAM"], resources: ["iam"] }, - { - _id: getUUIDString(), - resourceType: "general", - effect: "allow", - actions: ["UpdateOrgName"], - resources: ["account"] - }, { _id: getUUIDString(), resourceType: "general", effect: "allow", actions: [ + "UpdateOrgName", "CreateServiceAccessTokens", "CreatePersonalAccessTokens", "ListAccessTokens" diff --git a/modules/front-end/src/app/core/components/project-drawer/project-drawer.component.ts b/modules/front-end/src/app/core/components/project-drawer/project-drawer.component.ts index b52620841..8ff69d746 100644 --- a/modules/front-end/src/app/core/components/project-drawer/project-drawer.component.ts +++ b/modules/front-end/src/app/core/components/project-drawer/project-drawer.component.ts @@ -5,7 +5,7 @@ import {IProject} from '@shared/types'; import {ProjectService} from '@services/project.service'; import {PermissionsService} from "@services/permissions.service"; import {generalResourceRNPattern, permissionActions} from "@shared/permissions"; -import {ResourceTypeEnum} from "@features/safe/iam/components/policy-editor/types"; +import {ResourceTypeEnum} from "@shared/policy"; @Component({ selector: 'app-project-drawer', diff --git a/modules/front-end/src/app/core/services/permissions.service.ts b/modules/front-end/src/app/core/services/permissions.service.ts index 80720cd8e..3bd86ee47 100644 --- a/modules/front-end/src/app/core/services/permissions.service.ts +++ b/modules/front-end/src/app/core/services/permissions.service.ts @@ -2,7 +2,7 @@ import {Injectable} from "@angular/core"; import {lastValueFrom} from "rxjs"; import {IPolicy, IPolicyStatement} from "@features/safe/iam/types/policy"; import {MemberService} from "@services/member.service"; -import {EffectEnum, ResourceTypeEnum} from "@features/safe/iam/components/policy-editor/types"; +import {EffectEnum, ResourceTypeEnum} from "@shared/policy"; @Injectable({ providedIn: 'root' diff --git a/modules/front-end/src/app/core/services/resource.service.ts b/modules/front-end/src/app/core/services/resource.service.ts index c3ecf6a5c..d055d81a0 100644 --- a/modules/front-end/src/app/core/services/resource.service.ts +++ b/modules/front-end/src/app/core/services/resource.service.ts @@ -1,7 +1,7 @@ import { HttpClient } from "@angular/common/http"; import { getCurrentOrganization } from "@utils/project-env"; import { environment } from "src/environments/environment"; -import { Resource, ResourceTypeEnum } from "@features/safe/iam/components/policy-editor/types"; +import { Resource, ResourceTypeEnum } from "@shared/policy"; import { Observable } from "rxjs"; import { Injectable } from "@angular/core"; diff --git a/modules/front-end/src/app/features/safe/iam/components/policy-editor/actions-selector/actions-selector.component.ts b/modules/front-end/src/app/features/safe/iam/components/policy-editor/actions-selector/actions-selector.component.ts index 7e8b1d6c4..023b6433d 100644 --- a/modules/front-end/src/app/features/safe/iam/components/policy-editor/actions-selector/actions-selector.component.ts +++ b/modules/front-end/src/app/features/safe/iam/components/policy-editor/actions-selector/actions-selector.component.ts @@ -1,6 +1,6 @@ import {Component, EventEmitter, Input, Output, ViewChild} from "@angular/core"; import {NzSelectComponent} from "ng-zorro-antd/select"; -import {IamPolicyAction} from "@features//safe/iam/components/policy-editor/types"; +import {IamPolicyAction} from "@shared/policy"; @Component({ selector: 'actions-selector', diff --git a/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts b/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts index 90d0dd75e..bbe56e29b 100644 --- a/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts +++ b/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts @@ -7,7 +7,7 @@ import { resourcesTypes, ResourceType, ResourceTypeEnum -} from "@features/safe/iam/components/policy-editor/types"; +} from "@shared/policy"; import {deepCopy, encodeURIComponentFfc, uuidv4} from "@utils/index"; import {IPolicy, IPolicyStatement} from "@features/safe/iam/types/policy"; import {NzMessageService} from "ng-zorro-antd/message"; diff --git a/modules/front-end/src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.ts b/modules/front-end/src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.ts index aa6f7c70c..04b555af8 100644 --- a/modules/front-end/src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.ts +++ b/modules/front-end/src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.ts @@ -7,10 +7,9 @@ import { ResourceTypeEnum, RNViewModel, rscParamsDict -} from "@features/safe/iam/components/policy-editor/types"; +} from "@shared/policy"; import {ResourceService} from "@services/resource.service"; import {deepCopy} from "@utils/index"; - @Component({ selector: 'resources-selector', templateUrl: './resources-selector.component.html', diff --git a/modules/front-end/src/app/features/safe/organizations/project/project.component.ts b/modules/front-end/src/app/features/safe/organizations/project/project.component.ts index a7f228454..437a5afdf 100644 --- a/modules/front-end/src/app/features/safe/organizations/project/project.component.ts +++ b/modules/front-end/src/app/features/safe/organizations/project/project.component.ts @@ -6,11 +6,11 @@ import { EnvService } from '@services/env.service'; import { NzMessageService } from "ng-zorro-antd/message"; import {PermissionsService} from "@services/permissions.service"; import {generalResourceRNPattern, permissionActions} from "@shared/permissions"; -import {ResourceTypeEnum} from "@features/safe/iam/components/policy-editor/types"; import {MessageQueueService} from "@services/message-queue.service"; import { FormBuilder, FormGroup, Validators } from "@angular/forms"; import { EnvSecretService } from "@services/env-secret.service"; import { copyToClipboard } from '@utils/index'; +import { ResourceTypeEnum } from "@shared/policy"; @Component({ selector: 'app-project', diff --git a/modules/front-end/src/app/features/safe/iam/components/policy-editor/types.ts b/modules/front-end/src/app/shared/policy.ts similarity index 62% rename from modules/front-end/src/app/features/safe/iam/components/policy-editor/types.ts rename to modules/front-end/src/app/shared/policy.ts index 74e01065b..e4a7954f6 100644 --- a/modules/front-end/src/app/features/safe/iam/components/policy-editor/types.ts +++ b/modules/front-end/src/app/shared/policy.ts @@ -16,6 +16,8 @@ export interface IamPolicyAction { id: string; name: string; displayName: string; + description: string; + isOpenAPIApplicable: boolean; } export enum ResourceTypeEnum { @@ -117,172 +119,236 @@ export const resourceActionsDict: {[key: string]: IamPolicyAction[]} = { { id: uuidv4(), name: permissionActions.All, - displayName: $localize`:@@iam.action.all:All` + displayName: $localize`:@@iam.action.all:All`, + description: $localize`:@@iam.action.all:All`, + isOpenAPIApplicable: false }, ], [`${ResourceTypeEnum.General},account`]: [ { id: uuidv4(), name: permissionActions.UpdateOrgName, - displayName: $localize`:@@iam.action.update-org-name:Update org name` + displayName: $localize`:@@iam.action.update-org-name:Update org name`, + description: $localize`:@@iam.action.update-org-name:Update org name`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.ListAccessTokens, - displayName: $localize`:@@iam.action.list-access-tokens:List access tokens` + displayName: $localize`:@@iam.action.list-access-tokens:List access tokens`, + description: $localize`:@@iam.action.list-access-tokens:List access tokens`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.CreateServiceAccessTokens, - displayName: $localize`:@@iam.action.create-service-access-tokens:Create service access tokens` + displayName: $localize`:@@iam.action.create-service-access-tokens:Create service access tokens`, + description: $localize`:@@iam.action.create-service-access-tokens:Create service access tokens`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.CreatePersonalAccessTokens, - displayName: $localize`:@@iam.action.create-personal-access-tokens:Create personal access tokens` + displayName: $localize`:@@iam.action.create-personal-access-tokens:Create personal access tokens`, + description: $localize`:@@iam.action.create-personal-access-tokens:Create personal access tokens`, + isOpenAPIApplicable: true }, ], [`${ResourceTypeEnum.General},iam`]: [ { id: uuidv4(), name: permissionActions.CanManageIAM, - displayName: $localize`:@@iam.action.iam:IAM` + displayName: $localize`:@@iam.action.iam:IAM`, + description: $localize`:@@iam.action.iam:IAM`, + isOpenAPIApplicable: true }, ], [`${ResourceTypeEnum.General},project`]: [ // for all projects { id: uuidv4(), name: permissionActions.ListProjects, - displayName: $localize`:@@iam.action.list-projects:List projects` + displayName: $localize`:@@iam.action.list-projects:List projects`, + description: $localize`:@@iam.action.list-projects:List projects`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.CreateProject, - displayName: $localize`:@@iam.action.create-projects:Create projects` + displayName: $localize`:@@iam.action.create-projects:Create projects`, + description: $localize`:@@iam.action.create-projects:Create projects`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.DeleteProject, - displayName: $localize`:@@iam.action.delete-projects:Delete projects` + displayName: $localize`:@@iam.action.delete-projects:Delete projects`, + description: $localize`:@@iam.action.delete-projects:Delete projects`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.UpdateProjectSettings, - displayName: $localize`:@@iam.action.update-project-settings:Update project settings` + displayName: $localize`:@@iam.action.update-project-settings:Update project settings`, + description: $localize`:@@iam.action.update-project-settings:Update project settings`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.ListEnvs, - displayName: $localize`:@@iam.action.list-envs:List environments` + displayName: $localize`:@@iam.action.list-envs:List environments`, + description: $localize`:@@iam.action.list-envs:List environments`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.CreateEnv, - displayName: $localize`:@@iam.action.create-env:Create environment` + displayName: $localize`:@@iam.action.create-env:Create environment`, + description: $localize`:@@iam.action.create-env:Create environment`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.AccessEnvs, - displayName: $localize`:@@iam.action.access-envs:Access environments` + displayName: $localize`:@@iam.action.access-envs:Access environments`, + description: $localize`:@@iam.action.access-envs:Access environments`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.DeleteEnv, - displayName: $localize`:@@iam.action.delete-envs:Delete environments` + displayName: $localize`:@@iam.action.delete-envs:Delete environments`, + description: $localize`:@@iam.action.delete-envs:Delete environments`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.UpdateEnvSettings, - displayName: $localize`:@@iam.action.update-env-settings:Update environment settings` + displayName: $localize`:@@iam.action.update-env-settings:Update environment settings`, + description: $localize`:@@iam.action.update-env-settings:Update environment settings`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.DeleteEnvSecret, - displayName: $localize`:@@iam.action.delete-env-secret:Delete environment secret` + displayName: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, + description: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.CreateEnvSecret, - displayName: $localize`:@@iam.action.create-env-secret:Create environment secret` + displayName: $localize`:@@iam.action.create-env-secret:Create environment secret`, + description: $localize`:@@iam.action.create-env-secret:Create environment secret`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.UpdateEnvSecret, - displayName: $localize`:@@iam.action.update-env-secret:Update environment secret` + displayName: $localize`:@@iam.action.update-env-secret:Update environment secret`, + description: $localize`:@@iam.action.update-env-secret:Update environment secret`, + isOpenAPIApplicable: true }, ], [ResourceTypeEnum.Project]: [ // for a specific project { id: uuidv4(), name: permissionActions.AccessEnvs, - displayName: $localize`:@@iam.action.access-envs:Access environments` + displayName: $localize`:@@iam.action.access-envs:Access environments`, + description: $localize`:@@iam.action.access-envs:Access environments`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.DeleteProject, - displayName: $localize`:@@iam.action.delete-projects:Delete projects` + displayName: $localize`:@@iam.action.delete-projects:Delete projects`, + description: $localize`:@@iam.action.delete-projects:Delete projects`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.UpdateProjectSettings, - displayName: $localize`:@@iam.action.update-project-settings:Update project settings` + displayName: $localize`:@@iam.action.update-project-settings:Update project settings`, + description: $localize`:@@iam.action.update-project-settings:Update project settings`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.ListEnvs, - displayName: $localize`:@@iam.action.list-envs:List environments` + displayName: $localize`:@@iam.action.list-envs:List environments`, + description: $localize`:@@iam.action.list-envs:List environments`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.CreateEnv, - displayName: $localize`:@@iam.action.create-env:Create environment` + displayName: $localize`:@@iam.action.create-env:Create environment`, + description: $localize`:@@iam.action.create-env:Create environment`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.DeleteEnvSecret, - displayName: $localize`:@@iam.action.delete-env-secret:Delete environment secret` + displayName: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, + description: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.CreateEnvSecret, - displayName: $localize`:@@iam.action.create-env-secret:Create environment secret` + displayName: $localize`:@@iam.action.create-env-secret:Create environment secret`, + description: $localize`:@@iam.action.create-env-secret:Create environment secret`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.UpdateEnvSecret, - displayName: $localize`:@@iam.action.update-env-secret:Update environment secret` + displayName: $localize`:@@iam.action.update-env-secret:Update environment secret`, + description: $localize`:@@iam.action.update-env-secret:Update environment secret`, + isOpenAPIApplicable: true }, ], [ResourceTypeEnum.Env]: [ // for a specific environment { id: uuidv4(), name: permissionActions.AccessEnvs, - displayName: $localize`:@@iam.action.access-envs:Access environments` + displayName: $localize`:@@iam.action.access-envs:Access environments`, + description: $localize`:@@iam.action.access-envs:Access environments`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.DeleteEnv, - displayName: $localize`:@@iam.action.delete-envs:Delete environments` + displayName: $localize`:@@iam.action.delete-envs:Delete environments`, + description: $localize`:@@iam.action.delete-envs:Delete environments`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.UpdateEnvSettings, - displayName: $localize`:@@iam.action.update-env-settings:Update environment settings` + displayName: $localize`:@@iam.action.update-env-settings:Update environment settings`, + description: $localize`:@@iam.action.update-env-settings:Update environment settings`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.DeleteEnvSecret, - displayName: $localize`:@@iam.action.delete-env-secret:Delete environment secret` + displayName: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, + description: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.CreateEnvSecret, - displayName: $localize`:@@iam.action.create-env-secret:Create environment secret` + displayName: $localize`:@@iam.action.create-env-secret:Create environment secret`, + description: $localize`:@@iam.action.create-env-secret:Create environment secret`, + isOpenAPIApplicable: true }, { id: uuidv4(), name: permissionActions.UpdateEnvSecret, - displayName: $localize`:@@iam.action.update-env-secret:Update environment secret` + displayName: $localize`:@@iam.action.update-env-secret:Update environment secret`, + description: $localize`:@@iam.action.update-env-secret:Update environment secret`, + isOpenAPIApplicable: true }, ] } From 14dd12a174a932257edb28b96243c3e53bc3e26a Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Mon, 13 Mar 2023 12:13:50 +0100 Subject: [PATCH 22/44] refactor --- .../docker-entrypoint-initdb.d/init.js | 8 +- .../permission-check.component.ts | 3 +- .../directives/permission-check.directive.ts | 3 +- .../app/core/services/permissions.service.ts | 10 +- .../actions-selector.component.html | 2 +- .../front-end/src/app/shared/permissions.ts | 148 ++++- modules/front-end/src/app/shared/policy.ts | 256 ++------- modules/front-end/src/locale/messages.xlf | 472 ++++++++-------- modules/front-end/src/locale/messages.zh.xlf | 520 +++++++++--------- 9 files changed, 687 insertions(+), 735 deletions(-) diff --git a/infra/mongodb/docker-entrypoint-initdb.d/init.js b/infra/mongodb/docker-entrypoint-initdb.d/init.js index 7cfc935d1..b426b82b8 100644 --- a/infra/mongodb/docker-entrypoint-initdb.d/init.js +++ b/infra/mongodb/docker-entrypoint-initdb.d/init.js @@ -107,8 +107,8 @@ db.Policies.insertOne( effect: "allow", actions: [ "UpdateOrgName", - "CreateServiceAccessTokens", - "CreatePersonalAccessTokens", + "ManageServiceAccessTokens", + "ManagePersonalAccessTokens", "ListAccessTokens" ], resources: ["account"] @@ -162,8 +162,8 @@ db.Policies.insertOne( resourceType: "general", effect: "allow", actions: [ - "CreateServiceAccessTokens", - "CreatePersonalAccessTokens", + "ManageServiceAccessTokens", + "ManagePersonalAccessTokens", "ListAccessTokens" ], resources: ["account"] diff --git a/modules/front-end/src/app/core/components/permission-check/permission-check.component.ts b/modules/front-end/src/app/core/components/permission-check/permission-check.component.ts index dcb87fa8a..66f8c07a6 100644 --- a/modules/front-end/src/app/core/components/permission-check/permission-check.component.ts +++ b/modules/front-end/src/app/core/components/permission-check/permission-check.component.ts @@ -1,5 +1,6 @@ import {Component, Input, OnInit} from "@angular/core"; import {PermissionsService} from "@services/permissions.service"; +import { IamPolicyAction } from "@shared/policy"; @Component({ selector: 'permission-check', @@ -9,7 +10,7 @@ import {PermissionsService} from "@services/permissions.service"; export class PermissionCheckComponent implements OnInit { @Input() rn: string; - @Input() action: string; + @Input() action: IamPolicyAction; @Input() messageIfDeny: string = this.permissionsService.genericDenyMessage; canTakeAction: boolean = false; diff --git a/modules/front-end/src/app/core/directives/permission-check.directive.ts b/modules/front-end/src/app/core/directives/permission-check.directive.ts index 1f42ac178..ad7e27ee2 100644 --- a/modules/front-end/src/app/core/directives/permission-check.directive.ts +++ b/modules/front-end/src/app/core/directives/permission-check.directive.ts @@ -1,6 +1,7 @@ import {Directive, EventEmitter, HostListener, Input, Output} from "@angular/core"; import {NzMessageService} from "ng-zorro-antd/message"; import {PermissionsService} from "@services/permissions.service"; +import { IamPolicyAction } from "@shared/policy"; @Directive({ selector: '[permission-check]' @@ -8,7 +9,7 @@ import {PermissionsService} from "@services/permissions.service"; export class PermissionCheckDirective { @Input() rn: string; - @Input() action: string; + @Input() action: IamPolicyAction; @Input() messageIfDeny: string = this.permissionsService.genericDenyMessage; @Output() actionIfAllow = new EventEmitter(); diff --git a/modules/front-end/src/app/core/services/permissions.service.ts b/modules/front-end/src/app/core/services/permissions.service.ts index 3bd86ee47..a72a0f28b 100644 --- a/modules/front-end/src/app/core/services/permissions.service.ts +++ b/modules/front-end/src/app/core/services/permissions.service.ts @@ -2,7 +2,7 @@ import {Injectable} from "@angular/core"; import {lastValueFrom} from "rxjs"; import {IPolicy, IPolicyStatement} from "@features/safe/iam/types/policy"; import {MemberService} from "@services/member.service"; -import {EffectEnum, ResourceTypeEnum} from "@shared/policy"; +import { EffectEnum, IamPolicyAction, ResourceTypeEnum } from "@shared/policy"; @Injectable({ providedIn: 'root' @@ -63,7 +63,7 @@ export class PermissionsService { } // if return undefined, that means zero permission is defined on that resource - canTakeAction(rn: string, action: string): boolean | undefined | any { + canTakeAction(rn: string, action: IamPolicyAction): boolean | undefined | any { const [resourceType, _] = rn.split('/'); const statements = this.permissions.filter(s => { @@ -72,7 +72,7 @@ export class PermissionsService { } if (s.resourceType === ResourceTypeEnum.General) { - return s.resources.map(r => r.split('/')[0]).includes(resourceType) && s.actions.includes(action); + return s.resources.map(r => r.split('/')[0]).includes(resourceType) && s.actions.includes(action.name); } const matchingResource = s.resources.find(rsc => { @@ -89,13 +89,13 @@ export class PermissionsService { }); }); - return matchingResource !== undefined && s.actions.includes(action) + return matchingResource !== undefined && s.actions.includes(action.name) }); if (statements.find(s => s.effect === EffectEnum.Deny) !== undefined) { return false; } - return statements.find(s => s.effect !== EffectEnum.Deny && (s.actions.find(act => act === '*') || s.actions.includes(action))); + return statements.find(s => s.effect !== EffectEnum.Deny && (s.actions.find(act => act === '*') || s.actions.includes(action.name))); } } diff --git a/modules/front-end/src/app/features/safe/iam/components/policy-editor/actions-selector/actions-selector.component.html b/modules/front-end/src/app/features/safe/iam/components/policy-editor/actions-selector/actions-selector.component.html index 6b98472f4..6b5d655bd 100644 --- a/modules/front-end/src/app/features/safe/iam/components/policy-editor/actions-selector/actions-selector.component.html +++ b/modules/front-end/src/app/features/safe/iam/components/policy-editor/actions-selector/actions-selector.component.html @@ -7,7 +7,7 @@
-
+
{{act.displayName}} ({{act.name}})
diff --git a/modules/front-end/src/app/shared/permissions.ts b/modules/front-end/src/app/shared/permissions.ts index 1b8472d63..6aeffe976 100644 --- a/modules/front-end/src/app/shared/permissions.ts +++ b/modules/front-end/src/app/shared/permissions.ts @@ -1,3 +1,5 @@ +import { uuidv4 } from "@utils/index"; +import { IamPolicyAction } from "@shared/policy"; export const generalResourceRNPattern = { all: '*', @@ -6,30 +8,138 @@ export const generalResourceRNPattern = { project: 'project', } -export const permissionActions = { - All: '*', +export const permissionActions: {[key: string]: IamPolicyAction} = { + All: { + id: uuidv4(), + name: '*', + displayName: $localize`:@@iam.action.all:All`, + description: $localize`:@@iam.action.all:All`, + isOpenAPIApplicable: false + }, - ListProjects: 'ListProjects', - CreateProject: 'CreateProject', - DeleteProject: 'DeleteProject', - AccessEnvs: 'AccessEnvs', - UpdateProjectSettings: 'UpdateProjectSettings', - ListEnvs: 'ListEnvs', - CreateEnv: 'CreateEnv', - DeleteEnv: 'DeleteEnv', - UpdateEnvSettings: 'UpdateEnvSettings', - DeleteEnvSecret: 'DeleteEnvSecret', - CreateEnvSecret: 'CreateEnvSecret', - UpdateEnvSecret: 'UpdateEnvSecret', + ListProjects: { + id: uuidv4(), + name: 'ListProjects', + displayName: $localize`:@@iam.action.list-projects:List projects`, + description: $localize`:@@iam.action.list-projects:List projects`, + isOpenAPIApplicable: true + }, + CreateProject: { + id: uuidv4(), + name: 'CreateProject', + displayName: $localize`:@@iam.action.create-projects:Create projects`, + description: $localize`:@@iam.action.create-projects:Create projects`, + isOpenAPIApplicable: true + }, + DeleteProject: { + id: uuidv4(), + name: 'DeleteProject', + displayName: $localize`:@@iam.action.delete-projects:Delete projects`, + description: $localize`:@@iam.action.delete-projects:Delete projects`, + isOpenAPIApplicable: true + }, + AccessEnvs: { + id: uuidv4(), + name: 'AccessEnvs', + displayName: $localize`:@@iam.action.access-envs:Access environments`, + description: $localize`:@@iam.action.access-envs:Access environments`, + isOpenAPIApplicable: true + }, + UpdateProjectSettings: { + id: uuidv4(), + name: 'UpdateProjectSettings', + displayName: $localize`:@@iam.action.update-project-settings:Update project settings`, + description: $localize`:@@iam.action.update-project-settings:Update project settings`, + isOpenAPIApplicable: true + }, + ListEnvs: { + id: uuidv4(), + name: 'ListEnvs', + displayName: $localize`:@@iam.action.list-envs:List environments`, + description: $localize`:@@iam.action.list-envs:List environments`, + isOpenAPIApplicable: true + }, + CreateEnv: { + id: uuidv4(), + name: 'CreateEnv', + displayName: $localize`:@@iam.action.create-env:Create environment`, + description: $localize`:@@iam.action.create-env:Create environment`, + isOpenAPIApplicable: true + }, + DeleteEnv: { + id: uuidv4(), + name: 'DeleteEnv', + displayName: $localize`:@@iam.action.delete-envs:Delete environments`, + description: $localize`:@@iam.action.delete-envs:Delete environments`, + isOpenAPIApplicable: true + }, + UpdateEnvSettings: { + id: uuidv4(), + name: 'UpdateEnvSettings', + displayName: $localize`:@@iam.action.update-env-settings:Update environment settings`, + description: $localize`:@@iam.action.update-env-settings:Update environment settings`, + isOpenAPIApplicable: true + }, + DeleteEnvSecret: { + id: uuidv4(), + name: 'DeleteEnvSecret', + displayName: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, + description: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, + isOpenAPIApplicable: true + }, + CreateEnvSecret: { + id: uuidv4(), + name: 'CreateEnvSecret', + displayName: $localize`:@@iam.action.create-env-secret:Create environment secret`, + description: $localize`:@@iam.action.create-env-secret:Create environment secret`, + isOpenAPIApplicable: true + }, + UpdateEnvSecret: { + id: uuidv4(), + name: 'UpdateEnvSecret', + displayName: $localize`:@@iam.action.update-env-secret:Update environment secret`, + description: $localize`:@@iam.action.update-env-secret:Update environment secret`, + isOpenAPIApplicable: true + }, // account - UpdateOrgName: 'UpdateOrgName', + UpdateOrgName: { + id: uuidv4(), + name: 'UpdateOrgName', + displayName: $localize`:@@iam.action.update-org-name:Update org name`, + description: $localize`:@@iam.action.update-org-name:Update org name`, + isOpenAPIApplicable: true + }, // iam - CanManageIAM: 'CanManageIAM', + CanManageIAM: { + id: uuidv4(), + name: 'CanManageIAM', + displayName: $localize`:@@iam.action.iam:IAM`, + description: $localize`:@@iam.action.iam:IAM`, + isOpenAPIApplicable: true + }, // access tokens - ListAccessTokens: 'ListAccessTokens', - CreateServiceAccessTokens: 'CreateServiceAccessTokens', - CreatePersonalAccessTokens: 'CreatePersonalAccessTokens', + ListAccessTokens: { + id: uuidv4(), + name: 'ListAccessTokens', + displayName: $localize`:@@iam.action.list-access-tokens:List access tokens`, + description: $localize`:@@iam.action.list-access-tokens:List access tokens`, + isOpenAPIApplicable: true + }, + CreateServiceAccessTokens: { + id: uuidv4(), + name: 'ManageServiceAccessTokens', + displayName: $localize`:@@iam.action.manage-service-access-tokens:Manage service access tokens`, + description: $localize`:@@iam.action.manage-service-access-tokens:Manage service access tokens`, + isOpenAPIApplicable: true + }, + CreatePersonalAccessTokens: { + id: uuidv4(), + name: 'ManagePersonalAccessTokens', + displayName: $localize`:@@iam.action.manage-personal-access-tokens:Manage personal access tokens`, + description: $localize`:@@iam.action.manage-personal-access-tokens:Manage personal access tokens`, + isOpenAPIApplicable: true + }, } diff --git a/modules/front-end/src/app/shared/policy.ts b/modules/front-end/src/app/shared/policy.ts index e4a7954f6..1f1d5f197 100644 --- a/modules/front-end/src/app/shared/policy.ts +++ b/modules/front-end/src/app/shared/policy.ts @@ -116,239 +116,47 @@ export const rscParamsDict: {[key in ResourceTypeEnum]: ResourceParamViewModel[] export const resourceActionsDict: {[key: string]: IamPolicyAction[]} = { [ResourceTypeEnum.All]: [ - { - id: uuidv4(), - name: permissionActions.All, - displayName: $localize`:@@iam.action.all:All`, - description: $localize`:@@iam.action.all:All`, - isOpenAPIApplicable: false - }, + permissionActions.All, ], [`${ResourceTypeEnum.General},account`]: [ - { - id: uuidv4(), - name: permissionActions.UpdateOrgName, - displayName: $localize`:@@iam.action.update-org-name:Update org name`, - description: $localize`:@@iam.action.update-org-name:Update org name`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.ListAccessTokens, - displayName: $localize`:@@iam.action.list-access-tokens:List access tokens`, - description: $localize`:@@iam.action.list-access-tokens:List access tokens`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.CreateServiceAccessTokens, - displayName: $localize`:@@iam.action.create-service-access-tokens:Create service access tokens`, - description: $localize`:@@iam.action.create-service-access-tokens:Create service access tokens`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.CreatePersonalAccessTokens, - displayName: $localize`:@@iam.action.create-personal-access-tokens:Create personal access tokens`, - description: $localize`:@@iam.action.create-personal-access-tokens:Create personal access tokens`, - isOpenAPIApplicable: true - }, + permissionActions.UpdateOrgName, + permissionActions.ListAccessTokens, + permissionActions.CreateServiceAccessTokens, + permissionActions.CreatePersonalAccessTokens, ], [`${ResourceTypeEnum.General},iam`]: [ - { - id: uuidv4(), - name: permissionActions.CanManageIAM, - displayName: $localize`:@@iam.action.iam:IAM`, - description: $localize`:@@iam.action.iam:IAM`, - isOpenAPIApplicable: true - }, + permissionActions.CanManageIAM, ], [`${ResourceTypeEnum.General},project`]: [ // for all projects - { - id: uuidv4(), - name: permissionActions.ListProjects, - displayName: $localize`:@@iam.action.list-projects:List projects`, - description: $localize`:@@iam.action.list-projects:List projects`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.CreateProject, - displayName: $localize`:@@iam.action.create-projects:Create projects`, - description: $localize`:@@iam.action.create-projects:Create projects`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.DeleteProject, - displayName: $localize`:@@iam.action.delete-projects:Delete projects`, - description: $localize`:@@iam.action.delete-projects:Delete projects`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.UpdateProjectSettings, - displayName: $localize`:@@iam.action.update-project-settings:Update project settings`, - description: $localize`:@@iam.action.update-project-settings:Update project settings`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.ListEnvs, - displayName: $localize`:@@iam.action.list-envs:List environments`, - description: $localize`:@@iam.action.list-envs:List environments`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.CreateEnv, - displayName: $localize`:@@iam.action.create-env:Create environment`, - description: $localize`:@@iam.action.create-env:Create environment`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.AccessEnvs, - displayName: $localize`:@@iam.action.access-envs:Access environments`, - description: $localize`:@@iam.action.access-envs:Access environments`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.DeleteEnv, - displayName: $localize`:@@iam.action.delete-envs:Delete environments`, - description: $localize`:@@iam.action.delete-envs:Delete environments`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.UpdateEnvSettings, - displayName: $localize`:@@iam.action.update-env-settings:Update environment settings`, - description: $localize`:@@iam.action.update-env-settings:Update environment settings`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.DeleteEnvSecret, - displayName: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, - description: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.CreateEnvSecret, - displayName: $localize`:@@iam.action.create-env-secret:Create environment secret`, - description: $localize`:@@iam.action.create-env-secret:Create environment secret`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.UpdateEnvSecret, - displayName: $localize`:@@iam.action.update-env-secret:Update environment secret`, - description: $localize`:@@iam.action.update-env-secret:Update environment secret`, - isOpenAPIApplicable: true - }, + permissionActions.ListProjects, + permissionActions.CreateProject, + permissionActions.DeleteProject, + permissionActions.UpdateProjectSettings, + permissionActions.ListEnvs, + permissionActions.CreateEnv, + permissionActions.AccessEnvs, + permissionActions.DeleteEnv, + permissionActions.UpdateEnvSettings, + permissionActions.DeleteEnvSecret, + permissionActions.CreateEnvSecret, + permissionActions.UpdateEnvSecret, ], [ResourceTypeEnum.Project]: [ // for a specific project - { - id: uuidv4(), - name: permissionActions.AccessEnvs, - displayName: $localize`:@@iam.action.access-envs:Access environments`, - description: $localize`:@@iam.action.access-envs:Access environments`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.DeleteProject, - displayName: $localize`:@@iam.action.delete-projects:Delete projects`, - description: $localize`:@@iam.action.delete-projects:Delete projects`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.UpdateProjectSettings, - displayName: $localize`:@@iam.action.update-project-settings:Update project settings`, - description: $localize`:@@iam.action.update-project-settings:Update project settings`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.ListEnvs, - displayName: $localize`:@@iam.action.list-envs:List environments`, - description: $localize`:@@iam.action.list-envs:List environments`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.CreateEnv, - displayName: $localize`:@@iam.action.create-env:Create environment`, - description: $localize`:@@iam.action.create-env:Create environment`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.DeleteEnvSecret, - displayName: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, - description: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.CreateEnvSecret, - displayName: $localize`:@@iam.action.create-env-secret:Create environment secret`, - description: $localize`:@@iam.action.create-env-secret:Create environment secret`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.UpdateEnvSecret, - displayName: $localize`:@@iam.action.update-env-secret:Update environment secret`, - description: $localize`:@@iam.action.update-env-secret:Update environment secret`, - isOpenAPIApplicable: true - }, + permissionActions.AccessEnvs, + permissionActions.DeleteProject, + permissionActions.UpdateProjectSettings, + permissionActions.ListEnvs, + permissionActions.CreateEnv, + permissionActions.DeleteEnvSecret, + permissionActions.CreateEnvSecret, + permissionActions.UpdateEnvSecret, ], [ResourceTypeEnum.Env]: [ // for a specific environment - { - id: uuidv4(), - name: permissionActions.AccessEnvs, - displayName: $localize`:@@iam.action.access-envs:Access environments`, - description: $localize`:@@iam.action.access-envs:Access environments`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.DeleteEnv, - displayName: $localize`:@@iam.action.delete-envs:Delete environments`, - description: $localize`:@@iam.action.delete-envs:Delete environments`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.UpdateEnvSettings, - displayName: $localize`:@@iam.action.update-env-settings:Update environment settings`, - description: $localize`:@@iam.action.update-env-settings:Update environment settings`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.DeleteEnvSecret, - displayName: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, - description: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.CreateEnvSecret, - displayName: $localize`:@@iam.action.create-env-secret:Create environment secret`, - description: $localize`:@@iam.action.create-env-secret:Create environment secret`, - isOpenAPIApplicable: true - }, - { - id: uuidv4(), - name: permissionActions.UpdateEnvSecret, - displayName: $localize`:@@iam.action.update-env-secret:Update environment secret`, - description: $localize`:@@iam.action.update-env-secret:Update environment secret`, - isOpenAPIApplicable: true - }, + permissionActions.AccessEnvs, + permissionActions.DeleteEnv, + permissionActions.UpdateEnvSettings, + permissionActions.DeleteEnvSecret, + permissionActions.CreateEnvSecret, + permissionActions.UpdateEnvSecret, ] } diff --git a/modules/front-end/src/locale/messages.xlf b/modules/front-end/src/locale/messages.xlf index a37a40ac2..09b4d21f4 100644 --- a/modules/front-end/src/locale/messages.xlf +++ b/modules/front-end/src/locale/messages.xlf @@ -4989,234 +4989,6 @@ 68 - - All - - src/app/features/safe/iam/components/policy-editor/types.ts - 49 - - - - General - - src/app/features/safe/iam/components/policy-editor/types.ts - 54 - - - - Project - - src/app/features/safe/iam/components/policy-editor/types.ts - 59 - - - - Environment - - src/app/features/safe/iam/components/policy-editor/types.ts - 64 - - - - Project - - src/app/features/safe/iam/components/policy-editor/types.ts - 85 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 97 - - - - Environment - - src/app/features/safe/iam/components/policy-editor/types.ts - 107 - - - - All - - src/app/features/safe/iam/components/policy-editor/types.ts - 120 - - - - Update org name - - src/app/features/safe/iam/components/policy-editor/types.ts - 127 - - - - List access tokens - - src/app/features/safe/iam/components/policy-editor/types.ts - 132 - - - - Create service access tokens - - src/app/features/safe/iam/components/policy-editor/types.ts - 137 - - - - Create personal access tokens - - src/app/features/safe/iam/components/policy-editor/types.ts - 142 - - - - IAM - - src/app/features/safe/iam/components/policy-editor/types.ts - 149 - - - - List projects - - src/app/features/safe/iam/components/policy-editor/types.ts - 156 - - - - Create projects - - src/app/features/safe/iam/components/policy-editor/types.ts - 161 - - - - Delete projects - - src/app/features/safe/iam/components/policy-editor/types.ts - 166 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 223 - - - - Update project settings - - src/app/features/safe/iam/components/policy-editor/types.ts - 171 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 228 - - - - List environments - - src/app/features/safe/iam/components/policy-editor/types.ts - 176 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 233 - - - - Create environment - - src/app/features/safe/iam/components/policy-editor/types.ts - 181 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 238 - - - - Access environments - - src/app/features/safe/iam/components/policy-editor/types.ts - 186 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 218 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 260 - - - - Delete environments - - src/app/features/safe/iam/components/policy-editor/types.ts - 191 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 265 - - - - Update environment settings - - src/app/features/safe/iam/components/policy-editor/types.ts - 196 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 270 - - - - Delete environment secret - - src/app/features/safe/iam/components/policy-editor/types.ts - 201 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 243 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 275 - - - - Create environment secret - - src/app/features/safe/iam/components/policy-editor/types.ts - 206 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 248 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 280 - - - - Update environment secret - - src/app/features/safe/iam/components/policy-editor/types.ts - 211 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 253 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 285 - - Team @@ -6533,6 +6305,250 @@ 76 + + All + + src/app/shared/permissions.ts + 15 + + + src/app/shared/permissions.ts + 16 + + + + List projects + + src/app/shared/permissions.ts + 23 + + + src/app/shared/permissions.ts + 24 + + + + Create projects + + src/app/shared/permissions.ts + 30 + + + src/app/shared/permissions.ts + 31 + + + + Delete projects + + src/app/shared/permissions.ts + 37 + + + src/app/shared/permissions.ts + 38 + + + + Access environments + + src/app/shared/permissions.ts + 44 + + + src/app/shared/permissions.ts + 45 + + + + Update project settings + + src/app/shared/permissions.ts + 51 + + + src/app/shared/permissions.ts + 52 + + + + List environments + + src/app/shared/permissions.ts + 58 + + + src/app/shared/permissions.ts + 59 + + + + Create environment + + src/app/shared/permissions.ts + 65 + + + src/app/shared/permissions.ts + 66 + + + + Delete environments + + src/app/shared/permissions.ts + 72 + + + src/app/shared/permissions.ts + 73 + + + + Update environment settings + + src/app/shared/permissions.ts + 79 + + + src/app/shared/permissions.ts + 80 + + + + Delete environment secret + + src/app/shared/permissions.ts + 86 + + + src/app/shared/permissions.ts + 87 + + + + Create environment secret + + src/app/shared/permissions.ts + 93 + + + src/app/shared/permissions.ts + 94 + + + + Update environment secret + + src/app/shared/permissions.ts + 100 + + + src/app/shared/permissions.ts + 101 + + + + Update org name + + src/app/shared/permissions.ts + 109 + + + src/app/shared/permissions.ts + 110 + + + + IAM + + src/app/shared/permissions.ts + 118 + + + src/app/shared/permissions.ts + 119 + + + + List access tokens + + src/app/shared/permissions.ts + 127 + + + src/app/shared/permissions.ts + 128 + + + + Manage service access tokens + + src/app/shared/permissions.ts + 134 + + + src/app/shared/permissions.ts + 135 + + + + Manage personal access tokens + + src/app/shared/permissions.ts + 141 + + + src/app/shared/permissions.ts + 142 + + + + All + + src/app/shared/policy.ts + 51 + + + + General + + src/app/shared/policy.ts + 56 + + + + Project + + src/app/shared/policy.ts + 61 + + + + Environment + + src/app/shared/policy.ts + 66 + + + + Project + + src/app/shared/policy.ts + 87 + + + src/app/shared/policy.ts + 99 + + + + Environment + + src/app/shared/policy.ts + 109 + + diff --git a/modules/front-end/src/locale/messages.zh.xlf b/modules/front-end/src/locale/messages.zh.xlf index b1d6263a3..fe66adbc7 100644 --- a/modules/front-end/src/locale/messages.zh.xlf +++ b/modules/front-end/src/locale/messages.zh.xlf @@ -5440,258 +5440,6 @@ 任意 - - All - - src/app/features/safe/iam/components/policy-editor/types.ts - 49 - - 全部 - - - General - - src/app/features/safe/iam/components/policy-editor/types.ts - 54 - - 通用 - - - Project - - src/app/features/safe/iam/components/policy-editor/types.ts - 59 - - 项目 - - - Environment - - src/app/features/safe/iam/components/policy-editor/types.ts - 64 - - 环境 - - - Project - - src/app/features/safe/iam/components/policy-editor/types.ts - 85 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 97 - - 项目 - - - Environment - - src/app/features/safe/iam/components/policy-editor/types.ts - 107 - - 环境 - - - All - - src/app/features/safe/iam/components/policy-editor/types.ts - 120 - - 全部操作 - - - Update org name - - src/app/features/safe/iam/components/policy-editor/types.ts - 127 - - 修改机构名称 - - - List access tokens - - src/app/features/safe/iam/components/policy-editor/types.ts - 132 - - 查看访问策略列表 - - - Create service access tokens - - src/app/features/safe/iam/components/policy-editor/types.ts - 137 - - 创建 Service 访问策略 - - - Create personal access tokens - - src/app/features/safe/iam/components/policy-editor/types.ts - 142 - - 创建 Personal 访问策略 - - - IAM - - src/app/features/safe/iam/components/policy-editor/types.ts - 149 - - 权限管理 - - - List projects - - src/app/features/safe/iam/components/policy-editor/types.ts - 156 - - 查看项目列表 - - - Create projects - - src/app/features/safe/iam/components/policy-editor/types.ts - 161 - - 创建项目 - - - Delete projects - - src/app/features/safe/iam/components/policy-editor/types.ts - 166 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 223 - - 删除项目 - - - Update project settings - - src/app/features/safe/iam/components/policy-editor/types.ts - 171 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 228 - - 修改项目设置 - - - List environments - - src/app/features/safe/iam/components/policy-editor/types.ts - 176 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 233 - - 查看环境列表 - - - Create environment - - src/app/features/safe/iam/components/policy-editor/types.ts - 181 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 238 - - 创建环境 - - - Access environments - - src/app/features/safe/iam/components/policy-editor/types.ts - 186 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 218 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 260 - - 进入环境 - - - Delete environments - - src/app/features/safe/iam/components/policy-editor/types.ts - 191 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 265 - - 删除环境 - - - Update environment settings - - src/app/features/safe/iam/components/policy-editor/types.ts - 196 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 270 - - 修改环境设置 - - - Delete environment secret - - src/app/features/safe/iam/components/policy-editor/types.ts - 201 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 243 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 275 - - 删除环境秘钥 - - - Create environment secret - - src/app/features/safe/iam/components/policy-editor/types.ts - 206 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 248 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 280 - - 创建环境秘钥 - - - Update environment secret - - src/app/features/safe/iam/components/policy-editor/types.ts - 211 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 253 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 285 - - 修改环境秘钥 - Team @@ -7181,6 +6929,274 @@ 不包含用户 + + All + + src/app/shared/permissions.ts + 15 + + + src/app/shared/permissions.ts + 16 + + 全部操作 + + + List projects + + src/app/shared/permissions.ts + 23 + + + src/app/shared/permissions.ts + 24 + + 查看项目列表 + + + Create projects + + src/app/shared/permissions.ts + 30 + + + src/app/shared/permissions.ts + 31 + + 创建项目 + + + Delete projects + + src/app/shared/permissions.ts + 37 + + + src/app/shared/permissions.ts + 38 + + 删除项目 + + + Access environments + + src/app/shared/permissions.ts + 44 + + + src/app/shared/permissions.ts + 45 + + 进入环境 + + + Update project settings + + src/app/shared/permissions.ts + 51 + + + src/app/shared/permissions.ts + 52 + + 修改项目设置 + + + List environments + + src/app/shared/permissions.ts + 58 + + + src/app/shared/permissions.ts + 59 + + 查看环境列表 + + + Create environment + + src/app/shared/permissions.ts + 65 + + + src/app/shared/permissions.ts + 66 + + 创建环境 + + + Delete environments + + src/app/shared/permissions.ts + 72 + + + src/app/shared/permissions.ts + 73 + + 删除环境 + + + Update environment settings + + src/app/shared/permissions.ts + 79 + + + src/app/shared/permissions.ts + 80 + + 修改环境设置 + + + Delete environment secret + + src/app/shared/permissions.ts + 86 + + + src/app/shared/permissions.ts + 87 + + 删除环境秘钥 + + + Create environment secret + + src/app/shared/permissions.ts + 93 + + + src/app/shared/permissions.ts + 94 + + 创建环境秘钥 + + + Update environment secret + + src/app/shared/permissions.ts + 100 + + + src/app/shared/permissions.ts + 101 + + 修改环境秘钥 + + + Update org name + + src/app/shared/permissions.ts + 109 + + + src/app/shared/permissions.ts + 110 + + 修改机构名称 + + + IAM + + src/app/shared/permissions.ts + 118 + + + src/app/shared/permissions.ts + 119 + + 权限管理 + + + List access tokens + + src/app/shared/permissions.ts + 127 + + + src/app/shared/permissions.ts + 128 + + 查看访问策略列表 + + + Manage service access tokens + + src/app/shared/permissions.ts + 134 + + + src/app/shared/permissions.ts + 135 + + 管理 Service 访问策略 + + + Manage personal access tokens + + src/app/shared/permissions.ts + 141 + + + src/app/shared/permissions.ts + 142 + + 管理 Personal 访问策略 + + + All + + src/app/shared/policy.ts + 51 + + 全部 + + + General + + src/app/shared/policy.ts + 56 + + 通用 + + + Project + + src/app/shared/policy.ts + 61 + + 项目 + + + Environment + + src/app/shared/policy.ts + 66 + + 环境 + + + Project + + src/app/shared/policy.ts + 87 + + + src/app/shared/policy.ts + 99 + + 项目 + + + Environment + + src/app/shared/policy.ts + 109 + + 环境 + From 61418098f7efbaad495ae5786f2c3f2e5598ce52 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Mon, 13 Mar 2023 16:06:37 +0100 Subject: [PATCH 23/44] fixed error --- .../access-token-drawer/access-token-drawer.component.html | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html index 2a2403bdc..f8535ac65 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html @@ -98,6 +98,7 @@ [(nzVisible)]="isCreationConfirmModalVisible" i18n-nzTitle="@@integrations.access-tokens.access-token-created" nzTitle="Access token created" + (nzOnCancel)="isCreationConfirmModalVisible = false" [nzFooter]="confirmFooter" (nzOnOk)="isCreationConfirmModalVisible = false"> From 5bdec8e532e15b1c76353d2907b42d89afc5cb69 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Mon, 13 Mar 2023 16:08:26 +0100 Subject: [PATCH 24/44] fixed bug --- .../integrations/access-tokens/index/index.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html index ba877cbee..cd5851c50 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html @@ -96,7 +96,8 @@
  • Activate
  • -
  • Deactivate
  • Date: Mon, 13 Mar 2023 16:23:05 +0100 Subject: [PATCH 25/44] in progress --- .../src/app/core/services/permissions.service.ts | 6 +++--- .../front-end/src/app/core/services/policy.service.ts | 2 +- .../components/policy-editor/policy-editor.component.ts | 4 ++-- .../policies/details/permission/permission.component.ts | 3 ++- modules/front-end/src/app/shared/policy.ts | 9 ++++++++- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/modules/front-end/src/app/core/services/permissions.service.ts b/modules/front-end/src/app/core/services/permissions.service.ts index a72a0f28b..9cc4e4076 100644 --- a/modules/front-end/src/app/core/services/permissions.service.ts +++ b/modules/front-end/src/app/core/services/permissions.service.ts @@ -1,15 +1,15 @@ import {Injectable} from "@angular/core"; import {lastValueFrom} from "rxjs"; -import {IPolicy, IPolicyStatement} from "@features/safe/iam/types/policy"; +import {IPolicy} from "@features/safe/iam/types/policy"; import {MemberService} from "@services/member.service"; -import { EffectEnum, IamPolicyAction, ResourceTypeEnum } from "@shared/policy"; +import { EffectEnum, IamPolicyAction, IPolicyStatement, ResourceTypeEnum } from "@shared/policy"; @Injectable({ providedIn: 'root' }) export class PermissionsService { policies: IPolicy[]; - private permissions: IPolicyStatement[]; + permissions: IPolicyStatement[]; genericDenyMessage: string = $localize `:@@permissions.need-permissions-to-operate:You don't have permissions to take this action, please contact the admin to grant you the necessary permissions`; diff --git a/modules/front-end/src/app/core/services/policy.service.ts b/modules/front-end/src/app/core/services/policy.service.ts index 8fbf5cf39..d3b9d2f3f 100644 --- a/modules/front-end/src/app/core/services/policy.service.ts +++ b/modules/front-end/src/app/core/services/policy.service.ts @@ -8,12 +8,12 @@ import { IPagedPolicyGroup, IPagedPolicyMember, IPolicy, - IPolicyStatement, PolicyFilter, PolicyGroupFilter, PolicyMemberFilter } from "@features/safe/iam/types/policy"; import { catchError } from "rxjs/operators"; +import { IPolicyStatement } from "@shared/policy"; @Injectable({ providedIn: 'root' diff --git a/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts b/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts index bbe56e29b..2951538fa 100644 --- a/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts +++ b/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts @@ -1,7 +1,7 @@ import {Component, EventEmitter, Input, Output} from '@angular/core'; import { EffectEnum, - IamPolicyAction, + IamPolicyAction, IPolicyStatement, Resource, resourceActionsDict, resourcesTypes, @@ -9,7 +9,7 @@ import { ResourceTypeEnum } from "@shared/policy"; import {deepCopy, encodeURIComponentFfc, uuidv4} from "@utils/index"; -import {IPolicy, IPolicyStatement} from "@features/safe/iam/types/policy"; +import {IPolicy} from "@features/safe/iam/types/policy"; import {NzMessageService} from "ng-zorro-antd/message"; import {PolicyService} from "@services/policy.service"; import {Router} from "@angular/router"; diff --git a/modules/front-end/src/app/features/safe/iam/policies/details/permission/permission.component.ts b/modules/front-end/src/app/features/safe/iam/policies/details/permission/permission.component.ts index 35e30a40e..55724f5a4 100644 --- a/modules/front-end/src/app/features/safe/iam/policies/details/permission/permission.component.ts +++ b/modules/front-end/src/app/features/safe/iam/policies/details/permission/permission.component.ts @@ -1,8 +1,9 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { IPolicy, IPolicyStatement } from "@features/safe/iam/types/policy"; +import { IPolicy } from "@features/safe/iam/types/policy"; import { PolicyService } from "@services/policy.service"; import { NzMessageService } from "ng-zorro-antd/message"; +import { IPolicyStatement } from "@shared/policy"; @Component({ selector: 'permission', diff --git a/modules/front-end/src/app/shared/policy.ts b/modules/front-end/src/app/shared/policy.ts index 1f1d5f197..ea308475b 100644 --- a/modules/front-end/src/app/shared/policy.ts +++ b/modules/front-end/src/app/shared/policy.ts @@ -1,5 +1,12 @@ import {generalResourceRNPattern, permissionActions} from "@shared/permissions"; -import {uuidv4} from "@utils/index"; + +export interface IPolicyStatement { + id: string; + resourceType: string; + effect: string; + actions: string[]; + resources: string[]; +} export interface Resource { id: string; From 74190945142f081f4682fb86f89c3248d4baa424 Mon Sep 17 00:00:00 2001 From: cosmos-explorer <88151306+cosmos-explorer@users.noreply.github.com> Date: Tue, 14 Mar 2023 15:51:30 +0100 Subject: [PATCH 26/44] =?UTF-8?q?=F0=9F=A7=B9refactor=20iam=20(#269)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fixed error * fixed bug * in progress * refactor iam * translations * PR fix --- .../docker-entrypoint-initdb.d/init.js | 56 +++++--- .../src/Application/Resources/ResourceVm.cs | 2 + .../back-end/src/Domain/Resources/Resource.cs | 2 + .../src/Domain/Resources/ResourceType.cs | 6 +- .../Resources/ResourceService.cs | 66 +++++++-- .../access-token-drawer.component.html | 1 + .../app/core/services/permissions.service.ts | 12 +- .../src/app/core/services/policy.service.ts | 2 +- .../policy-editor/policy-editor.component.ts | 34 ++--- .../resources-selector.component.ts | 23 ++-- .../permission/permission.component.ts | 3 +- .../access-tokens/index/index.component.html | 4 +- .../project/project.component.ts | 2 +- .../front-end/src/app/shared/permissions.ts | 63 ++++++--- modules/front-end/src/app/shared/policy.ts | 86 ++++++++---- modules/front-end/src/locale/messages.xlf | 126 +++++++++-------- modules/front-end/src/locale/messages.zh.xlf | 130 ++++++++++-------- 17 files changed, 375 insertions(+), 243 deletions(-) diff --git a/infra/mongodb/docker-entrypoint-initdb.d/init.js b/infra/mongodb/docker-entrypoint-initdb.d/init.js index b426b82b8..00a7199df 100644 --- a/infra/mongodb/docker-entrypoint-initdb.d/init.js +++ b/infra/mongodb/docker-entrypoint-initdb.d/init.js @@ -96,42 +96,56 @@ db.Policies.insertOne( statements: [ { _id: getUUIDString(), - resourceType: "general", + resourceType: "account", + effect: "allow", + actions: ["UpdateOrgName"], + resources: ["account/*"] + }, + { + _id: getUUIDString(), + resourceType: "iam", effect: "allow", actions: ["CanManageIAM"], - resources: ["iam"] + resources: ["iam/*"] }, { _id: getUUIDString(), - resourceType: "general", + resourceType: "access-token", effect: "allow", actions: [ - "UpdateOrgName", "ManageServiceAccessTokens", "ManagePersonalAccessTokens", "ListAccessTokens" ], - resources: ["account"] + resources: ["access-token/*"] }, { _id: getUUIDString(), - resourceType: "general", + resourceType: "project", effect: "allow", actions: [ "ListProjects", "CreateProject", "DeleteProject", - "AccessEnvs", "UpdateProjectSettings", "ListEnvs", - "CreateEnv", + "CreateEnv" + ], + resources: ["project/*"] + }, + { + _id: getUUIDString(), + resourceType: "env", + effect: "allow", + actions: [ + "AccessEnvs", "DeleteEnv", "UpdateEnvSettings", "CreateEnvSecret", "DeleteEnvSecret", "UpdateEnvSecret" ], - resources: ["project"] + resources: ["project/*:env/*"] } ], createdAt: new Date(), @@ -148,25 +162,33 @@ db.Policies.insertOne( statements: [ { _id: getUUIDString(), - resourceType: "general", + resourceType: "access-token", + effect: "allow", + actions: [ + "ManageServiceAccessTokens", + "ManagePersonalAccessTokens", + "ListAccessTokens" + ], + resources: ["access-token/*"] + }, + { + _id: getUUIDString(), + resourceType: "project", effect: "allow", actions: [ - "AccessEnvs", "ListProjects", "ListEnvs" ], - resources: ["project"] + resources: ["project/*"] }, { _id: getUUIDString(), - resourceType: "general", + resourceType: "env", effect: "allow", actions: [ - "ManageServiceAccessTokens", - "ManagePersonalAccessTokens", - "ListAccessTokens" + "AccessEnvs" ], - resources: ["account"] + resources: ["project/*:env/*"] } ], createdAt: new Date(), diff --git a/modules/back-end/src/Application/Resources/ResourceVm.cs b/modules/back-end/src/Application/Resources/ResourceVm.cs index 918a5a63f..10b0ccb56 100644 --- a/modules/back-end/src/Application/Resources/ResourceVm.cs +++ b/modules/back-end/src/Application/Resources/ResourceVm.cs @@ -7,4 +7,6 @@ public class ResourceVm public string Name { get; set; } public string Rn { get; set; } + + public string Type { get; set; } } \ No newline at end of file diff --git a/modules/back-end/src/Domain/Resources/Resource.cs b/modules/back-end/src/Domain/Resources/Resource.cs index 5609ea06d..926de1d1d 100644 --- a/modules/back-end/src/Domain/Resources/Resource.cs +++ b/modules/back-end/src/Domain/Resources/Resource.cs @@ -7,4 +7,6 @@ public class Resource public string Name { get; set; } public string Rn { get; set; } + + public string Type { get; set; } } \ No newline at end of file diff --git a/modules/back-end/src/Domain/Resources/ResourceType.cs b/modules/back-end/src/Domain/Resources/ResourceType.cs index e1bdf237c..51af785e7 100644 --- a/modules/back-end/src/Domain/Resources/ResourceType.cs +++ b/modules/back-end/src/Domain/Resources/ResourceType.cs @@ -4,7 +4,11 @@ public class ResourceType { public const string All = "*"; - public const string General = "general"; + public const string Account = "account"; + + public const string IAM = "iam"; + + public const string AccessToken = "access-token"; public const string Project = "project"; diff --git a/modules/back-end/src/Infrastructure/Resources/ResourceService.cs b/modules/back-end/src/Infrastructure/Resources/ResourceService.cs index 6934caa33..d0cc83a53 100644 --- a/modules/back-end/src/Infrastructure/Resources/ResourceService.cs +++ b/modules/back-end/src/Infrastructure/Resources/ResourceService.cs @@ -25,7 +25,9 @@ public async Task> GetResourcesAsync(Guid organizationId, return filter.Type switch { ResourceType.All => GetAll(name), - ResourceType.General => GetGeneral(name), + ResourceType.Account => GetGeneral(ResourceType.Account, name), + ResourceType.IAM => GetGeneral(ResourceType.IAM, name), + ResourceType.AccessToken => GetGeneral(ResourceType.AccessToken, name), ResourceType.Env => await GetEnvsAsync(organizationId, name), ResourceType.Project => await GetProjectsAsync(organizationId, name), _ => Array.Empty() @@ -40,7 +42,8 @@ private IEnumerable GetAll(string name) { Id = new Guid("2bdcb290-2e1b-40d7-bdd1-697fb2193292"), Name = "All", - Rn = "*" + Rn = "*", + Type = ResourceType.All } }; @@ -52,36 +55,48 @@ private IEnumerable GetAll(string name) return resources; } - private IEnumerable GetGeneral(string name) + private IEnumerable GetGeneral(string resourceType, string name) { - var resources = new List + + var resource = resourceType switch { - new() + + ResourceType.Account => new Resource { Id = new Guid("e394832e-bd98-43de-b174-e0c98e03d19d"), Name = "Account", - Rn = "account" + Rn = "account/*", + Type = ResourceType.Account }, - new() + ResourceType.IAM => new Resource { Id = new Guid("d8791bd2-ca85-4629-a439-1dce20764211"), Name = "IAM", - Rn = "iam" + Rn = "iam/*", + Type = ResourceType.IAM }, - new() + ResourceType.AccessToken => new Resource { Id = new Guid("150083da-e20f-4670-948c-b842cf8a91a4"), - Name = "Project", - Rn = "project" - } + Name = "Access token", + Rn = "access-token/*", + Type = ResourceType.AccessToken + }, + _ => null }; + if (resource == null) + { + return new List(); + } + + var resources = new List { resource }; if (!string.IsNullOrWhiteSpace(name)) { resources = resources.Where(x => x.Name.Contains(name, StringComparison.OrdinalIgnoreCase)).ToList(); } - return resources; + return resources.ToList(); } public async Task> GetProjectsAsync(Guid organizationId, string name) @@ -105,8 +120,18 @@ public async Task> GetProjectsAsync(Guid organizationId, s { Id = x.Id, Name = x.Name, - Rn = x.Rn + Rn = x.Rn, + Type = ResourceType.Project + }).ToList(); + + resources.Insert(0, new Resource + { + Id = new Guid("e77679a2-e79b-43e5-aa9f-fd6c980239be"), + Name = "project", + Rn = "project/*", + Type = ResourceType.Project }); + return resources; } @@ -139,8 +164,19 @@ join organization in organizations on project.OrganizationId equals organization { Id = x.Id, Name = x.Name, - Rn = x.Rn + Rn = x.Rn, + Type = ResourceType.Env + }).ToList(); + + resources.Insert(0, new Resource + { + Id = new Guid("c62ed37a-74a9-4987-8ef4-b5a16127f307"), + Name = "env", + Rn = "project/*:env/*", + Type = ResourceType.Env }); + + return resources; } } \ No newline at end of file diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html index 2a2403bdc..f8535ac65 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html @@ -98,6 +98,7 @@ [(nzVisible)]="isCreationConfirmModalVisible" i18n-nzTitle="@@integrations.access-tokens.access-token-created" nzTitle="Access token created" + (nzOnCancel)="isCreationConfirmModalVisible = false" [nzFooter]="confirmFooter" (nzOnOk)="isCreationConfirmModalVisible = false"> diff --git a/modules/front-end/src/app/core/services/permissions.service.ts b/modules/front-end/src/app/core/services/permissions.service.ts index a72a0f28b..58a7b52bb 100644 --- a/modules/front-end/src/app/core/services/permissions.service.ts +++ b/modules/front-end/src/app/core/services/permissions.service.ts @@ -1,15 +1,15 @@ import {Injectable} from "@angular/core"; import {lastValueFrom} from "rxjs"; -import {IPolicy, IPolicyStatement} from "@features/safe/iam/types/policy"; +import {IPolicy} from "@features/safe/iam/types/policy"; import {MemberService} from "@services/member.service"; -import { EffectEnum, IamPolicyAction, ResourceTypeEnum } from "@shared/policy"; +import { EffectEnum, IamPolicyAction, IPolicyStatement, ResourceTypeEnum } from "@shared/policy"; @Injectable({ providedIn: 'root' }) export class PermissionsService { policies: IPolicy[]; - private permissions: IPolicyStatement[]; + permissions: IPolicyStatement[]; genericDenyMessage: string = $localize `:@@permissions.need-permissions-to-operate:You don't have permissions to take this action, please contact the admin to grant you the necessary permissions`; @@ -64,17 +64,11 @@ export class PermissionsService { // if return undefined, that means zero permission is defined on that resource canTakeAction(rn: string, action: IamPolicyAction): boolean | undefined | any { - const [resourceType, _] = rn.split('/'); - const statements = this.permissions.filter(s => { if (s.resourceType === ResourceTypeEnum.All) { return s.effect === EffectEnum.Allow; } - if (s.resourceType === ResourceTypeEnum.General) { - return s.resources.map(r => r.split('/')[0]).includes(resourceType) && s.actions.includes(action.name); - } - const matchingResource = s.resources.find(rsc => { // check exact match if (this.matchRule(rn, rsc)){ diff --git a/modules/front-end/src/app/core/services/policy.service.ts b/modules/front-end/src/app/core/services/policy.service.ts index 8fbf5cf39..d3b9d2f3f 100644 --- a/modules/front-end/src/app/core/services/policy.service.ts +++ b/modules/front-end/src/app/core/services/policy.service.ts @@ -8,12 +8,12 @@ import { IPagedPolicyGroup, IPagedPolicyMember, IPolicy, - IPolicyStatement, PolicyFilter, PolicyGroupFilter, PolicyMemberFilter } from "@features/safe/iam/types/policy"; import { catchError } from "rxjs/operators"; +import { IPolicyStatement } from "@shared/policy"; @Injectable({ providedIn: 'root' diff --git a/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts b/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts index bbe56e29b..34709a8f7 100644 --- a/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts +++ b/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts @@ -1,7 +1,7 @@ import {Component, EventEmitter, Input, Output} from '@angular/core'; import { EffectEnum, - IamPolicyAction, + IamPolicyAction, IPolicyStatement, isResourceGeneral, Resource, resourceActionsDict, resourcesTypes, @@ -9,7 +9,7 @@ import { ResourceTypeEnum } from "@shared/policy"; import {deepCopy, encodeURIComponentFfc, uuidv4} from "@utils/index"; -import {IPolicy, IPolicyStatement} from "@features/safe/iam/types/policy"; +import {IPolicy} from "@features/safe/iam/types/policy"; import {NzMessageService} from "ng-zorro-antd/message"; import {PolicyService} from "@services/policy.service"; import {Router} from "@angular/router"; @@ -37,30 +37,24 @@ class PolicyStatementViewModel { return find || act as unknown as IamPolicyAction; }); - this.selectedResources = statement.resources.map(rsc => ({id: uuidv4(), name: rsc, rn: rsc})); + this.selectedResources = statement.resources.map(rsc => ({id: uuidv4(), name: rsc, rn: rsc, type: this.resourceType.type})); + + // All the resources here are the same type, and if it's general type, resources only contains one element + const isGeneralResource = isResourceGeneral(this.resourceType?.type, statement.resources[0]); + this.availableActions = resourceActionsDict[this.resourceType?.type].filter((rs) => isGeneralResource || rs.isSpecificApplicable); } else { this.id = uuidv4(); this.effect = EffectEnum.Allow; this.selectedActions = []; this.selectedResources = []; + this.availableActions =[]; } - - const actionKey = this.resourceType?.type === ResourceTypeEnum.General ? - `${ResourceTypeEnum.General},${this.selectedResources[0]?.rn}` : - this.resourceType?.type; - - this.availableActions = resourceActionsDict[actionKey]; } onResourceTypeChange(){ this.selectedActions = []; this.selectedResources = []; - - const actionKey = this.resourceType?.type === ResourceTypeEnum.General ? - `${ResourceTypeEnum.General},${this.selectedResources[0]?.rn}` : - this.resourceType?.type; - - this.availableActions = resourceActionsDict[actionKey]; + this.availableActions = []; } selectedActions: IamPolicyAction[] = []; @@ -71,14 +65,10 @@ class PolicyStatementViewModel { selectedResources: Resource[] = []; onSelectedResourcesChange(resources: Resource[]) { this.selectedResources = [...resources]; + // All the resources here are the same type, and if it's general type, resources only contains one element + const isGeneralResource = isResourceGeneral(resources[0].type, resources[0].rn); - let actionKey: string = this.resourceType?.type; - if (this.resourceType?.type === ResourceTypeEnum.General) { - this.selectedActions = []; - actionKey = `${ResourceTypeEnum.General},${this.selectedResources[0]?.rn}`; - } - - this.availableActions = resourceActionsDict[actionKey]; + this.availableActions = resourceActionsDict[this.resourceType?.type].filter((rs) => isGeneralResource || rs.isSpecificApplicable); } getOutput(): IPolicyStatement { diff --git a/modules/front-end/src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.ts b/modules/front-end/src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.ts index 04b555af8..dc3b1e141 100644 --- a/modules/front-end/src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.ts +++ b/modules/front-end/src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.ts @@ -1,15 +1,16 @@ -import {Component, EventEmitter, Input, Output, ViewChild} from "@angular/core"; -import {NzSelectComponent} from "ng-zorro-antd/select"; +import { Component, EventEmitter, Input, Output, ViewChild } from "@angular/core"; +import { NzSelectComponent } from "ng-zorro-antd/select"; import { + isResourceGeneral, Resource, ResourceParamViewModel, ResourceType, - ResourceTypeEnum, RNViewModel, rscParamsDict } from "@shared/policy"; -import {ResourceService} from "@services/resource.service"; -import {deepCopy} from "@utils/index"; +import { ResourceService } from "@services/resource.service"; +import { deepCopy } from "@utils/index"; + @Component({ selector: 'resources-selector', templateUrl: './resources-selector.component.html', @@ -43,8 +44,10 @@ export class ResourcesSelectorComponent { @Input() selectedResources: Resource[] = []; onResourceChange() { - if (this.resourceType.type === ResourceTypeEnum.General) { + if (isResourceGeneral(this.resourceSelectModel.type, this.resourceSelectModel.rn)) { this.selectedResources = []; + } else { + this.selectedResources = this.selectedResources.filter((r) => !isResourceGeneral(r.type, r.rn)) } this.selectedResources = [...this.selectedResources, {...this.resourceSelectModel}]; this.onSelectedResourcesChange.next(this.selectedResources); @@ -87,14 +90,14 @@ export class ResourcesSelectorComponent { const paramValues = rsc.rn.split(':') .map(r => { const part = r.split('/'); - return {type: part[0], val: part[1]}}) - .reduce((acc, cur) => { - acc[cur.type] = cur.val; + return {type: part[0], val: part[1], isAnyChecked: part[1] === '*' }}) + .reduce((acc, { type, val, isAnyChecked}) => { + acc[type] = { val: val, isAnyChecked }; return acc; }, {}); if (paramValues) { - this.rscParams = this.rscParams.map(p => ({...p, val: paramValues[p.resourceType]})); + this.rscParams = this.rscParams.map(p => ({...p, val: paramValues[p.resourceType].val, isAnyChecked: paramValues[p.resourceType].isAnyChecked})); } } diff --git a/modules/front-end/src/app/features/safe/iam/policies/details/permission/permission.component.ts b/modules/front-end/src/app/features/safe/iam/policies/details/permission/permission.component.ts index 35e30a40e..55724f5a4 100644 --- a/modules/front-end/src/app/features/safe/iam/policies/details/permission/permission.component.ts +++ b/modules/front-end/src/app/features/safe/iam/policies/details/permission/permission.component.ts @@ -1,8 +1,9 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { IPolicy, IPolicyStatement } from "@features/safe/iam/types/policy"; +import { IPolicy } from "@features/safe/iam/types/policy"; import { PolicyService } from "@services/policy.service"; import { NzMessageService } from "ng-zorro-antd/message"; +import { IPolicyStatement } from "@shared/policy"; @Component({ selector: 'permission', diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html index ba877cbee..cd5851c50 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.html @@ -96,7 +96,8 @@
  • Activate
  • -
  • Deactivate
  • ): string { if (!project || !env) { return ''; } diff --git a/modules/front-end/src/app/shared/permissions.ts b/modules/front-end/src/app/shared/permissions.ts index 6aeffe976..b166598cf 100644 --- a/modules/front-end/src/app/shared/permissions.ts +++ b/modules/front-end/src/app/shared/permissions.ts @@ -3,9 +3,11 @@ import { IamPolicyAction } from "@shared/policy"; export const generalResourceRNPattern = { all: '*', - account: 'account', - iam: 'iam', - project: 'project', + account: 'account/*', + iam: 'iam/*', + accessToken: 'access-token/*', + project: 'project/*', + env: 'project/*:env/*' } export const permissionActions: {[key: string]: IamPolicyAction} = { @@ -14,92 +16,104 @@ export const permissionActions: {[key: string]: IamPolicyAction} = { name: '*', displayName: $localize`:@@iam.action.all:All`, description: $localize`:@@iam.action.all:All`, - isOpenAPIApplicable: false + isOpenAPIApplicable: false, + isSpecificApplicable: false }, - ListProjects: { id: uuidv4(), name: 'ListProjects', displayName: $localize`:@@iam.action.list-projects:List projects`, description: $localize`:@@iam.action.list-projects:List projects`, - isOpenAPIApplicable: true + isOpenAPIApplicable: true, + isSpecificApplicable: false }, CreateProject: { id: uuidv4(), name: 'CreateProject', displayName: $localize`:@@iam.action.create-projects:Create projects`, description: $localize`:@@iam.action.create-projects:Create projects`, - isOpenAPIApplicable: true + isOpenAPIApplicable: true, + isSpecificApplicable: false }, DeleteProject: { id: uuidv4(), name: 'DeleteProject', displayName: $localize`:@@iam.action.delete-projects:Delete projects`, description: $localize`:@@iam.action.delete-projects:Delete projects`, - isOpenAPIApplicable: true + isOpenAPIApplicable: true, + isSpecificApplicable: true }, AccessEnvs: { id: uuidv4(), name: 'AccessEnvs', displayName: $localize`:@@iam.action.access-envs:Access environments`, description: $localize`:@@iam.action.access-envs:Access environments`, - isOpenAPIApplicable: true + isOpenAPIApplicable: true, + isSpecificApplicable: true }, UpdateProjectSettings: { id: uuidv4(), name: 'UpdateProjectSettings', displayName: $localize`:@@iam.action.update-project-settings:Update project settings`, description: $localize`:@@iam.action.update-project-settings:Update project settings`, - isOpenAPIApplicable: true + isOpenAPIApplicable: true, + isSpecificApplicable: true }, ListEnvs: { id: uuidv4(), name: 'ListEnvs', displayName: $localize`:@@iam.action.list-envs:List environments`, description: $localize`:@@iam.action.list-envs:List environments`, - isOpenAPIApplicable: true + isOpenAPIApplicable: true, + isSpecificApplicable: true }, CreateEnv: { id: uuidv4(), name: 'CreateEnv', displayName: $localize`:@@iam.action.create-env:Create environment`, description: $localize`:@@iam.action.create-env:Create environment`, - isOpenAPIApplicable: true + isOpenAPIApplicable: true, + isSpecificApplicable: true }, DeleteEnv: { id: uuidv4(), name: 'DeleteEnv', displayName: $localize`:@@iam.action.delete-envs:Delete environments`, description: $localize`:@@iam.action.delete-envs:Delete environments`, - isOpenAPIApplicable: true + isOpenAPIApplicable: true, + isSpecificApplicable: true }, UpdateEnvSettings: { id: uuidv4(), name: 'UpdateEnvSettings', displayName: $localize`:@@iam.action.update-env-settings:Update environment settings`, description: $localize`:@@iam.action.update-env-settings:Update environment settings`, - isOpenAPIApplicable: true + isOpenAPIApplicable: true, + isSpecificApplicable: true }, DeleteEnvSecret: { id: uuidv4(), name: 'DeleteEnvSecret', displayName: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, description: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, - isOpenAPIApplicable: true + isOpenAPIApplicable: true, + isSpecificApplicable: true }, CreateEnvSecret: { id: uuidv4(), name: 'CreateEnvSecret', displayName: $localize`:@@iam.action.create-env-secret:Create environment secret`, description: $localize`:@@iam.action.create-env-secret:Create environment secret`, - isOpenAPIApplicable: true + isOpenAPIApplicable: true, + isSpecificApplicable: true }, UpdateEnvSecret: { id: uuidv4(), name: 'UpdateEnvSecret', displayName: $localize`:@@iam.action.update-env-secret:Update environment secret`, description: $localize`:@@iam.action.update-env-secret:Update environment secret`, - isOpenAPIApplicable: true + isOpenAPIApplicable: true, + isSpecificApplicable: true }, // account @@ -108,7 +122,8 @@ export const permissionActions: {[key: string]: IamPolicyAction} = { name: 'UpdateOrgName', displayName: $localize`:@@iam.action.update-org-name:Update org name`, description: $localize`:@@iam.action.update-org-name:Update org name`, - isOpenAPIApplicable: true + isOpenAPIApplicable: true, + isSpecificApplicable: false }, // iam @@ -117,7 +132,8 @@ export const permissionActions: {[key: string]: IamPolicyAction} = { name: 'CanManageIAM', displayName: $localize`:@@iam.action.iam:IAM`, description: $localize`:@@iam.action.iam:IAM`, - isOpenAPIApplicable: true + isOpenAPIApplicable: true, + isSpecificApplicable: false }, // access tokens @@ -126,20 +142,23 @@ export const permissionActions: {[key: string]: IamPolicyAction} = { name: 'ListAccessTokens', displayName: $localize`:@@iam.action.list-access-tokens:List access tokens`, description: $localize`:@@iam.action.list-access-tokens:List access tokens`, - isOpenAPIApplicable: true + isOpenAPIApplicable: true, + isSpecificApplicable: false }, CreateServiceAccessTokens: { id: uuidv4(), name: 'ManageServiceAccessTokens', displayName: $localize`:@@iam.action.manage-service-access-tokens:Manage service access tokens`, description: $localize`:@@iam.action.manage-service-access-tokens:Manage service access tokens`, - isOpenAPIApplicable: true + isOpenAPIApplicable: true, + isSpecificApplicable: false }, CreatePersonalAccessTokens: { id: uuidv4(), name: 'ManagePersonalAccessTokens', displayName: $localize`:@@iam.action.manage-personal-access-tokens:Manage personal access tokens`, description: $localize`:@@iam.action.manage-personal-access-tokens:Manage personal access tokens`, - isOpenAPIApplicable: true + isOpenAPIApplicable: true, + isSpecificApplicable: false }, } diff --git a/modules/front-end/src/app/shared/policy.ts b/modules/front-end/src/app/shared/policy.ts index 1f1d5f197..32030d5bd 100644 --- a/modules/front-end/src/app/shared/policy.ts +++ b/modules/front-end/src/app/shared/policy.ts @@ -1,10 +1,18 @@ import {generalResourceRNPattern, permissionActions} from "@shared/permissions"; -import {uuidv4} from "@utils/index"; + +export interface IPolicyStatement { + id: string; + resourceType: string; + effect: string; + actions: string[]; + resources: string[]; +} export interface Resource { id: string; name: string; rn: string; + type: ResourceTypeEnum; } export interface ValPlaceholder { @@ -18,11 +26,14 @@ export interface IamPolicyAction { displayName: string; description: string; isOpenAPIApplicable: boolean; + isSpecificApplicable: boolean; // can it be applied to a specific resource, ex: an environment with name "abc" } export enum ResourceTypeEnum { All = '*', - General = 'general', + Account = 'account', + IAM = 'iam', + AccessToken = 'access-token', Project = 'project', Env = 'env', } @@ -51,9 +62,19 @@ export const resourcesTypes: ResourceType[] = [ displayName: $localize`:@@iam.rsc-type.all:All` }, { - type: ResourceTypeEnum.General, - pattern: generalResourceRNPattern.project, - displayName: $localize`:@@iam.rsc-type.general:General` + type: ResourceTypeEnum.Account, + pattern: generalResourceRNPattern.account, + displayName: $localize`:@@iam.rsc-type.account:Account` + }, + { + type: ResourceTypeEnum.IAM, + pattern: generalResourceRNPattern.iam, + displayName: $localize`:@@iam.rsc-type.iam:IAM` + }, + { + type: ResourceTypeEnum.AccessToken, + pattern: generalResourceRNPattern.accessToken, + displayName: $localize`:@@iam.rsc-type.access-token:Access token` }, { type: ResourceTypeEnum.Project, @@ -77,7 +98,9 @@ export interface ResourceParamViewModel { export const rscParamsDict: {[key in ResourceTypeEnum]: ResourceParamViewModel[]} = { [ResourceTypeEnum.All]: [], - [ResourceTypeEnum.General]: [], + [ResourceTypeEnum.Account]: [], + [ResourceTypeEnum.IAM]: [], + [ResourceTypeEnum.AccessToken]: [], [ResourceTypeEnum.Project]: [ { val: '', @@ -118,40 +141,26 @@ export const resourceActionsDict: {[key: string]: IamPolicyAction[]} = { [ResourceTypeEnum.All]: [ permissionActions.All, ], - [`${ResourceTypeEnum.General},account`]: [ - permissionActions.UpdateOrgName, + [ResourceTypeEnum.Account]: [ + permissionActions.UpdateOrgName + ], + [ResourceTypeEnum.IAM]: [ + permissionActions.CanManageIAM, + ], + [ResourceTypeEnum.AccessToken]: [ permissionActions.ListAccessTokens, permissionActions.CreateServiceAccessTokens, permissionActions.CreatePersonalAccessTokens, ], - [`${ResourceTypeEnum.General},iam`]: [ - permissionActions.CanManageIAM, - ], - [`${ResourceTypeEnum.General},project`]: [ // for all projects + [ResourceTypeEnum.Project]: [ permissionActions.ListProjects, permissionActions.CreateProject, permissionActions.DeleteProject, permissionActions.UpdateProjectSettings, permissionActions.ListEnvs, permissionActions.CreateEnv, - permissionActions.AccessEnvs, - permissionActions.DeleteEnv, - permissionActions.UpdateEnvSettings, - permissionActions.DeleteEnvSecret, - permissionActions.CreateEnvSecret, - permissionActions.UpdateEnvSecret, - ], - [ResourceTypeEnum.Project]: [ // for a specific project - permissionActions.AccessEnvs, - permissionActions.DeleteProject, - permissionActions.UpdateProjectSettings, - permissionActions.ListEnvs, - permissionActions.CreateEnv, - permissionActions.DeleteEnvSecret, - permissionActions.CreateEnvSecret, - permissionActions.UpdateEnvSecret, ], - [ResourceTypeEnum.Env]: [ // for a specific environment + [ResourceTypeEnum.Env]: [ permissionActions.AccessEnvs, permissionActions.DeleteEnv, permissionActions.UpdateEnvSettings, @@ -160,3 +169,22 @@ export const resourceActionsDict: {[key: string]: IamPolicyAction[]} = { permissionActions.UpdateEnvSecret, ] } + +// check if the resource is a general resource +// if returns false, that means the actions which cannot be applied to a specific resource should be hidden +// ex: ListProjects should not be avaible for a specific project: project/abc +export function isResourceGeneral(type: ResourceTypeEnum, rn: string): boolean { + const generalResourceTypes = [ResourceTypeEnum.All, ResourceTypeEnum.Account, ResourceTypeEnum.IAM, ResourceTypeEnum.AccessToken]; + if (generalResourceTypes.includes(type)) { + return true; + } + + switch (type) { + case ResourceTypeEnum.Project: + return rn === generalResourceRNPattern.project; + case ResourceTypeEnum.Env: + return rn === generalResourceRNPattern.env; + } + + return false; +} diff --git a/modules/front-end/src/locale/messages.xlf b/modules/front-end/src/locale/messages.xlf index 09b4d21f4..70d514f75 100644 --- a/modules/front-end/src/locale/messages.xlf +++ b/modules/front-end/src/locale/messages.xlf @@ -446,14 +446,14 @@ Copy and save this token now, the token value will be masked once you leave the page. src/app/core/components/access-token-drawer/access-token-drawer.component.html - 108 + 109 OK src/app/core/components/access-token-drawer/access-token-drawer.component.html - 123 + 124 @@ -607,7 +607,7 @@ src/app/features/safe/iam/policies/details/permission/permission.component.ts - 40 + 41 src/app/features/safe/iam/policies/details/setting/setting.component.ts @@ -781,7 +781,7 @@ src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 140 + 130 src/app/features/safe/iam/groups/details/setting/setting.component.ts @@ -1413,11 +1413,11 @@ src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 142 + 132 src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 145 + 135 src/app/features/safe/iam/groups/details/policies/policies.component.ts @@ -1453,7 +1453,7 @@ src/app/features/safe/iam/policies/details/permission/permission.component.ts - 41 + 42 src/app/features/safe/iam/policies/details/setting/setting.component.ts @@ -4880,7 +4880,7 @@ src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 152 + 142 @@ -4923,7 +4923,7 @@ Make sure resource and operation are set for all permissions src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 158 + 148 @@ -5455,7 +5455,7 @@ Deactivate this access token? You can't use an inactive access token to make API calls but you can activate it again later. src/app/features/safe/integrations/access-tokens/index/index.component.html - 102 + 103 src/app/features/safe/integrations/access-tokens/index/index.component.html @@ -5466,7 +5466,7 @@ Deactivate src/app/features/safe/integrations/access-tokens/index/index.component.html - 107 + 108 @@ -6309,244 +6309,258 @@ All src/app/shared/permissions.ts - 15 + 17 src/app/shared/permissions.ts - 16 + 18 List projects src/app/shared/permissions.ts - 23 + 25 src/app/shared/permissions.ts - 24 + 26 Create projects src/app/shared/permissions.ts - 30 + 33 src/app/shared/permissions.ts - 31 + 34 Delete projects src/app/shared/permissions.ts - 37 + 41 src/app/shared/permissions.ts - 38 + 42 Access environments src/app/shared/permissions.ts - 44 + 49 src/app/shared/permissions.ts - 45 + 50 Update project settings src/app/shared/permissions.ts - 51 + 57 src/app/shared/permissions.ts - 52 + 58 List environments src/app/shared/permissions.ts - 58 + 65 src/app/shared/permissions.ts - 59 + 66 Create environment src/app/shared/permissions.ts - 65 + 73 src/app/shared/permissions.ts - 66 + 74 Delete environments src/app/shared/permissions.ts - 72 + 81 src/app/shared/permissions.ts - 73 + 82 Update environment settings src/app/shared/permissions.ts - 79 + 89 src/app/shared/permissions.ts - 80 + 90 Delete environment secret src/app/shared/permissions.ts - 86 + 97 src/app/shared/permissions.ts - 87 + 98 Create environment secret src/app/shared/permissions.ts - 93 + 105 src/app/shared/permissions.ts - 94 + 106 Update environment secret src/app/shared/permissions.ts - 100 + 113 src/app/shared/permissions.ts - 101 + 114 Update org name src/app/shared/permissions.ts - 109 + 123 src/app/shared/permissions.ts - 110 + 124 IAM src/app/shared/permissions.ts - 118 + 133 src/app/shared/permissions.ts - 119 + 134 List access tokens src/app/shared/permissions.ts - 127 + 143 src/app/shared/permissions.ts - 128 + 144 Manage service access tokens src/app/shared/permissions.ts - 134 + 151 src/app/shared/permissions.ts - 135 + 152 Manage personal access tokens src/app/shared/permissions.ts - 141 + 159 src/app/shared/permissions.ts - 142 + 160 All src/app/shared/policy.ts - 51 + 62 - - General + + Account src/app/shared/policy.ts - 56 + 67 + + + + IAM + + src/app/shared/policy.ts + 72 + + + + Access token + + src/app/shared/policy.ts + 77 Project src/app/shared/policy.ts - 61 + 82 Environment src/app/shared/policy.ts - 66 + 87 Project src/app/shared/policy.ts - 87 + 110 src/app/shared/policy.ts - 99 + 122 Environment src/app/shared/policy.ts - 109 + 132 diff --git a/modules/front-end/src/locale/messages.zh.xlf b/modules/front-end/src/locale/messages.zh.xlf index fe66adbc7..33347a956 100644 --- a/modules/front-end/src/locale/messages.zh.xlf +++ b/modules/front-end/src/locale/messages.zh.xlf @@ -457,7 +457,7 @@ Copy and save this token now, the token value will be masked once you leave the page. src/app/core/components/access-token-drawer/access-token-drawer.component.html - 108 + 109 请复制并保存 Token,一旦离开该页面后,该 Token 将会被隐藏。 @@ -465,7 +465,7 @@ OK src/app/core/components/access-token-drawer/access-token-drawer.component.html - 123 + 124 OK @@ -621,7 +621,7 @@ src/app/features/safe/iam/policies/details/permission/permission.component.ts - 40 + 41 src/app/features/safe/iam/policies/details/setting/setting.component.ts @@ -797,7 +797,7 @@ src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 140 + 130 src/app/features/safe/iam/groups/details/setting/setting.component.ts @@ -1489,11 +1489,11 @@ src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 142 + 132 src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 145 + 135 src/app/features/safe/iam/groups/details/policies/policies.component.ts @@ -1529,7 +1529,7 @@ src/app/features/safe/iam/policies/details/permission/permission.component.ts - 41 + 42 src/app/features/safe/iam/policies/details/setting/setting.component.ts @@ -5316,7 +5316,7 @@ src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 152 + 142 系统托管策略不允许被修改。 如确有需要,可以复制以后再根据需求进行修改。 @@ -5364,7 +5364,7 @@ Make sure resource and operation are set for all permissions src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 158 + 148 请确保已设置所有权限的资源和操作 @@ -5964,7 +5964,7 @@ Deactivate this access token? You can't use an inactive access token to make API calls but you can activate it again later. src/app/features/safe/integrations/access-tokens/index/index.component.html - 102 + 103 src/app/features/safe/integrations/access-tokens/index/index.component.html @@ -5976,7 +5976,7 @@ Deactivate src/app/features/safe/integrations/access-tokens/index/index.component.html - 107 + 108 停用 @@ -6933,11 +6933,11 @@ All src/app/shared/permissions.ts - 15 + 17 src/app/shared/permissions.ts - 16 + 18 全部操作 @@ -6945,11 +6945,11 @@ List projects src/app/shared/permissions.ts - 23 + 25 src/app/shared/permissions.ts - 24 + 26 查看项目列表 @@ -6957,11 +6957,11 @@ Create projects src/app/shared/permissions.ts - 30 + 33 src/app/shared/permissions.ts - 31 + 34 创建项目 @@ -6969,11 +6969,11 @@ Delete projects src/app/shared/permissions.ts - 37 + 41 src/app/shared/permissions.ts - 38 + 42 删除项目 @@ -6981,11 +6981,11 @@ Access environments src/app/shared/permissions.ts - 44 + 49 src/app/shared/permissions.ts - 45 + 50 进入环境 @@ -6993,11 +6993,11 @@ Update project settings src/app/shared/permissions.ts - 51 + 57 src/app/shared/permissions.ts - 52 + 58 修改项目设置 @@ -7005,11 +7005,11 @@ List environments src/app/shared/permissions.ts - 58 + 65 src/app/shared/permissions.ts - 59 + 66 查看环境列表 @@ -7017,11 +7017,11 @@ Create environment src/app/shared/permissions.ts - 65 + 73 src/app/shared/permissions.ts - 66 + 74 创建环境 @@ -7029,11 +7029,11 @@ Delete environments src/app/shared/permissions.ts - 72 + 81 src/app/shared/permissions.ts - 73 + 82 删除环境 @@ -7041,11 +7041,11 @@ Update environment settings src/app/shared/permissions.ts - 79 + 89 src/app/shared/permissions.ts - 80 + 90 修改环境设置 @@ -7053,11 +7053,11 @@ Delete environment secret src/app/shared/permissions.ts - 86 + 97 src/app/shared/permissions.ts - 87 + 98 删除环境秘钥 @@ -7065,11 +7065,11 @@ Create environment secret src/app/shared/permissions.ts - 93 + 105 src/app/shared/permissions.ts - 94 + 106 创建环境秘钥 @@ -7077,11 +7077,11 @@ Update environment secret src/app/shared/permissions.ts - 100 + 113 src/app/shared/permissions.ts - 101 + 114 修改环境秘钥 @@ -7089,11 +7089,11 @@ Update org name src/app/shared/permissions.ts - 109 + 123 src/app/shared/permissions.ts - 110 + 124 修改机构名称 @@ -7101,11 +7101,11 @@ IAM src/app/shared/permissions.ts - 118 + 133 src/app/shared/permissions.ts - 119 + 134 权限管理 @@ -7113,11 +7113,11 @@ List access tokens src/app/shared/permissions.ts - 127 + 143 src/app/shared/permissions.ts - 128 + 144 查看访问策略列表 @@ -7125,11 +7125,11 @@ Manage service access tokens src/app/shared/permissions.ts - 134 + 151 src/app/shared/permissions.ts - 135 + 152 管理 Service 访问策略 @@ -7137,11 +7137,11 @@ Manage personal access tokens src/app/shared/permissions.ts - 141 + 159 src/app/shared/permissions.ts - 142 + 160 管理 Personal 访问策略 @@ -7149,23 +7149,39 @@ All src/app/shared/policy.ts - 51 + 62 全部 - - General + + Account src/app/shared/policy.ts - 56 + 67 + + 账户管理 + + + IAM + + src/app/shared/policy.ts + 72 + + 权限管理 + + + Access token + + src/app/shared/policy.ts + 77 - 通用 + 访问策略 Project src/app/shared/policy.ts - 61 + 82 项目 @@ -7173,7 +7189,7 @@ Environment src/app/shared/policy.ts - 66 + 87 环境 @@ -7181,11 +7197,11 @@ Project src/app/shared/policy.ts - 87 + 110 src/app/shared/policy.ts - 99 + 122 项目 @@ -7193,7 +7209,7 @@ Environment src/app/shared/policy.ts - 109 + 132 环境 From 7c2709211e76c52e489dedcafac6d4c16dc5e963 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Wed, 15 Mar 2023 07:52:04 +0100 Subject: [PATCH 27/44] translation fix --- modules/front-end/src/locale/messages.xlf | 2281 ++++++++++-------- modules/front-end/src/locale/messages.zh.xlf | 486 +--- 2 files changed, 1319 insertions(+), 1448 deletions(-) diff --git a/modules/front-end/src/locale/messages.xlf b/modules/front-end/src/locale/messages.xlf index 87af57093..d6d7e7ca2 100644 --- a/modules/front-end/src/locale/messages.xlf +++ b/modules/front-end/src/locale/messages.xlf @@ -2,373 +2,366 @@ - - created + + Add access token - src/app/core/components/audit-log/audit-log.component.ts - 92 + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 7 - - updated + + Name - src/app/core/components/audit-log/audit-log.component.ts - 95 + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 15 - - - archived - src/app/core/components/audit-log/audit-log.component.ts - 98 + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 17 - - - restored - src/app/core/components/audit-log/audit-log.component.ts - 101 + src/app/core/components/env-drawer/env-drawer.component.html + 22 - - - removed - src/app/core/components/audit-log/audit-log.component.ts - 104 + src/app/core/components/env-drawer/env-drawer.component.html + 24 - - - flag - src/app/core/components/audit-log/audit-log.component.ts - 112 + src/app/core/components/group-drawer/group-drawer.component.html + 14 - - - segment - src/app/core/components/audit-log/audit-log.component.ts - 115 + src/app/core/components/group-drawer/group-drawer.component.html + 16 - - - Filter by name, comment - src/app/core/components/audit-logs/audit-logs.component.html - 6 + src/app/core/components/metric-drawer/metric-drawer.component.html + 12 - - - Filter by team member - src/app/core/components/audit-logs/audit-logs.component.html - 20 + src/app/core/components/metric-drawer/metric-drawer.component.html + 14 - - - Loading... - src/app/core/components/audit-logs/audit-logs.component.html - 26 + src/app/core/components/organization-drawer/organization-drawer.component.html + 13 - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 36 + src/app/core/components/organization-drawer/organization-drawer.component.html + 15 - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 66 + src/app/core/components/policy-drawer/policy-drawer.component.html + 14 - src/app/core/components/member-drawer/member-drawer.component.html - 38 + src/app/core/components/policy-drawer/policy-drawer.component.html + 16 - src/app/core/components/member-drawer/member-drawer.component.html - 55 + src/app/core/components/project-drawer/project-drawer.component.html + 23 - src/app/core/components/metric-drawer/metric-drawer.component.html - 43 + src/app/core/components/project-drawer/project-drawer.component.html + 25 - src/app/core/components/target-user/target-user.component.html - 44 + src/app/core/components/props-drawer/props-drawer.component.html + 39 - src/app/features/safe/end-users/index/index.component.html - 25 + src/app/core/components/props-drawer/props-drawer.component.html + 74 - src/app/features/safe/end-users/index/index.component.html - 60 + src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.html + 37,38 - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 138 + src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.html + 85,86 - src/app/features/safe/feature-flags/details/insights/insights.component.html - 18 + src/app/features/safe/data-sync/remote-sync/remote-sync.component.html + 25 - src/app/features/safe/feature-flags/details/setting/setting.component.html - 146,147 + src/app/features/safe/end-users/details/details.component.html + 16 - src/app/features/safe/feature-flags/index/index.component.html - 26 + src/app/features/safe/feature-flags/details/insights/insights.component.html + 56 - src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html - 38 + src/app/features/safe/feature-flags/details/setting/setting.component.html + 31 - - - Filter by type - src/app/core/components/audit-logs/audit-logs.component.html - 35 + src/app/features/safe/feature-flags/index/index.component.html + 70 - - - Feature flag - src/app/core/components/audit-logs/audit-logs.component.html - 36 + src/app/features/safe/feature-flags/index/index.component.html + 185 - - - Segment - src/app/core/components/audit-logs/audit-logs.component.html - 37 + src/app/features/safe/iam/groups/details/setting/setting.component.html + 10 - - - No data - src/app/core/components/audit-logs/audit-logs.component.html - 44 + src/app/features/safe/iam/groups/details/setting/setting.component.html + 17 - - - More - src/app/core/components/audit-logs/audit-logs.component.html - 60 + src/app/features/safe/iam/groups/details/team/team.component.html + 27 - - - Failed to load team members - src/app/core/components/audit-logs/audit-logs.component.ts - 106 + src/app/features/safe/iam/groups/index/index.component.html + 29 - - - Enabled - src/app/core/components/change-list/change-list.component.html - 8 + src/app/features/safe/iam/policies/details/groups/groups.component.html + 27 - - - Disabled - src/app/core/components/change-list/change-list.component.html - 12 + src/app/features/safe/iam/policies/details/setting/setting.component.html + 10 - - - Archived - src/app/core/components/change-list/change-list.component.html - 16 + src/app/features/safe/iam/policies/details/setting/setting.component.html + 17 - - - Unarchived - src/app/core/components/change-list/change-list.component.html - 20 + src/app/features/safe/iam/policies/details/team/team.component.html + 28 - - - Set - src/app/core/components/change-list/change-list.component.html - 24 + src/app/features/safe/iam/policies/index/index.component.html + 29 - - - from - src/app/core/components/change-list/change-list.component.html - 27 + src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.html + 30 - - - to - src/app/core/components/change-list/change-list.component.html - 34 + src/app/features/safe/iam/team/details/groups/groups.component.html + 27 - - - Added - src/app/core/components/change-list/change-list.component.html - 42 + src/app/features/safe/iam/team/details/inherited-policies/inherited-policies.component.html + 23 - - - to - src/app/core/components/change-list/change-list.component.html - 48 + src/app/features/safe/iam/team/details/setting/setting.component.html + 10 - - - From - src/app/core/components/change-list/change-list.component.html - 54 + src/app/features/safe/iam/team/index/index.component.html + 29 - - - removed - src/app/core/components/change-list/change-list.component.html + src/app/features/safe/integrations/access-tokens/index/index.component.html 57 - - - Serve - src/app/core/components/change-list/change-list.component.html - 79 + src/app/features/safe/organizations/profile/profile.component.html + 4 - - - Dispatch by - src/app/core/components/change-list/change-list.component.html - 85 + src/app/features/safe/organizations/profile/profile.component.html + 7 - src/app/shared/diff/feature-flag.differ.ts - 293 + src/app/features/safe/organizations/project/project.component.html + 120 - - - Review and save - src/app/core/components/change-review/change-review.component.html - 3 + src/app/features/safe/segments/details/setting/setting.component.html + 15 - src/app/features/safe/feature-flags/details/targeting/targeting.component.html - 17,19 + src/app/features/safe/segments/index/index.component.html + 35 - src/app/features/safe/segments/details/targeting/targeting.component.html - 22,24 + src/app/features/safe/segments/index/index.component.html + 82 - - The following changes may affects the insights data + + Validating... - src/app/core/components/change-review/change-review.component.html + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 16 + + + src/app/core/components/group-drawer/group-drawer.component.html 15 - - - Changes - src/app/core/components/change-review/change-review.component.html - 19 + src/app/core/components/policy-drawer/policy-drawer.component.html + 15 - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 160 + src/app/features/safe/feature-flags/index/index.component.html + 203 + + + src/app/features/safe/segments/index/index.component.html + 83 - - changes to submit + + Access token name cannot be empty - src/app/core/components/change-review/change-review.component.html - 23 + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 20 - - Comment + + This access token name is not available - src/app/core/components/change-review/change-review.component.html - 31 + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 21 + + + + Type + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 27 - src/app/core/components/change-review/change-review.component.html + src/app/features/safe/data-sync/remote-sync/remote-sync.component.html + 26 + + + src/app/features/safe/iam/policies/details/setting/setting.component.html 33 - src/app/core/components/props-drawer/props-drawer.component.html - 44 + src/app/features/safe/iam/policies/index/index.component.html + 30 - src/app/features/safe/data-sync/remote-sync/remote-sync.component.html - 29 + src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.html + 31 - src/app/features/safe/end-users/details/details.component.html - 18 + src/app/features/safe/iam/team/details/inherited-policies/inherited-policies.component.html + 25 + + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 58 - - Cancel + + Policies - src/app/core/components/change-review/change-review.component.html - 41 + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 45 - src/app/core/components/header/header.component.html - 79,80 + src/app/features/safe/iam/groups/details/details.component.html + 13 + + + Select policies - src/app/core/components/header/header.component.html - 110,111 + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 50 + + + Loading... - src/app/core/components/props-drawer/props-drawer.component.html - 103 + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 68 + + + src/app/core/components/audit-logs/audit-logs.component.html + 26 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 36 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 66 + + + src/app/core/components/member-drawer/member-drawer.component.html + 38 + + + src/app/core/components/member-drawer/member-drawer.component.html + 55 + + + src/app/core/components/metric-drawer/metric-drawer.component.html + 43 src/app/core/components/target-user/target-user.component.html - 68 + 44 + + + src/app/features/safe/end-users/index/index.component.html + 25 + + + src/app/features/safe/end-users/index/index.component.html + 60 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html + 136 + + + src/app/features/safe/feature-flags/details/insights/insights.component.html + 18 src/app/features/safe/feature-flags/details/setting/setting.component.html - 172,173 + 146,147 src/app/features/safe/feature-flags/index/index.component.html - 223 + 26 src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html - 75 + 38 - src/app/features/safe/segments/index/index.component.html - 102 + src/app/features/safe/integrations/access-tokens/index/index.component.html + 28 + + + Policies are mandatory for service type access tokens - src/app/features/safe/segments/index/index.component.html - 141 + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 82 + + + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 267 Save + + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 92 + src/app/core/components/change-review/change-review.component.html 43 @@ -442,186 +435,698 @@ 104 - - Permission will become invalid if you change the name + + Access token created - src/app/core/components/env-drawer/env-drawer.component.html - 15 + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 100 + + + Copy and save this token now, the token value will be masked once you leave the page. - src/app/core/components/project-drawer/project-drawer.component.html - 16 + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 109 - - Name + + OK - src/app/core/components/env-drawer/env-drawer.component.html - 22 + src/app/core/components/access-token-drawer/access-token-drawer.component.html + 124 + + + You don't have permissions to take this action, please contact the admin to grant you the necessary permissions - src/app/core/components/env-drawer/env-drawer.component.html - 24 + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 234 - src/app/core/components/group-drawer/group-drawer.component.html + src/app/core/services/permissions.service.ts 14 + + + Operation succeeded - src/app/core/components/group-drawer/group-drawer.component.html - 16 + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 243 - src/app/core/components/metric-drawer/metric-drawer.component.html - 12 + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 258 - src/app/core/components/metric-drawer/metric-drawer.component.html - 14 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts + 193 - src/app/core/components/organization-drawer/organization-drawer.component.html - 13 + src/app/core/components/group-drawer/group-drawer.component.ts + 68 - src/app/core/components/organization-drawer/organization-drawer.component.html - 15 + src/app/core/components/member-drawer/member-drawer.component.ts + 121 - src/app/core/components/policy-drawer/policy-drawer.component.html - 14 + src/app/core/components/metric-drawer/metric-drawer.component.ts + 241 - src/app/core/components/policy-drawer/policy-drawer.component.html - 16 + src/app/core/components/metric-drawer/metric-drawer.component.ts + 258 - src/app/core/components/project-drawer/project-drawer.component.html - 23 + src/app/core/components/policy-drawer/policy-drawer.component.ts + 68 - src/app/core/components/project-drawer/project-drawer.component.html - 25 + src/app/core/components/props-drawer/props-drawer.component.ts + 93 - src/app/core/components/props-drawer/props-drawer.component.html - 39 + src/app/core/components/props-drawer/props-drawer.component.ts + 116 - src/app/core/components/props-drawer/props-drawer.component.html - 74 + src/app/core/components/props-drawer/props-drawer.component.ts + 134 - src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.html - 37,38 + src/app/features/safe/experiments/metrics/metrics.component.ts + 85 - src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.html - 85,86 + src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts + 60 - src/app/features/safe/data-sync/remote-sync/remote-sync.component.html - 25 + src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts + 78 - src/app/features/safe/end-users/details/details.component.html - 16 + src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts + 87 - src/app/features/safe/feature-flags/details/insights/insights.component.html - 56 + src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts + 98 - src/app/features/safe/feature-flags/details/setting/setting.component.html - 31 + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 85 - src/app/features/safe/feature-flags/index/index.component.html - 70 + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 96 - src/app/features/safe/feature-flags/index/index.component.html - 185 + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 199 - src/app/features/safe/iam/groups/details/setting/setting.component.html - 10 + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 332 - src/app/features/safe/iam/groups/details/setting/setting.component.html - 17 + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 344 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 352 + + + src/app/features/safe/feature-flags/index/index.component.ts + 336 + + + src/app/features/safe/feature-flags/index/index.component.ts + 349 + + + src/app/features/safe/feature-flags/index/index.component.ts + 359 + + + src/app/features/safe/iam/groups/details/policies/policies.component.ts + 74 + + + src/app/features/safe/iam/groups/details/policies/policies.component.ts + 88 + + + src/app/features/safe/iam/groups/details/setting/setting.component.ts + 42 + + + src/app/features/safe/iam/groups/details/setting/setting.component.ts + 69 + + + src/app/features/safe/iam/groups/details/team/team.component.ts + 73 + + + src/app/features/safe/iam/groups/details/team/team.component.ts + 87 + + + src/app/features/safe/iam/groups/index/index.component.ts + 84 + + + src/app/features/safe/iam/policies/details/groups/groups.component.ts + 76 + + + src/app/features/safe/iam/policies/details/groups/groups.component.ts + 90 + + + src/app/features/safe/iam/policies/details/permission/permission.component.ts + 41 + + + src/app/features/safe/iam/policies/details/setting/setting.component.ts + 46 + + + src/app/features/safe/iam/policies/details/setting/setting.component.ts + 53 + + + src/app/features/safe/iam/policies/details/team/team.component.ts + 76 + + + src/app/features/safe/iam/policies/details/team/team.component.ts + 90 + + + src/app/features/safe/iam/policies/index/index.component.ts + 80 + + + src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.ts + 75 + + + src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.ts + 89 + + + src/app/features/safe/iam/team/details/groups/groups.component.ts + 81 + + + src/app/features/safe/iam/team/details/groups/groups.component.ts + 95 + + + src/app/features/safe/iam/team/details/setting/setting.component.ts + 51 + + + src/app/features/safe/iam/team/index/index.component.ts + 72 + + + src/app/features/safe/integrations/access-tokens/index/index.component.ts + 143 + + + src/app/features/safe/integrations/access-tokens/index/index.component.ts + 154 + + + src/app/features/safe/segments/details/setting/setting.component.ts + 60 + + + src/app/features/safe/segments/details/targeting/targeting.component.ts + 136 + + + src/app/features/safe/segments/index/index.component.ts + 41 + + + src/app/features/safe/segments/index/index.component.ts + 63 + + + src/app/features/safe/segments/index/index.component.ts + 76 + + + + Operation failed, please try again + + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 246 + + + src/app/core/components/metric-drawer/metric-drawer.component.ts + 244 + + + src/app/core/components/target-user/target-user.component.ts + 127 + + + src/app/core/components/target-user/target-user.component.ts + 159 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts + 213 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts + 229 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts + 296 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts + 309 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 283 + + + src/app/features/safe/feature-flags/details/targeting/targeting.component.ts + 109 + + + src/app/features/safe/feature-flags/index/index.component.ts + 339 + + + src/app/features/safe/onboarding/steps/steps.component.ts + 63 + + + src/app/features/safe/organizations/project/project.component.ts + 253 + + + src/app/features/safe/organizations/project/project.component.ts + 287 + + + src/app/features/safe/organizations/project/project.component.ts + 303 + + + src/app/features/safe/segments/index/index.component.ts + 79 + + + + Copied + + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 277 + + + src/app/core/components/header/header.component.ts + 160 + + + src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.ts + 60 + + + src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts + 110 + + + src/app/features/safe/feature-flags/details/setting/setting.component.ts + 42 + + + src/app/features/safe/feature-flags/index/index.component.ts + 204 + + + src/app/features/safe/feature-flags/index/index.component.ts + 373 + + + src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts + 131 + + + src/app/features/safe/iam/groups/details/setting/setting.component.ts + 80 + + + src/app/features/safe/iam/groups/index/index.component.ts + 78 + + + src/app/features/safe/iam/policies/details/setting/setting.component.ts + 80 + + + src/app/features/safe/iam/policies/index/index.component.ts + 88 + + + src/app/features/safe/iam/team/details/setting/setting.component.ts + 58 + + + src/app/features/safe/iam/team/index/index.component.ts + 92 + + + src/app/features/safe/organizations/project/project.component.ts + 181 + + + + created + + src/app/core/components/audit-log/audit-log.component.ts + 92 + + + + updated + + src/app/core/components/audit-log/audit-log.component.ts + 95 + + + archived - src/app/features/safe/iam/groups/details/team/team.component.html - 27 + src/app/core/components/audit-log/audit-log.component.ts + 98 + + + restored - src/app/features/safe/iam/groups/index/index.component.html - 29 + src/app/core/components/audit-log/audit-log.component.ts + 101 + + + removed - src/app/features/safe/iam/policies/details/groups/groups.component.html - 27 + src/app/core/components/audit-log/audit-log.component.ts + 104 + + + flag - src/app/features/safe/iam/policies/details/setting/setting.component.html - 10 + src/app/core/components/audit-log/audit-log.component.ts + 112 + + + segment - src/app/features/safe/iam/policies/details/setting/setting.component.html - 17 + src/app/core/components/audit-log/audit-log.component.ts + 115 + + + Filter by name, comment - src/app/features/safe/iam/policies/details/team/team.component.html - 28 + src/app/core/components/audit-logs/audit-logs.component.html + 6 + + + Filter by team member - src/app/features/safe/iam/policies/index/index.component.html - 29 + src/app/core/components/audit-logs/audit-logs.component.html + 20 + + + Filter by type - src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.html - 30 + src/app/core/components/audit-logs/audit-logs.component.html + 35 + + + Feature flag - src/app/features/safe/iam/team/details/groups/groups.component.html + src/app/core/components/audit-logs/audit-logs.component.html + 36 + + + + Segment + + src/app/core/components/audit-logs/audit-logs.component.html + 37 + + + + No data + + src/app/core/components/audit-logs/audit-logs.component.html + 44 + + + + More + + src/app/core/components/audit-logs/audit-logs.component.html + 60 + + + + Failed to load team members + + src/app/core/components/audit-logs/audit-logs.component.ts + 106 + + + + Enabled + + src/app/core/components/change-list/change-list.component.html + 8 + + + + Disabled + + src/app/core/components/change-list/change-list.component.html + 12 + + + + Archived + + src/app/core/components/change-list/change-list.component.html + 16 + + + + Unarchived + + src/app/core/components/change-list/change-list.component.html + 20 + + + + Set + + src/app/core/components/change-list/change-list.component.html + 24 + + + + from + + src/app/core/components/change-list/change-list.component.html 27 + + + to - src/app/features/safe/iam/team/details/inherited-policies/inherited-policies.component.html + src/app/core/components/change-list/change-list.component.html + 34 + + + + Added + + src/app/core/components/change-list/change-list.component.html + 42 + + + + to + + src/app/core/components/change-list/change-list.component.html + 48 + + + + From + + src/app/core/components/change-list/change-list.component.html + 54 + + + + removed + + src/app/core/components/change-list/change-list.component.html + 57 + + + + Serve + + src/app/core/components/change-list/change-list.component.html + 79 + + + + Dispatch by + + src/app/core/components/change-list/change-list.component.html + 85 + + + src/app/shared/diff/feature-flag.differ.ts + 293 + + + + Review and save + + src/app/core/components/change-review/change-review.component.html + 3 + + + src/app/features/safe/feature-flags/details/targeting/targeting.component.html + 17,19 + + + src/app/features/safe/segments/details/targeting/targeting.component.html + 22,24 + + + + The following changes may affects the insights data + + src/app/core/components/change-review/change-review.component.html + 15 + + + + Changes + + src/app/core/components/change-review/change-review.component.html + 19 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html + 158 + + + + changes to submit + + src/app/core/components/change-review/change-review.component.html 23 + + + Comment + + src/app/core/components/change-review/change-review.component.html + 31 + + + src/app/core/components/change-review/change-review.component.html + 33 + + + src/app/core/components/props-drawer/props-drawer.component.html + 44 + + + src/app/features/safe/data-sync/remote-sync/remote-sync.component.html + 29 + + + src/app/features/safe/end-users/details/details.component.html + 18 + + + + Cancel + + src/app/core/components/change-review/change-review.component.html + 41 + + + src/app/core/components/header/header.component.html + 79,80 + - src/app/features/safe/iam/team/details/setting/setting.component.html - 10 + src/app/core/components/header/header.component.html + 110,111 - src/app/features/safe/iam/team/index/index.component.html - 29 + src/app/core/components/props-drawer/props-drawer.component.html + 103 - src/app/features/safe/organizations/profile/profile.component.html - 4 + src/app/core/components/target-user/target-user.component.html + 68 - src/app/features/safe/organizations/profile/profile.component.html - 7 + src/app/features/safe/feature-flags/details/setting/setting.component.html + 172,173 - src/app/features/safe/organizations/project/project.component.html - 120 + src/app/features/safe/feature-flags/index/index.component.html + 223 - src/app/features/safe/segments/details/setting/setting.component.html - 15 + src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html + 75 src/app/features/safe/segments/index/index.component.html - 35 + 102 src/app/features/safe/segments/index/index.component.html - 82 + 141 + + + + Permission will become invalid if you change the name + + src/app/core/components/env-drawer/env-drawer.component.html + 15 + + + src/app/core/components/project-drawer/project-drawer.component.html + 16 @@ -733,23 +1238,23 @@ src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 36 + 37 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 64 + 65 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 79 + 80 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 88 + 89 src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 99 + 100 @@ -847,236 +1352,37 @@ src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 178 - - - - Compared to all users matching this rule - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 68 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 94 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 152 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 178 - - - - Default rule - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 88 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 172 - - - - Operation succeeded - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts - 193 - - - src/app/core/components/group-drawer/group-drawer.component.ts - 68 - - - src/app/core/components/member-drawer/member-drawer.component.ts - 121 - - - src/app/core/components/metric-drawer/metric-drawer.component.ts - 241 - - - src/app/core/components/metric-drawer/metric-drawer.component.ts - 258 - - - src/app/core/components/policy-drawer/policy-drawer.component.ts - 68 - - - src/app/core/components/props-drawer/props-drawer.component.ts - 93 - - - src/app/core/components/props-drawer/props-drawer.component.ts - 116 - - - src/app/core/components/props-drawer/props-drawer.component.ts - 134 - - - src/app/features/safe/experiments/metrics/metrics.component.ts - 85 - - - src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 59 - - - src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 77 - - - src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 86 - - - src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 97 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 85 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 96 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 199 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 332 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 344 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 352 - - - src/app/features/safe/feature-flags/index/index.component.ts - 336 - - - src/app/features/safe/feature-flags/index/index.component.ts - 349 - - - src/app/features/safe/feature-flags/index/index.component.ts - 359 - - - src/app/features/safe/iam/groups/details/policies/policies.component.ts - 74 - - - src/app/features/safe/iam/groups/details/policies/policies.component.ts - 88 - - - src/app/features/safe/iam/groups/details/setting/setting.component.ts - 42 - - - src/app/features/safe/iam/groups/details/setting/setting.component.ts - 69 - - - src/app/features/safe/iam/groups/details/team/team.component.ts - 73 - - - src/app/features/safe/iam/groups/details/team/team.component.ts - 87 - - - src/app/features/safe/iam/groups/index/index.component.ts - 84 - - - src/app/features/safe/iam/policies/details/groups/groups.component.ts - 76 - - - src/app/features/safe/iam/policies/details/groups/groups.component.ts - 90 - - - src/app/features/safe/iam/policies/details/permission/permission.component.ts - 40 - - - src/app/features/safe/iam/policies/details/setting/setting.component.ts - 46 - - - src/app/features/safe/iam/policies/details/setting/setting.component.ts - 53 - - - src/app/features/safe/iam/policies/details/team/team.component.ts - 76 - - - src/app/features/safe/iam/policies/details/team/team.component.ts - 90 - - - src/app/features/safe/iam/policies/index/index.component.ts - 80 - - - src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.ts - 75 - - - src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.ts - 89 - - - src/app/features/safe/iam/team/details/groups/groups.component.ts - 81 - - - src/app/features/safe/iam/team/details/groups/groups.component.ts - 95 - - - src/app/features/safe/iam/team/details/setting/setting.component.ts - 51 + 178 + + + Compared to all users matching this rule - src/app/features/safe/iam/team/index/index.component.ts - 72 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 68 - src/app/features/safe/segments/details/setting/setting.component.ts - 60 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 94 - src/app/features/safe/segments/details/targeting/targeting.component.ts - 136 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 152 - src/app/features/safe/segments/index/index.component.ts - 41 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 178 + + + Default rule - src/app/features/safe/segments/index/index.component.ts - 63 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 88 - src/app/features/safe/segments/index/index.component.ts - 76 + src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html + 172 @@ -1111,11 +1417,11 @@ src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 142 + 133 src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 145 + 136 src/app/features/safe/iam/groups/details/policies/policies.component.ts @@ -1151,7 +1457,7 @@ src/app/features/safe/iam/policies/details/permission/permission.component.ts - 41 + 42 src/app/features/safe/iam/policies/details/setting/setting.component.ts @@ -1197,6 +1503,14 @@ src/app/features/safe/iam/team/index/index.component.ts 75 + + src/app/features/safe/integrations/access-tokens/index/index.component.ts + 147 + + + src/app/features/safe/integrations/access-tokens/index/index.component.ts + 157 + src/app/features/safe/segments/details/targeting/targeting.component.ts 142 @@ -1459,25 +1773,6 @@ 7 - - Validating... - - src/app/core/components/group-drawer/group-drawer.component.html - 15 - - - src/app/core/components/policy-drawer/policy-drawer.component.html - 15 - - - src/app/features/safe/feature-flags/index/index.component.html - 203 - - - src/app/features/safe/segments/index/index.component.html - 83 - - Group name cannot be empty @@ -1823,61 +2118,6 @@ 62 - - Copied - - src/app/core/components/header/header.component.ts - 160 - - - src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.ts - 60 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 42 - - - src/app/features/safe/feature-flags/index/index.component.ts - 204 - - - src/app/features/safe/feature-flags/index/index.component.ts - 373 - - - src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 140 - - - src/app/features/safe/iam/groups/details/setting/setting.component.ts - 80 - - - src/app/features/safe/iam/groups/index/index.component.ts - 78 - - - src/app/features/safe/iam/policies/details/setting/setting.component.ts - 80 - - - src/app/features/safe/iam/policies/index/index.component.ts - 88 - - - src/app/features/safe/iam/team/details/setting/setting.component.ts - 58 - - - src/app/features/safe/iam/team/index/index.component.ts - 92 - - - src/app/features/safe/organizations/project/project.component.ts - 181 - - Thank you for sending us your feedback, we'll get back to you very soon! @@ -2069,7 +2309,7 @@ src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 153 + 151 src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts @@ -2177,69 +2417,6 @@ 116 - - Operation failed, please try again - - src/app/core/components/metric-drawer/metric-drawer.component.ts - 244 - - - src/app/core/components/target-user/target-user.component.ts - 127 - - - src/app/core/components/target-user/target-user.component.ts - 159 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts - 213 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts - 229 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts - 296 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts - 309 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 283 - - - src/app/features/safe/feature-flags/details/targeting/targeting.component.ts - 109 - - - src/app/features/safe/feature-flags/index/index.component.ts - 339 - - - src/app/features/safe/onboarding/steps/steps.component.ts - 63 - - - src/app/features/safe/organizations/project/project.component.ts - 253 - - - src/app/features/safe/organizations/project/project.component.ts - 287 - - - src/app/features/safe/organizations/project/project.component.ts - 303 - - - src/app/features/safe/segments/index/index.component.ts - 79 - - Create organization @@ -2389,6 +2566,10 @@ src/app/features/safe/iam/team/details/groups/groups.component.html 54 + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 39 + src/app/features/safe/organizations/organization/organization.component.html 29 @@ -2494,6 +2675,10 @@ src/app/features/safe/iam/team/index/index.component.html 34 + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 63 + src/app/features/safe/segments/index/index.component.html 37 @@ -2654,6 +2839,10 @@ src/app/features/safe/iam/team/index/index.component.html 72 + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 118 + src/app/features/safe/organizations/project/project.component.html 75 @@ -2877,7 +3066,7 @@ src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 150 + 148 src/app/features/safe/feature-flags/details/insights/insights.component.html @@ -2984,6 +3173,34 @@ 168,170 + + Active + + src/app/core/pipes/access-token-status.pipe.ts + 12 + + + + Inactive + + src/app/core/pipes/access-token-status.pipe.ts + 13 + + + + Personal + + src/app/core/pipes/access-token-type.pipe.ts + 9 + + + + Service + + src/app/core/pipes/access-token-type.pipe.ts + 10 + + System Managed @@ -2998,13 +3215,6 @@ 9 - - You don't have permissions to take this action, please contact the admin to grant you the necessary permissions - - src/app/core/services/permissions.service.ts - 13 - - Login @@ -3073,7 +3283,7 @@ src/app/features/safe/safe-routing.module.ts - 62 + 50 src/app/features/safe/safe.component.ts @@ -3211,29 +3421,6 @@ 51 - - Type - - src/app/features/safe/data-sync/remote-sync/remote-sync.component.html - 26 - - - src/app/features/safe/iam/policies/details/setting/setting.component.html - 33 - - - src/app/features/safe/iam/policies/index/index.component.html - 30 - - - src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.html - 31 - - - src/app/features/safe/iam/team/details/inherited-policies/inherited-policies.component.html - 25 - - URL @@ -3451,6 +3638,10 @@ src/app/features/safe/experiments/metrics/metrics.component.html 72 + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 94 + Loading failed, please try again @@ -3827,91 +4018,91 @@ Remove data src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 73 + 72 This would remove the experiment and all data, it cannot be reverted, are you sure to remove it? src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 78 + 77 Remove experiment src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 83 + 81 Restart src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 96 + 94 Pause src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 100 + 98 Period src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 105 + 103 Need more data to confirm the results of the experiment src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 119 + 117 The difference is not significant compared to the baseline src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 123 + 121 Winner src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 127 + 125 Start src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 135 + 133 Conversion / Users src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 152 + 150 Total events src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 156 + 154 Average src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 157 + 155 src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts @@ -3926,67 +4117,67 @@ Confidence interval src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 159 + 157 P-Value src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 162 + 160 The result is significant if P value is less than α(0.05) src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 166 + 164 Data is not available yet src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 179 + 177 Baseline src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 187 + 185 src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 217 + 215 Winner src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 195 + 193 It's not significant compared to baseline src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 198 + 196 Hide chart src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 273 + 271 Show chart src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 274 + 272 @@ -4525,6 +4716,10 @@ src/app/features/safe/feature-flags/index/index.component.html 75 + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 60 + Tags @@ -4778,7 +4973,7 @@ src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 152 + 143 @@ -4821,7 +5016,7 @@ Make sure resource and operation are set for all permissions src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 158 + 149 @@ -4887,213 +5082,6 @@ 68 - - All - - src/app/features/safe/iam/components/policy-editor/types.ts - 49 - - - - General - - src/app/features/safe/iam/components/policy-editor/types.ts - 54 - - - - Project - - src/app/features/safe/iam/components/policy-editor/types.ts - 59 - - - - Environment - - src/app/features/safe/iam/components/policy-editor/types.ts - 64 - - - - Project - - src/app/features/safe/iam/components/policy-editor/types.ts - 85 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 97 - - - - Environment - - src/app/features/safe/iam/components/policy-editor/types.ts - 107 - - - - All - - src/app/features/safe/iam/components/policy-editor/types.ts - 120 - - - - Update org name - - src/app/features/safe/iam/components/policy-editor/types.ts - 127 - - - - IAM - - src/app/features/safe/iam/components/policy-editor/types.ts - 134 - - - - List projects - - src/app/features/safe/iam/components/policy-editor/types.ts - 141 - - - - Create projects - - src/app/features/safe/iam/components/policy-editor/types.ts - 146 - - - - Delete projects - - src/app/features/safe/iam/components/policy-editor/types.ts - 151 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 208 - - - - Update project settings - - src/app/features/safe/iam/components/policy-editor/types.ts - 156 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 213 - - - - List environments - - src/app/features/safe/iam/components/policy-editor/types.ts - 161 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 218 - - - - Create environment - - src/app/features/safe/iam/components/policy-editor/types.ts - 166 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 223 - - - - Access environments - - src/app/features/safe/iam/components/policy-editor/types.ts - 171 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 203 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 245 - - - - Delete environments - - src/app/features/safe/iam/components/policy-editor/types.ts - 176 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 250 - - - - Update environment settings - - src/app/features/safe/iam/components/policy-editor/types.ts - 181 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 255 - - - - Delete environment secret - - src/app/features/safe/iam/components/policy-editor/types.ts - 186 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 228 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 260 - - - - Create environment secret - - src/app/features/safe/iam/components/policy-editor/types.ts - 191 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 233 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 265 - - - - Update environment secret - - src/app/features/safe/iam/components/policy-editor/types.ts - 196 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 238 - - - src/app/features/safe/iam/components/policy-editor/types.ts - 270 - - Team @@ -5131,13 +5119,6 @@ 13 - - Policies - - src/app/features/safe/iam/groups/details/details.component.html - 13 - - Filter by policy name @@ -5458,60 +5439,134 @@ 49 - - ? + + ? + + src/app/features/safe/iam/team/details/groups/groups.component.html + 49 + + + + Filter by policy name + + src/app/features/safe/iam/team/details/inherited-policies/inherited-policies.component.html + 5 + + + + Filter by Email + + src/app/features/safe/iam/team/index/index.component.html + 4 + + + + Add + + src/app/features/safe/iam/team/index/index.component.html + 11 + + + + Group + + src/app/features/safe/iam/team/index/index.component.html + 32 + + + + Initial password + + src/app/features/safe/iam/team/index/index.component.html + 33 + + + + + + + src/app/features/safe/iam/team/index/index.component.html + 51 + + + + more + + src/app/features/safe/iam/team/index/index.component.html + 51 + + + + Filter by name + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 5 + + + + Select creator + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 12 + + + + Filter by type - src/app/features/safe/iam/team/details/groups/groups.component.html - 49 + src/app/features/safe/integrations/access-tokens/index/index.component.html + 31 - - Filter by policy name + + Created by - src/app/features/safe/iam/team/details/inherited-policies/inherited-policies.component.html - 5 + src/app/features/safe/integrations/access-tokens/index/index.component.html + 59 - - Filter by Email + + Last used - src/app/features/safe/iam/team/index/index.component.html - 4 + src/app/features/safe/integrations/access-tokens/index/index.component.html + 61 - - Add + + Access token - src/app/features/safe/iam/team/index/index.component.html - 11 + src/app/features/safe/integrations/access-tokens/index/index.component.html + 62 - - Group + + Activate - src/app/features/safe/iam/team/index/index.component.html - 32 + src/app/features/safe/integrations/access-tokens/index/index.component.html + 97 - - Initial password + + Deactivate this access token? You can't use an inactive access token to make API calls but you can activate it again later. - src/app/features/safe/iam/team/index/index.component.html - 33 + src/app/features/safe/integrations/access-tokens/index/index.component.html + 103 + + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 113 - - + + + Deactivate - src/app/features/safe/iam/team/index/index.component.html - 51 + src/app/features/safe/integrations/access-tokens/index/index.component.html + 108 - - more + + Access tokens - src/app/features/safe/iam/team/index/index.component.html - 51 + src/app/features/safe/integrations/integrations-routing.module.ts + 16 @@ -5936,7 +5991,7 @@ Organization src/app/features/safe/safe-routing.module.ts - 50 + 57 @@ -6009,6 +6064,20 @@ 107,106 + + Integrations + + src/app/features/safe/safe.component.ts + 114,113 + + + + Access tokens + + src/app/features/safe/safe.component.ts + 119,118 + + This segment is not used by any feature flag @@ -6322,6 +6391,264 @@ 76 + + All + + src/app/shared/permissions.ts + 17 + + + src/app/shared/permissions.ts + 18 + + + + List projects + + src/app/shared/permissions.ts + 25 + + + src/app/shared/permissions.ts + 26 + + + + Create projects + + src/app/shared/permissions.ts + 33 + + + src/app/shared/permissions.ts + 34 + + + + Delete projects + + src/app/shared/permissions.ts + 41 + + + src/app/shared/permissions.ts + 42 + + + + Access environments + + src/app/shared/permissions.ts + 49 + + + src/app/shared/permissions.ts + 50 + + + + Update project settings + + src/app/shared/permissions.ts + 57 + + + src/app/shared/permissions.ts + 58 + + + + List environments + + src/app/shared/permissions.ts + 65 + + + src/app/shared/permissions.ts + 66 + + + + Create environment + + src/app/shared/permissions.ts + 73 + + + src/app/shared/permissions.ts + 74 + + + + Delete environments + + src/app/shared/permissions.ts + 81 + + + src/app/shared/permissions.ts + 82 + + + + Update environment settings + + src/app/shared/permissions.ts + 89 + + + src/app/shared/permissions.ts + 90 + + + + Delete environment secret + + src/app/shared/permissions.ts + 97 + + + src/app/shared/permissions.ts + 98 + + + + Create environment secret + + src/app/shared/permissions.ts + 105 + + + src/app/shared/permissions.ts + 106 + + + + Update environment secret + + src/app/shared/permissions.ts + 113 + + + src/app/shared/permissions.ts + 114 + + + + Update org name + + src/app/shared/permissions.ts + 123 + + + src/app/shared/permissions.ts + 124 + + + + IAM + + src/app/shared/permissions.ts + 133 + + + src/app/shared/permissions.ts + 134 + + + + List access tokens + + src/app/shared/permissions.ts + 143 + + + src/app/shared/permissions.ts + 144 + + + + Manage service access tokens + + src/app/shared/permissions.ts + 151 + + + src/app/shared/permissions.ts + 152 + + + + Manage personal access tokens + + src/app/shared/permissions.ts + 159 + + + src/app/shared/permissions.ts + 160 + + + + All + + src/app/shared/policy.ts + 62 + + + + Account + + src/app/shared/policy.ts + 67 + + + + IAM + + src/app/shared/policy.ts + 72 + + + + Access token + + src/app/shared/policy.ts + 77 + + + + Project + + src/app/shared/policy.ts + 82 + + + + Environment + + src/app/shared/policy.ts + 87 + + + + Project + + src/app/shared/policy.ts + 110 + + + src/app/shared/policy.ts + 122 + + + + Environment + + src/app/shared/policy.ts + 132 + + diff --git a/modules/front-end/src/locale/messages.zh.xlf b/modules/front-end/src/locale/messages.zh.xlf index ee5a89ce1..be6a062ec 100644 --- a/modules/front-end/src/locale/messages.zh.xlf +++ b/modules/front-end/src/locale/messages.zh.xlf @@ -337,7 +337,7 @@ src/app/features/safe/feature-flags/details/setting/setting.component.html - 136,137 + 146,147 src/app/features/safe/feature-flags/index/index.component.html @@ -425,7 +425,7 @@ src/app/features/safe/feature-flags/details/setting/setting.component.html - 164,166 + 174,176 src/app/features/safe/feature-flags/index/index.component.html @@ -549,27 +549,27 @@ src/app/features/safe/feature-flags/details/setting/setting.component.ts - 84 + 85 src/app/features/safe/feature-flags/details/setting/setting.component.ts - 95 + 96 src/app/features/safe/feature-flags/details/setting/setting.component.ts - 190 + 199 src/app/features/safe/feature-flags/details/setting/setting.component.ts - 322 + 332 src/app/features/safe/feature-flags/details/setting/setting.component.ts - 333 + 344 src/app/features/safe/feature-flags/details/setting/setting.component.ts - 341 + 352 src/app/features/safe/feature-flags/index/index.component.ts @@ -733,7 +733,7 @@ src/app/features/safe/feature-flags/details/setting/setting.component.ts - 274 + 283 src/app/features/safe/feature-flags/details/targeting/targeting.component.ts @@ -773,7 +773,7 @@ src/app/core/components/header/header.component.ts - 151 + 160 src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.ts @@ -797,7 +797,7 @@ src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 130 + 131 src/app/features/safe/iam/groups/details/setting/setting.component.ts @@ -901,66 +901,6 @@ 按团队成员查找 - - Loading... - - src/app/core/components/audit-logs/audit-logs.component.html - 26 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 36 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 66 - - - src/app/core/components/member-drawer/member-drawer.component.html - 38 - - - src/app/core/components/member-drawer/member-drawer.component.html - 55 - - - src/app/core/components/metric-drawer/metric-drawer.component.html - 43 - - - src/app/core/components/target-user/target-user.component.html - 44 - - - src/app/features/safe/end-users/index/index.component.html - 25 - - - src/app/features/safe/end-users/index/index.component.html - 60 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 138 - - - src/app/features/safe/feature-flags/details/insights/insights.component.html - 18 - - - src/app/features/safe/feature-flags/details/setting/setting.component.html - 146,147 - - - src/app/features/safe/feature-flags/index/index.component.html - 26 - - - src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html - 38 - - 数据加载中... - Filter by type @@ -1229,82 +1169,6 @@ 取消 - - Save - - src/app/core/components/change-review/change-review.component.html - 43 - - - src/app/core/components/env-drawer/env-drawer.component.html - 35 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 91 - - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.html - 202 - - - src/app/core/components/group-drawer/group-drawer.component.html - 32 - - - src/app/core/components/header/header.component.html - 80,81 - - - src/app/core/components/member-drawer/member-drawer.component.html - 61 - - - src/app/core/components/metric-drawer/metric-drawer.component.html - 121 - - - src/app/core/components/organization-drawer/organization-drawer.component.html - 18 - - - src/app/core/components/policy-drawer/policy-drawer.component.html - 32 - - - src/app/core/components/project-drawer/project-drawer.component.html - 29 - - - src/app/core/components/props-drawer/props-drawer.component.html - 90 - - - src/app/core/components/target-user/target-user.component.html - 69 - - - src/app/features/safe/feature-flags/details/setting/setting.component.html - 174,176 - - - src/app/features/safe/feature-flags/index/index.component.html - 224 - - - src/app/features/safe/iam/components/policy-editor/policy-editor.component.html - 9 - - - src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html - 76 - - - src/app/features/safe/segments/index/index.component.html - 104 - - 保存 - Permission will become invalid if you change the name @@ -1597,206 +1461,6 @@ 默认规则 - - Operation succeeded - - src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts - 193 - - - src/app/core/components/group-drawer/group-drawer.component.ts - 68 - - - src/app/core/components/member-drawer/member-drawer.component.ts - 121 - - - src/app/core/components/metric-drawer/metric-drawer.component.ts - 241 - - - src/app/core/components/metric-drawer/metric-drawer.component.ts - 258 - - - src/app/core/components/policy-drawer/policy-drawer.component.ts - 68 - - - src/app/core/components/props-drawer/props-drawer.component.ts - 93 - - - src/app/core/components/props-drawer/props-drawer.component.ts - 116 - - - src/app/core/components/props-drawer/props-drawer.component.ts - 134 - - - src/app/features/safe/experiments/metrics/metrics.component.ts - 85 - - - src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 59 - - - src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 77 - - - src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 86 - - - src/app/features/safe/feature-flags/components/flag-triggers/flag-triggers.component.ts - 97 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 85 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 96 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 199 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 332 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 344 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 352 - - - src/app/features/safe/feature-flags/index/index.component.ts - 336 - - - src/app/features/safe/feature-flags/index/index.component.ts - 349 - - - src/app/features/safe/feature-flags/index/index.component.ts - 359 - - - src/app/features/safe/iam/groups/details/policies/policies.component.ts - 74 - - - src/app/features/safe/iam/groups/details/policies/policies.component.ts - 88 - - - src/app/features/safe/iam/groups/details/setting/setting.component.ts - 42 - - - src/app/features/safe/iam/groups/details/setting/setting.component.ts - 69 - - - src/app/features/safe/iam/groups/details/team/team.component.ts - 73 - - - src/app/features/safe/iam/groups/details/team/team.component.ts - 87 - - - src/app/features/safe/iam/groups/index/index.component.ts - 84 - - - src/app/features/safe/iam/policies/details/groups/groups.component.ts - 76 - - - src/app/features/safe/iam/policies/details/groups/groups.component.ts - 90 - - - src/app/features/safe/iam/policies/details/permission/permission.component.ts - 40 - - - src/app/features/safe/iam/policies/details/setting/setting.component.ts - 46 - - - src/app/features/safe/iam/policies/details/setting/setting.component.ts - 53 - - - src/app/features/safe/iam/policies/details/team/team.component.ts - 76 - - - src/app/features/safe/iam/policies/details/team/team.component.ts - 90 - - - src/app/features/safe/iam/policies/index/index.component.ts - 80 - - - src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.ts - 75 - - - src/app/features/safe/iam/team/details/direct-policies/direct-policies.component.ts - 89 - - - src/app/features/safe/iam/team/details/groups/groups.component.ts - 81 - - - src/app/features/safe/iam/team/details/groups/groups.component.ts - 95 - - - src/app/features/safe/iam/team/details/setting/setting.component.ts - 51 - - - src/app/features/safe/iam/team/index/index.component.ts - 72 - - - src/app/features/safe/segments/details/setting/setting.component.ts - 60 - - - src/app/features/safe/segments/details/targeting/targeting.component.ts - 136 - - - src/app/features/safe/segments/index/index.component.ts - 41 - - - src/app/features/safe/segments/index/index.component.ts - 63 - - - src/app/features/safe/segments/index/index.component.ts - 76 - - 操作成功 - Operation failed @@ -1829,11 +1493,11 @@ src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 132 + 133 src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 135 + 136 src/app/features/safe/iam/groups/details/policies/policies.component.ts @@ -2597,62 +2261,6 @@ 您没有查看项目环境列表的权限, 请联系账户管理员添加相关权限 - - Copied - - src/app/core/components/header/header.component.ts - 160 - - - src/app/core/components/user-segments-flags-drawer/user-segments-flags-drawer.component.ts - 60 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 42 - - - src/app/features/safe/feature-flags/index/index.component.ts - 204 - - - src/app/features/safe/feature-flags/index/index.component.ts - 373 - - - src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 140 - - - src/app/features/safe/iam/groups/details/setting/setting.component.ts - 80 - - - src/app/features/safe/iam/groups/index/index.component.ts - 78 - - - src/app/features/safe/iam/policies/details/setting/setting.component.ts - 80 - - - src/app/features/safe/iam/policies/index/index.component.ts - 88 - - - src/app/features/safe/iam/team/details/setting/setting.component.ts - 58 - - - src/app/features/safe/iam/team/index/index.component.ts - 92 - - - src/app/features/safe/organizations/project/project.component.ts - 181 - - 复制成功 - Thank you for sending us your feedback, we'll get back to you very soon! @@ -2985,70 +2593,6 @@ 低于基准值 - - Operation failed, please try again - - src/app/core/components/metric-drawer/metric-drawer.component.ts - 244 - - - src/app/core/components/target-user/target-user.component.ts - 127 - - - src/app/core/components/target-user/target-user.component.ts - 159 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts - 213 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts - 229 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts - 296 - - - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.ts - 309 - - - src/app/features/safe/feature-flags/details/setting/setting.component.ts - 283 - - - src/app/features/safe/feature-flags/details/targeting/targeting.component.ts - 109 - - - src/app/features/safe/feature-flags/index/index.component.ts - 339 - - - src/app/features/safe/onboarding/steps/steps.component.ts - 63 - - - src/app/features/safe/organizations/project/project.component.ts - 253 - - - src/app/features/safe/organizations/project/project.component.ts - 287 - - - src/app/features/safe/organizations/project/project.component.ts - 303 - - - src/app/features/safe/segments/index/index.component.ts - 79 - - 操作失败,请重试 - Create organization @@ -5876,7 +5420,7 @@ src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 142 + 143 系统托管策略不允许被修改。 如确有需要,可以复制以后再根据需求进行修改。 @@ -5924,7 +5468,7 @@ Make sure resource and operation are set for all permissions src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 148 + 149 请确保已设置所有权限的资源和操作 From a00d40edf40cd59ad989fa1c86dad0409787f97b Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Thu, 16 Mar 2023 09:30:12 +0100 Subject: [PATCH 28/44] more work --- .../Application/AccessTokens/AccessTokenVm.cs | 2 +- .../AccessTokens/CreateAccessToken.cs | 12 +- .../src/Domain/AccessTokens/AccessToken.cs | 6 +- .../access-token-drawer.component.html | 79 +++--- .../access-token-drawer.component.less | 106 ++++--- .../access-token-drawer.component.ts | 157 +++++------ modules/front-end/src/app/core/core.module.ts | 92 ++++--- .../src/app/core/guards/accessTokens.guard.ts | 2 +- .../src/app/core/pipes/translation.pipe.ts | 19 +- .../app/core/services/access-token.service.ts | 5 +- .../translations/iam-operation.translation.ts | 8 - .../policy-editor.component.html | 4 +- .../src/app/features/safe/iam/types/policy.ts | 10 +- .../access-tokens/index/index.component.ts | 14 +- .../access-tokens/types/access-token.ts | 2 + .../access-tokens/types/permission-helper.ts | 53 ++++ .../front-end/src/app/shared/permissions.ts | 4 +- modules/front-end/src/app/shared/policy.ts | 75 ++--- modules/front-end/src/locale/messages.xlf | 245 +++++++++-------- modules/front-end/src/locale/messages.zh.xlf | 258 +++++++++--------- modules/front-end/src/styles-common.less | 7 +- 21 files changed, 609 insertions(+), 551 deletions(-) delete mode 100644 modules/front-end/src/app/core/translations/iam-operation.translation.ts create mode 100644 modules/front-end/src/app/features/safe/integrations/access-tokens/types/permission-helper.ts diff --git a/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs b/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs index e4660e40f..fdaa4bfb8 100644 --- a/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs +++ b/modules/back-end/src/Application/AccessTokens/AccessTokenVm.cs @@ -15,7 +15,7 @@ public class AccessTokenVm public string Token { get; set; } public MemberVm Creator { get; set; } - public IEnumerable Policies { get; set; } + public IEnumerable Permissions { get; set; } public DateTime? LastUsedAt { get; set; } } \ No newline at end of file diff --git a/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs b/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs index 80f18d6d3..c16d491cc 100644 --- a/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs +++ b/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs @@ -14,7 +14,7 @@ public class CreateAccessToken : IRequest public string Type { get; set; } - public IEnumerable PolicyIds { get; set; } + public IEnumerable Permissions { get; set; } } public class CreateAccessTokenValidator : AbstractValidator @@ -27,8 +27,8 @@ public CreateAccessTokenValidator() RuleFor(x => x.Type) .Must(AccessTokenTypes.IsDefined).WithErrorCode(ErrorCodes.InvalidAccessTokenType); - RuleFor(x => x.PolicyIds) - .Must(PolicyIds => PolicyIds.Any()) + RuleFor(x => x.Permissions) + .Must(Permissions => Permissions.Any()) .Unless(x => x.Type == AccessTokenTypes.Personal) .WithErrorCode(ErrorCodes.ServiceAccessTokenMustDefinePolicies); } @@ -51,13 +51,13 @@ public CreateAccessTokenHandler(IAccessTokenService service, IPolicyService poli public async Task Handle(CreateAccessToken request, CancellationToken cancellationToken) { - var policies = Enumerable.Empty(); + var permissions = request.Permissions; if (request.Type == AccessTokenTypes.Service) { - policies = await _policyService.FindManyAsync((x) => request.PolicyIds.Contains(x.Id)); + // TODO check currentUser has all the permissions } - var accessToken = new AccessToken(request.OrganizationId, _currentUser.Id, request.Name, request.Type, policies); + var accessToken = new AccessToken(request.OrganizationId, _currentUser.Id, request.Name, request.Type, permissions); await _service.AddOneAsync(accessToken); diff --git a/modules/back-end/src/Domain/AccessTokens/AccessToken.cs b/modules/back-end/src/Domain/AccessTokens/AccessToken.cs index 4b9a5b9f8..5759e5814 100644 --- a/modules/back-end/src/Domain/AccessTokens/AccessToken.cs +++ b/modules/back-end/src/Domain/AccessTokens/AccessToken.cs @@ -14,7 +14,7 @@ public class AccessToken : AuditedEntity public string Token { get; set; } public Guid CreatorId { get; set; } - public ICollection Policies { get; set; } + public IEnumerable Permissions { get; set; } public DateTime? LastUsedAt { get; set; } @@ -34,7 +34,7 @@ private string NewToken() return $"api-{header}{guid}"; } - public AccessToken(Guid organizationId, Guid creatorId, string name, string type, IEnumerable policies) + public AccessToken(Guid organizationId, Guid creatorId, string name, string type, IEnumerable permissions) { OrganizationId = organizationId; CreatorId = creatorId; @@ -42,7 +42,7 @@ public AccessToken(Guid organizationId, Guid creatorId, string name, string type Status = AccessTokenStatus.Active; Type = type; - Policies = policies.ToArray(); + Permissions = permissions; Token = NewToken(); } diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html index f8535ac65..ff4281e52 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.html @@ -5,7 +5,7 @@ nzPlacement="right" i18n-nzTitle="@@integrations.access-token.access-token-drawer.title" nzTitle="Add access token" - [nzWidth]="500" + [nzWidth]="700" (nzOnClose)="onClose()" [nzFooter]="footer"> @@ -39,50 +39,43 @@ + + +
    + Permissions +
    + + +
    + +
    +
    + + + +
    - - - Policies - - - - - - - - {{ policy.name }} - - - - - - - Loading... - - - -
    -
    -
    - - {{ policy.name }} +
    +
    + {{resource}} +
    +
    +
    - -
    -
    - -
    Policies are mandatory for service type access tokens
    - - - + + +
    +
    diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less index ea11d5fcc..d5030f94a 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less @@ -23,48 +23,78 @@ font-size: 15px; } -.selected-policies { - border: 1px solid @grey20-color; - background-color: #ffffff; - padding: 5px 0 1px 6px; - box-sizing: border-box; - border-radius: 8px; - margin-bottom: 12px; - margin-top: 12px; +.resource-type { + .permissions { + display: flex; + flex-direction: column; + gap: 8px; - .policy { - display: flex; - margin-bottom: 4px; - margin-right: 10px; + .permission { + display: flex; + flex-direction: column; - .inner-box { - width: 182px; - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; - padding: 4px 7px 6px 7px; - background: @grey20-color; - height: 23px; - line-height: 15px; - overflow: hidden; - text-overflow: ellipsis; - cursor: pointer; - white-space: nowrap; - } + .permission-header { + display: flex; + justify-content: flex-start; + gap: 8px; + align-items: center; + } - button { - display: flex; - background: @grey20-color; - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; - height: 23px; - width: 15px; - border: 0; + .permission-resources { + border-top: 1px solid @grey40-color; + display: flex; + flex-direction: column; - i { - width:10px; - height: 10px; - font-size: 10px; + .permission-resource { + padding: 0 8px; + } + } } } - } } + +//.selected-policies { +// border: 1px solid @grey20-color; +// background-color: #ffffff; +// padding: 5px 0 1px 6px; +// box-sizing: border-box; +// border-radius: 8px; +// margin-bottom: 12px; +// margin-top: 12px; +// +// .policy { +// display: flex; +// margin-bottom: 4px; +// margin-right: 10px; +// +// .inner-box { +// width: 182px; +// border-top-left-radius: 4px; +// border-bottom-left-radius: 4px; +// padding: 4px 7px 6px 7px; +// background: @grey20-color; +// height: 23px; +// line-height: 15px; +// overflow: hidden; +// text-overflow: ellipsis; +// cursor: pointer; +// white-space: nowrap; +// } +// +// button { +// display: flex; +// background: @grey20-color; +// border-top-right-radius: 4px; +// border-bottom-right-radius: 4px; +// height: 23px; +// width: 15px; +// border: 0; +// +// i { +// width:10px; +// height: 10px; +// font-size: 10px; +// } +// } +// } +//} diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts index 4eeecc425..88319d472 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts @@ -9,51 +9,55 @@ import { IAccessTokenPolicy } from "@features/safe/integrations/access-tokens/types/access-token"; import { NzSelectComponent } from "ng-zorro-antd/select"; -import { Subject } from "rxjs"; import { AccessTokenService } from "@services/access-token.service"; import { PermissionsService } from "@services/permissions.service"; import { generalResourceRNPattern, permissionActions } from "@shared/permissions"; import { PolicyFilter } from "@features/safe/iam/types/policy"; -import { IFeatureFlag } from "@features/safe/feature-flags/types/details"; import { NzModalService } from "ng-zorro-antd/modal"; import { copyToClipboard } from "@utils/index"; +import { + preProcessPermissions, + IPermissionStatementGroup, postProcessPermissions +} from "@features/safe/integrations/access-tokens/types/permission-helper"; +import { + IPolicyStatement, + ResourceType, ResourceTypeAccessToken, + ResourceTypeEnv, + ResourceTypeProject +} from "@shared/policy"; @Component({ selector: 'access-token-drawer', templateUrl: './access-token-drawer.component.html', styleUrls: ['./access-token-drawer.component.less'] }) -export class AccessTokenDrawerComponent implements OnInit { - - public policyCompareWith: (obj1: IAccessTokenPolicy, obj2: IAccessTokenPolicy) => boolean = (obj1: IAccessTokenPolicy, obj2: IAccessTokenPolicy) => { - if (obj1 && obj2) { - return obj1.id === obj2.id; - } else { - return false; - } - }; - +export class AccessTokenDrawerComponent { private _accessToken: IAccessToken; isEditing: boolean = false; + resourceTypes: ResourceType[] = [ResourceTypeAccessToken, ResourceTypeProject, ResourceTypeEnv]; // TODO replace with real open API resource types + authorizedResourceTypes: ResourceType[] = []; + permissions: { [key: string]: IPermissionStatementGroup }; @Input() set accessToken(accessToken: IAccessToken) { this.isEditing = accessToken && !!accessToken.id; - if (accessToken) { - this.selectedPolicyList = accessToken.policies.map((p) => ({...p, isSelected: true})); - this.isServiceAccessToken = accessToken.type === AccessTokenTypeEnum.Service; - this.patchForm(accessToken); + if (this.isEditing) { + this.permissions = preProcessPermissions(accessToken.permissions); + this.authorizedResourceTypes = this.resourceTypes.filter((rt) => this.permissions[rt.type]?.statements?.length > 0); } else { - this.resetForm(); + accessToken = { name: null, type: AccessTokenTypeEnum.Personal}; + this.setAuthorizedPermissions(); } + + this.isServiceAccessToken = accessToken.type === AccessTokenTypeEnum.Service; + this.patchForm(accessToken); this._accessToken = accessToken; + } @Input() visible: boolean = false; @Output() close: EventEmitter = new EventEmitter(); - policyDebouncer = new Subject(); - canTakeActionOnPersonalAccessToken = false; canTakeActionOnServiceAccessToken = false; constructor( @@ -64,29 +68,20 @@ export class AccessTokenDrawerComponent implements OnInit { private modal: NzModalService, private message: NzMessageService ) { - this.policyDebouncer.pipe( - debounceTime(100), - ).subscribe(query => this.searchPolicies(query)); + this.form = this.fb.group({ + name: ['', [Validators.required], [this.nameAsyncValidator], 'change'], + type: [AccessTokenTypeEnum.Personal, [Validators.required]] + }); - this.canTakeActionOnPersonalAccessToken = this.permissionsService.canTakeAction(generalResourceRNPattern.account, permissionActions.CreatePersonalAccessTokens); - this.canTakeActionOnServiceAccessToken = this.permissionsService.canTakeAction(generalResourceRNPattern.account, permissionActions.CreateServiceAccessTokens); + this.canTakeActionOnPersonalAccessToken = this.permissionsService.canTakeAction(generalResourceRNPattern.accessToken, permissionActions.ManagePersonalAccessTokens); + this.canTakeActionOnServiceAccessToken = this.permissionsService.canTakeAction(generalResourceRNPattern.accessToken, permissionActions.ManageServiceAccessTokens); } isServiceAccessToken: boolean = false @ViewChild("policyNodeSelector", {static: false}) policySelectNode: NzSelectComponent; - selectedPolicyList: IAccessTokenPolicy[] = []; - policySearchResultList: IAccessTokenPolicy[] = []; form: FormGroup; - ngOnInit(): void { - this.form = this.fb.group({ - name: ['', [Validators.required], [this.nameAsyncValidator], 'change'], - type: [AccessTokenTypeEnum.Personal, [Validators.required]], - policy: [null, []] - }); - } - get accessToken() { return this._accessToken; } @@ -121,60 +116,22 @@ export class AccessTokenDrawerComponent implements OnInit { onTypeChange() { const {type} = this.form.value; this.isServiceAccessToken = type === AccessTokenTypeEnum.Service; - this.selectedPolicyList = []; this.resetPolicy(); } - onPolicySelectChange() { - const {policy} = this.form.value; - - if (this.selectedPolicyList.some((sp) => sp.id === policy.id)) { - this.selectedPolicyList = this.selectedPolicyList.filter((sp) => sp.id !== policy.id); - } else { - this.selectedPolicyList = [...this.selectedPolicyList, {...policy}]; - } - - this.policySearchResultList = this.policySearchResultList.map((p) => ({ - ...p, - isSelected: this.selectedPolicyList.some((sp => sp.id === p.id)) - })); - this.policySelectNode.writeValue(undefined); - this.validatePoliciesControl(); - } - - removePolicy(policy: IAccessTokenPolicy) { - this.selectedPolicyList = this.selectedPolicyList.filter((p) => p.id !== policy.id); - this.validatePoliciesControl(); - } - - isLoadingPolicies = false; - searchPolicies(query: string = '') { + setAuthorizedPermissions() { const hasOwnerPolicy = this.permissionsService.policies.some((policy) => policy.name === 'Owner' && policy.type === 'SysManaged'); if (hasOwnerPolicy) { - this.isLoadingPolicies = true; - - this.policyService.getList(new PolicyFilter(query, 1, 50)).subscribe({ + this.policyService.getList(new PolicyFilter('', 1, 100)).subscribe({ next: policies => { - this.policySearchResultList = policies.items.map(p => ({ - ...p, - isSelected: this.selectedPolicyList.some((sp => sp.id === p.id)) - })); - - this.isLoadingPolicies = false; - }, error: () => this.isLoadingPolicies = false + this.permissions = preProcessPermissions(policies.items.flatMap(p => p.statements)); + this.authorizedResourceTypes = this.resourceTypes.filter((rt) => this.permissions[rt.type]?.statements?.length > 0); + } }); } else { - const regex = new RegExp(query,'ig'); - this.policySearchResultList = this.permissionsService.policies - .filter((policy) => query === '' || policy.name.match(regex)) - .map((policy) => ({ - ...policy, - isSelected: this.selectedPolicyList.some((sp => sp.id === policy.id)) - }) - ); + this.permissions = preProcessPermissions(this.permissionsService.permissions); } - } nameAsyncValidator = (control: FormControl) => control.valueChanges.pipe( @@ -193,38 +150,45 @@ export class AccessTokenDrawerComponent implements OnInit { first() ); - isLoading: boolean = false; - isPolicyIdsValid = true; + updatePermissionsAllChecked(statementGroup: IPermissionStatementGroup) { + statementGroup.indeterminate = false; + if (statementGroup.allChecked) { + statementGroup.statements = statementGroup.statements.map(item => ({ + ...item, + checked: true + })); + } else { + statementGroup.statements = statementGroup.statements.map(item => ({ + ...item, + checked: false + })); + } + } - validatePoliciesControl() { - const policyControl = this.form.get('policy'); - if (this.isServiceAccessToken && this.selectedPolicyList.length === 0) { - policyControl.setValidators(Validators.required); - policyControl.setErrors({required: true}); - this.isPolicyIdsValid = false; + updatePermissionSingleChecked(statementGroup: IPermissionStatementGroup){ + if (statementGroup.statements.every(item => !item.checked)) { + statementGroup.allChecked = false; + statementGroup.indeterminate = false; + } else if (statementGroup.statements.every(item => item.checked)) { + statementGroup.allChecked = true; + statementGroup.indeterminate = false; } else { - policyControl.clearValidators(); - policyControl.markAsPristine(); - this.isPolicyIdsValid = true; + statementGroup.indeterminate = true; } } + isLoading: boolean = false; + tokenName = ''; tokenValue = ''; isCreationConfirmModalVisible = false; doSubmit() { - // we validate name and type only here if (this.form.invalid) { for (const i in this.form.controls) { this.form.controls[i].markAsDirty(); this.form.controls[i].updateValueAndValidity(); } - } - // validate policies - this.validatePoliciesControl(); - - if (this.form.invalid || !this.isPolicyIdsValid) { return; } @@ -234,6 +198,7 @@ export class AccessTokenDrawerComponent implements OnInit { this.message.warning($localize `:@@permissions.need-permissions-to-operate:You don't have permissions to take this action, please contact the admin to grant you the necessary permissions`); return; } + this.isLoading = true; if (this.isEditing) { this.accessTokenService.update(this.accessToken.id, name).subscribe({ @@ -249,7 +214,7 @@ export class AccessTokenDrawerComponent implements OnInit { } ); } else { - const policies = this.isServiceAccessToken ? this.selectedPolicyList.map(p => p.id) : []; + const policies = this.isServiceAccessToken ? postProcessPermissions(this.permissions) : []; this.accessTokenService.create(name, type, policies).subscribe({ next: ({id, name, token}) => { diff --git a/modules/front-end/src/app/core/core.module.ts b/modules/front-end/src/app/core/core.module.ts index d049483d8..950d75890 100644 --- a/modules/front-end/src/app/core/core.module.ts +++ b/modules/front-end/src/app/core/core.module.ts @@ -82,6 +82,7 @@ import { NzInputNumberModule } from "ng-zorro-antd/input-number"; import { AccessTokenDrawerComponent } from "@core/components/access-token-drawer/access-token-drawer.component"; import { AccessTokenTypePipe } from "@core/pipes/access-token-type.pipe"; import { AccessTokenStatusPipe } from "@core/pipes/access-token-status.pipe"; +import { NzCollapseModule } from "ng-zorro-antd/collapse"; @NgModule({ declarations: [ @@ -123,51 +124,52 @@ import { AccessTokenStatusPipe } from "@core/pipes/access-token-status.pipe"; ChangeReviewComponent, AccessTokenDrawerComponent ], - imports: [ - CommonModule, - FormsModule, - OverlayModule, - ReactiveFormsModule, - RouterModule, - NzFormModule, - NzIconModule, - NzMenuModule, - NzModalModule, - NzInputModule, - NzOutletModule, - NzButtonModule, - NzDrawerModule, - NzMessageModule, - NzOverlayModule, - NzDropDownModule, - NzTableModule, - NzSelectModule, - NzDividerModule, - NzSpaceModule, - NzSpinModule, - NzRadioModule, - NzUploadModule, - NzTagModule, - NzToolTipModule, - NzListModule, - NzCheckboxModule, - NzTabsModule, - NzPopconfirmModule, - NzStepsModule, - NzAlertModule, - NzResultModule, - NzLayoutModule, - NzImageModule, - NzPopoverModule, - NzCodeEditorModule, - NzCardModule, - NzTypographyModule, - NzDatePickerModule, - NzEmptyModule, - NzTimelineModule, - NzBreadCrumbModule, - NzInputNumberModule - ], + imports: [ + CommonModule, + FormsModule, + OverlayModule, + ReactiveFormsModule, + RouterModule, + NzFormModule, + NzIconModule, + NzMenuModule, + NzModalModule, + NzInputModule, + NzOutletModule, + NzButtonModule, + NzDrawerModule, + NzMessageModule, + NzOverlayModule, + NzDropDownModule, + NzTableModule, + NzSelectModule, + NzDividerModule, + NzSpaceModule, + NzSpinModule, + NzRadioModule, + NzUploadModule, + NzTagModule, + NzToolTipModule, + NzListModule, + NzCheckboxModule, + NzTabsModule, + NzPopconfirmModule, + NzStepsModule, + NzAlertModule, + NzResultModule, + NzLayoutModule, + NzImageModule, + NzPopoverModule, + NzCodeEditorModule, + NzCardModule, + NzTypographyModule, + NzDatePickerModule, + NzEmptyModule, + NzTimelineModule, + NzBreadCrumbModule, + NzInputNumberModule, + NzCollapseModule + ], exports: [ CommonModule, ReactiveFormsModule, diff --git a/modules/front-end/src/app/core/guards/accessTokens.guard.ts b/modules/front-end/src/app/core/guards/accessTokens.guard.ts index c11c0c1b6..a9bf8ce4a 100644 --- a/modules/front-end/src/app/core/guards/accessTokens.guard.ts +++ b/modules/front-end/src/app/core/guards/accessTokens.guard.ts @@ -22,7 +22,7 @@ export class AccessTokensGuard implements CanActivate { } async checkPermission(url: string): Promise { - const canListAccessTokens = !!this.permissionsService.canTakeAction(generalResourceRNPattern.account, permissionActions.ListAccessTokens); + const canListAccessTokens = !!this.permissionsService.canTakeAction(generalResourceRNPattern.accessToken, permissionActions.ListAccessTokens); if (!canListAccessTokens) { this.message.warning(this.permissionsService.genericDenyMessage); diff --git a/modules/front-end/src/app/core/pipes/translation.pipe.ts b/modules/front-end/src/app/core/pipes/translation.pipe.ts index f3475e3e1..0e178776f 100644 --- a/modules/front-end/src/app/core/pipes/translation.pipe.ts +++ b/modules/front-end/src/app/core/pipes/translation.pipe.ts @@ -1,12 +1,11 @@ import {Inject, LOCALE_ID, Pipe, PipeTransform} from "@angular/core"; import ResourceTranslation from "@core/translations/resource.translation"; -import IamOperationTranslation from "@core/translations/iam-operation.translation"; import ExptStatusTranslation from "@core/translations/expt-status.translation"; import TriggerTypeTranslation from "@core/translations/trigger-type.translation"; const translationType = { resource: 'resource', - op: 'operation', + effect: 'effect', exptStatus: 'expt-status', triggerType: 'trigger-type' } @@ -16,14 +15,22 @@ export class TranslationPipe implements PipeTransform { constructor(@Inject(LOCALE_ID) private locale: string) { } - transform(value, defaultValue, type: 'resource' | 'operation' | 'expt-status' | 'trigger-type') { - let result; + transform(value, defaultValue, type: 'resource' | 'effect' | 'expt-status' | 'trigger-type') { + let result = null; switch (type){ case translationType.resource: result = ResourceTranslation[value] ? ResourceTranslation[value][this.locale] : null break; - case translationType.op: - result = IamOperationTranslation[value] ? IamOperationTranslation[value][this.locale] : null + case translationType.effect: + const effectAllow = new RegExp('allow', 'i'); + const effectDeny = new RegExp('deny', 'i'); + + if (value.match(effectAllow)) { + result = $localize `:@@iam.effect.allow:Allow`; + } else if (value.match(effectDeny)) { + result = $localize `:@@iam.effect.deny:Deny`; + } + break; case translationType.exptStatus: result = ExptStatusTranslation[value] ? ExptStatusTranslation[value][this.locale] : null diff --git a/modules/front-end/src/app/core/services/access-token.service.ts b/modules/front-end/src/app/core/services/access-token.service.ts index 29c301eb3..2383568d5 100644 --- a/modules/front-end/src/app/core/services/access-token.service.ts +++ b/modules/front-end/src/app/core/services/access-token.service.ts @@ -10,6 +10,7 @@ import { IPagedAccessToken } from "@features/safe/integrations/access-tokens/types/access-token"; import { IMetric } from "@features/safe/experiments/types"; +import { IPolicyStatement } from "@shared/policy"; @Injectable({ providedIn: 'root' @@ -43,8 +44,8 @@ export class AccessTokenService { return this.http.get(url).pipe(catchError(() => of(undefined))); } - create(name: string, type: string, policyIds: string[] = []): Observable { - return this.http.post(this.baseUrl, { name, type, policyIds }); + create(name: string, type: string, permissions: IPolicyStatement[] = []): Observable { + return this.http.post(this.baseUrl, { name, type, permissions }); } delete(id: string): Observable { diff --git a/modules/front-end/src/app/core/translations/iam-operation.translation.ts b/modules/front-end/src/app/core/translations/iam-operation.translation.ts deleted file mode 100644 index 74ffc6a67..000000000 --- a/modules/front-end/src/app/core/translations/iam-operation.translation.ts +++ /dev/null @@ -1,8 +0,0 @@ -export default { - 'Allow': { - zh: '允许操作' - }, - 'Deny':{ - zh: '禁止操作' - } -} diff --git a/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.html b/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.html index 15f996a64..eb3802b1f 100644 --- a/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.html +++ b/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.html @@ -45,8 +45,8 @@
    Allow or deny
    - - + +
    diff --git a/modules/front-end/src/app/features/safe/iam/types/policy.ts b/modules/front-end/src/app/features/safe/iam/types/policy.ts index f89ac317c..3b515b3e6 100644 --- a/modules/front-end/src/app/features/safe/iam/types/policy.ts +++ b/modules/front-end/src/app/features/safe/iam/types/policy.ts @@ -1,3 +1,5 @@ +import { IPolicyStatement } from "@shared/policy"; + export interface IPolicy { id: string; type: string; @@ -10,14 +12,6 @@ export interface IPolicy { resourceName?: string; } -export interface IPolicyStatement { - id: string; - resourceType: string; - effect: string; - actions: string[]; - resources: string[]; -} - export class PolicyFilter { name?: string; pageIndex: number; diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts index 2ee9a321e..5a2fe1814 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts @@ -30,6 +30,7 @@ export class IndexComponent implements OnInit { canTakeActionOnPersonalAccessToken = false; canTakeActionOnServiceAccessToken = false; + constructor( private router: Router, private message: NzMessageService, @@ -53,8 +54,8 @@ export class IndexComponent implements OnInit { }); }); - this.canTakeActionOnPersonalAccessToken = this.permissionsService.canTakeAction(generalResourceRNPattern.account, permissionActions.CreatePersonalAccessTokens); - this.canTakeActionOnServiceAccessToken = this.permissionsService.canTakeAction(generalResourceRNPattern.account, permissionActions.CreateServiceAccessTokens); + this.canTakeActionOnPersonalAccessToken = this.permissionsService.canTakeAction(generalResourceRNPattern.accessToken, permissionActions.ManagePersonalAccessTokens); + this.canTakeActionOnServiceAccessToken = this.permissionsService.canTakeAction(generalResourceRNPattern.accessToken, permissionActions.ManageServiceAccessTokens); } private search$ = new Subject(); @@ -107,9 +108,6 @@ export class IndexComponent implements OnInit { } accessTokenDrawerVisible: boolean = false; - private openAccessTokenDrawer(){ - this.accessTokenDrawerVisible = true; - } accessTokenDrawerClosed(data: any) { //{ isEditing: boolean, id: string, name: string } this.accessTokenDrawerVisible = false; @@ -131,10 +129,10 @@ export class IndexComponent implements OnInit { } } - currentAccessToken: IAccessToken; - creatOrEdit(accessToken: IAccessToken = { name: null, type: AccessTokenTypeEnum.Personal, policies: []}) { + currentAccessToken: IAccessToken = { name: null, type: AccessTokenTypeEnum.Personal, permissions: []}; + creatOrEdit(accessToken: IAccessToken = { name: null, type: AccessTokenTypeEnum.Personal, permissions: []}) { this.currentAccessToken = accessToken; - this.openAccessTokenDrawer(); + this.accessTokenDrawerVisible = true; } delete(accessToken: IAccessToken) { diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts index bcfba7446..497bb1db5 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/types/access-token.ts @@ -1,5 +1,6 @@ import { IPolicy } from "@features/safe/iam/types/policy"; import { IMember } from "@features/safe/iam/types/member"; +import { IPolicyStatement } from "@shared/policy"; export interface IAccessToken { id?: string; @@ -9,6 +10,7 @@ export interface IAccessToken { token?: string; name: string; policies?: IPolicy[], + permissions?: IPolicyStatement[], lastUsedAt?: string } diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/types/permission-helper.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/types/permission-helper.ts new file mode 100644 index 000000000..25c31070c --- /dev/null +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/types/permission-helper.ts @@ -0,0 +1,53 @@ +import { IamPolicyAction, IPolicyStatement, ResourceTypeEnum } from "@shared/policy"; +import { permissionActions } from "@shared/permissions"; +import { uuidv4 } from "@utils/index"; + +export interface IPermissionStatementGroup { + allChecked: boolean, + indeterminate: boolean, + statements: IPermissionStatement[] +} + +export interface IPermissionStatement extends IPolicyStatement { + action: IamPolicyAction; + checked: boolean +} + +export const preProcessPermissions = (statements: IPolicyStatement[]): { [key: string]: IPermissionStatementGroup} => { + return statements.flatMap((statement) => { + const {effect, resourceType, resources} = statement; + return statement.actions.map((action) => ({ + effect, + resourceType, + resources, + action: permissionActions[action] + })); + }).filter(({effect, resourceType, resources, action}) => action && action.isOpenAPIApplicable) + .reduce((acc, cur) => { + acc[cur.resourceType] = acc[cur.resourceType] || { allChecked: true, indeterminate: false, statements: [] }; + const idx = acc[cur.resourceType].statements.findIndex((api) => api.effect ===cur.effect && api.action.name ===cur.action.name && api.effect === 'allow'); + + if (idx !== -1) { // duplicate exists + const statement = acc[cur.resourceType].statements[idx]; + const resources = [...statement.resources, ...cur.resources]; + acc[cur.resourceType].statements.splice(idx, 1, { ...cur, checked: true, resources: resources.filter((resource, idx) => resources.indexOf(resource) === idx)}); + } else { + acc[cur.resourceType].statements.push({...cur, checked: true}); + } + + return acc; + }, {}); +} + +export const postProcessPermissions = (permissions: { [key: string]: IPermissionStatementGroup}): IPolicyStatement[] => { + return Object.keys(permissions) + .flatMap((property) => permissions[property].statements) + .filter((statement) => statement.checked) + .map(({id, effect, resourceType, resources, action}) => ({ + id: uuidv4(), + effect, + resourceType, + resources, + actions: [action.name] + })); +} diff --git a/modules/front-end/src/app/shared/permissions.ts b/modules/front-end/src/app/shared/permissions.ts index b166598cf..2546e3313 100644 --- a/modules/front-end/src/app/shared/permissions.ts +++ b/modules/front-end/src/app/shared/permissions.ts @@ -145,7 +145,7 @@ export const permissionActions: {[key: string]: IamPolicyAction} = { isOpenAPIApplicable: true, isSpecificApplicable: false }, - CreateServiceAccessTokens: { + ManageServiceAccessTokens: { id: uuidv4(), name: 'ManageServiceAccessTokens', displayName: $localize`:@@iam.action.manage-service-access-tokens:Manage service access tokens`, @@ -153,7 +153,7 @@ export const permissionActions: {[key: string]: IamPolicyAction} = { isOpenAPIApplicable: true, isSpecificApplicable: false }, - CreatePersonalAccessTokens: { + ManagePersonalAccessTokens: { id: uuidv4(), name: 'ManagePersonalAccessTokens', displayName: $localize`:@@iam.action.manage-personal-access-tokens:Manage personal access tokens`, diff --git a/modules/front-end/src/app/shared/policy.ts b/modules/front-end/src/app/shared/policy.ts index 32030d5bd..d6793280d 100644 --- a/modules/front-end/src/app/shared/policy.ts +++ b/modules/front-end/src/app/shared/policy.ts @@ -55,37 +55,48 @@ export interface RNViewModel { isInvalid?: boolean } +export const ResourceTypeAll: ResourceType = { + type: ResourceTypeEnum.All, + pattern: generalResourceRNPattern.all, + displayName: $localize`:@@iam.rsc-type.all:All` +}; + +export const ResourceTypeAccount: ResourceType = { + type: ResourceTypeEnum.Account, + pattern: generalResourceRNPattern.account, + displayName: $localize`:@@iam.rsc-type.account:Account` +}; + +export const ResourceTypeIAM: ResourceType = { + type: ResourceTypeEnum.IAM, + pattern: generalResourceRNPattern.iam, + displayName: $localize`:@@iam.rsc-type.iam:IAM` +}; + +export const ResourceTypeAccessToken: ResourceType = { + type: ResourceTypeEnum.AccessToken, + pattern: generalResourceRNPattern.accessToken, + displayName: $localize`:@@iam.rsc-type.access-token:Access token` +}; +export const ResourceTypeProject: ResourceType = { + type: ResourceTypeEnum.Project, + pattern: 'project/{project}', + displayName: $localize`:@@iam.rsc-type.project:Project` +}; + +export const ResourceTypeEnv = { + type: ResourceTypeEnum.Env, + pattern: 'project/{project}:env/{env}', + displayName: $localize`:@@iam.rsc-type.env:Environment` +}; + export const resourcesTypes: ResourceType[] = [ - { - type: ResourceTypeEnum.All, - pattern: generalResourceRNPattern.all, - displayName: $localize`:@@iam.rsc-type.all:All` - }, - { - type: ResourceTypeEnum.Account, - pattern: generalResourceRNPattern.account, - displayName: $localize`:@@iam.rsc-type.account:Account` - }, - { - type: ResourceTypeEnum.IAM, - pattern: generalResourceRNPattern.iam, - displayName: $localize`:@@iam.rsc-type.iam:IAM` - }, - { - type: ResourceTypeEnum.AccessToken, - pattern: generalResourceRNPattern.accessToken, - displayName: $localize`:@@iam.rsc-type.access-token:Access token` - }, - { - type: ResourceTypeEnum.Project, - pattern: 'project/{project}', - displayName: $localize`:@@iam.rsc-type.project:Project` - }, - { - type: ResourceTypeEnum.Env, - pattern: 'project/{project}:env/{env}', - displayName: $localize`:@@iam.rsc-type.env:Environment` - } + ResourceTypeAll, + ResourceTypeAccount, + ResourceTypeIAM, + ResourceTypeAccessToken, + ResourceTypeProject, + ResourceTypeEnv ]; export interface ResourceParamViewModel { @@ -149,8 +160,8 @@ export const resourceActionsDict: {[key: string]: IamPolicyAction[]} = { ], [ResourceTypeEnum.AccessToken]: [ permissionActions.ListAccessTokens, - permissionActions.CreateServiceAccessTokens, - permissionActions.CreatePersonalAccessTokens, + permissionActions.ManageServiceAccessTokens, + permissionActions.ManagePersonalAccessTokens, ], [ResourceTypeEnum.Project]: [ permissionActions.ListProjects, diff --git a/modules/front-end/src/locale/messages.xlf b/modules/front-end/src/locale/messages.xlf index d6d7e7ca2..dd6f1b03b 100644 --- a/modules/front-end/src/locale/messages.xlf +++ b/modules/front-end/src/locale/messages.xlf @@ -260,107 +260,41 @@ 58 - - Policies + + Permissions src/app/core/components/access-token-drawer/access-token-drawer.component.html 45 - src/app/features/safe/iam/groups/details/details.component.html - 13 + src/app/features/safe/iam/components/policy-editor/policy-editor.component.html + 14 - - - Select policies - src/app/core/components/access-token-drawer/access-token-drawer.component.html - 50 + src/app/features/safe/iam/policies/details/details.component.html + 7 - - Loading... + + All src/app/core/components/access-token-drawer/access-token-drawer.component.html - 68 - - - src/app/core/components/audit-logs/audit-logs.component.html - 26 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 36 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 66 - - - src/app/core/components/member-drawer/member-drawer.component.html - 38 - - - src/app/core/components/member-drawer/member-drawer.component.html - 55 - - - src/app/core/components/metric-drawer/metric-drawer.component.html - 43 - - - src/app/core/components/target-user/target-user.component.html - 44 - - - src/app/features/safe/end-users/index/index.component.html - 25 - - - src/app/features/safe/end-users/index/index.component.html 60 - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 136 - - - src/app/features/safe/feature-flags/details/insights/insights.component.html - 18 - - - src/app/features/safe/feature-flags/details/setting/setting.component.html - 146,147 - - - src/app/features/safe/feature-flags/index/index.component.html - 26 - - - src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html - 38 - - - src/app/features/safe/integrations/access-tokens/index/index.component.html - 28 - - - - Policies are mandatory for service type access tokens - - src/app/core/components/access-token-drawer/access-token-drawer.component.html - 82 + src/app/features/safe/experiments/metrics/metrics.component.html + 12 - src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 267 + src/app/features/safe/feature-flags/details/insights/insights.component.ts + 58 Save src/app/core/components/access-token-drawer/access-token-drawer.component.html - 92 + 85 src/app/core/components/change-review/change-review.component.html @@ -439,28 +373,28 @@ Access token created src/app/core/components/access-token-drawer/access-token-drawer.component.html - 100 + 93 Copy and save this token now, the token value will be masked once you leave the page. src/app/core/components/access-token-drawer/access-token-drawer.component.html - 109 + 102 OK src/app/core/components/access-token-drawer/access-token-drawer.component.html - 124 + 117 You don't have permissions to take this action, please contact the admin to grant you the necessary permissions src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 234 + 198 src/app/core/services/permissions.service.ts @@ -471,11 +405,11 @@ Operation succeeded src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 243 + 208 src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 258 + 223 src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts @@ -655,11 +589,11 @@ src/app/features/safe/integrations/access-tokens/index/index.component.ts - 143 + 141 src/app/features/safe/integrations/access-tokens/index/index.component.ts - 154 + 152 src/app/features/safe/segments/details/setting/setting.component.ts @@ -686,7 +620,7 @@ Operation failed, please try again src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 246 + 211 src/app/core/components/metric-drawer/metric-drawer.component.ts @@ -749,11 +683,18 @@ 79 + + Policies are mandatory for service type access tokens + + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 232 + + Copied src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 277 + 242 src/app/core/components/header/header.component.ts @@ -875,6 +816,69 @@ 20 + + Loading... + + src/app/core/components/audit-logs/audit-logs.component.html + 26 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 36 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 66 + + + src/app/core/components/member-drawer/member-drawer.component.html + 38 + + + src/app/core/components/member-drawer/member-drawer.component.html + 55 + + + src/app/core/components/metric-drawer/metric-drawer.component.html + 43 + + + src/app/core/components/target-user/target-user.component.html + 44 + + + src/app/features/safe/end-users/index/index.component.html + 25 + + + src/app/features/safe/end-users/index/index.component.html + 60 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html + 136 + + + src/app/features/safe/feature-flags/details/insights/insights.component.html + 18 + + + src/app/features/safe/feature-flags/details/setting/setting.component.html + 146,147 + + + src/app/features/safe/feature-flags/index/index.component.html + 26 + + + src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html + 38 + + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 28 + + Filter by type @@ -1505,11 +1509,11 @@ src/app/features/safe/integrations/access-tokens/index/index.component.ts - 147 + 145 src/app/features/safe/integrations/access-tokens/index/index.component.ts - 157 + 155 src/app/features/safe/segments/details/targeting/targeting.component.ts @@ -3215,6 +3219,20 @@ 9 + + Allow + + src/app/core/pipes/translation.pipe.ts + 29 + + + + Deny + + src/app/core/pipes/translation.pipe.ts + 31 + + Login @@ -3574,17 +3592,6 @@ 3 - - All - - src/app/features/safe/experiments/metrics/metrics.component.html - 12 - - - src/app/features/safe/feature-flags/details/insights/insights.component.ts - 58 - - Custom event @@ -4983,17 +4990,6 @@ 5 - - Permissions - - src/app/features/safe/iam/components/policy-editor/policy-editor.component.html - 14 - - - src/app/features/safe/iam/policies/details/details.component.html - 7 - - Resource type @@ -5119,6 +5115,13 @@ 13 + + Policies + + src/app/features/safe/iam/groups/details/details.component.html + 13 + + Filter by policy name @@ -6593,7 +6596,7 @@ All src/app/shared/policy.ts - 62 + 61 @@ -6607,46 +6610,46 @@ IAM src/app/shared/policy.ts - 72 + 73 Access token src/app/shared/policy.ts - 77 + 79 Project src/app/shared/policy.ts - 82 + 84 Environment src/app/shared/policy.ts - 87 + 90 Project src/app/shared/policy.ts - 110 + 121 src/app/shared/policy.ts - 122 + 133 Environment src/app/shared/policy.ts - 132 + 143 diff --git a/modules/front-end/src/locale/messages.zh.xlf b/modules/front-end/src/locale/messages.zh.xlf index be6a062ec..76092a4aa 100644 --- a/modules/front-end/src/locale/messages.zh.xlf +++ b/modules/front-end/src/locale/messages.zh.xlf @@ -265,111 +265,43 @@ 类型 - - Policies + + Permissions src/app/core/components/access-token-drawer/access-token-drawer.component.html 45 - src/app/features/safe/iam/groups/details/details.component.html - 13 + src/app/features/safe/iam/components/policy-editor/policy-editor.component.html + 14 - 策略 - - - Select policies - src/app/core/components/access-token-drawer/access-token-drawer.component.html - 50 + src/app/features/safe/iam/policies/details/details.component.html + 7 - 选择策略 + 权限 - - Loading... + + All src/app/core/components/access-token-drawer/access-token-drawer.component.html - 68 - - - src/app/core/components/audit-logs/audit-logs.component.html - 26 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 36 - - - src/app/core/components/experiment-drawer/experiment-drawer.component.html - 66 - - - src/app/core/components/member-drawer/member-drawer.component.html - 38 - - - src/app/core/components/member-drawer/member-drawer.component.html - 55 - - - src/app/core/components/metric-drawer/metric-drawer.component.html - 43 - - - src/app/core/components/target-user/target-user.component.html - 44 - - - src/app/features/safe/end-users/index/index.component.html - 25 - - - src/app/features/safe/end-users/index/index.component.html 60 - src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html - 136 - - - src/app/features/safe/feature-flags/details/insights/insights.component.html - 18 - - - src/app/features/safe/feature-flags/details/setting/setting.component.html - 146,147 - - - src/app/features/safe/feature-flags/index/index.component.html - 26 - - - src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html - 38 - - - src/app/features/safe/integrations/access-tokens/index/index.component.html - 28 - - 数据加载中... - - - Policies are mandatory for service type access tokens - - src/app/core/components/access-token-drawer/access-token-drawer.component.html - 82 + src/app/features/safe/experiments/metrics/metrics.component.html + 12 - src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 267 + src/app/features/safe/feature-flags/details/insights/insights.component.ts + 58 - 策略不能为空 + 全部 Save src/app/core/components/access-token-drawer/access-token-drawer.component.html - 92 + 85 src/app/core/components/change-review/change-review.component.html @@ -449,7 +381,7 @@ Access token created src/app/core/components/access-token-drawer/access-token-drawer.component.html - 100 + 93 成功创建访问秘钥 @@ -457,7 +389,7 @@ Copy and save this token now, the token value will be masked once you leave the page. src/app/core/components/access-token-drawer/access-token-drawer.component.html - 109 + 102 请复制并保存 Token,一旦离开该页面后,该 Token 将会被隐藏。 @@ -465,7 +397,7 @@ OK src/app/core/components/access-token-drawer/access-token-drawer.component.html - 124 + 117 OK @@ -473,7 +405,7 @@ You don't have permissions to take this action, please contact the admin to grant you the necessary permissions src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 234 + 198 src/app/core/services/permissions.service.ts @@ -485,11 +417,11 @@ Operation succeeded src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 243 + 208 src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 258 + 223 src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts @@ -669,11 +601,11 @@ src/app/features/safe/integrations/access-tokens/index/index.component.ts - 143 + 141 src/app/features/safe/integrations/access-tokens/index/index.component.ts - 154 + 152 src/app/features/safe/segments/details/setting/setting.component.ts @@ -701,7 +633,7 @@ Operation failed, please try again src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 246 + 211 src/app/core/components/metric-drawer/metric-drawer.component.ts @@ -765,11 +697,19 @@ 操作失败,请重试 + + Policies are mandatory for service type access tokens + + src/app/core/components/access-token-drawer/access-token-drawer.component.ts + 232 + + 策略不能为空 + Copied src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 277 + 242 src/app/core/components/header/header.component.ts @@ -901,6 +841,70 @@ 按团队成员查找 + + Loading... + + src/app/core/components/audit-logs/audit-logs.component.html + 26 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 36 + + + src/app/core/components/experiment-drawer/experiment-drawer.component.html + 66 + + + src/app/core/components/member-drawer/member-drawer.component.html + 38 + + + src/app/core/components/member-drawer/member-drawer.component.html + 55 + + + src/app/core/components/metric-drawer/metric-drawer.component.html + 43 + + + src/app/core/components/target-user/target-user.component.html + 44 + + + src/app/features/safe/end-users/index/index.component.html + 25 + + + src/app/features/safe/end-users/index/index.component.html + 60 + + + src/app/features/safe/feature-flags/details/experimentation/experimentation.component.html + 136 + + + src/app/features/safe/feature-flags/details/insights/insights.component.html + 18 + + + src/app/features/safe/feature-flags/details/setting/setting.component.html + 146,147 + + + src/app/features/safe/feature-flags/index/index.component.html + 26 + + + src/app/features/safe/iam/components/policy-editor/resources-selector/resources-selector.component.html + 38 + + + src/app/features/safe/integrations/access-tokens/index/index.component.html + 28 + + 数据加载中... + Filter by type @@ -1581,11 +1585,11 @@ src/app/features/safe/integrations/access-tokens/index/index.component.ts - 147 + 145 src/app/features/safe/integrations/access-tokens/index/index.component.ts - 157 + 155 src/app/features/safe/segments/details/targeting/targeting.component.ts @@ -3448,6 +3452,22 @@ 客户托管 + + Allow + + src/app/core/pipes/translation.pipe.ts + 29 + + 允许 + + + Deny + + src/app/core/pipes/translation.pipe.ts + 31 + + 禁止 + Login @@ -3852,18 +3872,6 @@ 概览 - - All - - src/app/features/safe/experiments/metrics/metrics.component.html - 12 - - - src/app/features/safe/feature-flags/details/insights/insights.component.ts - 58 - - 全部 - Custom event @@ -5432,18 +5440,6 @@ 复制 - - Permissions - - src/app/features/safe/iam/components/policy-editor/policy-editor.component.html - 14 - - - src/app/features/safe/iam/policies/details/details.component.html - 7 - - 权限 - Resource type @@ -5584,6 +5580,14 @@ 团队 + + Policies + + src/app/features/safe/iam/groups/details/details.component.html + 13 + + 策略 + Filter by policy name @@ -7245,7 +7249,7 @@ All src/app/shared/policy.ts - 62 + 61 全部 @@ -7261,7 +7265,7 @@ IAM src/app/shared/policy.ts - 72 + 73 权限管理 @@ -7269,7 +7273,7 @@ Access token src/app/shared/policy.ts - 77 + 79 访问策略 @@ -7277,7 +7281,7 @@ Project src/app/shared/policy.ts - 82 + 84 项目 @@ -7285,7 +7289,7 @@ Environment src/app/shared/policy.ts - 87 + 90 环境 @@ -7293,11 +7297,11 @@ Project src/app/shared/policy.ts - 110 + 121 src/app/shared/policy.ts - 122 + 133 项目 @@ -7305,7 +7309,7 @@ Environment src/app/shared/policy.ts - 132 + 143 环境 diff --git a/modules/front-end/src/styles-common.less b/modules/front-end/src/styles-common.less index be09ea3af..50b6a3b5a 100644 --- a/modules/front-end/src/styles-common.less +++ b/modules/front-end/src/styles-common.less @@ -22,8 +22,11 @@ app-root { padding: 6px 0 7px 0; } -.ant-collapse>.ant-collapse-item>.ant-collapse-header { - padding: 0; +.ant-collapse { + border-radius: 8px; + .ant-collapse-item>.ant-collapse-header { + padding: 8px 16px; + } } .menu-list li a i { From 9098ebbc35fb22d5ab2012be2af7f0aa88ddaa93 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Thu, 16 Mar 2023 09:33:07 +0100 Subject: [PATCH 29/44] style --- .../access-token-drawer/access-token-drawer.component.less | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less index d5030f94a..e1a472ed6 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.less @@ -4,6 +4,10 @@ color: @red60-color; } +i { + cursor: pointer; +} + #confirm-modal-ok { color: @white; From 67f9b6c23a0ba4bf387c10debbe1a5f93dbb0135 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Thu, 16 Mar 2023 10:11:30 +0100 Subject: [PATCH 30/44] refactor --- .../access-token-drawer.component.ts | 28 +- .../env-drawer/env-drawer.component.ts | 2 +- .../components/header/header.component.ts | 2 +- .../project-drawer.component.ts | 3 +- .../src/app/core/guards/accessTokens.guard.ts | 2 +- .../src/app/core/guards/iam.guard.ts | 2 +- .../access-tokens/index/index.component.ts | 2 +- .../access-tokens/types/permission-helper.ts | 3 +- .../organization/organization.component.ts | 2 +- .../project/project.component.ts | 3 +- .../front-end/src/app/shared/permissions.ts | 164 --------- modules/front-end/src/app/shared/policy.ts | 183 +++++++++- modules/front-end/src/locale/messages.xlf | 308 ++++++++-------- modules/front-end/src/locale/messages.zh.xlf | 330 +++++++++--------- 14 files changed, 526 insertions(+), 508 deletions(-) delete mode 100644 modules/front-end/src/app/shared/permissions.ts diff --git a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts index 88319d472..58d8885c3 100644 --- a/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts +++ b/modules/front-end/src/app/core/components/access-token-drawer/access-token-drawer.component.ts @@ -6,21 +6,19 @@ import { PolicyService } from "@services/policy.service"; import { AccessTokenTypeEnum, IAccessToken, - IAccessTokenPolicy } from "@features/safe/integrations/access-tokens/types/access-token"; import { NzSelectComponent } from "ng-zorro-antd/select"; import { AccessTokenService } from "@services/access-token.service"; import { PermissionsService } from "@services/permissions.service"; -import { generalResourceRNPattern, permissionActions } from "@shared/permissions"; +import { EffectEnum, generalResourceRNPattern, permissionActions } from "@shared/policy"; import { PolicyFilter } from "@features/safe/iam/types/policy"; import { NzModalService } from "ng-zorro-antd/modal"; -import { copyToClipboard } from "@utils/index"; +import { copyToClipboard, uuidv4 } from "@utils/index"; import { preProcessPermissions, IPermissionStatementGroup, postProcessPermissions } from "@features/safe/integrations/access-tokens/types/permission-helper"; import { - IPolicyStatement, ResourceType, ResourceTypeAccessToken, ResourceTypeEnv, ResourceTypeProject @@ -43,7 +41,6 @@ export class AccessTokenDrawerComponent { this.isEditing = accessToken && !!accessToken.id; if (this.isEditing) { this.permissions = preProcessPermissions(accessToken.permissions); - this.authorizedResourceTypes = this.resourceTypes.filter((rt) => this.permissions[rt.type]?.statements?.length > 0); } else { accessToken = { name: null, type: AccessTokenTypeEnum.Personal}; this.setAuthorizedPermissions(); @@ -52,7 +49,7 @@ export class AccessTokenDrawerComponent { this.isServiceAccessToken = accessToken.type === AccessTokenTypeEnum.Service; this.patchForm(accessToken); this._accessToken = accessToken; - + this.authorizedResourceTypes = this.resourceTypes.filter((rt) => this.permissions[rt.type]?.statements?.length > 0); } @Input() visible: boolean = false; @@ -123,12 +120,19 @@ export class AccessTokenDrawerComponent { const hasOwnerPolicy = this.permissionsService.policies.some((policy) => policy.name === 'Owner' && policy.type === 'SysManaged'); if (hasOwnerPolicy) { - this.policyService.getList(new PolicyFilter('', 1, 100)).subscribe({ - next: policies => { - this.permissions = preProcessPermissions(policies.items.flatMap(p => p.statements)); - this.authorizedResourceTypes = this.resourceTypes.filter((rt) => this.permissions[rt.type]?.statements?.length > 0); - } - }); + const permissions = Object.keys(permissionActions) + .filter((property) => permissionActions[property].isOpenAPIApplicable) + .map((property) => { + const { resourceType, name } = permissionActions[property]; + return { + id: uuidv4(), + resourceType, + effect: EffectEnum.Allow, + actions: [name], + resources: [generalResourceRNPattern[resourceType]] + } + }); + this.permissions = preProcessPermissions(permissions); } else { this.permissions = preProcessPermissions(this.permissionsService.permissions); } diff --git a/modules/front-end/src/app/core/components/env-drawer/env-drawer.component.ts b/modules/front-end/src/app/core/components/env-drawer/env-drawer.component.ts index d61135a57..5232c75d6 100644 --- a/modules/front-end/src/app/core/components/env-drawer/env-drawer.component.ts +++ b/modules/front-end/src/app/core/components/env-drawer/env-drawer.component.ts @@ -4,7 +4,7 @@ import { NzMessageService } from 'ng-zorro-antd/message'; import { IEnvironment } from '@shared/types'; import { EnvService } from '@services/env.service'; import { ProjectService } from "@services/project.service"; -import { generalResourceRNPattern, permissionActions } from "@shared/permissions"; +import { generalResourceRNPattern, permissionActions } from "@shared/policy"; import { PermissionsService } from "@services/permissions.service"; @Component({ diff --git a/modules/front-end/src/app/core/components/header/header.component.ts b/modules/front-end/src/app/core/components/header/header.component.ts index 6c74af2fd..c4fef8fa6 100644 --- a/modules/front-end/src/app/core/components/header/header.component.ts +++ b/modules/front-end/src/app/core/components/header/header.component.ts @@ -5,7 +5,7 @@ import { ProjectService } from '@services/project.service'; import { Router } from '@angular/router'; import { Breadcrumb, BreadcrumbService } from '@services/bread-crumb.service'; import { PermissionsService } from "@services/permissions.service"; -import { generalResourceRNPattern, permissionActions } from "@shared/permissions"; +import { generalResourceRNPattern, permissionActions } from "@shared/policy"; import { NzMessageService } from "ng-zorro-antd/message"; import { MessageQueueService } from "@services/message-queue.service"; import { Observable } from "rxjs"; diff --git a/modules/front-end/src/app/core/components/project-drawer/project-drawer.component.ts b/modules/front-end/src/app/core/components/project-drawer/project-drawer.component.ts index 8ff69d746..c298adad7 100644 --- a/modules/front-end/src/app/core/components/project-drawer/project-drawer.component.ts +++ b/modules/front-end/src/app/core/components/project-drawer/project-drawer.component.ts @@ -4,8 +4,7 @@ import {NzMessageService} from 'ng-zorro-antd/message'; import {IProject} from '@shared/types'; import {ProjectService} from '@services/project.service'; import {PermissionsService} from "@services/permissions.service"; -import {generalResourceRNPattern, permissionActions} from "@shared/permissions"; -import {ResourceTypeEnum} from "@shared/policy"; +import {ResourceTypeEnum, generalResourceRNPattern, permissionActions} from "@shared/policy"; @Component({ selector: 'app-project-drawer', diff --git a/modules/front-end/src/app/core/guards/accessTokens.guard.ts b/modules/front-end/src/app/core/guards/accessTokens.guard.ts index a9bf8ce4a..d16795762 100644 --- a/modules/front-end/src/app/core/guards/accessTokens.guard.ts +++ b/modules/front-end/src/app/core/guards/accessTokens.guard.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router'; import {PermissionsService} from "@services/permissions.service"; -import {generalResourceRNPattern, permissionActions} from "@shared/permissions"; +import {generalResourceRNPattern, permissionActions} from "@shared/policy"; import {NzMessageService} from "ng-zorro-antd/message"; @Injectable({ diff --git a/modules/front-end/src/app/core/guards/iam.guard.ts b/modules/front-end/src/app/core/guards/iam.guard.ts index 9539775fb..67a852d15 100644 --- a/modules/front-end/src/app/core/guards/iam.guard.ts +++ b/modules/front-end/src/app/core/guards/iam.guard.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router'; import {PermissionsService} from "@services/permissions.service"; -import {generalResourceRNPattern, permissionActions} from "@shared/permissions"; +import {generalResourceRNPattern, permissionActions} from "@shared/policy"; import {NzMessageService} from "ng-zorro-antd/message"; @Injectable({ diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts index 5a2fe1814..d6bdad500 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/index/index.component.ts @@ -13,7 +13,7 @@ import { IOrganization } from "@shared/types"; import { CURRENT_ORGANIZATION } from "@utils/localstorage-keys"; import { TeamService } from "@services/team.service"; import { PermissionsService } from "@services/permissions.service"; -import { generalResourceRNPattern, permissionActions } from "@shared/permissions"; +import { generalResourceRNPattern, permissionActions } from "@shared/policy"; @Component({ selector: 'access-tokens', diff --git a/modules/front-end/src/app/features/safe/integrations/access-tokens/types/permission-helper.ts b/modules/front-end/src/app/features/safe/integrations/access-tokens/types/permission-helper.ts index 25c31070c..3b7119a77 100644 --- a/modules/front-end/src/app/features/safe/integrations/access-tokens/types/permission-helper.ts +++ b/modules/front-end/src/app/features/safe/integrations/access-tokens/types/permission-helper.ts @@ -1,5 +1,4 @@ -import { IamPolicyAction, IPolicyStatement, ResourceTypeEnum } from "@shared/policy"; -import { permissionActions } from "@shared/permissions"; +import { IamPolicyAction, IPolicyStatement, permissionActions } from "@shared/policy"; import { uuidv4 } from "@utils/index"; export interface IPermissionStatementGroup { diff --git a/modules/front-end/src/app/features/safe/organizations/organization/organization.component.ts b/modules/front-end/src/app/features/safe/organizations/organization/organization.component.ts index 684034bf5..13336a2b7 100644 --- a/modules/front-end/src/app/features/safe/organizations/organization/organization.component.ts +++ b/modules/front-end/src/app/features/safe/organizations/organization/organization.component.ts @@ -6,7 +6,7 @@ import { IOrganization } from '@shared/types'; import { OrganizationService } from '@services/organization.service'; import { getCurrentOrganization } from "@utils/project-env"; import {PermissionsService} from "@services/permissions.service"; -import {generalResourceRNPattern, permissionActions} from "@shared/permissions"; +import {generalResourceRNPattern, permissionActions} from "@shared/policy"; import { MessageQueueService } from '@core/services/message-queue.service'; @Component({ diff --git a/modules/front-end/src/app/features/safe/organizations/project/project.component.ts b/modules/front-end/src/app/features/safe/organizations/project/project.component.ts index 3348aabab..7bbcee7bb 100644 --- a/modules/front-end/src/app/features/safe/organizations/project/project.component.ts +++ b/modules/front-end/src/app/features/safe/organizations/project/project.component.ts @@ -5,12 +5,11 @@ import { OrganizationService } from '@services/organization.service'; import { EnvService } from '@services/env.service'; import { NzMessageService } from "ng-zorro-antd/message"; import {PermissionsService} from "@services/permissions.service"; -import {generalResourceRNPattern, permissionActions} from "@shared/permissions"; import {MessageQueueService} from "@services/message-queue.service"; import { FormBuilder, FormGroup, Validators } from "@angular/forms"; import { EnvSecretService } from "@services/env-secret.service"; import { copyToClipboard } from '@utils/index'; -import { ResourceTypeEnum } from "@shared/policy"; +import { ResourceTypeEnum, generalResourceRNPattern, permissionActions } from "@shared/policy"; @Component({ selector: 'app-project', diff --git a/modules/front-end/src/app/shared/permissions.ts b/modules/front-end/src/app/shared/permissions.ts deleted file mode 100644 index 2546e3313..000000000 --- a/modules/front-end/src/app/shared/permissions.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { uuidv4 } from "@utils/index"; -import { IamPolicyAction } from "@shared/policy"; - -export const generalResourceRNPattern = { - all: '*', - account: 'account/*', - iam: 'iam/*', - accessToken: 'access-token/*', - project: 'project/*', - env: 'project/*:env/*' -} - -export const permissionActions: {[key: string]: IamPolicyAction} = { - All: { - id: uuidv4(), - name: '*', - displayName: $localize`:@@iam.action.all:All`, - description: $localize`:@@iam.action.all:All`, - isOpenAPIApplicable: false, - isSpecificApplicable: false - }, - ListProjects: { - id: uuidv4(), - name: 'ListProjects', - displayName: $localize`:@@iam.action.list-projects:List projects`, - description: $localize`:@@iam.action.list-projects:List projects`, - isOpenAPIApplicable: true, - isSpecificApplicable: false - }, - CreateProject: { - id: uuidv4(), - name: 'CreateProject', - displayName: $localize`:@@iam.action.create-projects:Create projects`, - description: $localize`:@@iam.action.create-projects:Create projects`, - isOpenAPIApplicable: true, - isSpecificApplicable: false - }, - DeleteProject: { - id: uuidv4(), - name: 'DeleteProject', - displayName: $localize`:@@iam.action.delete-projects:Delete projects`, - description: $localize`:@@iam.action.delete-projects:Delete projects`, - isOpenAPIApplicable: true, - isSpecificApplicable: true - }, - AccessEnvs: { - id: uuidv4(), - name: 'AccessEnvs', - displayName: $localize`:@@iam.action.access-envs:Access environments`, - description: $localize`:@@iam.action.access-envs:Access environments`, - isOpenAPIApplicable: true, - isSpecificApplicable: true - }, - UpdateProjectSettings: { - id: uuidv4(), - name: 'UpdateProjectSettings', - displayName: $localize`:@@iam.action.update-project-settings:Update project settings`, - description: $localize`:@@iam.action.update-project-settings:Update project settings`, - isOpenAPIApplicable: true, - isSpecificApplicable: true - }, - ListEnvs: { - id: uuidv4(), - name: 'ListEnvs', - displayName: $localize`:@@iam.action.list-envs:List environments`, - description: $localize`:@@iam.action.list-envs:List environments`, - isOpenAPIApplicable: true, - isSpecificApplicable: true - }, - CreateEnv: { - id: uuidv4(), - name: 'CreateEnv', - displayName: $localize`:@@iam.action.create-env:Create environment`, - description: $localize`:@@iam.action.create-env:Create environment`, - isOpenAPIApplicable: true, - isSpecificApplicable: true - }, - DeleteEnv: { - id: uuidv4(), - name: 'DeleteEnv', - displayName: $localize`:@@iam.action.delete-envs:Delete environments`, - description: $localize`:@@iam.action.delete-envs:Delete environments`, - isOpenAPIApplicable: true, - isSpecificApplicable: true - }, - UpdateEnvSettings: { - id: uuidv4(), - name: 'UpdateEnvSettings', - displayName: $localize`:@@iam.action.update-env-settings:Update environment settings`, - description: $localize`:@@iam.action.update-env-settings:Update environment settings`, - isOpenAPIApplicable: true, - isSpecificApplicable: true - }, - DeleteEnvSecret: { - id: uuidv4(), - name: 'DeleteEnvSecret', - displayName: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, - description: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, - isOpenAPIApplicable: true, - isSpecificApplicable: true - }, - CreateEnvSecret: { - id: uuidv4(), - name: 'CreateEnvSecret', - displayName: $localize`:@@iam.action.create-env-secret:Create environment secret`, - description: $localize`:@@iam.action.create-env-secret:Create environment secret`, - isOpenAPIApplicable: true, - isSpecificApplicable: true - }, - UpdateEnvSecret: { - id: uuidv4(), - name: 'UpdateEnvSecret', - displayName: $localize`:@@iam.action.update-env-secret:Update environment secret`, - description: $localize`:@@iam.action.update-env-secret:Update environment secret`, - isOpenAPIApplicable: true, - isSpecificApplicable: true - }, - - // account - UpdateOrgName: { - id: uuidv4(), - name: 'UpdateOrgName', - displayName: $localize`:@@iam.action.update-org-name:Update org name`, - description: $localize`:@@iam.action.update-org-name:Update org name`, - isOpenAPIApplicable: true, - isSpecificApplicable: false - }, - - // iam - CanManageIAM: { - id: uuidv4(), - name: 'CanManageIAM', - displayName: $localize`:@@iam.action.iam:IAM`, - description: $localize`:@@iam.action.iam:IAM`, - isOpenAPIApplicable: true, - isSpecificApplicable: false - }, - - // access tokens - ListAccessTokens: { - id: uuidv4(), - name: 'ListAccessTokens', - displayName: $localize`:@@iam.action.list-access-tokens:List access tokens`, - description: $localize`:@@iam.action.list-access-tokens:List access tokens`, - isOpenAPIApplicable: true, - isSpecificApplicable: false - }, - ManageServiceAccessTokens: { - id: uuidv4(), - name: 'ManageServiceAccessTokens', - displayName: $localize`:@@iam.action.manage-service-access-tokens:Manage service access tokens`, - description: $localize`:@@iam.action.manage-service-access-tokens:Manage service access tokens`, - isOpenAPIApplicable: true, - isSpecificApplicable: false - }, - ManagePersonalAccessTokens: { - id: uuidv4(), - name: 'ManagePersonalAccessTokens', - displayName: $localize`:@@iam.action.manage-personal-access-tokens:Manage personal access tokens`, - description: $localize`:@@iam.action.manage-personal-access-tokens:Manage personal access tokens`, - isOpenAPIApplicable: true, - isSpecificApplicable: false - }, -} diff --git a/modules/front-end/src/app/shared/policy.ts b/modules/front-end/src/app/shared/policy.ts index d6793280d..e80ecd4c0 100644 --- a/modules/front-end/src/app/shared/policy.ts +++ b/modules/front-end/src/app/shared/policy.ts @@ -1,4 +1,4 @@ -import {generalResourceRNPattern, permissionActions} from "@shared/permissions"; +import { uuidv4 } from "@utils/index"; export interface IPolicyStatement { id: string; @@ -23,6 +23,7 @@ export interface ValPlaceholder { export interface IamPolicyAction { id: string; name: string; + resourceType?: ResourceTypeEnum, displayName: string; description: string; isOpenAPIApplicable: boolean; @@ -55,6 +56,15 @@ export interface RNViewModel { isInvalid?: boolean } +export const generalResourceRNPattern = { + all: '*', + account: 'account/*', + iam: 'iam/*', + accessToken: 'access-token/*', + project: 'project/*', + env: 'project/*:env/*' +}; + export const ResourceTypeAll: ResourceType = { type: ResourceTypeEnum.All, pattern: generalResourceRNPattern.all, @@ -148,6 +158,177 @@ export const rscParamsDict: {[key in ResourceTypeEnum]: ResourceParamViewModel[] ], }; +export const permissionActions: {[key: string]: IamPolicyAction} = { + All: { + id: uuidv4(), + name: '*', + resourceType: ResourceTypeEnum.All, + displayName: $localize`:@@iam.action.all:All`, + description: $localize`:@@iam.action.all:All`, + isOpenAPIApplicable: false, + isSpecificApplicable: false + }, + ListProjects: { + id: uuidv4(), + name: 'ListProjects', + resourceType: ResourceTypeEnum.Project, + displayName: $localize`:@@iam.action.list-projects:List projects`, + description: $localize`:@@iam.action.list-projects:List projects`, + isOpenAPIApplicable: true, + isSpecificApplicable: false + }, + CreateProject: { + id: uuidv4(), + name: 'CreateProject', + resourceType: ResourceTypeEnum.Project, + displayName: $localize`:@@iam.action.create-projects:Create projects`, + description: $localize`:@@iam.action.create-projects:Create projects`, + isOpenAPIApplicable: true, + isSpecificApplicable: false + }, + DeleteProject: { + id: uuidv4(), + name: 'DeleteProject', + resourceType: ResourceTypeEnum.Project, + displayName: $localize`:@@iam.action.delete-projects:Delete projects`, + description: $localize`:@@iam.action.delete-projects:Delete projects`, + isOpenAPIApplicable: true, + isSpecificApplicable: true + }, + UpdateProjectSettings: { + id: uuidv4(), + name: 'UpdateProjectSettings', + resourceType: ResourceTypeEnum.Project, + displayName: $localize`:@@iam.action.update-project-settings:Update project settings`, + description: $localize`:@@iam.action.update-project-settings:Update project settings`, + isOpenAPIApplicable: true, + isSpecificApplicable: true + }, + ListEnvs: { + id: uuidv4(), + name: 'ListEnvs', + resourceType: ResourceTypeEnum.Project, + displayName: $localize`:@@iam.action.list-envs:List environments`, + description: $localize`:@@iam.action.list-envs:List environments`, + isOpenAPIApplicable: true, + isSpecificApplicable: true + }, + CreateEnv: { + id: uuidv4(), + name: 'CreateEnv', + resourceType: ResourceTypeEnum.Project, + displayName: $localize`:@@iam.action.create-env:Create environment`, + description: $localize`:@@iam.action.create-env:Create environment`, + isOpenAPIApplicable: true, + isSpecificApplicable: true + }, + AccessEnvs: { + id: uuidv4(), + name: 'AccessEnvs', + resourceType: ResourceTypeEnum.Env, + displayName: $localize`:@@iam.action.access-envs:Access environments`, + description: $localize`:@@iam.action.access-envs:Access environments`, + isOpenAPIApplicable: true, + isSpecificApplicable: true + }, + DeleteEnv: { + id: uuidv4(), + name: 'DeleteEnv', + resourceType: ResourceTypeEnum.Env, + displayName: $localize`:@@iam.action.delete-envs:Delete environments`, + description: $localize`:@@iam.action.delete-envs:Delete environments`, + isOpenAPIApplicable: true, + isSpecificApplicable: true + }, + UpdateEnvSettings: { + id: uuidv4(), + name: 'UpdateEnvSettings', + resourceType: ResourceTypeEnum.Env, + displayName: $localize`:@@iam.action.update-env-settings:Update environment settings`, + description: $localize`:@@iam.action.update-env-settings:Update environment settings`, + isOpenAPIApplicable: true, + isSpecificApplicable: true + }, + DeleteEnvSecret: { + id: uuidv4(), + name: 'DeleteEnvSecret', + resourceType: ResourceTypeEnum.Env, + displayName: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, + description: $localize`:@@iam.action.delete-env-secret:Delete environment secret`, + isOpenAPIApplicable: true, + isSpecificApplicable: true + }, + CreateEnvSecret: { + id: uuidv4(), + name: 'CreateEnvSecret', + resourceType: ResourceTypeEnum.Env, + displayName: $localize`:@@iam.action.create-env-secret:Create environment secret`, + description: $localize`:@@iam.action.create-env-secret:Create environment secret`, + isOpenAPIApplicable: true, + isSpecificApplicable: true + }, + UpdateEnvSecret: { + id: uuidv4(), + name: 'UpdateEnvSecret', + resourceType: ResourceTypeEnum.Env, + displayName: $localize`:@@iam.action.update-env-secret:Update environment secret`, + description: $localize`:@@iam.action.update-env-secret:Update environment secret`, + isOpenAPIApplicable: true, + isSpecificApplicable: true + }, + + // account + UpdateOrgName: { + id: uuidv4(), + name: 'UpdateOrgName', + resourceType: ResourceTypeEnum.Account, + displayName: $localize`:@@iam.action.update-org-name:Update org name`, + description: $localize`:@@iam.action.update-org-name:Update org name`, + isOpenAPIApplicable: true, + isSpecificApplicable: false + }, + + // iam + CanManageIAM: { + id: uuidv4(), + name: 'CanManageIAM', + resourceType: ResourceTypeEnum.IAM, + displayName: $localize`:@@iam.action.iam:IAM`, + description: $localize`:@@iam.action.iam:IAM`, + isOpenAPIApplicable: true, + isSpecificApplicable: false + }, + + // access tokens + ListAccessTokens: { + id: uuidv4(), + name: 'ListAccessTokens', + resourceType: ResourceTypeEnum.AccessToken, + displayName: $localize`:@@iam.action.list-access-tokens:List access tokens`, + description: $localize`:@@iam.action.list-access-tokens:List access tokens`, + isOpenAPIApplicable: true, + isSpecificApplicable: false + }, + ManageServiceAccessTokens: { + id: uuidv4(), + name: 'ManageServiceAccessTokens', + resourceType: ResourceTypeEnum.AccessToken, + displayName: $localize`:@@iam.action.manage-service-access-tokens:Manage service access tokens`, + description: $localize`:@@iam.action.manage-service-access-tokens:Manage service access tokens`, + isOpenAPIApplicable: true, + isSpecificApplicable: false + }, + ManagePersonalAccessTokens: { + id: uuidv4(), + name: 'ManagePersonalAccessTokens', + resourceType: ResourceTypeEnum.AccessToken, + displayName: $localize`:@@iam.action.manage-personal-access-tokens:Manage personal access tokens`, + description: $localize`:@@iam.action.manage-personal-access-tokens:Manage personal access tokens`, + isOpenAPIApplicable: true, + isSpecificApplicable: false + }, +} + export const resourceActionsDict: {[key: string]: IamPolicyAction[]} = { [ResourceTypeEnum.All]: [ permissionActions.All, diff --git a/modules/front-end/src/locale/messages.xlf b/modules/front-end/src/locale/messages.xlf index dd6f1b03b..cc23986ae 100644 --- a/modules/front-end/src/locale/messages.xlf +++ b/modules/front-end/src/locale/messages.xlf @@ -394,7 +394,7 @@ You don't have permissions to take this action, please contact the admin to grant you the necessary permissions src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 198 + 202 src/app/core/services/permissions.service.ts @@ -405,11 +405,11 @@ Operation succeeded src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 208 + 212 src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 223 + 227 src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts @@ -620,7 +620,7 @@ Operation failed, please try again src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 211 + 215 src/app/core/components/metric-drawer/metric-drawer.component.ts @@ -668,15 +668,15 @@ src/app/features/safe/organizations/project/project.component.ts - 253 + 252 src/app/features/safe/organizations/project/project.component.ts - 287 + 286 src/app/features/safe/organizations/project/project.component.ts - 303 + 302 src/app/features/safe/segments/index/index.component.ts @@ -687,14 +687,14 @@ Policies are mandatory for service type access tokens src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 232 + 236 Copied src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 242 + 246 src/app/core/components/header/header.component.ts @@ -750,7 +750,7 @@ src/app/features/safe/organizations/project/project.component.ts - 181 + 180 @@ -2478,28 +2478,28 @@ Edit project src/app/core/components/project-drawer/project-drawer.component.ts - 30 + 29 Add project src/app/core/components/project-drawer/project-drawer.component.ts - 33 + 32 Project successfully updated src/app/core/components/project-drawer/project-drawer.component.ts - 113 + 112 Project successfully created src/app/core/components/project-drawer/project-drawer.component.ts - 126 + 125 @@ -5938,28 +5938,28 @@ Environment successfully removed src/app/features/safe/organizations/project/project.component.ts - 106 + 105 Project successfully removed src/app/features/safe/organizations/project/project.component.ts - 122 + 121 Add secret src/app/features/safe/organizations/project/project.component.ts - 205 + 204 Edit secret: src/app/features/safe/organizations/project/project.component.ts - 230 + 229 @@ -6394,262 +6394,262 @@ 76 - + All - src/app/shared/permissions.ts - 17 + src/app/shared/policy.ts + 71 + + + Account - src/app/shared/permissions.ts - 18 + src/app/shared/policy.ts + 77 - - List projects + + IAM - src/app/shared/permissions.ts - 25 + src/app/shared/policy.ts + 83 + + + Access token - src/app/shared/permissions.ts - 26 + src/app/shared/policy.ts + 89 - - Create projects + + Project - src/app/shared/permissions.ts - 33 + src/app/shared/policy.ts + 94 + + + Environment - src/app/shared/permissions.ts - 34 + src/app/shared/policy.ts + 100 - - Delete projects + + Project - src/app/shared/permissions.ts - 41 + src/app/shared/policy.ts + 131 - src/app/shared/permissions.ts - 42 + src/app/shared/policy.ts + 143 - - Access environments - - src/app/shared/permissions.ts - 49 - + + Environment - src/app/shared/permissions.ts - 50 + src/app/shared/policy.ts + 153 - - Update project settings + + All - src/app/shared/permissions.ts - 57 + src/app/shared/policy.ts + 166 - src/app/shared/permissions.ts - 58 + src/app/shared/policy.ts + 167 - - List environments + + List projects - src/app/shared/permissions.ts - 65 + src/app/shared/policy.ts + 175 - src/app/shared/permissions.ts - 66 + src/app/shared/policy.ts + 176 - - Create environment + + Create projects - src/app/shared/permissions.ts - 73 + src/app/shared/policy.ts + 184 - src/app/shared/permissions.ts - 74 + src/app/shared/policy.ts + 185 - - Delete environments + + Delete projects - src/app/shared/permissions.ts - 81 + src/app/shared/policy.ts + 193 - src/app/shared/permissions.ts - 82 + src/app/shared/policy.ts + 194 - - Update environment settings + + Update project settings - src/app/shared/permissions.ts - 89 + src/app/shared/policy.ts + 202 - src/app/shared/permissions.ts - 90 + src/app/shared/policy.ts + 203 - - Delete environment secret + + List environments - src/app/shared/permissions.ts - 97 + src/app/shared/policy.ts + 211 - src/app/shared/permissions.ts - 98 + src/app/shared/policy.ts + 212 - - Create environment secret + + Create environment - src/app/shared/permissions.ts - 105 + src/app/shared/policy.ts + 220 - src/app/shared/permissions.ts - 106 + src/app/shared/policy.ts + 221 - - Update environment secret + + Access environments - src/app/shared/permissions.ts - 113 + src/app/shared/policy.ts + 229 - src/app/shared/permissions.ts - 114 + src/app/shared/policy.ts + 230 - - Update org name + + Delete environments - src/app/shared/permissions.ts - 123 + src/app/shared/policy.ts + 238 - src/app/shared/permissions.ts - 124 + src/app/shared/policy.ts + 239 - - IAM + + Update environment settings - src/app/shared/permissions.ts - 133 + src/app/shared/policy.ts + 247 - src/app/shared/permissions.ts - 134 + src/app/shared/policy.ts + 248 - - List access tokens + + Delete environment secret - src/app/shared/permissions.ts - 143 + src/app/shared/policy.ts + 256 - src/app/shared/permissions.ts - 144 + src/app/shared/policy.ts + 257 - - Manage service access tokens + + Create environment secret - src/app/shared/permissions.ts - 151 + src/app/shared/policy.ts + 265 - src/app/shared/permissions.ts - 152 + src/app/shared/policy.ts + 266 - - Manage personal access tokens + + Update environment secret - src/app/shared/permissions.ts - 159 + src/app/shared/policy.ts + 274 - src/app/shared/permissions.ts - 160 + src/app/shared/policy.ts + 275 - - All + + Update org name src/app/shared/policy.ts - 61 + 285 - - - Account src/app/shared/policy.ts - 67 + 286 - + IAM src/app/shared/policy.ts - 73 + 296 - - - Access token src/app/shared/policy.ts - 79 + 297 - - Project + + List access tokens src/app/shared/policy.ts - 84 + 307 - - - Environment src/app/shared/policy.ts - 90 + 308 - - Project + + Manage service access tokens src/app/shared/policy.ts - 121 + 316 src/app/shared/policy.ts - 133 + 317 - - Environment + + Manage personal access tokens src/app/shared/policy.ts - 143 + 325 + + + src/app/shared/policy.ts + 326 diff --git a/modules/front-end/src/locale/messages.zh.xlf b/modules/front-end/src/locale/messages.zh.xlf index 76092a4aa..2740acee4 100644 --- a/modules/front-end/src/locale/messages.zh.xlf +++ b/modules/front-end/src/locale/messages.zh.xlf @@ -405,7 +405,7 @@ You don't have permissions to take this action, please contact the admin to grant you the necessary permissions src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 198 + 202 src/app/core/services/permissions.service.ts @@ -417,11 +417,11 @@ Operation succeeded src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 208 + 212 src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 223 + 227 src/app/core/components/expt-rules-drawer/expt-rules-drawer.component.ts @@ -633,7 +633,7 @@ Operation failed, please try again src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 211 + 215 src/app/core/components/metric-drawer/metric-drawer.component.ts @@ -681,15 +681,15 @@ src/app/features/safe/organizations/project/project.component.ts - 253 + 252 src/app/features/safe/organizations/project/project.component.ts - 287 + 286 src/app/features/safe/organizations/project/project.component.ts - 303 + 302 src/app/features/safe/segments/index/index.component.ts @@ -701,7 +701,7 @@ Policies are mandatory for service type access tokens src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 232 + 236 策略不能为空 @@ -709,7 +709,7 @@ Copied src/app/core/components/access-token-drawer/access-token-drawer.component.ts - 242 + 246 src/app/core/components/header/header.component.ts @@ -765,7 +765,7 @@ src/app/features/safe/organizations/project/project.component.ts - 181 + 180 复制成功 @@ -2661,7 +2661,7 @@ Edit project src/app/core/components/project-drawer/project-drawer.component.ts - 30 + 29 编辑项目 @@ -2669,7 +2669,7 @@ Add project src/app/core/components/project-drawer/project-drawer.component.ts - 33 + 32 添加项目 @@ -2677,7 +2677,7 @@ Project successfully updated src/app/core/components/project-drawer/project-drawer.component.ts - 113 + 112 项目更新成功 @@ -2685,7 +2685,7 @@ Project successfully created src/app/core/components/project-drawer/project-drawer.component.ts - 126 + 125 项目创建成功 @@ -6513,7 +6513,7 @@ Environment successfully removed src/app/features/safe/organizations/project/project.component.ts - 106 + 105 环境创建成功 @@ -6521,7 +6521,7 @@ Project successfully removed src/app/features/safe/organizations/project/project.component.ts - 122 + 121 项目删除成功 @@ -6529,7 +6529,7 @@ Add secret src/app/features/safe/organizations/project/project.component.ts - 205 + 204 添加秘钥 @@ -6537,7 +6537,7 @@ Edit secret: src/app/features/safe/organizations/project/project.component.ts - 230 + 229 编辑: @@ -7029,289 +7029,289 @@ 不包含用户 + + All + + src/app/shared/policy.ts + 71 + + 全部 + + + Account + + src/app/shared/policy.ts + 77 + + 账户管理 + + + IAM + + src/app/shared/policy.ts + 83 + + 权限管理 + + + Access token + + src/app/shared/policy.ts + 89 + + 访问策略 + + + Project + + src/app/shared/policy.ts + 94 + + 项目 + + + Environment + + src/app/shared/policy.ts + 100 + + 环境 + + + Project + + src/app/shared/policy.ts + 131 + + + src/app/shared/policy.ts + 143 + + 项目 + + + Environment + + src/app/shared/policy.ts + 153 + + 环境 + All - src/app/shared/permissions.ts - 17 + src/app/shared/policy.ts + 166 - src/app/shared/permissions.ts - 18 + src/app/shared/policy.ts + 167 全部操作 List projects - src/app/shared/permissions.ts - 25 + src/app/shared/policy.ts + 175 - src/app/shared/permissions.ts - 26 + src/app/shared/policy.ts + 176 查看项目列表 Create projects - src/app/shared/permissions.ts - 33 + src/app/shared/policy.ts + 184 - src/app/shared/permissions.ts - 34 + src/app/shared/policy.ts + 185 创建项目 Delete projects - src/app/shared/permissions.ts - 41 + src/app/shared/policy.ts + 193 - src/app/shared/permissions.ts - 42 + src/app/shared/policy.ts + 194 删除项目 - - Access environments - - src/app/shared/permissions.ts - 49 - - - src/app/shared/permissions.ts - 50 - - 进入环境 - Update project settings - src/app/shared/permissions.ts - 57 + src/app/shared/policy.ts + 202 - src/app/shared/permissions.ts - 58 + src/app/shared/policy.ts + 203 修改项目设置 List environments - src/app/shared/permissions.ts - 65 + src/app/shared/policy.ts + 211 - src/app/shared/permissions.ts - 66 + src/app/shared/policy.ts + 212 查看环境列表 Create environment - src/app/shared/permissions.ts - 73 + src/app/shared/policy.ts + 220 - src/app/shared/permissions.ts - 74 + src/app/shared/policy.ts + 221 创建环境 + + Access environments + + src/app/shared/policy.ts + 229 + + + src/app/shared/policy.ts + 230 + + 进入环境 + Delete environments - src/app/shared/permissions.ts - 81 + src/app/shared/policy.ts + 238 - src/app/shared/permissions.ts - 82 + src/app/shared/policy.ts + 239 删除环境 Update environment settings - src/app/shared/permissions.ts - 89 + src/app/shared/policy.ts + 247 - src/app/shared/permissions.ts - 90 + src/app/shared/policy.ts + 248 修改环境设置 Delete environment secret - src/app/shared/permissions.ts - 97 + src/app/shared/policy.ts + 256 - src/app/shared/permissions.ts - 98 + src/app/shared/policy.ts + 257 删除环境秘钥 Create environment secret - src/app/shared/permissions.ts - 105 + src/app/shared/policy.ts + 265 - src/app/shared/permissions.ts - 106 + src/app/shared/policy.ts + 266 创建环境秘钥 Update environment secret - src/app/shared/permissions.ts - 113 + src/app/shared/policy.ts + 274 - src/app/shared/permissions.ts - 114 + src/app/shared/policy.ts + 275 修改环境秘钥 Update org name - src/app/shared/permissions.ts - 123 + src/app/shared/policy.ts + 285 - src/app/shared/permissions.ts - 124 + src/app/shared/policy.ts + 286 修改机构名称 IAM - src/app/shared/permissions.ts - 133 + src/app/shared/policy.ts + 296 - src/app/shared/permissions.ts - 134 + src/app/shared/policy.ts + 297 权限管理 List access tokens - src/app/shared/permissions.ts - 143 + src/app/shared/policy.ts + 307 - src/app/shared/permissions.ts - 144 + src/app/shared/policy.ts + 308 查看访问策略列表 Manage service access tokens - src/app/shared/permissions.ts - 151 + src/app/shared/policy.ts + 316 - src/app/shared/permissions.ts - 152 + src/app/shared/policy.ts + 317 管理 Service 访问策略 Manage personal access tokens - - src/app/shared/permissions.ts - 159 - - - src/app/shared/permissions.ts - 160 - - 管理 Personal 访问策略 - - - All src/app/shared/policy.ts - 61 + 325 - 全部 - - - Account - - src/app/shared/policy.ts - 67 - - 账户管理 - - - IAM - - src/app/shared/policy.ts - 73 - - 权限管理 - - - Access token - - src/app/shared/policy.ts - 79 - - 访问策略 - - - Project src/app/shared/policy.ts - 84 - - 项目 - - - Environment - - src/app/shared/policy.ts - 90 - - 环境 - - - Project - - src/app/shared/policy.ts - 121 - - - src/app/shared/policy.ts - 133 - - 项目 - - - Environment - - src/app/shared/policy.ts - 143 + 326 - 环境 + 管理 Personal 访问策略 From 2984fac7daf02464e56561383ce8529ac9859e74 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Thu, 16 Mar 2023 10:30:00 +0100 Subject: [PATCH 31/44] refactor --- .../policy-editor/policy-editor.component.ts | 9 +++-- modules/front-end/src/app/shared/policy.ts | 33 ------------------- modules/front-end/src/locale/messages.xlf | 10 +++--- modules/front-end/src/locale/messages.zh.xlf | 10 +++--- 4 files changed, 14 insertions(+), 48 deletions(-) diff --git a/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts b/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts index b451dd2ca..5a3528719 100644 --- a/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts +++ b/modules/front-end/src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts @@ -3,9 +3,8 @@ import { EffectEnum, IamPolicyAction, IPolicyStatement, - isResourceGeneral, + isResourceGeneral, permissionActions, Resource, - resourceActionsDict, resourcesTypes, ResourceType } from "@shared/policy"; @@ -32,7 +31,7 @@ class PolicyStatementViewModel { this.resourceType = resourcesTypes.find(rt => rt.type === statement.resourceType) || null; this.effect = statement.effect === 'allow' ? EffectEnum.Allow : EffectEnum.Deny; - const allActions = Object.keys(resourceActionsDict).flatMap(p => resourceActionsDict[p]); + const allActions = [...Object.values(permissionActions)]; this.selectedActions = statement.actions.map(act => { const find = allActions.find(a => act === a.name); return find || act as unknown as IamPolicyAction; @@ -42,7 +41,7 @@ class PolicyStatementViewModel { // All the resources here are the same type, and if it's general type, resources only contains one element const isGeneralResource = isResourceGeneral(this.resourceType?.type, statement.resources[0]); - this.availableActions = resourceActionsDict[this.resourceType?.type].filter((rs) => isGeneralResource || rs.isSpecificApplicable); + this.availableActions = [...Object.values(permissionActions)].filter((rs) => rs.resourceType === this.resourceType?.type && (isGeneralResource || rs.isSpecificApplicable)); } else { this.id = uuidv4(); this.effect = EffectEnum.Allow; @@ -69,7 +68,7 @@ class PolicyStatementViewModel { // All the resources here are the same type, and if it's general type, resources only contains one element const isGeneralResource = isResourceGeneral(resources[0].type, resources[0].rn); - this.availableActions = resourceActionsDict[this.resourceType?.type].filter((rs) => isGeneralResource || rs.isSpecificApplicable); + this.availableActions = [...Object.values(permissionActions)].filter((rs) => rs.resourceType === this.resourceType?.type && (isGeneralResource || rs.isSpecificApplicable)); } getOutput(): IPolicyStatement { diff --git a/modules/front-end/src/app/shared/policy.ts b/modules/front-end/src/app/shared/policy.ts index e80ecd4c0..42a9acec9 100644 --- a/modules/front-end/src/app/shared/policy.ts +++ b/modules/front-end/src/app/shared/policy.ts @@ -329,39 +329,6 @@ export const permissionActions: {[key: string]: IamPolicyAction} = { }, } -export const resourceActionsDict: {[key: string]: IamPolicyAction[]} = { - [ResourceTypeEnum.All]: [ - permissionActions.All, - ], - [ResourceTypeEnum.Account]: [ - permissionActions.UpdateOrgName - ], - [ResourceTypeEnum.IAM]: [ - permissionActions.CanManageIAM, - ], - [ResourceTypeEnum.AccessToken]: [ - permissionActions.ListAccessTokens, - permissionActions.ManageServiceAccessTokens, - permissionActions.ManagePersonalAccessTokens, - ], - [ResourceTypeEnum.Project]: [ - permissionActions.ListProjects, - permissionActions.CreateProject, - permissionActions.DeleteProject, - permissionActions.UpdateProjectSettings, - permissionActions.ListEnvs, - permissionActions.CreateEnv, - ], - [ResourceTypeEnum.Env]: [ - permissionActions.AccessEnvs, - permissionActions.DeleteEnv, - permissionActions.UpdateEnvSettings, - permissionActions.DeleteEnvSecret, - permissionActions.CreateEnvSecret, - permissionActions.UpdateEnvSecret, - ] -} - // check if the resource is a general resource // if returns false, that means the actions which cannot be applied to a specific resource should be hidden // ex: ListProjects should not be avaible for a specific project: project/abc diff --git a/modules/front-end/src/locale/messages.xlf b/modules/front-end/src/locale/messages.xlf index cc23986ae..a4911a949 100644 --- a/modules/front-end/src/locale/messages.xlf +++ b/modules/front-end/src/locale/messages.xlf @@ -722,7 +722,7 @@ src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 131 + 130 src/app/features/safe/iam/groups/details/setting/setting.component.ts @@ -1421,11 +1421,11 @@ src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 133 + 132 src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 136 + 135 src/app/features/safe/iam/groups/details/policies/policies.component.ts @@ -4980,7 +4980,7 @@ src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 143 + 142 @@ -5012,7 +5012,7 @@ Make sure resource and operation are set for all permissions src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 149 + 148 diff --git a/modules/front-end/src/locale/messages.zh.xlf b/modules/front-end/src/locale/messages.zh.xlf index 2740acee4..5a2292d3f 100644 --- a/modules/front-end/src/locale/messages.zh.xlf +++ b/modules/front-end/src/locale/messages.zh.xlf @@ -737,7 +737,7 @@ src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 131 + 130 src/app/features/safe/iam/groups/details/setting/setting.component.ts @@ -1497,11 +1497,11 @@ src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 133 + 132 src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 136 + 135 src/app/features/safe/iam/groups/details/policies/policies.component.ts @@ -5428,7 +5428,7 @@ src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 143 + 142 系统托管策略不允许被修改。 如确有需要,可以复制以后再根据需求进行修改。 @@ -5464,7 +5464,7 @@ Make sure resource and operation are set for all permissions src/app/features/safe/iam/components/policy-editor/policy-editor.component.ts - 149 + 148 请确保已设置所有权限的资源和操作 From ee542fe00e2e5f53c23b69b53d27d89fd6a4c1de Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Thu, 16 Mar 2023 12:33:32 +0100 Subject: [PATCH 32/44] check permissions when creating access token --- .../AccessTokens/CreateAccessToken.cs | 46 +++++++++++++++++-- .../src/Application/Bases/ErrorCodes.cs | 1 + .../app/core/services/permissions.service.ts | 2 +- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs b/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs index c16d491cc..04c80f83a 100644 --- a/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs +++ b/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs @@ -1,5 +1,6 @@ +using System.Text.RegularExpressions; using Application.Bases; -using Application.Policies; +using Application.Bases.Exceptions; using Application.Users; using Domain.AccessTokens; using Domain.Policies; @@ -36,16 +37,16 @@ public CreateAccessTokenValidator() public class CreateAccessTokenHandler : IRequestHandler { - private readonly IPolicyService _policyService; + private readonly IMemberService _memberService; private readonly ICurrentUser _currentUser; private readonly IAccessTokenService _service; private readonly IMapper _mapper; - public CreateAccessTokenHandler(IAccessTokenService service, IPolicyService policyService, ICurrentUser currentUser, IMapper mapper) + public CreateAccessTokenHandler(IAccessTokenService service, IMemberService memberService, ICurrentUser currentUser, IMapper mapper) { _service = service; _currentUser = currentUser; - _policyService = policyService; + _memberService = memberService; _mapper = mapper; } @@ -54,7 +55,30 @@ public async Task Handle(CreateAccessToken request, CancellationT var permissions = request.Permissions; if (request.Type == AccessTokenTypes.Service) { - // TODO check currentUser has all the permissions + var authorizedPolices = await _memberService.GetPoliciesAsync(request.OrganizationId, _currentUser.Id); + var ownerPolicy = authorizedPolices.FirstOrDefault((x) => x.Name == "Owner"); + if (ownerPolicy != null) + { + permissions = request.Permissions; + } + else + { + var haveUnauthorizedPermissions = request.Permissions.Any(x => + { + var matchedPolicy = authorizedPolices.FirstOrDefault(policy => + policy.Statements.Any(statement => + statement.ResourceType == x.ResourceType && statement.Effect == "allow" && + x.Resources.All(rsc => statement.Resources.Any(resource => MatchRule(rsc, resource))) && + x.Actions.All(act => statement.Actions.Any(action => MatchRule(act, action))))); + + return matchedPolicy == null; + }); + + if (haveUnauthorizedPermissions) + { + throw new BusinessException(ErrorCodes.Forbidden); + } + } } var accessToken = new AccessToken(request.OrganizationId, _currentUser.Id, request.Name, request.Type, permissions); @@ -63,4 +87,16 @@ public async Task Handle(CreateAccessToken request, CancellationT return _mapper.Map(accessToken); } + + // use "*" (star) as a wildcard for example: + // "a*b" => everything that starts with "a" and ends with "b" + // "a*" => everything that starts with "a" + // "*b" => everything that ends with "b" + // "*a*" => everything that has an "a" in it + // "*a*b*"=> everything that has an "a" in it, followed by anything, followed by a "b", followed by anything + private bool MatchRule(string str, string rule) + { + Func escapeRegex = (s) => Regex.Replace(s, "([.*+?^=!:${}()|\\[\\]\\\\/])", "\\$1"); + return new Regex("^" + rule.Split('*').Select(escapeRegex).Aggregate((x, y) => x + ".*" + y) + "$").IsMatch(str); + } } \ No newline at end of file diff --git a/modules/back-end/src/Application/Bases/ErrorCodes.cs b/modules/back-end/src/Application/Bases/ErrorCodes.cs index 581e2af2d..2fe1a370f 100644 --- a/modules/back-end/src/Application/Bases/ErrorCodes.cs +++ b/modules/back-end/src/Application/Bases/ErrorCodes.cs @@ -5,6 +5,7 @@ public static class ErrorCodes // general public const string InternalServerError = nameof(InternalServerError); public const string Unauthorized = nameof(Unauthorized); + public const string Forbidden = nameof(Forbidden); // application public const string ResourceNotFound = nameof(ResourceNotFound); diff --git a/modules/front-end/src/app/core/services/permissions.service.ts b/modules/front-end/src/app/core/services/permissions.service.ts index 58a7b52bb..8ffe78fc2 100644 --- a/modules/front-end/src/app/core/services/permissions.service.ts +++ b/modules/front-end/src/app/core/services/permissions.service.ts @@ -28,7 +28,7 @@ export class PermissionsService { // "*b" => everything that ends with "b" // "*a*" => everything that has an "a" in it // "*a*b*"=> everything that has an "a" in it, followed by anything, followed by a "b", followed by anything - private matchRule(str, rule) { + private matchRule(str: string, rule: string): boolean { var escapeRegex = (s) => s.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); return new RegExp("^" + rule.split("*").map(escapeRegex).join(".*") + "$").test(str); } From 115e7f50d634cd07be3693dce6e04c96d1ea5cf1 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Thu, 16 Mar 2023 12:46:36 +0100 Subject: [PATCH 33/44] prevent creating access tokens with the same name && ignore case when checking if name is used --- .../src/Application/AccessTokens/CreateAccessToken.cs | 9 ++++++++- .../Application/AccessTokens/IsAccessTokenNameUsed.cs | 2 +- modules/back-end/src/Application/Bases/ErrorCodes.cs | 1 + .../back-end/src/Application/Groups/IsGroupNameUsed.cs | 2 +- .../src/Application/Policies/IsPolicyNameUsed.cs | 2 +- .../src/Application/Segments/IsSegmentNameUsed.cs | 2 +- 6 files changed, 13 insertions(+), 5 deletions(-) diff --git a/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs b/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs index 04c80f83a..c76ab8086 100644 --- a/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs +++ b/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs @@ -80,7 +80,14 @@ public async Task Handle(CreateAccessToken request, CancellationT } } } - + + var existingAt = await _service.FindOneAsync(at => string.Equals(at.Name, request.Name, StringComparison.OrdinalIgnoreCase)); + + if (existingAt != null) + { + throw new BusinessException(ErrorCodes.EntityExistsAlready); + } + var accessToken = new AccessToken(request.OrganizationId, _currentUser.Id, request.Name, request.Type, permissions); await _service.AddOneAsync(accessToken); diff --git a/modules/back-end/src/Application/AccessTokens/IsAccessTokenNameUsed.cs b/modules/back-end/src/Application/AccessTokens/IsAccessTokenNameUsed.cs index 3dfaf7f46..e90a63487 100644 --- a/modules/back-end/src/Application/AccessTokens/IsAccessTokenNameUsed.cs +++ b/modules/back-end/src/Application/AccessTokens/IsAccessTokenNameUsed.cs @@ -19,7 +19,7 @@ public IsAccessTokenNameUsedHandler(IAccessTokenService service) public async Task Handle(IsAccessTokenNameUsed request, CancellationToken cancellationToken) { var isNameUsed = - await _service.AnyAsync(x => x.OrganizationId == request.OrganizationId && x.Name == request.Name); + await _service.AnyAsync(x => x.OrganizationId == request.OrganizationId && string.Equals(x.Name, request.Name, StringComparison.OrdinalIgnoreCase)); return isNameUsed; } diff --git a/modules/back-end/src/Application/Bases/ErrorCodes.cs b/modules/back-end/src/Application/Bases/ErrorCodes.cs index 2fe1a370f..c02a72951 100644 --- a/modules/back-end/src/Application/Bases/ErrorCodes.cs +++ b/modules/back-end/src/Application/Bases/ErrorCodes.cs @@ -10,6 +10,7 @@ public static class ErrorCodes // application public const string ResourceNotFound = nameof(ResourceNotFound); public const string InvalidJson = nameof(InvalidJson); + public const string EntityExistsAlready = nameof(EntityExistsAlready); // identity error codes public const string MethodIsRequired = nameof(MethodIsRequired); diff --git a/modules/back-end/src/Application/Groups/IsGroupNameUsed.cs b/modules/back-end/src/Application/Groups/IsGroupNameUsed.cs index 5a123d0fe..a1b187f28 100644 --- a/modules/back-end/src/Application/Groups/IsGroupNameUsed.cs +++ b/modules/back-end/src/Application/Groups/IsGroupNameUsed.cs @@ -19,7 +19,7 @@ public IsGroupNameUsedHandler(IGroupService service) public async Task Handle(IsGroupNameUsed request, CancellationToken cancellationToken) { var isNameUsed = - await _service.AnyAsync(x => x.OrganizationId == request.OrganizationId && x.Name == request.Name); + await _service.AnyAsync(x => x.OrganizationId == request.OrganizationId && string.Equals(x.Name, request.Name, StringComparison.OrdinalIgnoreCase)); return isNameUsed; } diff --git a/modules/back-end/src/Application/Policies/IsPolicyNameUsed.cs b/modules/back-end/src/Application/Policies/IsPolicyNameUsed.cs index 9d28da1f0..1ca097a9f 100644 --- a/modules/back-end/src/Application/Policies/IsPolicyNameUsed.cs +++ b/modules/back-end/src/Application/Policies/IsPolicyNameUsed.cs @@ -19,7 +19,7 @@ public IsPolicyNameUsedHandler(IPolicyService service) public async Task Handle(IsPolicyNameUsed request, CancellationToken cancellationToken) { var isNameUsed = - await _service.AnyAsync(x => x.OrganizationId == request.OrganizationId && x.Name == request.Name); + await _service.AnyAsync(x => x.OrganizationId == request.OrganizationId && string.Equals(x.Name, request.Name, StringComparison.OrdinalIgnoreCase)); return isNameUsed; } diff --git a/modules/back-end/src/Application/Segments/IsSegmentNameUsed.cs b/modules/back-end/src/Application/Segments/IsSegmentNameUsed.cs index 50109f8d7..cb3e819f5 100644 --- a/modules/back-end/src/Application/Segments/IsSegmentNameUsed.cs +++ b/modules/back-end/src/Application/Segments/IsSegmentNameUsed.cs @@ -18,6 +18,6 @@ public IsSegmentNameUsedHandler(ISegmentService service) public async Task Handle(IsSegmentNameUsed request, CancellationToken cancellationToken) { - return await _service.AnyAsync(x => !x.IsArchived && x.EnvId == request.EnvId && x.Name == request.Name); + return await _service.AnyAsync(x => !x.IsArchived && x.EnvId == request.EnvId && string.Equals(x.Name, request.Name, StringComparison.OrdinalIgnoreCase)); } } \ No newline at end of file From 81297a4b577545798462db5a8bdb030d42ceedb6 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Thu, 16 Mar 2023 12:52:22 +0100 Subject: [PATCH 34/44] fixed bug --- .../back-end/src/Application/AccessTokens/CreateAccessToken.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs b/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs index c76ab8086..d2df3cfdf 100644 --- a/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs +++ b/modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs @@ -52,7 +52,7 @@ public CreateAccessTokenHandler(IAccessTokenService service, IMemberService memb public async Task Handle(CreateAccessToken request, CancellationToken cancellationToken) { - var permissions = request.Permissions; + IEnumerable permissions = new List(); if (request.Type == AccessTokenTypes.Service) { var authorizedPolices = await _memberService.GetPoliciesAsync(request.OrganizationId, _currentUser.Id); From 9d975a1fa1b21247da4970d4c3ec05671fedfba0 Mon Sep 17 00:00:00 2001 From: cosmos-explorer Date: Fri, 17 Mar 2023 09:23:08 +0100 Subject: [PATCH 35/44] environment ajustement --- .../project/project.component.html | 10 ++-- modules/front-end/src/locale/messages.xlf | 43 ++++++++--------- modules/front-end/src/locale/messages.zh.xlf | 46 +++++++++---------- modules/front-end/src/styles-common.less | 8 ++++ 4 files changed, 60 insertions(+), 47 deletions(-) diff --git a/modules/front-end/src/app/features/safe/organizations/project/project.component.html b/modules/front-end/src/app/features/safe/organizations/project/project.component.html index 9fc0332c9..defa22bc2 100644 --- a/modules/front-end/src/app/features/safe/organizations/project/project.component.html +++ b/modules/front-end/src/app/features/safe/organizations/project/project.component.html @@ -15,7 +15,7 @@
    - +
    @@ -23,7 +23,7 @@
    - Environment name + Name Current
    {{env.name}}
    @@ -33,7 +33,7 @@
    {{env.key}}
    -
    Description
    +
    Description
    {{env.description}}
    @@ -91,6 +91,10 @@
    + + {{project.name}} + Current + Current