-
Notifications
You must be signed in to change notification settings - Fork 7
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
Update Permissions and Roles #502
Conversation
Instead, these roles should be managed through Group Roles, which are expected to provide the pre-existing more granular `update_` and `delete_` roles.
@pytest.mark.parametrize( | ||
"mocked_token", [["delete_test_resources"], ["create_datasets"]], indirect=True | ||
) | ||
def test_post_unauthorized(client_test_resource: TestClient, mocked_token: Mock): | ||
response = client_test_resource.post( | ||
"/test_resources/v0", | ||
json={"title": "example"}, | ||
headers={"Authorization": "fake-token"}, | ||
) | ||
assert response.status_code == 403, response.json() | ||
response_json = response.json() | ||
assert response_json["detail"] == "You do not have permission to create test_resources." |
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.
No longer relevant (no permissions required).
def test_delete_unauthenticated( | ||
client_test_resource: TestClient, engine_test_resource_filled: Engine | ||
): | ||
response = client_test_resource.delete("/test_resources/v0/1") | ||
assert response.status_code == 401, response.json() | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"mocked_token", [["create_test_resources"], ["delete_datasets"]], indirect=True | ||
) | ||
def test_delete_unauthorized(client_test_resource: TestClient, mocked_token: Mock): | ||
response = client_test_resource.delete( | ||
"/test_resources/v0/1", | ||
headers={"Authorization": "fake-token"}, | ||
) | ||
assert response.status_code == 403, response.json() | ||
response_json = response.json() | ||
assert response_json["detail"] == "You do not have permission to delete test_resources." |
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.
Covered in test_router_delete.py
below.
@pytest.mark.parametrize( | ||
"mocked_token", | ||
[ | ||
["edit_aiod_resources"], | ||
["create_test_resources"], | ||
["crud_test_resources"], | ||
["create_test_resources", "delete_datasets"], | ||
["edit_aiod_resources", "crud_test_resources"], | ||
], | ||
indirect=True, | ||
) | ||
def test_post_authorized(client_test_resource, mocked_token: Mock): | ||
response = client_test_resource.post( | ||
"/test_resources/v0", | ||
json={"title": "example"}, | ||
headers={"Authorization": "fake-token"}, | ||
) | ||
assert response.status_code == 200, response.json() |
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.
Covered in test_router_post
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 code changes look okay to me, I do not see any issues. The tests work as well.
src/authentication.py
Outdated
@@ -60,8 +65,8 @@ def has_any_role(self, *roles: str) -> bool: | |||
|
|||
@property | |||
def is_reviewer(self): | |||
assert _REVIEWER_ROLE is not None, "Must configure role `reviewer` in config.toml file." # noqa: S101 | |||
return _REVIEWER_ROLE in self.roles | |||
assert REVIEWER_ROLE is not None, "Must configure role `reviewer` in config.toml file." # noqa: S101 |
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.
REVIEWER_ROLE is not longer defined in the toml file.
the assertion on line 41 is not enough?
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.
Good catch! I initially didn't have the assert on import, but decided that doing it on import is better since we really do not want to start the REST API without proper configuration anyway. Then forgot to remove this.
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 also moved validation to a separate function to avoid an issue where it prohibited some services which inadvertendly imported this module wouldn't function (because the environment variable wasn't forwarded to their container).
I see that a user can see assets in draft of other users. is this normal? |
@@ -28,7 +28,6 @@ AIBUILDER_API_TOKEN="" | |||
ES_USER=elastic | |||
ES_PASSWORD=changeme | |||
ES_DISCOVERY_TYPE=single-node | |||
ES_ROLE="edit_aiod_resources" |
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.
There are many "edit_aiod_resources"
around in the code that I guess could also be deleted
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.
As far as I can tell, I only missed a few in test code and documentation (sigh, IDE search), but otherwise there should be no mention. I'll clear those up now as well. Unless there's usage in the metadata catalogue source that you think I missed?
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.
data/keycloak/data/import/aiod-realm.json: "name" : "edit_aiod_resources",
data/keycloak/data/import/aiod-users-0.json: "realmRoles" : [ "default-roles-aiod", "edit_aiod_resources" ],
docs/developer/authentication.md:| user | password | edit_aiod_resources, default-roles-aiod, offline_access, uma_authorization | |
docs/hosting/authentication.md:Currently, only the ` edit_aiod_resources` role is defined, granting users the ability to upload and edit resources.
src/tests/resources/authentication/user_privileged.json: "edit_aiod_resources"
src/tests/resources/authentication/user_inactive.json: "edit_aiod_resources"
src/tests/test_authentication.py: "edit_aiod_resources",
src/tests/testutils/default_sqlalchemy.py
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.
Sorry wasn't done yet updating the PR. I removed the roles from keycloak, tests, and updated the documentation.
Yes. I deliberately left that out of this PR. Read permissions affect many endpoints and in different ways, so I figured it made more sense to chunk it for separate review, I'm already working on that. |
Since loading is also done by some other services which do not need all the configurations to be set.
@mrorro answered your questions and finished processing the feedback. sorry for being unclear on the state earlier. |
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.
LGTM
Change
Many different roles were defined:
create_*
,update_*
, anddelete_*
roles, to allow create/update/delete right for individual asset types (e.g., datasets)crud_*
role, which encompassed the previous rolesedit_aiod_resources
, which mostly seemed to provide the same rights ascrud_*
but for all asset types at onceWith the introduction of using permissions and a review process, we will rely less on roles and thus remove some. In this PR specifically, we remove the use of the
edit_aiod_resources
andcrud_*
roles. They should be implemented as Role Groups in keycloak, giving the users the individual, more granular permissions. Thecreate_*
roles are also no longer used (with an exception forPlatform
s), as users do not need special roles to create assets (instead, they now undergo a review process).Since connectors (currently) do not use the API, but directly insert into the database, they are not affected by these changes. In the future, we will rely on specific roles for each platform to allow which users can upload/edit assets associated with a specific platform (in general, users will not be able to upload/edit anything from a platform that is not the default "aiod").
The PR then also adds the checks for the
update
anddelete
endpoints to ensure that edit requests either have the correct role (i.e., it is some editor making the modification) or they are the owner (through the AIoD permission system).Documentation will be updated in a separate PR.
How to Test
Unit tests are updated, probably the most important thing is to do a code review.
Otherwise, monkey testing using the
user
andreviewer
in default keycloak.The user can upload, edit, delete their (draft) asset, and the
reviewer
(because it's simply a different user with no privileges other than reviewing) cannot edit or delete the asset uploaded byuser
(and vice versa).Checklist
Related Issues
Progress on #449.