Add accessToSecrets to service account lists (#5749)
This commit is contained in:
parent
5756aa851b
commit
6c68b46acb
|
@ -5,3 +5,7 @@ export class ServiceAccountView {
|
|||
creationDate: string;
|
||||
revisionDate: string;
|
||||
}
|
||||
|
||||
export class ServiceAccountSecretsDetailsView extends ServiceAccountView {
|
||||
accessToSecrets: number;
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ export class OverviewComponent implements OnInit, OnDestroy {
|
|||
orgId$,
|
||||
this.serviceAccountService.serviceAccount$.pipe(startWith(null)),
|
||||
]).pipe(
|
||||
switchMap(([orgId]) => this.serviceAccountService.getServiceAccounts(orgId)),
|
||||
switchMap(([orgId]) => this.serviceAccountService.getServiceAccounts(orgId, false)),
|
||||
share()
|
||||
);
|
||||
|
||||
|
|
|
@ -16,3 +16,12 @@ export class ServiceAccountResponse extends BaseResponse {
|
|||
this.revisionDate = this.getResponseProperty("RevisionDate");
|
||||
}
|
||||
}
|
||||
|
||||
export class ServiceAccountSecretsDetailsResponse extends ServiceAccountResponse {
|
||||
accessToSecrets: number;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.accessToSecrets = this.getResponseProperty("AccessToSecrets");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,11 +8,17 @@ import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.
|
|||
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||
|
||||
import { ServiceAccountView } from "../models/view/service-account.view";
|
||||
import {
|
||||
ServiceAccountSecretsDetailsView,
|
||||
ServiceAccountView,
|
||||
} from "../models/view/service-account.view";
|
||||
import { BulkOperationStatus } from "../shared/dialogs/bulk-status-dialog.component";
|
||||
|
||||
import { ServiceAccountRequest } from "./models/requests/service-account.request";
|
||||
import { ServiceAccountResponse } from "./models/responses/service-account.response";
|
||||
import {
|
||||
ServiceAccountResponse,
|
||||
ServiceAccountSecretsDetailsResponse,
|
||||
} from "./models/responses/service-account.response";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
|
@ -28,16 +34,24 @@ export class ServiceAccountService {
|
|||
private encryptService: EncryptService
|
||||
) {}
|
||||
|
||||
async getServiceAccounts(organizationId: string): Promise<ServiceAccountView[]> {
|
||||
async getServiceAccounts(
|
||||
organizationId: string,
|
||||
includeAccessToSecrets?: boolean
|
||||
): Promise<ServiceAccountSecretsDetailsView[]> {
|
||||
const params = new URLSearchParams();
|
||||
if (includeAccessToSecrets) {
|
||||
params.set("includeAccessToSecrets", "true");
|
||||
}
|
||||
|
||||
const r = await this.apiService.send(
|
||||
"GET",
|
||||
"/organizations/" + organizationId + "/service-accounts",
|
||||
"/organizations/" + organizationId + "/service-accounts?" + params.toString(),
|
||||
null,
|
||||
true,
|
||||
true
|
||||
);
|
||||
const results = new ListResponse(r, ServiceAccountResponse);
|
||||
return await this.createServiceAccountViews(organizationId, results.data);
|
||||
const results = new ListResponse(r, ServiceAccountSecretsDetailsResponse);
|
||||
return await this.createServiceAccountSecretsDetailsViews(organizationId, results.data);
|
||||
}
|
||||
|
||||
async getByServiceAccountId(
|
||||
|
@ -127,21 +141,39 @@ export class ServiceAccountService {
|
|||
serviceAccountView.organizationId = serviceAccountResponse.organizationId;
|
||||
serviceAccountView.creationDate = serviceAccountResponse.creationDate;
|
||||
serviceAccountView.revisionDate = serviceAccountResponse.revisionDate;
|
||||
serviceAccountView.name = await this.encryptService.decryptToUtf8(
|
||||
new EncString(serviceAccountResponse.name),
|
||||
organizationKey
|
||||
);
|
||||
serviceAccountView.name = serviceAccountResponse.name
|
||||
? await this.encryptService.decryptToUtf8(
|
||||
new EncString(serviceAccountResponse.name),
|
||||
organizationKey
|
||||
)
|
||||
: null;
|
||||
return serviceAccountView;
|
||||
}
|
||||
|
||||
private async createServiceAccountViews(
|
||||
private async createServiceAccountSecretsDetailsView(
|
||||
organizationKey: SymmetricCryptoKey,
|
||||
response: ServiceAccountSecretsDetailsResponse
|
||||
): Promise<ServiceAccountSecretsDetailsView> {
|
||||
const view = new ServiceAccountSecretsDetailsView();
|
||||
view.id = response.id;
|
||||
view.organizationId = response.organizationId;
|
||||
view.creationDate = response.creationDate;
|
||||
view.revisionDate = response.revisionDate;
|
||||
view.accessToSecrets = response.accessToSecrets;
|
||||
view.name = response.name
|
||||
? await this.encryptService.decryptToUtf8(new EncString(response.name), organizationKey)
|
||||
: null;
|
||||
return view;
|
||||
}
|
||||
|
||||
private async createServiceAccountSecretsDetailsViews(
|
||||
organizationId: string,
|
||||
serviceAccountResponses: ServiceAccountResponse[]
|
||||
): Promise<ServiceAccountView[]> {
|
||||
serviceAccountResponses: ServiceAccountSecretsDetailsResponse[]
|
||||
): Promise<ServiceAccountSecretsDetailsView[]> {
|
||||
const orgKey = await this.getOrganizationKey(organizationId);
|
||||
return await Promise.all(
|
||||
serviceAccountResponses.map(async (s: ServiceAccountResponse) => {
|
||||
return await this.createServiceAccountView(orgKey, s);
|
||||
serviceAccountResponses.map(async (s: ServiceAccountSecretsDetailsResponse) => {
|
||||
return await this.createServiceAccountSecretsDetailsView(orgKey, s);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
|
@ -64,8 +64,7 @@
|
|||
</a>
|
||||
</td>
|
||||
<td bitCell>
|
||||
<!-- TODO add number of secrets once mapping is implemented-->
|
||||
<span> 0 </span>
|
||||
<span> {{ serviceAccount.accessToSecrets }} </span>
|
||||
</td>
|
||||
<td bitCell>{{ serviceAccount.revisionDate | date : "medium" }}</td>
|
||||
<td bitCell>
|
||||
|
|
|
@ -6,25 +6,28 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
|
|||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { TableDataSource } from "@bitwarden/components";
|
||||
|
||||
import { ServiceAccountView } from "../models/view/service-account.view";
|
||||
import {
|
||||
ServiceAccountSecretsDetailsView,
|
||||
ServiceAccountView,
|
||||
} from "../models/view/service-account.view";
|
||||
|
||||
@Component({
|
||||
selector: "sm-service-accounts-list",
|
||||
templateUrl: "./service-accounts-list.component.html",
|
||||
})
|
||||
export class ServiceAccountsListComponent implements OnDestroy {
|
||||
protected dataSource = new TableDataSource<ServiceAccountView>();
|
||||
protected dataSource = new TableDataSource<ServiceAccountSecretsDetailsView>();
|
||||
|
||||
@Input()
|
||||
get serviceAccounts(): ServiceAccountView[] {
|
||||
get serviceAccounts(): ServiceAccountSecretsDetailsView[] {
|
||||
return this._serviceAccounts;
|
||||
}
|
||||
set serviceAccounts(serviceAccounts: ServiceAccountView[]) {
|
||||
set serviceAccounts(serviceAccounts: ServiceAccountSecretsDetailsView[]) {
|
||||
this.selection.clear();
|
||||
this._serviceAccounts = serviceAccounts;
|
||||
this.dataSource.data = serviceAccounts;
|
||||
}
|
||||
private _serviceAccounts: ServiceAccountView[];
|
||||
private _serviceAccounts: ServiceAccountSecretsDetailsView[];
|
||||
|
||||
@Input()
|
||||
set search(search: string) {
|
||||
|
@ -72,8 +75,8 @@ export class ServiceAccountsListComponent implements OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
delete(serviceAccount: ServiceAccountView) {
|
||||
this.deleteServiceAccountsEvent.emit([serviceAccount]);
|
||||
delete(serviceAccount: ServiceAccountSecretsDetailsView) {
|
||||
this.deleteServiceAccountsEvent.emit([serviceAccount as ServiceAccountView]);
|
||||
}
|
||||
|
||||
bulkDeleteServiceAccounts() {
|
||||
|
|
|
@ -4,7 +4,10 @@ import { combineLatest, Observable, startWith, switchMap } from "rxjs";
|
|||
|
||||
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
|
||||
|
||||
import { ServiceAccountView } from "../models/view/service-account.view";
|
||||
import {
|
||||
ServiceAccountSecretsDetailsView,
|
||||
ServiceAccountView,
|
||||
} from "../models/view/service-account.view";
|
||||
import { AccessPolicyService } from "../shared/access-policies/access-policy.service";
|
||||
|
||||
import {
|
||||
|
@ -23,7 +26,7 @@ import { ServiceAccountService } from "./service-account.service";
|
|||
templateUrl: "./service-accounts.component.html",
|
||||
})
|
||||
export class ServiceAccountsComponent implements OnInit {
|
||||
protected serviceAccounts$: Observable<ServiceAccountView[]>;
|
||||
protected serviceAccounts$: Observable<ServiceAccountSecretsDetailsView[]>;
|
||||
protected search: string;
|
||||
|
||||
private organizationId: string;
|
||||
|
@ -78,7 +81,7 @@ export class ServiceAccountsComponent implements OnInit {
|
|||
);
|
||||
}
|
||||
|
||||
private async getServiceAccounts(): Promise<ServiceAccountView[]> {
|
||||
return await this.serviceAccountService.getServiceAccounts(this.organizationId);
|
||||
private async getServiceAccounts(): Promise<ServiceAccountSecretsDetailsView[]> {
|
||||
return await this.serviceAccountService.getServiceAccounts(this.organizationId, true);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue