Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(permissions): filter fields in forms based on read/write permissions #2180

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
420e45f
feat(permissions): filter fields in forms based on read/write permiss…
tomwwinter Jan 15, 2024
0e627bc
fix: reset demo-permission-generator
tomwwinter Jan 15, 2024
ab8a9d6
refactor: disable-wrapper component for better Cognitive Complexity s…
tomwwinter Jan 15, 2024
efa5e04
Merge branch 'master' into tw/feat/1912-filter-fields-if-user-has-no-…
tomwwinter Jan 15, 2024
020d3bb
fix: use correct import path in ability.service.ts
tomwwinter Jan 15, 2024
e5301eb
refactor: move filter logic to entity-form component/service
tomwwinter Jan 15, 2024
38f8c81
fix: typo
tomwwinter Jan 15, 2024
41d779c
test: improve test coverage
tomwwinter Jan 15, 2024
ed6181e
Merge branch 'master' into tw/feat/1912-filter-fields-if-user-has-no-…
tomwwinter Jan 15, 2024
5248fe0
fix: test syntax
tomwwinter Jan 16, 2024
f99b8d0
fix: test syntax
tomwwinter Jan 16, 2024
754bf3e
fix: pr review feedback
tomwwinter Jan 16, 2024
cf79872
fix: typo
tomwwinter Jan 16, 2024
b1feafc
fix: typo
tomwwinter Jan 16, 2024
c2290c8
fix: pr review feedback
tomwwinter Jan 16, 2024
6e5a4f2
Merge branch 'master' into tw/feat/1912-filter-fields-if-user-has-no-…
tomwwinter Jan 18, 2024
b692321
fix: remove unnecessary function call
tomwwinter Jan 18, 2024
8142222
fix: code format
tomwwinter Jan 18, 2024
dd2f5ff
fix: code format
tomwwinter Jan 18, 2024
4988f07
Merge branch 'master' into tw/feat/1912-filter-fields-if-user-has-no-…
TheSlimvReal Jan 22, 2024
baecf55
disabled check also happens on form initialization
TheSlimvReal Jan 22, 2024
14e58a9
Merge branch 'master' into tw/feat/1912-filter-fields-if-user-has-no-…
tomwwinter Jan 24, 2024
429428d
fix: use create permissions when form creates new entity
tomwwinter Jan 24, 2024
28d6bdb
fix: use create permissions when form creates new entity
tomwwinter Jan 24, 2024
587ff54
removed unnecessary variable
TheSlimvReal Jan 25, 2024
017a45b
Merge branch 'master' into tw/feat/1912-filter-fields-if-user-has-no-…
TheSlimvReal Jan 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,26 @@ describe("EntityFormService", () => {
expect(formGroup.valid).toBeTrue();
});

it("should use create permissions to disable fields when creating a new entity", () => {
const formFields = [{ id: "name" }, { id: "dateOfBirth" }];
TestBed.inject(EntityAbility).update([
{ subject: "Child", action: "read", fields: ["name", "dateOfBirth"] },
{ subject: "Child", action: "update", fields: ["name"] },
{ subject: "Child", action: "create", fields: ["dateOfBirth"] },
]);

const formGroup = service.createFormGroup(
formFields,
new Child(),
false,
true,
true,
);

expect(formGroup.get("name").disabled).toBeTrue();
expect(formGroup.get("dateOfBirth").enabled).toBeTrue();
});

it("should always keep properties disabled if user does not have 'update' permissions for them", () => {
const formFields = [{ id: "name" }, { id: "dateOfBirth" }];
TestBed.inject(EntityAbility).update([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,14 @@ export class EntityFormService {
* @param entity
* @param forTable
* @param withPermissionCheck if true, fields without 'update' permissions will stay disabled when enabling form
* @param creatingNew if true, fields without 'create' permissions will stay disabled initially
*/
public createFormGroup<T extends Entity>(
formFields: ColumnConfig[],
entity: T,
forTable = false,
withPermissionCheck = true,
creatingNew = false,
TheSlimvReal marked this conversation as resolved.
Show resolved Hide resolved
): EntityForm<T> {
const formConfig = {};
const copy = entity.copy();
Expand All @@ -138,10 +140,12 @@ export class EntityFormService {
this.subscriptions.push(valueChangesSubscription);

if (withPermissionCheck) {
this.disableReadOnlyFormControls(group, entity);
this.disableReadOnlyFormControls(group, entity, creatingNew);
const statusChangesSubscription = group.statusChanges
.pipe(filter((status) => status !== "DISABLED"))
.subscribe(() => this.disableReadOnlyFormControls(group, entity));
.subscribe(() =>
this.disableReadOnlyFormControls(group, entity, creatingNew),
);
this.subscriptions.push(statusChangesSubscription);
}

Expand Down Expand Up @@ -207,9 +211,11 @@ export class EntityFormService {
private disableReadOnlyFormControls<T extends Entity>(
form: EntityForm<T>,
entity: T,
creatingNew: boolean,
) {
const action = creatingNew ? "create" : "update";
Object.keys(form.controls).forEach((fieldId) => {
if (this.ability.cannot("update", entity, fieldId)) {
if (this.ability.cannot(action, entity, fieldId)) {
form.get(fieldId).disable({ onlySelf: true, emitEvent: false });
}
});
Expand Down
3 changes: 3 additions & 0 deletions src/app/core/entity-details/form/form.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ export class FormComponent<E extends Entity> implements FormConfig, OnInit {
this.form = this.entityFormService.createFormGroup(
[].concat(...this.fieldGroups.map((group) => group.fields)),
this.entity,
false,
true,
this.creatingNew,
);

if (!this.creatingNew) {
Expand Down