|
1 | 1 | import logging |
| 2 | +from datetime import datetime, timezone |
2 | 3 | from http import HTTPStatus |
3 | 4 | from typing import Annotated |
4 | 5 |
|
@@ -41,33 +42,45 @@ def request_group_access( |
41 | 42 | settings: Annotated[Settings, Depends(get_settings)], |
42 | 43 | ): |
43 | 44 | """ |
44 | | - Request access to a group. Assumes the user does not already have a |
45 | | - GroupMembership record for this group. |
| 45 | + Request access to a group. Users can re-request access if their last |
| 46 | + request was rejected; otherwise the request is rejected if a membership |
| 47 | + already exists. |
46 | 48 | """ |
47 | 49 | group_id = request_data.group_id |
48 | 50 | existing_membership = GroupMembership.get_by_user_id_and_group_id( |
49 | 51 | user_id=user.access_token.sub, |
50 | 52 | group_id=group_id, |
51 | 53 | session=db_session, |
52 | 54 | ) |
| 55 | + membership: GroupMembership |
53 | 56 | if existing_membership is not None: |
54 | | - raise HTTPException( |
55 | | - status_code=HTTPStatus.CONFLICT, |
56 | | - detail=f"User {user.access_token.sub} already has a membership for {group_id}" |
| 57 | + if existing_membership.approval_status != ApprovalStatusEnum.REJECTED: |
| 58 | + raise HTTPException( |
| 59 | + status_code=HTTPStatus.CONFLICT, |
| 60 | + detail=f"User {user.access_token.sub} already has a membership for {group_id}" |
| 61 | + ) |
| 62 | + membership = existing_membership |
| 63 | + membership.approval_status = ApprovalStatusEnum.PENDING |
| 64 | + membership.rejection_reason = None |
| 65 | + membership.updated_by = None |
| 66 | + membership.updated_at = datetime.now(timezone.utc) |
| 67 | + membership.save(session=db_session, commit=False) |
| 68 | + logger.info("Re-requested group membership for %s(%s)", group_id, user.access_token.sub) |
| 69 | + else: |
| 70 | + group = BiocommonsGroup.get_by_id(group_id, db_session) |
| 71 | + user_record = BiocommonsUser.get_or_create( |
| 72 | + auth0_id=user.access_token.sub, |
| 73 | + db_session=db_session, |
| 74 | + auth0_client=auth0_client |
57 | 75 | ) |
58 | | - group = BiocommonsGroup.get_by_id(group_id, db_session) |
59 | | - user_record = BiocommonsUser.get_or_create( |
60 | | - auth0_id=user.access_token.sub, |
61 | | - db_session=db_session, |
62 | | - auth0_client=auth0_client |
63 | | - ) |
64 | | - membership = GroupMembership( |
65 | | - group=group, |
66 | | - user=user_record, |
67 | | - approval_status=ApprovalStatusEnum.PENDING, |
68 | | - updated_by=None |
69 | | - ) |
70 | | - membership.save(session=db_session, commit=False) |
| 76 | + membership = GroupMembership( |
| 77 | + group=group, |
| 78 | + user=user_record, |
| 79 | + approval_status=ApprovalStatusEnum.PENDING, |
| 80 | + updated_by=None |
| 81 | + ) |
| 82 | + membership.save(session=db_session, commit=False) |
| 83 | + logger.info("Requested group membership for %s(%s)", group_id, user.access_token.sub) |
71 | 84 | logger.info("Queueing emails to group admins for approval") |
72 | 85 | admin_emails = membership.group.get_admins(auth0_client=auth0_client) |
73 | 86 | for email in admin_emails: |
@@ -113,8 +126,15 @@ def approve_group_access( |
113 | 126 | status_code=HTTPStatus.NOT_FOUND, |
114 | 127 | detail="No membership request found for this user" |
115 | 128 | ) |
| 129 | + if membership.approval_status not in {ApprovalStatusEnum.PENDING, ApprovalStatusEnum.REVOKED}: |
| 130 | + raise HTTPException( |
| 131 | + status_code=HTTPStatus.BAD_REQUEST, |
| 132 | + detail="Only pending or revoked group memberships can be approved.", |
| 133 | + ) |
116 | 134 | membership.approval_status = ApprovalStatusEnum.APPROVED |
117 | 135 | membership.updated_by = approving_user_record |
| 136 | + membership.rejection_reason = None |
| 137 | + membership.revocation_reason = None |
118 | 138 | membership.grant_auth0_role(auth0_client=auth0_client) |
119 | 139 | membership.save(session=db_session, commit=False) |
120 | 140 | if membership.user is None: |
|
0 commit comments