diff --git a/app/main/views/register.py b/app/main/views/register.py index f41d23c70..7a1a07c17 100644 --- a/app/main/views/register.py +++ b/app/main/views/register.py @@ -189,19 +189,34 @@ def set_up_your_profile(): invite_data = redis_client.get(f"invitedata-{state}") # TODO fails here. invite_data = json.loads(invite_data) - invited_user_id = invite_data["invited_user_id"] - invited_user_email_address = get_invited_user_email_address(invited_user_id) + current_app.logger.debug(hilite(f"HERE IS INVITE DATA {invite_data}")) + is_org_invite = False + if invite_data.get("invited_user_id"): + invited_user_id = invite_data["invited_user_id"] + + invited_user_email_address = get_invited_user_email_address(invited_user_id) + else: + invited_user_id = invite_data["id"] + is_org_invite = True + invited_user_email_address = get_invited_org_user_email_address( + invited_user_id + ) + current_app.logger.info( f"#invites: does user email match expected? {user_email == invited_user_email_address}" ) check_invited_user_email_address_matches_expected( user_email, invited_user_email_address ) + if is_org_invite: + invited_org_user_accept_invite(invited_user_id) + + else: + invited_user_accept_invite(invited_user_id) - invited_user_accept_invite(invited_user_id) current_app.logger.info( f"#invites: accepted invite user with invited_user_id \ - {invited_user_id} to service {invite_data['service_id']}" + {invited_user_id}" ) # We need to avoid taking a second trip through the login.gov code because we cannot pull the # access token twice. So once we retrieve these values, let's park them in redis for 15 minutes @@ -242,22 +257,29 @@ def set_up_your_profile(): current_app.logger.info("#invites: going to activate user") activate_user(user["id"]) current_app.logger.info(f"#invites: activated user with user.id {user['id']}") - usr = User.from_id(user["id"]) - usr.add_to_service( - invite_data["service_id"], - invite_data["permissions"], - invite_data["folder_permissions"], - invite_data["from_user_id"], - ) + if invite_data.get("service_id"): + usr = User.from_id(user["id"]) - # notify-admin-1766 - # redirect new users to templates area of new service instead of dashboard - service_id = invite_data["service_id"] - url = url_for(".service_dashboard", service_id=service_id) - url = f"{url}/templates" - current_app.logger.info(f"#invites redirecting to {url}") - return redirect(url) + usr.add_to_service( + invite_data["service_id"], + invite_data["permissions"], + invite_data["folder_permissions"], + invite_data["from_user_id"], + ) + + # notify-admin-1766 + # redirect new users to templates area of new service instead of dashboard + service_id = invite_data["service_id"] + url = url_for(".service_dashboard", service_id=service_id) + url = f"{url}/templates" + current_app.logger.info(f"#invites redirecting to {url}") + return redirect(url) + else: + org_id = invite_data["organization"] + url = url_for(".organization_dashboard", org_id=org_id) + current_app.logger.info(f"#invites redirecting to {url}") + return redirect(url) # we take two trips through this method, but should only hit this # line on the first trip. On the second trip, we should get redirected @@ -272,6 +294,13 @@ def get_invited_user_email_address(invited_user_id): return invited_user.email_address +def get_invited_org_user_email_address(invited_user_id): + # InvitedUser is an unhashable type and hard to mock in tests + # so this convenience method is a workaround for that + invited_user = InvitedOrgUser.by_id(invited_user_id) + return invited_user.email_address + + def invited_user_accept_invite(invited_user_id): invited_user = InvitedUser.by_id(invited_user_id) @@ -292,5 +321,27 @@ def invited_user_accept_invite(invited_user_id): invited_user.accept_invite() +def invited_org_user_accept_invite(invited_user_id): + invited_user = InvitedOrgUser.by_id(invited_user_id) + + current_app.logger.debug(hilite(f"INVITED ORG USER {invited_user.serialize()}")) + + if invited_user.status == InvitedUserStatus.EXPIRED: + current_app.logger.error("User invitation has expired") + flash( + "Your invitation has expired; please contact the person who invited you for additional help." + ) + abort(401, "Your invitation has expired #invites") + + if invited_user.status == InvitedUserStatus.CANCELLED: + current_app.logger.error("User invitation has been cancelled") + flash( + "Your invitation is no longer valid; please contact the person who invited you for additional help." + ) + abort(401, "Your invitation was canceled #invites") + + invited_user.accept_invite() + + def debug_msg(msg): current_app.logger.debug(hilite(msg)) diff --git a/app/models/user.py b/app/models/user.py index 1b04666fb..0ab0347de 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -255,9 +255,15 @@ class User(JSONModel, UserMixin): if org_id: value = self.belongs_to_organization(org_id) - current_app.logger.debug( - f"has_permissions returns org: {org_id} returning {value}" - ) + if not value: + + # TODO this is sketch! Fix this! + # This is temporary to restore org invite functionality only + self.add_to_organization(org_id) + value = self.belongs_to_organization(org_id) + current_app.logger.debug( + f"has_permissions returns org: {org_id} returning {value}" + ) return value if not permissions and self.belongs_to_service(service_id): @@ -317,6 +323,11 @@ class User(JSONModel, UserMixin): abort(403) def belongs_to_organization(self, organization_id): + + # TODO this is sketch! Fix this! + # This is temporary to restore org invite functionality only + if str(organization_id) not in self.organization_ids: + self.add_to_organization(organization_id) return str(organization_id) in self.organization_ids @property diff --git a/app/notify_client/org_invite_api_client.py b/app/notify_client/org_invite_api_client.py index d8b9c185d..1018fb637 100644 --- a/app/notify_client/org_invite_api_client.py +++ b/app/notify_client/org_invite_api_client.py @@ -53,7 +53,12 @@ class OrgInviteApiClient(NotifyAdminAPIClient): current_app.logger.debug(hilite(f"RESP is {resp}")) invite_data_key = f"invitedata-{unquote(state)}" - redis_invite_data = resp["invite"] + # For historical reasons 'invite' signifies a service invite + # and 'data' signifies an org invite + if resp.get("invite"): + redis_invite_data = resp["invite"] + else: + redis_invite_data = resp["data"] redis_invite_data = json.dumps(redis_invite_data) redis_client.set(invite_data_key, redis_invite_data, ex=ttl) current_app.logger.debug(