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/authorization #435

Merged
merged 24 commits into from
Feb 18, 2025
Merged

Feat/authorization #435

merged 24 commits into from
Feb 18, 2025

Conversation

PGijsbers
Copy link
Collaborator

@PGijsbers PGijsbers commented Jan 30, 2025

Change

Adds a review workflow to the REST API, in short:

  • A user's uploaded asset is in draft.
  • The user can submit it for review.
  • A user can review it (reject -> back to draft, accept -> published)

Not included:

  • An easy way for reviewers to see what needs reviewing.
  • An easy for way for users to see the review result.
  • Developer documentation. I'll wait until we had a few follow up PRs iterating over this implementation.

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):

git fetch origin
./scripts/down.sh
git checkout auth/defaults  # if #445 is not merged yet, otherwise `develop`
./scripts/clean.sh
./scripts/up.sh
./scripts/down.sh
git checkout feat/authorization
./scripts/up.sh

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

  • Tests have been added or updated to reflect the changes, or their absence is explicitly explained.
  • Documentation has been added or updated to reflect the changes, or their absence is explicitly explained.
  • A self-review has been conducted checking:
    • No unintended changes have been committed.
    • The changes in isolation seem reasonable.
    • Anything that may be odd or unintuitive is provided with a GitHub comment explaining it (but consider if this should not be a code comment or in the documentation instead).
  • All CI checks pass before pinging a reviewer, or provide an explanation if they do not.

Related Issues

Related PRs:

  • Auth/defaults #445 adds reviewer role to default instance
  • feat/reviewqueue branch is the first follow up PR to this, and will introduce endpoints for reviewers to see what needs reviewing.

class KeycloakUser:
name: str
roles: set[str]
_subject_identifier: str
Copy link
Collaborator Author

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 new User 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. The User class only retains the information required to identify a user uniquely (i.e., the subject_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
Copy link
Collaborator Author

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
Copy link
Collaborator Author

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)
Copy link
Collaborator Author

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(
Copy link
Collaborator Author

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.

@PGijsbers PGijsbers mentioned this pull request Feb 11, 2025
4 tasks
Copy link
Collaborator

@Taniya-Das Taniya-Das left a 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()
Copy link
Collaborator

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.

@PGijsbers
Copy link
Collaborator Author

Once the reviewer rejects a submission, and puts a comment, I think it would be useful if the user could see the comments.

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.

I think it makes sense to define a size, to make error handling better.

We should probably chat about it sometime in the WP3 discussion.

@PGijsbers PGijsbers merged commit c4eca25 into develop Feb 18, 2025
1 check passed
@PGijsbers PGijsbers deleted the feat/authorization branch February 18, 2025 11:45
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

Successfully merging this pull request may close these issues.

2 participants