-
Notifications
You must be signed in to change notification settings - Fork 7
Update Permissions and Roles #502
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
Changes from 15 commits
d382663
6b15ea3
7910bfa
bb0fcdc
84e9a0b
829ae1d
c300a9d
042dac9
3b81a7a
469cf79
a3a2173
d611a80
7dad71d
30b75f7
3bdab43
1b1196f
e7f4037
31b43c3
4e6c372
11b5165
1a0ae33
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,15 +35,20 @@ | |
oidc = OpenIdConnect(openIdConnectUrl=KEYCLOAK_CONFIG.get("openid_connect_url"), auto_error=False) | ||
|
||
|
||
# These variables are required for the API to function, so we provide context beyond KeyError. | ||
# Should be managed together with other settings in the future (#67) | ||
REVIEWER_ROLE = os.getenv("REVIEWER_ROLE_NAME") | ||
assert REVIEWER_ROLE, "Environment variable 'REVIEWER_ROLE_NAME' not set." # noqa: S101 | ||
client_secret = os.getenv("KEYCLOAK_CLIENT_SECRET") | ||
assert client_secret, "Environment variable 'KEYCLOAK_CLIENT_SECRET' not set." # noqa: S101 | ||
|
||
keycloak_openid = KeycloakOpenID( | ||
server_url=KEYCLOAK_CONFIG.get("server_url"), | ||
client_id=KEYCLOAK_CONFIG.get("client_id"), | ||
client_secret_key=client_secret, | ||
realm_name=KEYCLOAK_CONFIG.get("realm"), | ||
verify=True, | ||
) | ||
_REVIEWER_ROLE = os.getenv("REVIEWER_ROLE_NAME") | ||
|
||
|
||
@dataclasses.dataclass | ||
|
@@ -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 commentThe reason will be displayed to describe this comment to others. Learn more. REVIEWER_ROLE is not longer defined in the toml file. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe 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). |
||
return REVIEWER_ROLE in self.roles | ||
|
||
|
||
async def _get_user(token) -> KeycloakUser: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,11 +41,8 @@ def test_platform_get_unauthenticated( | |
@pytest.mark.parametrize( | ||
"mocked_token", | ||
[ | ||
["edit_aiod_resources"], | ||
["delete_test_resources"], | ||
["crud_test_resources"], | ||
["delete_test_resources", "create_datasets"], | ||
["edit_aiod_resources", "crud_test_resources"], | ||
], | ||
indirect=True, | ||
) | ||
|
@@ -59,60 +56,6 @@ def test_delete_authorized( | |
assert response.status_code == 200, response.json() | ||
|
||
|
||
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." | ||
Comment on lines
-62
to
-79
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Covered in |
||
|
||
|
||
@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() | ||
Comment on lines
-82
to
-99
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Covered in |
||
|
||
|
||
@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." | ||
Comment on lines
-102
to
-113
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No longer relevant (no permissions required). |
||
|
||
|
||
def test_post_unauthenticated(client_test_resource: TestClient): | ||
response = client_test_resource.post("/test_resources/v0", json={"title": "example"}) | ||
assert response.status_code == 401, response.json() | ||
|
@@ -126,11 +69,8 @@ def test_post_unauthenticated(client_test_resource: TestClient): | |
@pytest.mark.parametrize( | ||
"mocked_token", | ||
[ | ||
["edit_aiod_resources"], | ||
["update_test_resources"], | ||
["crud_test_resources"], | ||
["update_test_resources", "delete_datasets"], | ||
["edit_aiod_resources", "crud_test_resources"], | ||
], | ||
indirect=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.
There are many
"edit_aiod_resources"
around in the code that I guess could also be deletedThere 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.
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.