[SM-923] Migrate Project -> Service Accounts access policy selector (#8789)
* Add request and response models * Add view * Add support in ap item types * Add new endpoints to the access policy service * Migrate to access policy selector --------- Co-authored-by: cd-bitwarden <106776772+cd-bitwarden@users.noreply.github.com>
This commit is contained in:
parent
26988730b1
commit
bdbb16ab4c
|
@ -67,3 +67,7 @@ export class ServiceAccountProjectPolicyPermissionDetailsView {
|
||||||
export class ServiceAccountGrantedPoliciesView {
|
export class ServiceAccountGrantedPoliciesView {
|
||||||
grantedProjectPolicies: ServiceAccountProjectPolicyPermissionDetailsView[];
|
grantedProjectPolicies: ServiceAccountProjectPolicyPermissionDetailsView[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ProjectServiceAccountsAccessPoliciesView {
|
||||||
|
serviceAccountAccessPolicies: ServiceAccountProjectAccessPolicyView[];
|
||||||
|
}
|
||||||
|
|
|
@ -1,17 +1,27 @@
|
||||||
<div class="tw-w-2/5">
|
<form [formGroup]="formGroup" [bitSubmit]="submit" *ngIf="!loading; else spinner">
|
||||||
<p class="tw-mt-8">
|
<div class="tw-w-2/5">
|
||||||
{{ "projectMachineAccountsDescription" | i18n }}
|
<p class="tw-mt-8" *ngIf="!loading">
|
||||||
</p>
|
{{ "projectMachineAccountsDescription" | i18n }}
|
||||||
<sm-access-selector
|
</p>
|
||||||
[rows]="rows$ | async"
|
<sm-access-policy-selector
|
||||||
granteeType="serviceAccounts"
|
[loading]="loading"
|
||||||
[label]="'machineAccounts' | i18n"
|
formControlName="accessPolicies"
|
||||||
[hint]="'projectMachineAccountsSelectHint' | i18n"
|
[addButtonMode]="true"
|
||||||
[columnTitle]="'machineAccounts' | i18n"
|
[items]="items"
|
||||||
[emptyMessage]="'projectEmptyMachineAccountAccessPolicies' | i18n"
|
[label]="'machineAccounts' | i18n"
|
||||||
(onCreateAccessPolicies)="handleCreateAccessPolicies($event)"
|
[hint]="'projectMachineAccountsSelectHint' | i18n"
|
||||||
(onDeleteAccessPolicy)="handleDeleteAccessPolicy($event)"
|
[columnTitle]="'machineAccounts' | i18n"
|
||||||
(onUpdateAccessPolicy)="handleUpdateAccessPolicy($event)"
|
[emptyMessage]="'projectEmptyMachineAccountAccessPolicies' | i18n"
|
||||||
>
|
>
|
||||||
</sm-access-selector>
|
</sm-access-policy-selector>
|
||||||
</div>
|
<button bitButton buttonType="primary" bitFormButton type="submit" class="tw-mt-7">
|
||||||
|
{{ "save" | i18n }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<ng-template #spinner>
|
||||||
|
<div class="tw-items-center tw-justify-center tw-pt-64 tw-text-center">
|
||||||
|
<i class="bwi bwi-spinner bwi-spin bwi-3x"></i>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
|
@ -1,93 +1,69 @@
|
||||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from "@angular/core";
|
||||||
|
import { FormControl, FormGroup } from "@angular/forms";
|
||||||
import { ActivatedRoute } from "@angular/router";
|
import { ActivatedRoute } from "@angular/router";
|
||||||
import { map, Observable, startWith, Subject, switchMap, takeUntil } from "rxjs";
|
import { combineLatest, Subject, switchMap, takeUntil } from "rxjs";
|
||||||
|
|
||||||
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
|
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
|
||||||
import { SelectItemView } from "@bitwarden/components";
|
|
||||||
|
|
||||||
|
import { ProjectServiceAccountsAccessPoliciesView } from "../../models/view/access-policy.view";
|
||||||
import {
|
import {
|
||||||
ProjectAccessPoliciesView,
|
ApItemValueType,
|
||||||
ServiceAccountProjectAccessPolicyView,
|
convertToProjectServiceAccountsAccessPoliciesView,
|
||||||
} from "../../models/view/access-policy.view";
|
} from "../../shared/access-policies/access-policy-selector/models/ap-item-value.type";
|
||||||
|
import {
|
||||||
|
ApItemViewType,
|
||||||
|
convertPotentialGranteesToApItemViewType,
|
||||||
|
convertProjectServiceAccountsViewToApItemViews,
|
||||||
|
} from "../../shared/access-policies/access-policy-selector/models/ap-item-view.type";
|
||||||
import { AccessPolicyService } from "../../shared/access-policies/access-policy.service";
|
import { AccessPolicyService } from "../../shared/access-policies/access-policy.service";
|
||||||
import {
|
|
||||||
AccessSelectorComponent,
|
|
||||||
AccessSelectorRowView,
|
|
||||||
} from "../../shared/access-policies/access-selector.component";
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "sm-project-service-accounts",
|
selector: "sm-project-service-accounts",
|
||||||
templateUrl: "./project-service-accounts.component.html",
|
templateUrl: "./project-service-accounts.component.html",
|
||||||
})
|
})
|
||||||
export class ProjectServiceAccountsComponent implements OnInit, OnDestroy {
|
export class ProjectServiceAccountsComponent implements OnInit, OnDestroy {
|
||||||
|
private currentAccessPolicies: ApItemViewType[];
|
||||||
private destroy$ = new Subject<void>();
|
private destroy$ = new Subject<void>();
|
||||||
private organizationId: string;
|
private organizationId: string;
|
||||||
private projectId: string;
|
private projectId: string;
|
||||||
|
|
||||||
protected rows$: Observable<AccessSelectorRowView[]> =
|
private currentAccessPolicies$ = combineLatest([this.route.params]).pipe(
|
||||||
this.accessPolicyService.projectAccessPolicyChanges$.pipe(
|
switchMap(([params]) =>
|
||||||
startWith(null),
|
this.accessPolicyService
|
||||||
switchMap(() =>
|
.getProjectServiceAccountsAccessPolicies(params.organizationId, params.projectId)
|
||||||
this.accessPolicyService.getProjectAccessPolicies(this.organizationId, this.projectId),
|
.then((policies) => {
|
||||||
),
|
return convertProjectServiceAccountsViewToApItemViews(policies);
|
||||||
map((policies) =>
|
}),
|
||||||
policies.serviceAccountAccessPolicies.map((policy) => ({
|
),
|
||||||
type: "serviceAccount",
|
);
|
||||||
name: policy.serviceAccountName,
|
|
||||||
id: policy.serviceAccountId,
|
|
||||||
accessPolicyId: policy.id,
|
|
||||||
read: policy.read,
|
|
||||||
write: policy.write,
|
|
||||||
icon: AccessSelectorComponent.serviceAccountIcon,
|
|
||||||
static: false,
|
|
||||||
})),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
protected async handleUpdateAccessPolicy(policy: AccessSelectorRowView) {
|
private potentialGrantees$ = combineLatest([this.route.params]).pipe(
|
||||||
try {
|
switchMap(([params]) =>
|
||||||
return await this.accessPolicyService.updateAccessPolicy(
|
this.accessPolicyService
|
||||||
AccessSelectorComponent.getBaseAccessPolicyView(policy),
|
.getServiceAccountsPotentialGrantees(params.organizationId)
|
||||||
);
|
.then((grantees) => {
|
||||||
} catch (e) {
|
return convertPotentialGranteesToApItemViewType(grantees);
|
||||||
this.validationService.showError(e);
|
}),
|
||||||
}
|
),
|
||||||
}
|
);
|
||||||
|
|
||||||
protected handleCreateAccessPolicies(selected: SelectItemView[]) {
|
protected formGroup = new FormGroup({
|
||||||
const projectAccessPoliciesView = new ProjectAccessPoliciesView();
|
accessPolicies: new FormControl([] as ApItemValueType[]),
|
||||||
projectAccessPoliciesView.serviceAccountAccessPolicies = selected
|
});
|
||||||
.filter(
|
|
||||||
(selection) => AccessSelectorComponent.getAccessItemType(selection) === "serviceAccount",
|
|
||||||
)
|
|
||||||
.map((filtered) => {
|
|
||||||
const view = new ServiceAccountProjectAccessPolicyView();
|
|
||||||
view.grantedProjectId = this.projectId;
|
|
||||||
view.serviceAccountId = filtered.id;
|
|
||||||
view.read = true;
|
|
||||||
view.write = false;
|
|
||||||
return view;
|
|
||||||
});
|
|
||||||
|
|
||||||
return this.accessPolicyService.createProjectAccessPolicies(
|
protected loading = true;
|
||||||
this.organizationId,
|
protected potentialGrantees: ApItemViewType[];
|
||||||
this.projectId,
|
protected items: ApItemViewType[];
|
||||||
projectAccessPoliciesView,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async handleDeleteAccessPolicy(policy: AccessSelectorRowView) {
|
|
||||||
try {
|
|
||||||
await this.accessPolicyService.deleteAccessPolicy(policy.accessPolicyId);
|
|
||||||
} catch (e) {
|
|
||||||
this.validationService.showError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
|
private changeDetectorRef: ChangeDetectorRef,
|
||||||
private validationService: ValidationService,
|
private validationService: ValidationService,
|
||||||
private accessPolicyService: AccessPolicyService,
|
private accessPolicyService: AccessPolicyService,
|
||||||
|
private platformUtilsService: PlatformUtilsService,
|
||||||
|
private i18nService: I18nService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
@ -95,10 +71,97 @@ export class ProjectServiceAccountsComponent implements OnInit, OnDestroy {
|
||||||
this.organizationId = params.organizationId;
|
this.organizationId = params.organizationId;
|
||||||
this.projectId = params.projectId;
|
this.projectId = params.projectId;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
combineLatest([this.potentialGrantees$, this.currentAccessPolicies$])
|
||||||
|
.pipe(takeUntil(this.destroy$))
|
||||||
|
.subscribe(([potentialGrantees, currentAccessPolicies]) => {
|
||||||
|
this.potentialGrantees = potentialGrantees;
|
||||||
|
this.items = this.getItems(potentialGrantees, currentAccessPolicies);
|
||||||
|
this.setSelected(currentAccessPolicies);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
this.destroy$.next();
|
this.destroy$.next();
|
||||||
this.destroy$.complete();
|
this.destroy$.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
submit = async () => {
|
||||||
|
if (this.isFormInvalid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const formValues = this.formGroup.value.accessPolicies;
|
||||||
|
this.formGroup.disable();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const accessPoliciesView = await this.updateProjectServiceAccountsAccessPolicies(
|
||||||
|
this.organizationId,
|
||||||
|
this.projectId,
|
||||||
|
formValues,
|
||||||
|
);
|
||||||
|
|
||||||
|
const updatedView = convertProjectServiceAccountsViewToApItemViews(accessPoliciesView);
|
||||||
|
this.items = this.getItems(this.potentialGrantees, updatedView);
|
||||||
|
this.setSelected(updatedView);
|
||||||
|
|
||||||
|
this.platformUtilsService.showToast(
|
||||||
|
"success",
|
||||||
|
null,
|
||||||
|
this.i18nService.t("projectAccessUpdated"),
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
this.validationService.showError(e);
|
||||||
|
this.setSelected(this.currentAccessPolicies);
|
||||||
|
}
|
||||||
|
this.formGroup.enable();
|
||||||
|
};
|
||||||
|
|
||||||
|
private setSelected(policiesToSelect: ApItemViewType[]) {
|
||||||
|
this.loading = true;
|
||||||
|
this.currentAccessPolicies = policiesToSelect;
|
||||||
|
if (policiesToSelect != undefined) {
|
||||||
|
// Must detect changes so that AccessSelector @Inputs() are aware of the latest
|
||||||
|
// potentialGrantees, otherwise no selected values will be patched below
|
||||||
|
this.changeDetectorRef.detectChanges();
|
||||||
|
this.formGroup.patchValue({
|
||||||
|
accessPolicies: policiesToSelect.map((m) => ({
|
||||||
|
type: m.type,
|
||||||
|
id: m.id,
|
||||||
|
permission: m.permission,
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private isFormInvalid(): boolean {
|
||||||
|
this.formGroup.markAllAsTouched();
|
||||||
|
return this.formGroup.invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async updateProjectServiceAccountsAccessPolicies(
|
||||||
|
organizationId: string,
|
||||||
|
projectId: string,
|
||||||
|
selectedPolicies: ApItemValueType[],
|
||||||
|
): Promise<ProjectServiceAccountsAccessPoliciesView> {
|
||||||
|
const view = convertToProjectServiceAccountsAccessPoliciesView(projectId, selectedPolicies);
|
||||||
|
return await this.accessPolicyService.putProjectServiceAccountsAccessPolicies(
|
||||||
|
organizationId,
|
||||||
|
projectId,
|
||||||
|
view,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getItems(potentialGrantees: ApItemViewType[], currentAccessPolicies: ApItemViewType[]) {
|
||||||
|
// If the user doesn't have access to the service account, they won't be in the potentialGrantees list.
|
||||||
|
// Add them to the potentialGrantees list if they are selected.
|
||||||
|
const items = [...potentialGrantees];
|
||||||
|
for (const policy of currentAccessPolicies) {
|
||||||
|
const exists = potentialGrantees.some((grantee) => grantee.id === policy.id);
|
||||||
|
if (!exists) {
|
||||||
|
items.push(policy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
ServiceAccountGrantedPoliciesView,
|
ServiceAccountGrantedPoliciesView,
|
||||||
ServiceAccountProjectPolicyPermissionDetailsView,
|
ServiceAccountProjectPolicyPermissionDetailsView,
|
||||||
ServiceAccountProjectAccessPolicyView,
|
ServiceAccountProjectAccessPolicyView,
|
||||||
|
ProjectServiceAccountsAccessPoliciesView,
|
||||||
} from "../../../../models/view/access-policy.view";
|
} from "../../../../models/view/access-policy.view";
|
||||||
|
|
||||||
import { ApItemEnum } from "./enums/ap-item.enum";
|
import { ApItemEnum } from "./enums/ap-item.enum";
|
||||||
|
@ -102,3 +103,23 @@ export function convertToServiceAccountGrantedPoliciesView(
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function convertToProjectServiceAccountsAccessPoliciesView(
|
||||||
|
projectId: string,
|
||||||
|
selectedPolicyValues: ApItemValueType[],
|
||||||
|
): ProjectServiceAccountsAccessPoliciesView {
|
||||||
|
const view = new ProjectServiceAccountsAccessPoliciesView();
|
||||||
|
|
||||||
|
view.serviceAccountAccessPolicies = selectedPolicyValues
|
||||||
|
.filter((x) => x.type == ApItemEnum.ServiceAccount)
|
||||||
|
.map((filtered) => {
|
||||||
|
const policyView = new ServiceAccountProjectAccessPolicyView();
|
||||||
|
policyView.serviceAccountId = filtered.id;
|
||||||
|
policyView.grantedProjectId = projectId;
|
||||||
|
policyView.read = ApPermissionEnumUtil.toRead(filtered.permission);
|
||||||
|
policyView.write = ApPermissionEnumUtil.toWrite(filtered.permission);
|
||||||
|
return policyView;
|
||||||
|
});
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { SelectItemView } from "@bitwarden/components";
|
||||||
import {
|
import {
|
||||||
ProjectPeopleAccessPoliciesView,
|
ProjectPeopleAccessPoliciesView,
|
||||||
ServiceAccountGrantedPoliciesView,
|
ServiceAccountGrantedPoliciesView,
|
||||||
|
ProjectServiceAccountsAccessPoliciesView,
|
||||||
ServiceAccountPeopleAccessPoliciesView,
|
ServiceAccountPeopleAccessPoliciesView,
|
||||||
} from "../../../../models/view/access-policy.view";
|
} from "../../../../models/view/access-policy.view";
|
||||||
import { PotentialGranteeView } from "../../../../models/view/potential-grantee.view";
|
import { PotentialGranteeView } from "../../../../models/view/potential-grantee.view";
|
||||||
|
@ -98,6 +99,29 @@ export function convertGrantedPoliciesToAccessPolicyItemViews(
|
||||||
return accessPolicies;
|
return accessPolicies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function convertProjectServiceAccountsViewToApItemViews(
|
||||||
|
value: ProjectServiceAccountsAccessPoliciesView,
|
||||||
|
): ApItemViewType[] {
|
||||||
|
const accessPolicies: ApItemViewType[] = [];
|
||||||
|
|
||||||
|
value.serviceAccountAccessPolicies.forEach((accessPolicyView) => {
|
||||||
|
accessPolicies.push({
|
||||||
|
type: ApItemEnum.ServiceAccount,
|
||||||
|
icon: ApItemEnumUtil.itemIcon(ApItemEnum.ServiceAccount),
|
||||||
|
id: accessPolicyView.serviceAccountId,
|
||||||
|
accessPolicyId: accessPolicyView.id,
|
||||||
|
labelName: accessPolicyView.serviceAccountName,
|
||||||
|
listName: accessPolicyView.serviceAccountName,
|
||||||
|
permission: ApPermissionEnumUtil.toApPermissionEnum(
|
||||||
|
accessPolicyView.read,
|
||||||
|
accessPolicyView.write,
|
||||||
|
),
|
||||||
|
readOnly: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return accessPolicies;
|
||||||
|
}
|
||||||
|
|
||||||
export function convertPotentialGranteesToApItemViewType(
|
export function convertPotentialGranteesToApItemViewType(
|
||||||
grantees: PotentialGranteeView[],
|
grantees: PotentialGranteeView[],
|
||||||
): ApItemViewType[] {
|
): ApItemViewType[] {
|
||||||
|
|
|
@ -19,6 +19,7 @@ import {
|
||||||
UserServiceAccountAccessPolicyView,
|
UserServiceAccountAccessPolicyView,
|
||||||
ServiceAccountPeopleAccessPoliciesView,
|
ServiceAccountPeopleAccessPoliciesView,
|
||||||
ServiceAccountGrantedPoliciesView,
|
ServiceAccountGrantedPoliciesView,
|
||||||
|
ProjectServiceAccountsAccessPoliciesView,
|
||||||
ServiceAccountProjectPolicyPermissionDetailsView,
|
ServiceAccountProjectPolicyPermissionDetailsView,
|
||||||
} from "../../models/view/access-policy.view";
|
} from "../../models/view/access-policy.view";
|
||||||
import { PotentialGranteeView } from "../../models/view/potential-grantee.view";
|
import { PotentialGranteeView } from "../../models/view/potential-grantee.view";
|
||||||
|
@ -29,6 +30,7 @@ import { ServiceAccountGrantedPoliciesRequest } from "../access-policies/models/
|
||||||
|
|
||||||
import { AccessPolicyUpdateRequest } from "./models/requests/access-policy-update.request";
|
import { AccessPolicyUpdateRequest } from "./models/requests/access-policy-update.request";
|
||||||
import { AccessPolicyRequest } from "./models/requests/access-policy.request";
|
import { AccessPolicyRequest } from "./models/requests/access-policy.request";
|
||||||
|
import { ProjectServiceAccountsAccessPoliciesRequest } from "./models/requests/project-service-accounts-access-policies.request";
|
||||||
import {
|
import {
|
||||||
GroupServiceAccountAccessPolicyResponse,
|
GroupServiceAccountAccessPolicyResponse,
|
||||||
UserServiceAccountAccessPolicyResponse,
|
UserServiceAccountAccessPolicyResponse,
|
||||||
|
@ -38,6 +40,7 @@ import {
|
||||||
} from "./models/responses/access-policy.response";
|
} from "./models/responses/access-policy.response";
|
||||||
import { PotentialGranteeResponse } from "./models/responses/potential-grantee.response";
|
import { PotentialGranteeResponse } from "./models/responses/potential-grantee.response";
|
||||||
import { ProjectPeopleAccessPoliciesResponse } from "./models/responses/project-people-access-policies.response";
|
import { ProjectPeopleAccessPoliciesResponse } from "./models/responses/project-people-access-policies.response";
|
||||||
|
import { ProjectServiceAccountsAccessPoliciesResponse } from "./models/responses/project-service-accounts-access-policies.response";
|
||||||
import { ServiceAccountGrantedPoliciesPermissionDetailsResponse } from "./models/responses/service-account-granted-policies-permission-details.response";
|
import { ServiceAccountGrantedPoliciesPermissionDetailsResponse } from "./models/responses/service-account-granted-policies-permission-details.response";
|
||||||
import { ServiceAccountPeopleAccessPoliciesResponse } from "./models/responses/service-account-people-access-policies.response";
|
import { ServiceAccountPeopleAccessPoliciesResponse } from "./models/responses/service-account-people-access-policies.response";
|
||||||
import { ServiceAccountProjectPolicyPermissionDetailsResponse } from "./models/responses/service-account-project-policy-permission-details.response";
|
import { ServiceAccountProjectPolicyPermissionDetailsResponse } from "./models/responses/service-account-project-policy-permission-details.response";
|
||||||
|
@ -175,6 +178,40 @@ export class AccessPolicyService {
|
||||||
return await this.createServiceAccountGrantedPoliciesView(result, organizationId);
|
return await this.createServiceAccountGrantedPoliciesView(result, organizationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getProjectServiceAccountsAccessPolicies(
|
||||||
|
organizationId: string,
|
||||||
|
projectId: string,
|
||||||
|
): Promise<ProjectServiceAccountsAccessPoliciesView> {
|
||||||
|
const r = await this.apiService.send(
|
||||||
|
"GET",
|
||||||
|
"/projects/" + projectId + "/access-policies/service-accounts",
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = new ProjectServiceAccountsAccessPoliciesResponse(r);
|
||||||
|
return await this.createProjectServiceAccountsAccessPoliciesView(result, organizationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async putProjectServiceAccountsAccessPolicies(
|
||||||
|
organizationId: string,
|
||||||
|
projectId: string,
|
||||||
|
policies: ProjectServiceAccountsAccessPoliciesView,
|
||||||
|
): Promise<ProjectServiceAccountsAccessPoliciesView> {
|
||||||
|
const request = this.getProjectServiceAccountsAccessPoliciesRequest(policies);
|
||||||
|
const r = await this.apiService.send(
|
||||||
|
"PUT",
|
||||||
|
"/projects/" + projectId + "/access-policies/service-accounts",
|
||||||
|
request,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = new ProjectServiceAccountsAccessPoliciesResponse(r);
|
||||||
|
return await this.createProjectServiceAccountsAccessPoliciesView(result, organizationId);
|
||||||
|
}
|
||||||
|
|
||||||
async createProjectAccessPolicies(
|
async createProjectAccessPolicies(
|
||||||
organizationId: string,
|
organizationId: string,
|
||||||
projectId: string,
|
projectId: string,
|
||||||
|
@ -325,6 +362,18 @@ export class AccessPolicyService {
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getProjectServiceAccountsAccessPoliciesRequest(
|
||||||
|
policies: ProjectServiceAccountsAccessPoliciesView,
|
||||||
|
): ProjectServiceAccountsAccessPoliciesRequest {
|
||||||
|
const request = new ProjectServiceAccountsAccessPoliciesRequest();
|
||||||
|
|
||||||
|
request.serviceAccountAccessPolicyRequests = policies.serviceAccountAccessPolicies.map((ap) => {
|
||||||
|
return this.getAccessPolicyRequest(ap.serviceAccountId, ap);
|
||||||
|
});
|
||||||
|
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
private async createServiceAccountGrantedPoliciesView(
|
private async createServiceAccountGrantedPoliciesView(
|
||||||
response: ServiceAccountGrantedPoliciesPermissionDetailsResponse,
|
response: ServiceAccountGrantedPoliciesPermissionDetailsResponse,
|
||||||
organizationId: string,
|
organizationId: string,
|
||||||
|
@ -535,4 +584,19 @@ export class AccessPolicyService {
|
||||||
currentUserInGroup: response.currentUserInGroup,
|
currentUserInGroup: response.currentUserInGroup,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async createProjectServiceAccountsAccessPoliciesView(
|
||||||
|
response: ProjectServiceAccountsAccessPoliciesResponse,
|
||||||
|
organizationId: string,
|
||||||
|
): Promise<ProjectServiceAccountsAccessPoliciesView> {
|
||||||
|
const orgKey = await this.getOrganizationKey(organizationId);
|
||||||
|
|
||||||
|
const view = new ProjectServiceAccountsAccessPoliciesView();
|
||||||
|
view.serviceAccountAccessPolicies = await Promise.all(
|
||||||
|
response.serviceAccountAccessPolicies.map(async (ap) => {
|
||||||
|
return await this.createServiceAccountProjectAccessPolicyView(orgKey, ap);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
return view;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { AccessPolicyRequest } from "./access-policy.request";
|
||||||
|
|
||||||
|
export class ProjectServiceAccountsAccessPoliciesRequest {
|
||||||
|
serviceAccountAccessPolicyRequests?: AccessPolicyRequest[];
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { BaseResponse } from "@bitwarden/common/models/response/base.response";
|
||||||
|
|
||||||
|
import { ServiceAccountProjectAccessPolicyResponse } from "./access-policy.response";
|
||||||
|
|
||||||
|
export class ProjectServiceAccountsAccessPoliciesResponse extends BaseResponse {
|
||||||
|
serviceAccountAccessPolicies: ServiceAccountProjectAccessPolicyResponse[];
|
||||||
|
|
||||||
|
constructor(response: any) {
|
||||||
|
super(response);
|
||||||
|
const serviceAccountAccessPolicies = this.getResponseProperty("ServiceAccountAccessPolicies");
|
||||||
|
this.serviceAccountAccessPolicies = serviceAccountAccessPolicies.map(
|
||||||
|
(k: any) => new ServiceAccountProjectAccessPolicyResponse(k),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue