Skip to content

Commit

Permalink
Merge pull request #1045 from ScilifelabDataCentre/fix-internal-serve…
Browse files Browse the repository at this point in the history
…r-error

Catch KeyNotFoundError
  • Loading branch information
i-oden authored Mar 14, 2022
2 parents d6feb0f + ba731fd commit d3fb38d
Show file tree
Hide file tree
Showing 4 changed files with 296 additions and 41 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ Please add a _short_ line describing the PR you make, if the PR implements a spe
## Sprint (2022-03-09 - 2022-03-23)

- Introduce a separate error message if someone tried to add an unit user to projects individually. ([#1039](https://github.com/ScilifelabDataCentre/dds_web/pull/1039))
- Catch KeyNotFoundError when user tries to give access to a project they themselves do not have access to ([#1045](https://github.com/ScilifelabDataCentre/dds_web/pull/1045))
- Display an error message when the user makes too many authentication requests. ([#1034](https://github.com/ScilifelabDataCentre/dds_web/pull/1034))
34 changes: 22 additions & 12 deletions dds_web/api/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,9 +600,11 @@ def post(self):
else:
list_of_projects = [project]

self.give_project_access(
errors = self.give_project_access(
project_list=list_of_projects, current_user=auth.current_user(), user=user
)
if errors:
return {"errors": errors}

return {"message": f"Project access updated for user '{user.primary_email}'."}

Expand Down Expand Up @@ -644,15 +646,23 @@ def verify_renew_access_permission(user, project):
def give_project_access(project_list, current_user, user):
"""Give specific user project access."""
# Loop through and check that the project(s) is(are) active
fix_errors = {}
for proj in project_list:
if proj.is_active:
project_keys_row = models.ProjectUserKeys.query.filter_by(
project_id=proj.id, user_id=user.username
).one_or_none()
if not project_keys_row:
share_project_private_key(
from_user=current_user,
to_another=user,
project=proj,
from_user_token=dds_web.security.auth.obtain_current_encrypted_token(),
)
try:
if proj.is_active:
project_keys_row = models.ProjectUserKeys.query.filter_by(
project_id=proj.id, user_id=user.username
).one_or_none()
if not project_keys_row:
share_project_private_key(
from_user=current_user,
to_another=user,
project=proj,
from_user_token=dds_web.security.auth.obtain_current_encrypted_token(),
)
except KeyNotFoundError as keyerr:
fix_errors[
proj.public_id
] = "You do not have access to this project. Please contact the responsible unit."

return fix_errors
100 changes: 73 additions & 27 deletions dds_web/api/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,8 @@ def invite_user(email, new_user_role, project=None, unit=None):
"status": http.HTTPStatus.INTERNAL_SERVER_ERROR,
}

# Compose and send email
AddUser.compose_and_send_email_to_user(userobj=new_invite, mail_type="invite", link=link)

projects_not_shared = {}
goahead = False
# Append invite to unit if applicable
if new_invite.role in ["Unit Admin", "Unit Personnel"]:
# TODO Change / move this later. This is just so that we can add an initial Unit Admin.
Expand All @@ -204,20 +203,30 @@ def invite_user(email, new_user_role, project=None, unit=None):
raise ddserr.DDSArgumentError(message="Invalid unit publid id.")

unit_row.invites.append(new_invite)
goahead = True
else:
raise ddserr.DDSArgumentError(message="Cannot invite this user.")
raise ddserr.DDSArgumentError(
message="You need to specify a unit to invite a Unit Personnel or Unit Admin."
)

if "Unit" in auth.current_user().role:
# Give new unit user access to all projects of the unit
auth.current_user().unit.invites.append(new_invite)
for unit_project in auth.current_user().unit.projects:
if unit_project.is_active:
share_project_private_key(
from_user=auth.current_user(),
to_another=new_invite,
from_user_token=dds_web.security.auth.obtain_current_encrypted_token(),
project=unit_project,
)
try:
share_project_private_key(
from_user=auth.current_user(),
to_another=new_invite,
from_user_token=dds_web.security.auth.obtain_current_encrypted_token(),
project=unit_project,
)
except ddserr.KeyNotFoundError as keyerr:
projects_not_shared[
unit_project.public_id
] = "You do not have access to the project(s)"
else:
goahead = True

if not project: # specified project is disregarded for unituser invites
msg = f"{str(new_invite)} was successful."
Expand All @@ -227,21 +236,49 @@ def invite_user(email, new_user_role, project=None, unit=None):
else:
db.session.add(new_invite)
if project:
share_project_private_key(
from_user=auth.current_user(),
to_another=new_invite,
project=project,
from_user_token=dds_web.security.auth.obtain_current_encrypted_token(),
is_project_owner=new_user_role == "Project Owner",
)
try:
share_project_private_key(
from_user=auth.current_user(),
to_another=new_invite,
project=project,
from_user_token=dds_web.security.auth.obtain_current_encrypted_token(),
is_project_owner=new_user_role == "Project Owner",
)
except ddserr.KeyNotFoundError as keyerr:
projects_not_shared[
project.public_id
] = "You do not have access to the specified project."
else:
goahead = True
else:
goahead = True

# Compose and send email
status_code = http.HTTPStatus.OK
if goahead:
try:
db.session.commit()
except sqlalchemy.exc.SQLAlchemyError as sqlerr:
db.session.rollback()
raise ddserr.DatabaseError(message=str(sqlerr))

db.session.commit()
msg = f"{str(new_invite)} was successful."
AddUser.compose_and_send_email_to_user(
userobj=new_invite, mail_type="invite", link=link
)
msg = f"{str(new_invite)} was successful."
else:
msg = (
f"The user could not be added to the project(s)."
if projects_not_shared
else "Unknown error!"
) + " The invite did not succeed."
status_code = ddserr.InviteError.code.value

return {
"email": new_invite.email,
"message": msg,
"status": http.HTTPStatus.OK,
"status": status_code,
"errors": projects_not_shared,
}

@staticmethod
Expand Down Expand Up @@ -314,13 +351,22 @@ def add_to_project(whom, project, role, send_email=True):
)
)

share_project_private_key(
from_user=auth.current_user(),
to_another=whom,
from_user_token=dds_web.security.auth.obtain_current_encrypted_token(),
project=project,
is_project_owner=is_owner,
)
try:
share_project_private_key(
from_user=auth.current_user(),
to_another=whom,
from_user_token=dds_web.security.auth.obtain_current_encrypted_token(),
project=project,
is_project_owner=is_owner,
)
except ddserr.KeyNotFoundError as keyerr:
return {
"message": (
"You do not have access to the current project. To get access, "
"ask the a user within the responsible unit to grant you access."
),
"status": ddserr.AccessDeniedError.code.value,
}

try:
db.session.commit()
Expand Down
Loading

0 comments on commit d3fb38d

Please sign in to comment.