1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-21 11:35:34 +01:00

[SM-810] remove token permission UI (#5681)

* Remove permission field from access token dialog; remove unused i18n key

* remove permissions column from access token table

* fix SA name placehold in access token dialog

* remove comment

* pass SA view into dialog upon opening
This commit is contained in:
Will Martin 2023-06-28 14:57:42 -04:00 committed by GitHub
parent 300fade281
commit 6530680b8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 53 additions and 64 deletions

View File

@ -6195,10 +6195,6 @@
"message": "Access token created and copied to clipboard", "message": "Access token created and copied to clipboard",
"description": "Notification to inform the user that the access token has been created and copied to the clipboard." "description": "Notification to inform the user that the access token has been created and copied to the clipboard."
}, },
"accessTokenPermissionsBetaNotification": {
"message": "Permissions management is unavailable for beta.",
"description": "Notification to inform the user that the feature for managing access token permissions is not available in the beta version."
},
"revokeAccessToken": { "revokeAccessToken": {
"message": "Revoke access token", "message": "Revoke access token",
"description": "Invalidates / cancels an access token and as such removes access to secrets for the client application." "description": "Invalidates / cancels an access token and as such removes access to secrets for the client application."

View File

@ -32,7 +32,6 @@
</label> </label>
</th> </th>
<th bitCell>{{ "name" | i18n }}</th> <th bitCell>{{ "name" | i18n }}</th>
<th bitCell>{{ "permissions" | i18n }}</th>
<th bitCell>{{ "expires" | i18n }}</th> <th bitCell>{{ "expires" | i18n }}</th>
<th bitCell>{{ "lastEdited" | i18n }}</th> <th bitCell>{{ "lastEdited" | i18n }}</th>
<th bitCell class="tw-w-0"> <th bitCell class="tw-w-0">
@ -57,7 +56,6 @@
/> />
</td> </td>
<td bitCell>{{ token.name }}</td> <td bitCell>{{ token.name }}</td>
<td bitCell>{{ permission(token) | i18n }}</td>
<td bitCell> <td bitCell>
{{ token.expireAt === null ? ("never" | i18n) : (token.expireAt | date : "medium") }} {{ token.expireAt === null ? ("never" | i18n) : (token.expireAt | date : "medium") }}
</td> </td>

View File

@ -39,8 +39,4 @@ export class AccessListComponent {
const selected = this.tokens.filter((s) => this.selection.selected.includes(s.id)); const selected = this.tokens.filter((s) => this.selection.selected.includes(s.id));
this.revokeAccessTokensEvent.emit(selected); this.revokeAccessTokensEvent.emit(selected);
} }
protected permission(token: AccessTokenView) {
return "canRead";
}
} }

View File

@ -1,6 +1,14 @@
import { Component, OnInit } from "@angular/core"; import { Component, OnDestroy, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router"; import { ActivatedRoute } from "@angular/router";
import { combineLatestWith, firstValueFrom, Observable, startWith, switchMap } from "rxjs"; import {
combineLatestWith,
firstValueFrom,
Observable,
startWith,
Subject,
switchMap,
takeUntil,
} from "rxjs";
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
import { ModalService } from "@bitwarden/angular/services/modal.service"; import { ModalService } from "@bitwarden/angular/services/modal.service";
@ -8,7 +16,9 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { openUserVerificationPrompt } from "@bitwarden/web-vault/app/auth/shared/components/user-verification"; import { openUserVerificationPrompt } from "@bitwarden/web-vault/app/auth/shared/components/user-verification";
import { ServiceAccountView } from "../../models/view/service-account.view";
import { AccessTokenView } from "../models/view/access-token.view"; import { AccessTokenView } from "../models/view/access-token.view";
import { ServiceAccountService } from "../service-account.service";
import { AccessService } from "./access.service"; import { AccessService } from "./access.service";
import { AccessTokenCreateDialogComponent } from "./dialogs/access-token-create-dialog.component"; import { AccessTokenCreateDialogComponent } from "./dialogs/access-token-create-dialog.component";
@ -17,11 +27,11 @@ import { AccessTokenCreateDialogComponent } from "./dialogs/access-token-create-
selector: "sm-access-tokens", selector: "sm-access-tokens",
templateUrl: "./access-tokens.component.html", templateUrl: "./access-tokens.component.html",
}) })
export class AccessTokenComponent implements OnInit { export class AccessTokenComponent implements OnInit, OnDestroy {
accessTokens$: Observable<AccessTokenView[]>; accessTokens$: Observable<AccessTokenView[]>;
private serviceAccountId: string; private destroy$ = new Subject<void>();
private organizationId: string; private serviceAccountView: ServiceAccountView;
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
@ -29,19 +39,39 @@ export class AccessTokenComponent implements OnInit {
private dialogService: DialogServiceAbstraction, private dialogService: DialogServiceAbstraction,
private modalService: ModalService, private modalService: ModalService,
private platformUtilsService: PlatformUtilsService, private platformUtilsService: PlatformUtilsService,
private i18nService: I18nService private i18nService: I18nService,
private serviceAccountService: ServiceAccountService
) {} ) {}
ngOnInit() { ngOnInit() {
this.accessTokens$ = this.accessService.accessToken$.pipe( this.accessTokens$ = this.accessService.accessToken$.pipe(
startWith(null), startWith(null),
combineLatestWith(this.route.params), combineLatestWith(this.route.params),
switchMap(async ([_, params]) => { switchMap(async ([_, params]) =>
this.organizationId = params.organizationId; this.accessService.getAccessTokens(params.organizationId, params.serviceAccountId)
this.serviceAccountId = params.serviceAccountId; )
return await this.getAccessTokens();
})
); );
this.serviceAccountService.serviceAccount$
.pipe(
startWith(null),
combineLatestWith(this.route.params),
switchMap(([_, params]) =>
this.serviceAccountService.getByServiceAccountId(
params.serviceAccountId,
params.organizationId
)
),
takeUntil(this.destroy$)
)
.subscribe((serviceAccountView) => {
this.serviceAccountView = serviceAccountView;
});
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
} }
protected async revoke(tokens: AccessTokenView[]) { protected async revoke(tokens: AccessTokenView[]) {
@ -59,7 +89,7 @@ export class AccessTokenComponent implements OnInit {
} }
await this.accessService.revokeAccessTokens( await this.accessService.revokeAccessTokens(
this.serviceAccountId, this.serviceAccountView.id,
tokens.map((t) => t.id) tokens.map((t) => t.id)
); );
@ -69,8 +99,7 @@ export class AccessTokenComponent implements OnInit {
protected openNewAccessTokenDialog() { protected openNewAccessTokenDialog() {
AccessTokenCreateDialogComponent.openNewAccessTokenDialog( AccessTokenCreateDialogComponent.openNewAccessTokenDialog(
this.dialogService, this.dialogService,
this.serviceAccountId, this.serviceAccountView
this.organizationId
); );
} }
@ -89,8 +118,4 @@ export class AccessTokenComponent implements OnInit {
return firstValueFrom(ref.closed); return firstValueFrom(ref.closed);
} }
private async getAccessTokens(): Promise<AccessTokenView[]> {
return await this.accessService.getAccessTokens(this.organizationId, this.serviceAccountId);
}
} }

View File

@ -12,19 +12,6 @@
<bit-label>{{ "name" | i18n }}</bit-label> <bit-label>{{ "name" | i18n }}</bit-label>
<input bitInput formControlName="name" /> <input bitInput formControlName="name" />
</bit-form-field> </bit-form-field>
<div class="tw-mb-6">
<bit-form-field class="tw-mb-0">
<bit-label>{{ "permissions" | i18n }}</bit-label>
<select bitInput disabled>
<option selected value="canRead">
{{ "canRead" | i18n }}
</option>
</select>
</bit-form-field>
<span class="tw-text-sm tw-text-muted">
{{ "accessTokenPermissionsBetaNotification" | i18n }}
</span>
</div>
<sm-expiration-options <sm-expiration-options
formControlName="expirationDateControl" formControlName="expirationDateControl"
[expirationDayOptions]="expirationDayOptions" [expirationDayOptions]="expirationDayOptions"

View File

@ -3,7 +3,6 @@ import { Component, Inject, OnInit } from "@angular/core";
import { FormControl, FormGroup, Validators } from "@angular/forms"; import { FormControl, FormGroup, Validators } from "@angular/forms";
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { BitValidators } from "@bitwarden/components"; import { BitValidators } from "@bitwarden/components";
import { ServiceAccountView } from "../../../models/view/service-account.view"; import { ServiceAccountView } from "../../../models/view/service-account.view";
@ -13,7 +12,6 @@ import { AccessService } from "../access.service";
import { AccessTokenDetails, AccessTokenDialogComponent } from "./access-token-dialog.component"; import { AccessTokenDetails, AccessTokenDialogComponent } from "./access-token-dialog.component";
export interface AccessTokenOperation { export interface AccessTokenOperation {
organizationId: string;
serviceAccountView: ServiceAccountView; serviceAccountView: ServiceAccountView;
} }
@ -35,17 +33,12 @@ export class AccessTokenCreateDialogComponent implements OnInit {
constructor( constructor(
public dialogRef: DialogRef, public dialogRef: DialogRef,
@Inject(DIALOG_DATA) public data: AccessTokenOperation, @Inject(DIALOG_DATA) public data: AccessTokenOperation,
private i18nService: I18nService,
private dialogService: DialogServiceAbstraction, private dialogService: DialogServiceAbstraction,
private accessService: AccessService private accessService: AccessService
) {} ) {}
async ngOnInit() { async ngOnInit() {
if ( if (!this.data.serviceAccountView) {
!this.data.organizationId ||
!this.data.serviceAccountView?.id ||
!this.data.serviceAccountView?.name
) {
this.dialogRef.close(); this.dialogRef.close();
throw new Error( throw new Error(
`The access token create dialog was not called with the appropriate operation values.` `The access token create dialog was not called with the appropriate operation values.`
@ -62,7 +55,7 @@ export class AccessTokenCreateDialogComponent implements OnInit {
accessTokenView.name = this.formGroup.value.name; accessTokenView.name = this.formGroup.value.name;
accessTokenView.expireAt = this.formGroup.value.expirationDateControl; accessTokenView.expireAt = this.formGroup.value.expirationDateControl;
const accessToken = await this.accessService.createAccessToken( const accessToken = await this.accessService.createAccessToken(
this.data.organizationId, this.data.serviceAccountView.organizationId,
this.data.serviceAccountView.id, this.data.serviceAccountView.id,
accessTokenView accessTokenView
); );
@ -90,18 +83,11 @@ export class AccessTokenCreateDialogComponent implements OnInit {
static openNewAccessTokenDialog( static openNewAccessTokenDialog(
dialogService: DialogServiceAbstraction, dialogService: DialogServiceAbstraction,
serviceAccountId: string, serviceAccountView: ServiceAccountView
organizationId: string
) { ) {
// TODO once service account names are implemented in service account contents page pass in here.
const serviceAccountView = new ServiceAccountView();
serviceAccountView.id = serviceAccountId;
serviceAccountView.name = "placeholder";
return dialogService.open<unknown, AccessTokenOperation>(AccessTokenCreateDialogComponent, { return dialogService.open<unknown, AccessTokenOperation>(AccessTokenCreateDialogComponent, {
data: { data: {
organizationId: organizationId, serviceAccountView,
serviceAccountView: serviceAccountView,
}, },
}); });
} }

View File

@ -15,6 +15,8 @@ import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { ServiceAccountView } from "../models/view/service-account.view";
import { AccessTokenCreateDialogComponent } from "./access/dialogs/access-token-create-dialog.component"; import { AccessTokenCreateDialogComponent } from "./access/dialogs/access-token-create-dialog.component";
import { ServiceAccountService } from "./service-account.service"; import { ServiceAccountService } from "./service-account.service";
@ -32,6 +34,7 @@ export class ServiceAccountComponent implements OnInit, OnDestroy {
startWith(null) startWith(null)
); );
private serviceAccountView: ServiceAccountView;
protected serviceAccount$ = combineLatest([this.route.params, this.onChange$]).pipe( protected serviceAccount$ = combineLatest([this.route.params, this.onChange$]).pipe(
switchMap(([params, _]) => switchMap(([params, _]) =>
this.serviceAccountService.getByServiceAccountId( this.serviceAccountService.getByServiceAccountId(
@ -61,9 +64,8 @@ export class ServiceAccountComponent implements OnInit, OnDestroy {
) {} ) {}
ngOnInit(): void { ngOnInit(): void {
this.route.params.pipe(takeUntil(this.destroy$)).subscribe((params) => { this.serviceAccount$.pipe(takeUntil(this.destroy$)).subscribe((serviceAccountView) => {
this.serviceAccountId = params.serviceAccountId; this.serviceAccountView = serviceAccountView;
this.organizationId = params.organizationId;
}); });
} }
@ -75,8 +77,7 @@ export class ServiceAccountComponent implements OnInit, OnDestroy {
protected openNewAccessTokenDialog() { protected openNewAccessTokenDialog() {
AccessTokenCreateDialogComponent.openNewAccessTokenDialog( AccessTokenCreateDialogComponent.openNewAccessTokenDialog(
this.dialogService, this.dialogService,
this.serviceAccountId, this.serviceAccountView
this.organizationId
); );
} }
} }