Skip to content

Commit

Permalink
Merge pull request #1571 from ScilifelabDataCentre/DDS-2174-KeyNotFou…
Browse files Browse the repository at this point in the history
…ndError

KeyNotFoundError
  • Loading branch information
rv0lt authored Dec 3, 2024
2 parents 0954097 + 5aeed32 commit 4db54b4
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 2 deletions.
3 changes: 2 additions & 1 deletion SPRINTLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,8 @@ _Nothing merged during this sprint_

- Logging: Add which user name reset password ([https://github.com/ScilifelabDataCentre/dds_web/pull/1574](https://github.com/ScilifelabDataCentre/dds_web/pull/1574))

# 2024-12-02 - 2024-12-13
# 2024-12-02 – 2024-12-13

- Change the error raised upon attempt to download data after a password reset to an AuthenticationError to avoid getting an alert ([#1571](https://github.com/ScilifelabDataCentre/dds_web/pull/1571))
- Filter out the MaintenanceModeException from the logs ([#1573](https://github.com/ScilifelabDataCentre/dds_web/pull/1573))
- Bugfix: Quick and dirty change to prevent `dds ls --tree` from failing systematically ([#1575](https://github.com/ScilifelabDataCentre/dds_web/pull/1575)
2 changes: 1 addition & 1 deletion dds_web/api/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ def get(self):
"""Get private key from database."""
# Verify project ID and access
project = project_schemas.ProjectRequiredSchema().load(flask.request.args)

dds_web.utils.verify_project_user_key(project=project)
flask.current_app.logger.debug("Getting the private key.")

return flask.jsonify(
Expand Down
18 changes: 18 additions & 0 deletions dds_web/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,24 @@ def verify_project_access(project) -> None:
)


def verify_project_user_key(project) -> None:
"""Verify that current authenticated user has a row in projectUserKeys."""
project_key = models.ProjectUserKeys.query.filter_by(
project_id=project.id, user_id=auth.current_user().username
).one_or_none()
if not project_key:
msg = (
"You have lost access to this project. "
"This is likely due to a password reset, in which case you have lost access to all active projects. "
f"In order to regain access to this project, please contact {project.responsible_unit.external_display_name} ({project.responsible_unit.contact_email}) and ask them to run 'dds project access fix'."
)
raise AccessDeniedError(
message=msg,
username=auth.current_user().username,
project=project.public_id,
)


def verify_cli_version(version_cli: str = None) -> None:
"""Verify that the CLI version in header is compatible with the web version."""
# Verify that version is specified
Expand Down
64 changes: 64 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,70 @@ def test_verify_project_access_ok(client: flask.testing.FlaskClient) -> None:
utils.verify_project_access(project=project)


def test_verify_project_user_key_denied(client: flask.testing.FlaskClient) -> None:
"""A user must have an entry in projectUserKeys to access a project."""
# User
user = models.UnitUser.query.filter_by(unit_id=1).first()
assert user

# Get project
project = models.Project.query.filter_by(unit_id=1).first()
assert project

# get projectUserKey
projectUserKey = models.ProjectUserKeys.query.filter_by(
project_id=project.id, user_id=user.username
).one_or_none()
assert projectUserKey

# delete projectUserKey
db.session.delete(projectUserKey)
db.session.commit()

# verify no projectUserKey
projectUserKey = models.ProjectUserKeys.query.filter_by(
project_id=project.id, user_id=user.username
).one_or_none()
assert not projectUserKey

# Set auth.current_user
flask.g.flask_httpauth_user = user

# Verify project access -- not ok
with pytest.raises(AccessDeniedError) as err:
utils.verify_project_user_key(project=project)

error_msg = (
"You have lost access to this project. "
"This is likely due to a password reset, in which case you have lost access to all active projects. "
f"In order to regain access to this project, please contact {project.responsible_unit.external_display_name} ({project.responsible_unit.contact_email}) and ask them to run 'dds project access fix'."
)
assert error_msg in str(err.value)


def test_verify_project_user_key_ok(client: flask.testing.FlaskClient) -> None:
"""A user must have an entry in projectUserKeys to access a project."""
# user
user = models.UnitUser.query.filter_by(unit_id=1).first()
assert user

# Get project
project = models.Project.query.filter_by(unit_id=1).first()
assert project

# get projectUserKey
projectUserKey = models.ProjectUserKeys.query.filter_by(
project_id=project.id, user_id=user.username
).one_or_none()
assert projectUserKey

# Set auth.current_user
flask.g.flask_httpauth_user = user

# Verify project access -- ok
utils.verify_project_access(project=project)


# verify_cli_version


Expand Down

0 comments on commit 4db54b4

Please sign in to comment.