1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-11 13:53:34 +00:00

[SM-574] Hide edit/delete when user only has read access (#4941)

* Hide edit/delete when user only has read access

* Wire up read/write for secret response

* Remove variable

* Resolve changes after merge

* SM-671: Fix small bug in sm/SM-574 branch to pass secret instead of secret id on deletion (#5096)

---------

Co-authored-by: Colton Hurst <colton@coltonhurst.com>
This commit is contained in:
Oscar Hinton
2023-03-30 16:51:31 +02:00
committed by GitHub
parent 4cb0d7f0ef
commit 873c35fbd4
9 changed files with 52 additions and 5 deletions

View File

@@ -7,4 +7,6 @@ export class SecretListView {
creationDate: string; creationDate: string;
revisionDate: string; revisionDate: string;
projects: SecretProjectView[]; projects: SecretProjectView[];
read: boolean;
write: boolean;
} }

View File

@@ -9,4 +9,7 @@ export class SecretView {
creationDate: string; creationDate: string;
revisionDate: string; revisionDate: string;
projects: SecretProjectView[]; projects: SecretProjectView[];
read: boolean;
write: boolean;
} }

View File

@@ -39,7 +39,14 @@
<button type="submit" bitButton buttonType="primary" bitFormButton> <button type="submit" bitButton buttonType="primary" bitFormButton>
{{ "save" | i18n }} {{ "save" | i18n }}
</button> </button>
<button type="button" bitButton buttonType="secondary" bitFormButton bitDialogClose> <button
type="button"
bitButton
buttonType="secondary"
bitFormButton
bitDialogClose
[disabled]="false"
>
{{ "cancel" | i18n }} {{ "cancel" | i18n }}
</button> </button>
<button <button

View File

@@ -44,6 +44,7 @@ export class SecretDialogComponent implements OnInit {
projects: ProjectListView[]; projects: ProjectListView[];
private destroy$ = new Subject<void>(); private destroy$ = new Subject<void>();
constructor( constructor(
public dialogRef: DialogRef, public dialogRef: DialogRef,
@Inject(DIALOG_DATA) private data: SecretOperation, @Inject(DIALOG_DATA) private data: SecretOperation,
@@ -80,8 +81,12 @@ export class SecretDialogComponent implements OnInit {
notes: secret.note, notes: secret.note,
project: secret.projects[0]?.id ?? "", project: secret.projects[0]?.id ?? "",
}); });
this.loading = false; this.loading = false;
this.formGroup.enable();
if (secret.write) {
this.formGroup.enable();
}
} }
ngOnDestroy(): void { ngOnDestroy(): void {

View File

@@ -9,6 +9,8 @@ export class SecretListItemResponse extends BaseResponse {
creationDate: string; creationDate: string;
revisionDate: string; revisionDate: string;
projects: SecretProjectResponse[]; projects: SecretProjectResponse[];
read: boolean;
write: boolean;
constructor(response: any) { constructor(response: any) {
super(response); super(response);
@@ -17,6 +19,8 @@ export class SecretListItemResponse extends BaseResponse {
this.name = this.getResponseProperty("Key"); this.name = this.getResponseProperty("Key");
this.creationDate = this.getResponseProperty("CreationDate"); this.creationDate = this.getResponseProperty("CreationDate");
this.revisionDate = this.getResponseProperty("RevisionDate"); this.revisionDate = this.getResponseProperty("RevisionDate");
this.read = this.getResponseProperty("Read");
this.write = this.getResponseProperty("Write");
const project = this.getResponseProperty("projects"); const project = this.getResponseProperty("projects");
this.projects = project == null ? null : project.map((k: any) => new SecretProjectResponse(k)); this.projects = project == null ? null : project.map((k: any) => new SecretProjectResponse(k));

View File

@@ -10,6 +10,10 @@ export class SecretResponse extends BaseResponse {
note: string; note: string;
creationDate: string; creationDate: string;
revisionDate: string; revisionDate: string;
read: boolean;
write: boolean;
projects: SecretProjectResponse[]; projects: SecretProjectResponse[];
constructor(response: any) { constructor(response: any) {
@@ -22,6 +26,9 @@ export class SecretResponse extends BaseResponse {
this.creationDate = this.getResponseProperty("CreationDate"); this.creationDate = this.getResponseProperty("CreationDate");
this.revisionDate = this.getResponseProperty("RevisionDate"); this.revisionDate = this.getResponseProperty("RevisionDate");
this.read = this.getResponseProperty("Read");
this.write = this.getResponseProperty("Write");
const projects = this.getResponseProperty("Projects"); const projects = this.getResponseProperty("Projects");
this.projects = this.projects =
projects == null ? null : projects.map((k: any) => new SecretProjectResponse(k)); projects == null ? null : projects.map((k: any) => new SecretProjectResponse(k));

View File

@@ -176,6 +176,9 @@ export class SecretService {
secretView.value = value; secretView.value = value;
secretView.note = note; secretView.note = note;
secretView.read = secretResponse.read;
secretView.write = secretResponse.write;
if (secretResponse.projects != null) { if (secretResponse.projects != null) {
secretView.projects = await this.decryptProjectsMappedToSecrets( secretView.projects = await this.decryptProjectsMappedToSecrets(
orgKey, orgKey,
@@ -214,6 +217,9 @@ export class SecretService {
projectIds.includes(p.id) projectIds.includes(p.id)
); );
secretListView.read = s.read;
secretListView.write = s.write;
return secretListView; return secretListView;
}) })
); );

View File

@@ -98,7 +98,12 @@
</td> </td>
<bit-menu #secretMenu> <bit-menu #secretMenu>
<button type="button" bitMenuItem (click)="editSecretEvent.emit(secret.id)" *ngIf="!trash"> <button
type="button"
bitMenuItem
(click)="editSecretEvent.emit(secret.id)"
*ngIf="secret.write && !trash"
>
<i class="bwi bwi-fw bwi-pencil" aria-hidden="true"></i> <i class="bwi bwi-fw bwi-pencil" aria-hidden="true"></i>
{{ "editSecret" | i18n }} {{ "editSecret" | i18n }}
</button> </button>
@@ -129,7 +134,12 @@
<i class="bwi bwi-fw bwi-refresh" aria-hidden="true"></i> <i class="bwi bwi-fw bwi-refresh" aria-hidden="true"></i>
{{ "restoreSecret" | i18n }} {{ "restoreSecret" | i18n }}
</button> </button>
<button type="button" bitMenuItem (click)="deleteSecretsEvent.emit([secret])"> <button
type="button"
bitMenuItem
(click)="deleteSecretsEvent.emit([secret])"
*ngIf="secret.write"
>
<i class="bwi bwi-fw bwi-trash tw-text-danger" aria-hidden="true"></i> <i class="bwi bwi-fw bwi-trash tw-text-danger" aria-hidden="true"></i>
<span class="tw-text-danger">{{ <span class="tw-text-danger">{{
(trash ? "permanentlyDelete" : "deleteSecret") | i18n (trash ? "permanentlyDelete" : "deleteSecret") | i18n

View File

@@ -28,6 +28,7 @@ export class BitFormButtonDirective implements OnDestroy {
private destroy$ = new Subject<void>(); private destroy$ = new Subject<void>();
@Input() type: string; @Input() type: string;
@Input() disabled?: boolean;
constructor( constructor(
buttonComponent: ButtonLikeAbstraction, buttonComponent: ButtonLikeAbstraction,
@@ -44,7 +45,9 @@ export class BitFormButtonDirective implements OnDestroy {
}); });
submitDirective.disabled$.pipe(takeUntil(this.destroy$)).subscribe((disabled) => { submitDirective.disabled$.pipe(takeUntil(this.destroy$)).subscribe((disabled) => {
buttonComponent.disabled = disabled; if (this.disabled !== false) {
buttonComponent.disabled = disabled;
}
}); });
} }