You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current way how resource definitions work is that JADNC provides a generic base class, which users can derive from for a specific resource type. JADNC contains scanning logic that picks up such non-generic (resource-bound) classes and calls into them from various places.
When no resource-bound class is found for a specific resource, then resource callbacks are skipped for that resource type. This is accomplished via a non-generic IResourceDefinition interface, which is a type intended for internal use only to track which callbacks are available. It put me on the wrong track when I started using JADNC: I expected this was something for me to implement (similar to services and repositories), but it is not.
Proposal
I'd like to make resource definitions a first-class pluggable extensibility point, similar to services and repositories, so that resource definitions are always called into. We would provide an interface along with a default generic implementation (that contains no logic). Users can then implement the interface themselves and register their generic type -and- derive from our default generic implementation and register that -and- declare resource-bound definitions, which may derive from their own generic base class.
The use case I have in mind for this is authorization. Assume the system stores whether users have read/write access per resource type. While it is possible to annotate controller methods with attributes, this would not be sufficient. It would only work for primary requests like /articles and /articles/1, but not secondary requests like /articles/1/author. The controller would need to contain custom logic that inspects the relationship parameter and runs the permission check for that too. It is even debatable whether a permission check on articles should be done in that case, because the request is not targeting an article.
But it gets worse: a request like /articles?include=author would not get checked for access to the author resource. The current way to deal with that would be to override ResourceDefinition.OnApplyIncludes for all resource types in the project. A similar override for ResourceDefinition.OnApplyFilter is needed to properly check a request like /articles?filter=any(revisions) to ensure the caller has read permission on the revisions table.
If it were possible to plug in a generic resource definition, it could handle the permission check for all resource types in the project. Resource-bound classes would then call into the base class to ensure authorization is always applied.
The text was updated successfully, but these errors were encountered:
Very much entangled with the challenge of allowing for complex authorization on deeply resource-nested endpoint are ResourceHooks. I'm very happy you have a reason to dive into this! My original reason for introducing these hooks was exactly this: complex authorization. I think it will be fruitful for the design considerations to read through the resource hooks document to get a better idea of how the hooks aimed to solve this problem (and related problems) and to get a better idea how we could perhaps integrate the most recent extensibility points in ResourceDefinition together with the hooks system into a really neat system.
Current situation
The current way how resource definitions work is that JADNC provides a generic base class, which users can derive from for a specific resource type. JADNC contains scanning logic that picks up such non-generic (resource-bound) classes and calls into them from various places.
Example:
When no resource-bound class is found for a specific resource, then resource callbacks are skipped for that resource type. This is accomplished via a non-generic
IResourceDefinition
interface, which is a type intended for internal use only to track which callbacks are available. It put me on the wrong track when I started using JADNC: I expected this was something for me to implement (similar to services and repositories), but it is not.Proposal
I'd like to make resource definitions a first-class pluggable extensibility point, similar to services and repositories, so that resource definitions are always called into. We would provide an interface along with a default generic implementation (that contains no logic). Users can then implement the interface themselves and register their generic type -and- derive from our default generic implementation and register that -and- declare resource-bound definitions, which may derive from their own generic base class.
Example:
Use case
The use case I have in mind for this is authorization. Assume the system stores whether users have read/write access per resource type. While it is possible to annotate controller methods with attributes, this would not be sufficient. It would only work for primary requests like
/articles
and/articles/1
, but not secondary requests like/articles/1/author
. The controller would need to contain custom logic that inspects therelationship
parameter and runs the permission check for that too. It is even debatable whether a permission check on articles should be done in that case, because the request is not targeting an article.But it gets worse: a request like
/articles?include=author
would not get checked for access to the author resource. The current way to deal with that would be to overrideResourceDefinition.OnApplyIncludes
for all resource types in the project. A similar override forResourceDefinition.OnApplyFilter
is needed to properly check a request like/articles?filter=any(revisions)
to ensure the caller has read permission on the revisions table.If it were possible to plug in a generic resource definition, it could handle the permission check for all resource types in the project. Resource-bound classes would then call into the base class to ensure authorization is always applied.
The text was updated successfully, but these errors were encountered: