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

Consolidate access control API #445

Closed
andrus opened this issue Jul 21, 2020 · 3 comments
Closed

Consolidate access control API #445

andrus opened this issue Jul 21, 2020 · 3 comments

Comments

@andrus
Copy link
Contributor

andrus commented Jul 21, 2020

There is a number of disparate access control mechanisms in Agrest that allow to exclude object properties, or objects themselves from updates or selects, as the next section shows, there's a bunch of overlap and very little consistency among them. Some important controls are missing all together. Would be great to reduce the number of APIs involved here and provide a single access control model.

Existing APIs (as of 3.5)

API Read Write Per-Runtime Per-Request Filters Objects Filters Properties
Size Constraint + + via query limit
Constraint + + + via query expression +
EntityConstraint (incl.@ClientReadable, @ClientWritable) + + + +
EntityEncoderFilter + + + in memory with custom function

Size Constraint

...

Constraint

  • API: Constraint<T> extends Function<AgEntity<T>, ConstrainedAgEntity<T>>
  • Functionality: restrict read/write access to properties (attributes/relationships). Limited capability to restrict objects via Expression appended to SelectQuery.
  • How to create: Constraint builder API.

Limitations:

  • No per-runtime capability
  • ConstrainedAgEntity seems like a redundant concept. Can be merged directly to ResourceEntity

EntityConstraint

(gone per #491)

  • API: allowsId, allowsAttribute, allowsRelationship
  • Functionality: restrict read/write access to properties (attributes/relationships) per entity
  • How to create: @ClientReadable / @ClientWritable annotations; injection;

Limitations:

  • No simple builder API, like in Constraint
  • @ClientReadable / @ClientWritable are per class property lists, not per property (Cayenne influence), making them unusable.
  • No per-request capability (which is handled by Constraint)

EntityEncoderFilter

  • API: matches(entity), encode(object), willEncode(object)
  • Functionality: restrict read access to objects per entity or group of entities based on custom lambdas
  • How to create: EntityEncoderFilter.forEntity(X.class).objectCondition(f1).encoder(f2) .. added to SelectBuilder or AgRuntime

Limitations:

  • need to implement both "object condition" and "encoder", that are essentially the same thing. Suppose the latter allows not simply for exclusion, but also for customizing the encoder. So mixing two things here - access control and JSON shaping.
  • no per-request capability for writes.

(Filter updates - Missing)

Limitations:

  • We don't have anything in Agrest for this. Though it is rather easy to implement and call in an endpoint method before calling Agrest, I think it would be beneficial to have an explicit Agrest API to provide direction to the users (Function<EntityUpdate,Boolean> ? )
@andrus andrus changed the title Unified property/object access control Property/object/update filters for access control Jul 21, 2020
@andrus andrus changed the title Property/object/update filters for access control New Filter API for access control of properties and objects Jul 21, 2020
@andrus andrus changed the title New Filter API for access control of properties and objects Consolidate access control API Jul 21, 2020
@andrus
Copy link
Contributor Author

andrus commented Oct 10, 2021

API as of 4.7

With #491 implemented, the matrix of security mechanisms looks like this:

API Read Write Per-Runtime Per-Request Filters Objects Filters Properties
Size Constraint + - - + via query limit -
Constraint + + - + via query expression +
Per-property policies (@Ag*, AgEntityOverlay) + + + + - +
EntityEncoderFilter + - + + in memory with custom function

While having the same number of rows, it is actually model-driven and much more straightforward internally (no more ClientReadable/ClientWritable, no more injectable EntityConstraint). We now have a unified property filtering model that can be applied either per-runtime or per-request.

The next steps will be removing Constraint API, replacing it with AgRequest for server-side qualifier, and AgEntityOverlay for property filtering. See #493 for details.

@andrus
Copy link
Contributor Author

andrus commented Nov 25, 2021

API as of 4.8

Property Access

API Read Write Per-Runtime Per-Request Notes
@Ag* annotations + + + - Individual entity properties are annotated
PropertyAccessRules + + + + Part of AgEntityOverlay API. Easy to add per-request or per runtime

This API is mostly final. EntityEncoderFilter can also do property filtering, but should really not do it, so excluded from the table.

Object Access

API Read Write Per-Runtime Per-Request Per-Entity Notes
Size Constraint + - - + - via query limit
EntityEncoderFilter + - + + can be, but kinda muddy in memory with custom function

This API needs review and improvement. The following tasks were opened to handle it:

@andrus
Copy link
Contributor Author

andrus commented Dec 24, 2022

Closing this mega task. It is 95% done. We'll focus on specific remaining features and enhancements:

@andrus andrus closed this as completed Dec 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant