SM-1146: Total counts update on CRUD

This commit is contained in:
Maciej Zieniuk 2024-06-24 16:54:07 +02:00
parent df122148da
commit 8793cc0267
No known key found for this signature in database
GPG Key ID: 9CACE59F1272ACD9
4 changed files with 72 additions and 13 deletions

View File

@ -1,13 +1,26 @@
import { Component, OnDestroy, OnInit } from "@angular/core"; import { Component, OnDestroy, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router"; import { ActivatedRoute } from "@angular/router";
import { concatMap, distinctUntilChanged, map, Observable, Subject, takeUntil } from "rxjs"; import {
combineLatest,
concatMap,
distinctUntilChanged,
map,
Observable,
startWith,
Subject,
switchMap,
takeUntil,
} from "rxjs";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { SecretsManagerLogo } from "@bitwarden/web-vault/app/layouts/secrets-manager-logo"; import { SecretsManagerLogo } from "@bitwarden/web-vault/app/layouts/secrets-manager-logo";
import { OrganizationCounts } from "../models/view/counts.view"; import { OrganizationCounts } from "../models/view/counts.view";
import { ProjectService } from "../projects/project.service";
import { SecretService } from "../secrets/secret.service";
import { SecretsManagerService } from "../secrets-manager.service"; import { SecretsManagerService } from "../secrets-manager.service";
import { ServiceAccountService } from "../service-accounts/service-account.service";
@Component({ @Component({
selector: "sm-navigation", selector: "sm-navigation",
@ -24,6 +37,9 @@ export class NavigationComponent implements OnInit, OnDestroy {
protected route: ActivatedRoute, protected route: ActivatedRoute,
private organizationService: OrganizationService, private organizationService: OrganizationService,
private secretsManagerService: SecretsManagerService, private secretsManagerService: SecretsManagerService,
private projectService: ProjectService,
private secretService: SecretService,
private serviceAccountService: ServiceAccountService,
) {} ) {}
ngOnInit() { ngOnInit() {
@ -39,9 +55,14 @@ export class NavigationComponent implements OnInit, OnDestroy {
takeUntil(this.destroy$), takeUntil(this.destroy$),
); );
orgId$ combineLatest([
orgId$,
this.projectService.project$.pipe(startWith(null)),
this.secretService.secret$.pipe(startWith(null)),
this.serviceAccountService.serviceAccount$.pipe(startWith(null)),
])
.pipe( .pipe(
concatMap((orgId) => this.secretsManagerService.getCounts(orgId)), switchMap(([orgId]) => this.secretsManagerService.getCounts(orgId)),
takeUntil(this.destroy$), takeUntil(this.destroy$),
) )
.subscribe((organizationCounts) => { .subscribe((organizationCounts) => {

View File

@ -18,6 +18,9 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
import { DialogService } from "@bitwarden/components"; import { DialogService } from "@bitwarden/components";
import { ProjectView } from "../../models/view/project.view"; import { ProjectView } from "../../models/view/project.view";
import { SecretService } from "../../secrets/secret.service";
import { ServiceAccountService } from "../../service-accounts/service-account.service";
import { AccessPolicyService } from "../../shared/access-policies/access-policy.service";
import { import {
OperationType, OperationType,
ProjectDialogComponent, ProjectDialogComponent,
@ -42,6 +45,9 @@ export class ProjectComponent implements OnInit, OnDestroy {
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private projectService: ProjectService, private projectService: ProjectService,
private secretService: SecretService,
private accessPolicyService: AccessPolicyService,
private serviceAccountService: ServiceAccountService,
private router: Router, private router: Router,
private dialogService: DialogService, private dialogService: DialogService,
private platformUtilsService: PlatformUtilsService, private platformUtilsService: PlatformUtilsService,
@ -64,8 +70,13 @@ export class ProjectComponent implements OnInit, OnDestroy {
const organization$ = this.route.params.pipe( const organization$ = this.route.params.pipe(
concatMap((params) => this.organizationService.get$(params.organizationId)), concatMap((params) => this.organizationService.get$(params.organizationId)),
); );
const projectCounts$ = this.route.params.pipe( const projectCounts$ = combineLatest([
switchMap((params) => this.route.params,
this.secretService.secret$.pipe(startWith(null)),
this.accessPolicyService.accessPolicy$.pipe(startWith(null)),
this.serviceAccountService.serviceAccount$.pipe(startWith(null)),
]).pipe(
switchMap(([params]) =>
this.projectService.getProjectCounts(params.organizationId, params.projectId), this.projectService.getProjectCounts(params.organizationId, params.projectId),
), ),
); );

View File

@ -7,7 +7,9 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
import { DialogService } from "@bitwarden/components"; import { DialogService } from "@bitwarden/components";
import { ServiceAccountView } from "../models/view/service-account.view"; import { ServiceAccountView } from "../models/view/service-account.view";
import { AccessPolicyService } from "../shared/access-policies/access-policy.service";
import { AccessService } from "./access/access.service";
import { AccessTokenCreateDialogComponent } from "./access/dialogs/access-token-create-dialog.component"; import { AccessTokenCreateDialogComponent } from "./access/dialogs/access-token-create-dialog.component";
import { ServiceAccountCounts } from "./models/view/counts.view"; import { ServiceAccountCounts } from "./models/view/counts.view";
import { ServiceAccountService } from "./service-account.service"; import { ServiceAccountService } from "./service-account.service";
@ -40,6 +42,8 @@ export class ServiceAccountComponent implements OnInit, OnDestroy {
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private serviceAccountService: ServiceAccountService, private serviceAccountService: ServiceAccountService,
private accessPolicyService: AccessPolicyService,
private accessService: AccessService,
private dialogService: DialogService, private dialogService: DialogService,
private router: Router, private router: Router,
private platformUtilsService: PlatformUtilsService, private platformUtilsService: PlatformUtilsService,
@ -47,7 +51,12 @@ export class ServiceAccountComponent implements OnInit, OnDestroy {
) {} ) {}
ngOnInit(): void { ngOnInit(): void {
const serviceAccountCounts$ = combineLatest([this.route.params, this.onChange$]).pipe( const serviceAccountCounts$ = combineLatest([
this.route.params,
this.accessPolicyService.accessPolicy$.pipe(startWith(null)),
this.accessService.accessToken$.pipe(startWith(null)),
this.onChange$,
]).pipe(
switchMap(([params, _]) => switchMap(([params, _]) =>
this.serviceAccountService.getCounts(params.organizationId, params.serviceAccountId), this.serviceAccountService.getCounts(params.organizationId, params.serviceAccountId),
), ),

View File

@ -1,4 +1,5 @@
import { Injectable } from "@angular/core"; import { Injectable } from "@angular/core";
import { Subject } from "rxjs";
import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { ListResponse } from "@bitwarden/common/models/response/list.response"; import { ListResponse } from "@bitwarden/common/models/response/list.response";
@ -45,6 +46,15 @@ import { GrantedProjectAccessPolicyPermissionDetailsResponse } from "./models/re
providedIn: "root", providedIn: "root",
}) })
export class AccessPolicyService { export class AccessPolicyService {
protected _accessPolicy: Subject<
| ProjectPeopleAccessPoliciesView
| ProjectServiceAccountsAccessPoliciesView
| ServiceAccountPeopleAccessPoliciesView
| ServiceAccountGrantedPoliciesView
> = new Subject();
accessPolicy$ = this._accessPolicy.asObservable();
constructor( constructor(
private cryptoService: CryptoService, private cryptoService: CryptoService,
protected apiService: ApiService, protected apiService: ApiService,
@ -69,7 +79,7 @@ export class AccessPolicyService {
async putProjectPeopleAccessPolicies( async putProjectPeopleAccessPolicies(
projectId: string, projectId: string,
peoplePoliciesView: ProjectPeopleAccessPoliciesView, peoplePoliciesView: ProjectPeopleAccessPoliciesView,
) { ): Promise<ProjectPeopleAccessPoliciesView> {
const request = this.getPeopleAccessPoliciesRequest(peoplePoliciesView); const request = this.getPeopleAccessPoliciesRequest(peoplePoliciesView);
const r = await this.apiService.send( const r = await this.apiService.send(
"PUT", "PUT",
@ -79,7 +89,9 @@ export class AccessPolicyService {
true, true,
); );
const results = new ProjectPeopleAccessPoliciesResponse(r); const results = new ProjectPeopleAccessPoliciesResponse(r);
return this.createPeopleAccessPoliciesView(results); const view = this.createPeopleAccessPoliciesView(results);
this._accessPolicy.next(view);
return view;
} }
async getServiceAccountPeopleAccessPolicies( async getServiceAccountPeopleAccessPolicies(
@ -100,7 +112,7 @@ export class AccessPolicyService {
async putServiceAccountPeopleAccessPolicies( async putServiceAccountPeopleAccessPolicies(
serviceAccountId: string, serviceAccountId: string,
peoplePoliciesView: ServiceAccountPeopleAccessPoliciesView, peoplePoliciesView: ServiceAccountPeopleAccessPoliciesView,
) { ): Promise<ProjectPeopleAccessPoliciesView> {
const request = this.getPeopleAccessPoliciesRequest(peoplePoliciesView); const request = this.getPeopleAccessPoliciesRequest(peoplePoliciesView);
const r = await this.apiService.send( const r = await this.apiService.send(
"PUT", "PUT",
@ -110,7 +122,9 @@ export class AccessPolicyService {
true, true,
); );
const results = new ServiceAccountPeopleAccessPoliciesResponse(r); const results = new ServiceAccountPeopleAccessPoliciesResponse(r);
return this.createPeopleAccessPoliciesView(results); const view = this.createPeopleAccessPoliciesView(results);
this._accessPolicy.next(view);
return view;
} }
async getServiceAccountGrantedPolicies( async getServiceAccountGrantedPolicies(
@ -144,7 +158,9 @@ export class AccessPolicyService {
); );
const result = new ServiceAccountGrantedPoliciesPermissionDetailsResponse(r); const result = new ServiceAccountGrantedPoliciesPermissionDetailsResponse(r);
return await this.createServiceAccountGrantedPoliciesView(result, organizationId); const view = await this.createServiceAccountGrantedPoliciesView(result, organizationId);
this._accessPolicy.next(view);
return view;
} }
async getProjectServiceAccountsAccessPolicies( async getProjectServiceAccountsAccessPolicies(
@ -178,7 +194,9 @@ export class AccessPolicyService {
); );
const result = new ProjectServiceAccountsAccessPoliciesResponse(r); const result = new ProjectServiceAccountsAccessPoliciesResponse(r);
return await this.createProjectServiceAccountsAccessPoliciesView(result, organizationId); const view = await this.createProjectServiceAccountsAccessPoliciesView(result, organizationId);
this._accessPolicy.next(view);
return view;
} }
async getSecretAccessPolicies( async getSecretAccessPolicies(
@ -435,7 +453,7 @@ export class AccessPolicyService {
private createPeopleAccessPoliciesView( private createPeopleAccessPoliciesView(
response: ProjectPeopleAccessPoliciesResponse | ServiceAccountPeopleAccessPoliciesResponse, response: ProjectPeopleAccessPoliciesResponse | ServiceAccountPeopleAccessPoliciesResponse,
) { ): ProjectPeopleAccessPoliciesView | ServiceAccountPeopleAccessPoliciesView {
return { return {
userAccessPolicies: this.createUserAccessPolicyViews(response.userAccessPolicies), userAccessPolicies: this.createUserAccessPolicyViews(response.userAccessPolicies),
groupAccessPolicies: this.createGroupAccessPolicyViews(response.groupAccessPolicies), groupAccessPolicies: this.createGroupAccessPolicyViews(response.groupAccessPolicies),