[SM-572] Hide Project's People and Service accounts tabs based on permission (#4885)

* Hide tabs based on permission

* Swap to a new endpoint

* Swap to different server implementation

* Swap to server's ProjectPermissionDetails

* remove async

* remove write access observable

* Fix mac decrypt error
This commit is contained in:
Thomas Avery 2023-03-02 09:02:48 -06:00 committed by GitHub
parent 5cc73d41d9
commit 5f05f73626
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 49 additions and 15 deletions

View File

@ -5,3 +5,8 @@ export class ProjectView {
creationDate: string; creationDate: string;
revisionDate: string; revisionDate: string;
} }
export class ProjectPermissionDetailsView extends ProjectView {
read: boolean;
write: boolean;
}

View File

@ -16,3 +16,14 @@ export class ProjectResponse extends BaseResponse {
this.revisionDate = this.getResponseProperty("RevisionDate"); this.revisionDate = this.getResponseProperty("RevisionDate");
} }
} }
export class ProjectPermissionDetailsResponse extends ProjectResponse {
read: boolean;
write: boolean;
constructor(response: any) {
super(response);
this.read = this.getResponseProperty("Read");
this.write = this.getResponseProperty("Write");
}
}

View File

@ -9,12 +9,15 @@ import { SymmetricCryptoKey } from "@bitwarden/common/models/domain/symmetric-cr
import { ListResponse } from "@bitwarden/common/models/response/list.response"; import { ListResponse } from "@bitwarden/common/models/response/list.response";
import { ProjectListView } from "../models/view/project-list.view"; import { ProjectListView } from "../models/view/project-list.view";
import { ProjectView } from "../models/view/project.view"; import { ProjectPermissionDetailsView, ProjectView } from "../models/view/project.view";
import { BulkOperationStatus } from "../shared/dialogs/bulk-status-dialog.component"; import { BulkOperationStatus } from "../shared/dialogs/bulk-status-dialog.component";
import { ProjectRequest } from "./models/requests/project.request"; import { ProjectRequest } from "./models/requests/project.request";
import { ProjectListItemResponse } from "./models/responses/project-list-item.response"; import { ProjectListItemResponse } from "./models/responses/project-list-item.response";
import { ProjectResponse } from "./models/responses/project.response"; import {
ProjectPermissionDetailsResponse,
ProjectResponse,
} from "./models/responses/project.response";
@Injectable({ @Injectable({
providedIn: "root", providedIn: "root",
@ -29,10 +32,10 @@ export class ProjectService {
private encryptService: EncryptService private encryptService: EncryptService
) {} ) {}
async getByProjectId(projectId: string): Promise<ProjectView> { async getByProjectId(projectId: string): Promise<ProjectPermissionDetailsView> {
const r = await this.apiService.send("GET", "/projects/" + projectId, null, true, true); const r = await this.apiService.send("GET", "/projects/" + projectId, null, true, true);
const projectResponse = new ProjectResponse(r); const projectResponse = new ProjectPermissionDetailsResponse(r);
return await this.createProjectView(projectResponse); return await this.createProjectPermissionDetailsView(projectResponse);
} }
async getProjects(organizationId: string): Promise<ProjectListView[]> { async getProjects(organizationId: string): Promise<ProjectListView[]> {
@ -96,7 +99,9 @@ export class ProjectService {
return request; return request;
} }
private async createProjectView(projectResponse: ProjectResponse): Promise<ProjectView> { private async createProjectView(
projectResponse: ProjectResponse | ProjectPermissionDetailsResponse
) {
const orgKey = await this.getOrganizationKey(projectResponse.organizationId); const orgKey = await this.getOrganizationKey(projectResponse.organizationId);
const projectView = new ProjectView(); const projectView = new ProjectView();
@ -108,10 +113,19 @@ export class ProjectService {
new EncString(projectResponse.name), new EncString(projectResponse.name),
orgKey orgKey
); );
return projectView; return projectView;
} }
private async createProjectPermissionDetailsView(
projectResponse: ProjectPermissionDetailsResponse
): Promise<ProjectPermissionDetailsView> {
return {
...(await this.createProjectView(projectResponse)),
read: projectResponse.read,
write: projectResponse.write,
};
}
private async createProjectsListView( private async createProjectsListView(
organizationId: string, organizationId: string,
projects: ProjectListItemResponse[] projects: ProjectListItemResponse[]

View File

@ -4,8 +4,10 @@
</bit-breadcrumbs> </bit-breadcrumbs>
<bit-tab-nav-bar label="Main" slot="tabs"> <bit-tab-nav-bar label="Main" slot="tabs">
<bit-tab-link [route]="['secrets']">{{ "secrets" | i18n }}</bit-tab-link> <bit-tab-link [route]="['secrets']">{{ "secrets" | i18n }}</bit-tab-link>
<ng-container *ngIf="project.write">
<bit-tab-link [route]="['people']">{{ "people" | i18n }}</bit-tab-link> <bit-tab-link [route]="['people']">{{ "people" | i18n }}</bit-tab-link>
<bit-tab-link [route]="['service-accounts']">{{ "serviceAccounts" | i18n }}</bit-tab-link> <bit-tab-link [route]="['service-accounts']">{{ "serviceAccounts" | i18n }}</bit-tab-link>
</ng-container>
</bit-tab-nav-bar> </bit-tab-nav-bar>
<sm-new-menu></sm-new-menu> <sm-new-menu></sm-new-menu>
</sm-header> </sm-header>

View File

@ -2,7 +2,7 @@ import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router"; import { ActivatedRoute } from "@angular/router";
import { Observable, switchMap } from "rxjs"; import { Observable, switchMap } from "rxjs";
import { ProjectView } from "../../models/view/project.view"; import { ProjectPermissionDetailsView } from "../../models/view/project.view";
import { ProjectService } from "../project.service"; import { ProjectService } from "../project.service";
@Component({ @Component({
@ -10,7 +10,7 @@ import { ProjectService } from "../project.service";
templateUrl: "./project.component.html", templateUrl: "./project.component.html",
}) })
export class ProjectComponent implements OnInit { export class ProjectComponent implements OnInit {
project$: Observable<ProjectView>; project$: Observable<ProjectPermissionDetailsView>;
constructor(private route: ActivatedRoute, private projectService: ProjectService) {} constructor(private route: ActivatedRoute, private projectService: ProjectService) {}

View File

@ -277,10 +277,12 @@ export class AccessPolicyService {
...this.createBaseAccessPolicyView(response), ...this.createBaseAccessPolicyView(response),
grantedProjectId: response.grantedProjectId, grantedProjectId: response.grantedProjectId,
serviceAccountId: response.serviceAccountId, serviceAccountId: response.serviceAccountId,
grantedProjectName: await this.encryptService.decryptToUtf8( grantedProjectName: response.grantedProjectName
? await this.encryptService.decryptToUtf8(
new EncString(response.grantedProjectName), new EncString(response.grantedProjectName),
organizationKey organizationKey
), )
: null,
serviceAccountName: await this.encryptService.decryptToUtf8( serviceAccountName: await this.encryptService.decryptToUtf8(
new EncString(response.serviceAccountName), new EncString(response.serviceAccountName),
organizationKey organizationKey