Пример #1
0
def test_delete_user_where_org_has_affiliations(session, auth_mock,
                                                keycloak_mock):  # pylint:disable=unused-argument
    """Assert that a user can be deleted."""
    user_model = factory_user_model(user_info=TestUserInfo.user_test)
    contact = factory_contact_model()
    contact_link = ContactLinkModel()
    contact_link.contact = contact
    contact_link.user = user_model
    contact_link = contact_link.flush()
    contact_link.commit()

    org = OrgService.create_org(TestOrgInfo.org1,
                                user_id=user_model.id).as_dict()
    org_id = org['id']

    entity = factory_entity_model(entity_info=TestEntityInfo.entity_lear_mock)

    affiliation = AffiliationModel(org_id=org_id, entity_id=entity.id)
    affiliation.save()
    with pytest.raises(BusinessException) as exception:
        UserService.delete_user(TestJwtClaims.user_test)
        assert exception.code == Error.DELETE_FAILED_ONLY_OWNER

    updated_user = UserModel.find_by_jwt_token(TestJwtClaims.user_test)
    contacts = UserService.get_contacts(TestJwtClaims.user_test)
    assert len(contacts) == 1

    user_orgs = MembershipModel.find_orgs_for_user(updated_user.id)
    for org in user_orgs:
        assert org.status_code == 'ACTIVE'
Пример #2
0
    def delete_org(
        org_id,
        token_info: Dict = None,
    ):
        """Soft-Deletes an Org.

        It should not be deletable if there are members or business associated with the org
        """
        # Check authorization for the user
        current_app.logger.debug('<org Inactivated')
        check_auth(token_info, one_of_roles=OWNER, org_id=org_id)

        org: OrgModel = OrgModel.find_by_org_id(org_id)
        if not org:
            raise BusinessException(Error.DATA_NOT_FOUND, None)

        count_members = len([
            member for member in org.members if member.status in VALID_STATUSES
        ])
        if count_members > 1 or len(org.affiliated_entities) >= 1:
            raise BusinessException(Error.ORG_CANNOT_BE_DISSOLVED, None)

        org.delete()

        # Remove user from thr group if the user doesn't have any other orgs membership
        user = UserModel.find_by_jwt_token(token=token_info)
        if len(MembershipModel.find_orgs_for_user(user.id)) == 0:
            KeycloakService.remove_from_account_holders_group(
                user.keycloak_guid)
        current_app.logger.debug('org Inactivated>')
Пример #3
0
 def _add_or_remove_group(model: MembershipModel):
     """Add or remove the user from/to account holders group."""
     if model.membership_status.id == Status.ACTIVE.value:
         KeycloakService.join_account_holders_group(model.user.keycloak_guid)
     elif model.membership_status.id == Status.INACTIVE.value and len(
             MembershipModel.find_orgs_for_user(model.user.id)) == 0:
         # Check if the user has any other active org membership, if none remove from the group
         KeycloakService.remove_from_account_holders_group(model.user.keycloak_guid)
Пример #4
0
    def _modify_task(user):
        """Clone on-hold task to a new active task; handle user-based and org-based tasks."""
        # find users org. ideally only one org
        org_list = MembershipModel.find_orgs_for_user(user.identifier)
        org: OrgModel = next(iter(org_list or []), None)
        if org:
            # check if there is any holding tasks
            # Find if the corresponding task is NEW_ACCOUNT_STAFF_REVIEW / GOVN type, clone and close it
            task_model: TaskModel = TaskModel.find_by_task_for_account(
                org.id, TaskStatus.HOLD.value)
            if task_model is None:
                # Else, find if there are any associated task of BCEID_ADMIN type, clone and close it
                task_model: TaskModel = TaskModel.find_by_user_and_status(
                    org.id, TaskStatus.HOLD.value)

            if task_model:
                task_info = {
                    'name':
                    org.name,
                    'relationshipId':
                    task_model.relationship_id,
                    'relatedTo':
                    user.identifier,
                    'dateSubmitted':
                    task_model.date_submitted,
                    'relationshipType':
                    task_model.relationship_type,
                    'type':
                    task_model.type,
                    'action':
                    task_model.action,
                    'status':
                    TaskStatus.OPEN.value,
                    'relationship_status':
                    TaskRelationshipStatus.PENDING_STAFF_REVIEW.value,
                    'account_id':
                    task_model.account_id
                }
                new_task = TaskService.create_task(task_info=task_info,
                                                   do_commit=False)

                # Send notification mail to staff review task
                from auth_api.services import Org as OrgService  # pylint:disable=cyclic-import, import-outside-toplevel
                if task_model.relationship_type == TaskRelationshipType.USER.value:
                    OrgService.send_staff_review_account_reminder(
                        relationship_id=user.identifier,
                        task_relationship_type=TaskRelationshipType.USER.value)
                else:
                    OrgService.send_staff_review_account_reminder(
                        relationship_id=org.id)

                remarks = [
                    f'User Uploaded New affidavit .Created New task id: {new_task.identifier}'
                ]
                TaskService.close_task(task_model.id, remarks)
Пример #5
0
    def get_orgs(user_id):
        """Return the orgs associated with this user."""
        # TODO DO_NOT_USE this def if there is a database transaction involved,
        # as the below logic removes object from model
        orgs = MembershipModel.find_orgs_for_user(user_id)
        # because members are fetched using backpopulates,cant add these conditions programmatically.
        # so resorting to manually looping   # noqa:E501

        for org in orgs:
            # user can have multiple memberships.if the user getting denied first and added again,
            # it will be multiple memberships..filter out denied records # noqa:E501
            # fix for https://github.com/bcgov/entity/issues/1951   # noqa:E501
            org.members = list(
                filter(lambda member: (member.user_id == user_id and (member.status in VALID_STATUSES)), org.members))
        return orgs
Пример #6
0
    def delete_user(token):
        """Delete User Profile.

        Does the following
        1) Find the user using token
        2) Find all org membership for the user
        3) Check if the current user is the only owner for any org - If yes, deny the action
        4) Mark the membership as inactive on all orgs for the user
        5) Delete the contact information for the user and the accepted terms of service
        6) Mark the user record as inactive
        """
        current_app.logger.debug('<delete_user')

        user: UserModel = UserModel.find_by_jwt_token(token)
        if not user:
            raise BusinessException(Error.DATA_NOT_FOUND, None)
        if user.status == UserStatus.INACTIVE.value:
            raise BusinessException(Error.DELETE_FAILED_INACTIVE_USER, None)

        user_orgs: List[OrgModel] = MembershipModel.find_orgs_for_user(user.id)

        current_app.logger.info('Found {} orgs for the user'.format(
            len(user_orgs) if user_orgs else 0))

        if user_orgs:
            for org in user_orgs:
                current_app.logger.debug(
                    f'Org : {org.name},  Status : {org.status_code}')
                if org.status_code == Status.ACTIVE.name:
                    User.__remove_org_membership(org, user.id)

        # Delete contact
        User.__delete_contact(user=user)

        # Set the user status as inactive
        user.status = UserStatus.INACTIVE.value

        # Remove accepted terms
        user.terms_of_use_accepted_version = None
        user.terms_of_use_version = None
        user.is_terms_of_use_accepted = False

        user.save()

        # Remove user from account_holders group
        KeycloakService.remove_from_account_holders_group(user.keycloak_guid)

        current_app.logger.debug('<delete_user')
Пример #7
0
def test_delete_user_where_org_has_another_owner(session, auth_mock,
                                                 keycloak_mock, monkeypatch):  # pylint:disable=unused-argument
    """Assert that a user can be deleted."""
    # Create a user and org
    user_model = factory_user_model(user_info=TestUserInfo.user_test)
    contact = factory_contact_model()
    contact_link = ContactLinkModel()
    contact_link.contact = contact
    contact_link.user = user_model
    contact_link.commit()

    patch_token_info(TestJwtClaims.get_test_user(user_model.keycloak_guid),
                     monkeypatch)
    org = OrgService.create_org(TestOrgInfo.org1, user_id=user_model.id)
    org_dictionary = org.as_dict()
    org_id = org_dictionary['id']

    entity = factory_entity_model(entity_info=TestEntityInfo.entity_lear_mock)
    affiliation = AffiliationModel(org_id=org_id, entity_id=entity.id)
    affiliation.save()

    # Create another user and add membership to the above org
    user_model2 = factory_user_model(user_info=TestUserInfo.user2)
    contact = factory_contact_model()
    contact_link = ContactLinkModel()
    contact_link.contact = contact
    contact_link.user = user_model2
    contact_link.commit()

    membership = MembershipModel(org_id=org_id,
                                 user_id=user_model2.id,
                                 membership_type_code='ADMIN',
                                 membership_type_status=Status.ACTIVE.value)
    membership.save()
    membership.commit()

    # with pytest.raises(BusinessException) as exception:
    patch_token_info(TestJwtClaims.get_test_user(user_model2.keycloak_guid),
                     monkeypatch)
    UserService.delete_user()

    updated_user = UserModel.find_by_jwt_token()
    assert len(updated_user.contacts) == 0

    user_orgs = MembershipModel.find_orgs_for_user(updated_user.id)
    for org in user_orgs:
        assert org.status_code == 'INACTIVE'
Пример #8
0
def test_delete_user(session, auth_mock):  # pylint:disable=unused-argument
    """Assert that a user can be deleted."""
    user_model = factory_user_model(user_info=TestUserInfo.user_test)
    contact = factory_contact_model()
    contact_link = ContactLinkModel()
    contact_link.contact = contact
    contact_link.user = user_model
    contact_link.commit()

    org = OrgService.create_org(TestOrgInfo.org1, user_id=user_model.id)

    UserService.delete_user(TestJwtClaims.user_test)
    updated_user = UserModel.find_by_jwt_token(TestJwtClaims.user_test)
    assert len(updated_user.contacts) == 0

    user_orgs = MembershipModel.find_orgs_for_user(updated_user.id)
    for org in user_orgs:
        assert org.status_code == 'INACTIVE'
Пример #9
0
    def _modify_task(user):
        # find users org. ideally only one org
        org_list = MembershipModel.find_orgs_for_user(user.identifier)
        org: OrgModel = next(iter(org_list or []), None)
        if org:
            # check if there is any holding tasks
            task_model: TaskModel = TaskModel.find_by_task_for_account(
                org.id, TaskStatus.HOLD.value)
            if task_model:
                task_type = TaskTypePrefix.NEW_ACCOUNT_STAFF_REVIEW.value
                task_info = {
                    'name':
                    org.name,
                    'relationshipId':
                    org.id,
                    'relatedTo':
                    user.identifier,
                    'dateSubmitted':
                    task_model.date_submitted,
                    'relationshipType':
                    TaskRelationshipType.ORG.value,
                    'type':
                    task_type,
                    'status':
                    TaskStatus.OPEN.value,
                    'relationship_status':
                    TaskRelationshipStatus.PENDING_STAFF_REVIEW.value
                }
                new_task = TaskService.create_task(task_info=task_info,
                                                   do_commit=False)

                # Send notification mail to staff review task
                from auth_api.services import Org as OrgService  # pylint:disable=cyclic-import, import-outside-toplevel
                OrgService.send_staff_review_account_reminder(
                    relationship_id=org.id)

                remark = f'User Uploaded New affidavit .Created New task id: {new_task.identifier}'
                TaskService.close_task(task_model.id, remark)
Пример #10
0
    def delete_org(
        org_id,
        token_info: Dict = None,
    ):
        """Soft-Deletes an Org.

        It should not be deletable if there are members or business associated with the org
        """
        # Check authorization for the user
        current_app.logger.debug('<org Inactivated')
        check_auth(token_info, one_of_roles=(ADMIN, STAFF), org_id=org_id)

        org: OrgModel = OrgModel.find_by_org_id(org_id)
        if not org:
            raise BusinessException(Error.DATA_NOT_FOUND, None)

        count_members = len([
            member for member in org.members if member.status in VALID_STATUSES
        ])
        if count_members > 1 or len(org.affiliated_entities) >= 1:
            raise BusinessException(Error.ORG_CANNOT_BE_DISSOLVED, None)

        org.status_code = OrgStatus.INACTIVE.value
        org.save()

        # Don't remove account if it's staff who deactivate org.
        is_staff_admin = token_info and Role.STAFF_CREATE_ACCOUNTS.value in token_info.get(
            'realm_access').get('roles')
        if not is_staff_admin:
            # Remove user from thr group if the user doesn't have any other orgs membership
            user = UserModel.find_by_jwt_token(token=token_info)
            if len(MembershipModel.find_orgs_for_user(user.id)) == 0:
                KeycloakService.remove_from_account_holders_group(
                    user.keycloak_guid)

        current_app.logger.debug('org Inactivated>')
Пример #11
0
 def get_orgs(user_id, valid_statuses=VALID_STATUSES):
     """Return the orgs associated with this user."""
     return MembershipModel.find_orgs_for_user(user_id, valid_statuses)
Пример #12
0
    def delete_org(org_id):
        """Soft-Deletes an Org.

        Only admin can perform this.
        1 - All businesses gets unaffiliated.
        2 - All team members removed.
        3 - If there is any credit on the account then cannot be deleted.

        Premium:
        1 - If there is any active PAD transactions going on, then cannot be deleted.

        """
        current_app.logger.debug(f'<Delete Org {org_id}')
        # Affiliation uses OrgService, adding as local import
        # pylint:disable=import-outside-toplevel, cyclic-import
        from auth_api.services.affiliation import Affiliation as AffiliationService

        check_auth(one_of_roles=(ADMIN, STAFF), org_id=org_id)

        org: OrgModel = OrgModel.find_by_org_id(org_id)
        if not org:
            raise BusinessException(Error.DATA_NOT_FOUND, None)
        if org.status_code not in (OrgStatus.ACTIVE.value,
                                   OrgStatus.PENDING_INVITE_ACCEPT.value):
            raise BusinessException(Error.NOT_ACTIVE_ACCOUNT, None)

        # Deactivate pay account
        Org._delete_pay_account(org_id)

        # Find all active affiliations and remove them.
        entities = AffiliationService.find_affiliations_by_org_id(org_id)
        for entity in entities:
            AffiliationService.delete_affiliation(
                org_id=org_id,
                business_identifier=entity['business_identifier'],
                reset_passcode=True)

        # Deactivate all members.
        members = MembershipModel.find_members_by_org_id(org_id)
        for member in members:
            member.status = Status.INACTIVE.value
            member.flush()

            user: UserModel = UserModel.find_by_id(member.user_id)
            # Remove user from keycloak group if they are not part of any orgs
            if len(MembershipModel.find_orgs_for_user(member.user_id)) == 0:
                KeycloakService.remove_from_account_holders_group(
                    user.keycloak_guid)

            # If the admin is BCeID user, mark the affidavit INACTIVE.
            if user.login_source == LoginSource.BCEID.value and member.membership_type_code == ADMIN:
                affidavit: AffidavitModel = AffidavitModel.find_approved_by_user_id(
                    user.id)
                if affidavit:
                    affidavit.status_code = AffidavitStatus.INACTIVE.value
                    affidavit.flush()

        # Set the account as INACTIVE
        org.status_code = OrgStatus.INACTIVE.value
        org.save()

        current_app.logger.debug('org Inactivated>')