-
Notifications
You must be signed in to change notification settings - Fork 6
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/authorization #435
Feat/authorization #435
Conversation
The considered alternative is to not differentiate, but then you would normally want to do an extra database roundtrip on every authentication request, which seems rather wasteful. In many cases this may not be needed at all.
The correct workflow would be to retract the asset first, then edit it. Currently no guard against editing published assets since that would require a more comprehensive review process.
1142f17
to
5791532
Compare
class KeycloakUser: | ||
name: str | ||
roles: set[str] | ||
_subject_identifier: str |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two changes:
-
Rename
User
->KeycloakUser
: this allows me to introduce a newUser
class in our permission model. The distinction is as follows:KeycloakUser
is provided in API calls and identifiers the user that makes a request, including its roles. TheUser
class only retains the information required to identify a user uniquely (i.e., thesubject_identifier
), nothing more. This is primarily because we do not want to duplicate information such name or roles between our database and the identity provider. -
Addition of the
_subject_identifier
field: this is required so we can unique identify a user making the request. Which is needed because now permissions about editing may be constrained to specific users.
@@ -0,0 +1,81 @@ | |||
import enum |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This module contains the broad definitions required for authorization: who is a user and what are its permissions.
A Permission
has information about what a User
can do with a specific asset, as identified by its aiod_entry
.
There are some place-holder comments/stubs for future work with permissions. This PR largely does not concern that (except for administrator permissions).
@@ -0,0 +1,69 @@ | |||
import enum |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Module for the reviewing components. In particular, a User
may submit their asset for review, resulting in a Submission
. The Submission
may be reviewed by a reviewer, resulting in a Review
.
src/main.py
Outdated
@@ -132,7 +133,7 @@ def create_app() -> FastAPI: | |||
|
|||
drop_database = args.build_db == "drop-then-build" | |||
create_database(delete_first=drop_database) | |||
AIoDConcept.metadata.create_all(EngineSingleton().engine, checkfirst=True) | |||
SQLModel.metadata.create_all(EngineSingleton().engine, checkfirst=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The User/Permission/Review entities do not derive from AIoDConcept, but still need to be included in the database creation logic.
@@ -132,6 +134,30 @@ def create(self, url_prefix: str) -> APIRouter: | |||
description=f"Retrieve the number of {self.resource_name_plural}.", | |||
**default_kwargs, | |||
) | |||
router.add_api_route( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to experiment with creating dedicated endpoints instead, where it's the review endpoints are not split by asset. I'll do that in a follow-up PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, it looks good. It works as intended.
One suggestion - Once the reviewer rejects a submission, and puts a comment, I think it would be useful if the user could see the comments.
decision_date: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) | ||
|
||
# Not sure if size should be limited, especially if we want to use this for structured data. | ||
comment: str | None = Field() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense to define a size, to make error handling better.
I agree! But we can set up endpoints for that in a follow up PR. The reason to split it off is to get the main user/permission model into the main branch, which will allow us to more easily make independent smaller PRs for features such as those.
We should probably chat about it sometime in the WP3 discussion. |
Change
Adds a review workflow to the REST API, in short:
Not included:
How to Test
I added extra unit tests. If you want to test this through the API, please follow these instructions to make sure there is a reviewer account with a reviewer role (from the root of the repo):
Now there is a user (
user:password
) and a reviewer (reviewer:password
) that can make use of the new endpoints.user: create a case_study (or other asset) and note its identifier.
user: submit the case_study for review (by its identifier) using the new
/RESOURCE_TYPE/submit/v1/{identifier}
endpoint. Remember the "submission_identifier" that's returned.either: List all case studies, you should see it with status "submitted".
reviewer: Submit a review with the
/RESOURCE_TYPE/review/v1
endpoint, use the "submission_identifier" obtained earlier.Checklist
Related Issues
Related PRs: