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/read permissions #509

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
Open

Feat/read permissions #509

wants to merge 9 commits into from

Conversation

PGijsbers
Copy link
Collaborator

@PGijsbers PGijsbers commented Apr 3, 2025

Change

Make draft assets private, only visible with explicit permission.
That means:

  • Assets in draft are never considered count or list assets, not even if you have read-permissions
  • Assets in draft can only be retrieved by ASSET/{identifier} if the user as read permissions for that asset
  • Reviewers currently can see the asset through the get_submission endpoint, but not directly.

How to Test

Primarily try to think if there are permutations which do not work with these changes.
In particular ones that inadvertently may expose the draft asset.
More generally, tests are updated and it can be manually tested.

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 to #449

server_data = client.get(f"/publications/v1/{response.json()['identifier']}").json()
server_data = client.get(
f"/publications/v1/{response.json()['identifier']}",
headers={"Authorization": "Fake token"},
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll see this in several places: to access draft assets we now need to authenticate, which requires mocking the keycloak introspection (done above with with logged_in_user(...):) and provide a fake token.

Comment on lines -22 to +23
def test_entry_status_can_update_on_put(
def test_entry_status_does_not_update_on_put(
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 test was updated in a previous PR and the name was not updated to reflect the new behavior. Entry Status can only be updated through the review process endpoints currently.

status=EntryStatus.DRAFT,
date_deleted=deletion_time,
),
factory_test_resource(title="test_resource_to_keep", status=EntryStatus.DRAFT,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's the same function, but renamed. factory did not say what it was a factory function of (factory functions are helper functions to produce an object). normally I would name this test_resource_factory but that test_ prefix would make Pytest think it is a test function. Somewhat unfortunate.

resource_name: str,
auto_publish: None,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auto_publish is a new fixture (please skip ahead and look at it then continue). Basically: it automatically makes any aiod entry have status published, which avoids us having to either 1) fake the review process every time we post an asset and want it to be published or 2) update tests by adding the required authentication for GET requests on a draft asset.

Comment on lines -53 to +55
response = client.get(default_endpoint, allow_redirects=False)
response = client.get(default_endpoint, follow_redirects=False)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

allow_redirects was deprecated, otherwise unrelated

Comment on lines +16 to +17
factory_test_resource(title="My third test resource", status=EntryStatus.DRAFT,
platform_resource_identifier="4"),
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that the new list has one more asset, but its in draft. So here we are now automatically also checking if draft assets are included in get_all requests (and later similar in count requests).

Comment on lines +70 to +74
register_asset(person)
register_asset(publication)
register_asset(Publication(name="2"))
register_asset(Publication(name="3"))
register_asset(contact)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

register_asset helper function makes sure there is also an associated user, permission, and, if required, review entry.


@pytest.mark.parametrize(
"title",
["\"'é:?", "!@#$%^&*()`~", "Ω≈ç√∫˜µ≤≥÷", "田中さんにあげて下さい", " أي بعد, ", "𝑻𝒉𝒆 𝐪𝐮𝐢𝐜𝐤", "گچپژ"],
)
def test_unicode(client_test_resource: TestClient, title: str, mocked_privileged_token: Mock):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we phase out the mocked_privileged_token in favor of the logged_in_user. It's more specific about to which calls it applies and which roles apply (if any).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and allows faking multiple users in the same test

original = keycloak_openid.introspect
user = user or kc_user_with_roles()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It became a pretty common pattern not to care about what user was logged in, just that is was a particular user. It made sense to me to make that default behavior.

Comment on lines +93 to +100
def bypass_reviewer_publish_everything() -> None:
"""Function to set the AIoD entry to published without a review.
This function is a *test utility* to simplify test setups, and avoid
e.g., authentication for get requests.
"""
with DbSession() as session:
session.exec(update(AIoDEntryORM).values(status=EntryStatus.PUBLISHED))
session.commit()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically what auto_publish also does, except on a manual invocation. There were some situations where the update trigger lead to failure for a reason I could not figure out, or where you do not want the asset published immediately but rather after some checks, in those cases we can use this manual override.

@PGijsbers PGijsbers marked this pull request as ready for review April 7, 2025 19:13
@PGijsbers PGijsbers requested a review from Taniya-Das April 7, 2025 19:13
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.

1 participant