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

Catch KeyNotFoundError #1045

Merged
merged 31 commits into from
Mar 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
f376351
catch key error
Mar 10, 2022
95cd8d2
changelog
Mar 10, 2022
aa775c4
Update CHANGELOG.md
i-oden Mar 10, 2022
24e97c7
test adding space
Mar 10, 2022
4280109
Update dds_web/api/user.py
i-oden Mar 11, 2022
c2bc55d
moved try except and return a message dict
Mar 11, 2022
8a2a8f4
resolve
Mar 11, 2022
2eee60f
only send email any worked
Mar 11, 2022
9100c21
try except for commit
Mar 11, 2022
10fd0b3
changed goahead
Mar 11, 2022
72cbaab
added space
Mar 11, 2022
1891da1
moved token in tests
Mar 11, 2022
c8f9a6a
moved token again
Mar 11, 2022
c6f4b1d
change messages
Mar 11, 2022
359334b
reformat messages
Mar 11, 2022
5ab3519
Merge branch 'dev' into fix-internal-server-error
i-oden Mar 11, 2022
ada86d5
adding more tests
Mar 11, 2022
1c19d51
uncommented http status
Mar 11, 2022
3b603ce
Merge branch 'fix-internal-server-error' of https://github.com/Scilif…
Mar 11, 2022
6ff6765
tests
Mar 12, 2022
46ab67f
added tests for user.py
Mar 13, 2022
c0d4374
test for invite superadmin as unitadmin
Mar 13, 2022
f984e96
test invite superadmin and unit admin as unit personnel
Mar 13, 2022
4b48d76
test invite other roles as project owner
Mar 13, 2022
e4679c8
fixed tests
Mar 13, 2022
a117087
test invite with invalid unit
Mar 13, 2022
226eba9
test with valid unit
Mar 13, 2022
f4b1520
push the old tests too
Mar 13, 2022
7f235ea
Update dds_web/api/user.py
i-oden Mar 14, 2022
c295817
Update dds_web/api/user.py
i-oden Mar 14, 2022
ba731fd
Update dds_web/api/user.py
i-oden Mar 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -601,9 +601,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 @@ -645,15 +647,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 @@ -193,9 +193,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 @@ -206,20 +205,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 @@ -229,21 +238,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 @@ -316,13 +353,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