def test_find_user_authorization_by_business_number_and_corp_type_multiple_membership( session): # pylint:disable=unused-argument """Assert that authorization view returns result when fetched using Corp type instead of jwt. When multiple membership is present , return the one with Owner access """ user1 = factory_user_model() user2 = factory_user_model(user_info=TestUserInfo.user2) org = factory_org_model() factory_membership_model(user1.id, org.id, member_type='COORDINATOR') membership_owner = factory_membership_model(user2.id, org.id) entity = factory_entity_model() factory_affiliation_model(entity.id, org.id) authorization = Authorization.find_user_authorization_by_business_number_and_corp_type( entity.business_identifier, 'CP') assert authorization is not None assert authorization.org_membership == membership_owner.membership_type_code
def test_create_user_and_add_membership_admin_skip_auth_mode( session, auth_mock, keycloak_mock): # pylint:disable=unused-argument """Assert that an admin can be added as anonymous.""" org = factory_org_model(org_info=TestOrgInfo.org_anonymous) membership = [TestAnonymousMembership.generate_random_user(COORDINATOR)] users = UserService.create_user_and_add_membership(membership, org.id, single_mode=True) assert len(users['users']) == 1 assert users['users'][0][ 'username'] == IdpHint.BCROS.value + '/' + membership[0]['username'] assert users['users'][0]['type'] == Role.ANONYMOUS_USER.name members = MembershipModel.find_members_by_org_id(org.id) # only one member should be there since its a STAFF created org assert len(members) == 1 assert members[0].membership_type_code == COORDINATOR
def test_check_auth_for_service_account_valid_with_business_id(session): # pylint:disable=unused-argument """Assert that check_auth is working as expected.""" user = factory_user_model() org = factory_org_model() factory_membership_model(user.id, org.id) factory_product_model(org.id, product_code=ProductCode.BUSINESS.value) entity = factory_entity_model() factory_affiliation_model(entity.id, org.id) # Test for service account with CP corp type check_auth( { 'realm_access': { 'roles': ['system'] }, 'product_code': ProductCode.BUSINESS.value }, business_identifier=entity.business_identifier)
def test_reset_password(session, auth_mock, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert that the password can be changed.""" org = factory_org_model(org_info=TestOrgInfo.org_anonymous) user = factory_user_model() factory_membership_model(user.id, org.id) factory_product_model(org.id, product_code=ProductCode.DIR_SEARCH.value) claims = TestJwtClaims.get_test_real_user(user.keycloak_guid) patch_token_info(claims, monkeypatch) membership = [TestAnonymousMembership.generate_random_user(USER)] users = UserService.create_user_and_add_membership(membership, org.id) user_name = users['users'][0]['username'] user_info = {'username': user_name, 'password': '******'} kc_user = UserService.reset_password_for_anon_user(user_info, user_name) # cant assert anything else since password wont be gotten back assert kc_user.user_name == user_name.replace(f'{IdpHint.BCROS.value}/', '').lower()
def test_reset_password_by_member(session, auth_mock, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert that the password cant be changed by member.""" org = factory_org_model(org_info=TestOrgInfo.org_anonymous) user = factory_user_model() factory_membership_model(user.id, org.id) factory_product_model(org.id, product_code=ProductCode.DIR_SEARCH.value) admin_claims = TestJwtClaims.get_test_real_user(user.keycloak_guid) membership = [TestAnonymousMembership.generate_random_user(USER)] patch_token_info(admin_claims, monkeypatch) users = UserService.create_user_and_add_membership(membership, org.id) user_name = users['users'][0]['username'] user_info = {'username': user_name, 'password': '******'} with pytest.raises(HTTPException) as excinfo: patch_token_info(TestJwtClaims.public_user_role, monkeypatch) UserService.reset_password_for_anon_user(user_info, user_name) assert excinfo.exception.code == 403
def test_delete_otp_for_user(session, auth_mock, keycloak_mock): """Assert that the otp cant be reset.""" kc_service = KeycloakService() org = factory_org_model(org_info=TestOrgInfo.org_anonymous) admin_user = factory_user_model() factory_membership_model(admin_user.id, org.id) admin_claims = TestJwtClaims.get_test_real_user(admin_user.keycloak_guid) membership = [TestAnonymousMembership.generate_random_user(USER)] keycloak_service = KeycloakService() request = KeycloakScenario.create_user_request() request.user_name = membership[0]['username'] keycloak_service.add_user(request) user = kc_service.get_user_by_username(request.user_name) user = factory_user_model(TestUserInfo.get_bceid_user_with_kc_guid(user.id)) factory_membership_model(user.id, org.id) UserService.delete_otp_for_user(user.username, admin_claims) user1 = kc_service.get_user_by_username(request.user_name) assert 'CONFIGURE_TOTP' in json.loads(user1.value()).get('requiredActions')
def test_authorizations_for_account_returns_200(app, client, jwt, session): # pylint:disable=unused-argument """Assert authorizations for product returns 200.""" product_code = 'PPR' user = factory_user_model() org = factory_org_model() factory_membership_model(user.id, org.id) claims = copy.deepcopy(TestJwtClaims.edit_role.value) claims['sub'] = str(user.keycloak_guid) headers = factory_auth_header(jwt=jwt, claims=claims) rv = client.get( f'/api/v1/accounts/{org.id}/products/{product_code}/authorizations', headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_200_OK assert len(rv.json.get('roles')) == 0
def test_get_user_authorizations(session): # pylint:disable=unused-argument """Assert that listing all user authorizations is working.""" user = factory_user_model() org = factory_org_model() membership = factory_membership_model(user.id, org.id) entity = factory_entity_model() factory_affiliation_model(entity.id, org.id) authorization = Authorization.get_user_authorizations( str(user.keycloak_guid)) assert authorization is not None assert authorization['authorizations'][0].get( 'orgMembership', None) == membership.membership_type_code # Test with invalid user authorization = Authorization.get_user_authorizations(str(uuid.uuid4())) assert authorization is not None assert len(authorization['authorizations']) == 0
def test_get_user_authorizations_for_entity_service_account(session): """Assert that user authorizations for entity is working.""" user = factory_user_model() org = factory_org_model() factory_membership_model(user.id, org.id) factory_product_model(org.id, product_code=ProductCode.BUSINESS.value) entity = factory_entity_model() factory_affiliation_model(entity.id, org.id) # Test for service accounts with correct product code authorization = Authorization.get_user_authorizations_for_entity( { 'loginSource': '', 'realm_access': { 'roles': ['system'] }, 'product_code': ProductCode.BUSINESS.value }, entity.business_identifier) assert bool(authorization) is True assert authorization.get('orgMembership', None) == 'ADMIN' # Test for service accounts with wrong product code authorization = Authorization.get_user_authorizations_for_entity( { 'loginSource': '', 'realm_access': { 'roles': ['system'] }, 'product_code': 'INVALIDCP' }, entity.business_identifier) assert bool(authorization) is False assert authorization.get('orgMembership', None) is None # Test for service accounts with no product code authorization = Authorization.get_user_authorizations_for_entity( { 'loginSource': '', 'realm_access': { 'roles': ['system'] } }, entity.business_identifier) assert bool(authorization) is False assert authorization.get('orgMembership', None) is None
def test_create_user_and_add_membership_admin_bulk_mode(session, auth_mock, keycloak_mock): # pylint:disable=unused-argument """Assert that an admin can add a member.""" org = factory_org_model(org_info=TestOrgInfo.org_anonymous) user = factory_user_model() factory_membership_model(user.id, org.id) factory_product_model(org.id, product_code=ProductCode.DIR_SEARCH.value) claims = TestJwtClaims.get_test_real_user(user.keycloak_guid) membership = [TestAnonymousMembership.generate_random_user(USER)] users = UserService.create_user_and_add_membership(membership, org.id, token_info=claims) assert len(users['users']) == 1 assert users['users'][0]['username'] == IdpHint.BCROS.value + '/' + membership[0]['username'] assert users['users'][0]['type'] == Role.ANONYMOUS_USER.name members = MembershipModel.find_members_by_org_id(org.id) # staff didnt create members..so count is count of owner+other 1 member assert len(members) == 2
def test_authorizations_for_affiliated_users_returns_200(client, jwt, session): # pylint:disable=unused-argument """Assert authorizations for affiliated users returns 200.""" user = factory_user_model() org = factory_org_model() factory_membership_model(user.id, org.id) entity = factory_entity_model() factory_affiliation_model(entity.id, org.id) claims = copy.deepcopy(TestJwtClaims.edit_user_role.value) claims['sub'] = str(user.keycloak_guid) headers = factory_auth_header(jwt=jwt, claims=claims) rv = client.get( f'/api/v1/entities/{entity.business_identifier}/authorizations', headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_200_OK assert rv.json.get('orgMembership') == 'OWNER'
def test_authorizations_for_extended_returns_200(app, client, jwt, session): # pylint:disable=unused-argument """Assert authorizations for product returns 200.""" product_code = 'PPR' user = factory_user_model() org = factory_org_model() factory_membership_model(user.id, org.id) factory_product_model(org.id) claims = copy.deepcopy(TestJwtClaims.public_user_role.value) claims['sub'] = str(user.keycloak_guid) headers = factory_auth_header(jwt=jwt, claims=claims) rv = client.get(f'/api/v1/accounts/{org.id}/products/{product_code}/authorizations?expanded=true', headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_200_OK assert schema_utils.validate(rv.json, 'account_response')[0] assert len(rv.json.get('roles')) > 0 assert rv.json.get('account').get('name') == org.name
def test_get_user_authorizations_for_entity_service_account(session): """Assert that user authorizations for entity is working.""" user = factory_user_model() org = factory_org_model() factory_membership_model(user.id, org.id) entity = factory_entity_model() factory_affiliation_model(entity.id, org.id) # Test for service accounts with correct corp type authorization = Authorization.get_user_authorizations_for_entity( { 'loginSource': '', 'realm_access': { 'roles': ['system'] }, 'corp_type': 'CP' }, entity.business_identifier) assert bool(authorization) is True assert authorization.get('orgMembership', None) == 'OWNER' # Test for service accounts with wrong corp type authorization = Authorization.get_user_authorizations_for_entity( { 'loginSource': '', 'realm_access': { 'roles': ['system'] }, 'corp_type': 'INVALIDCP' }, entity.business_identifier) assert bool(authorization) is False assert authorization.get('orgMembership', None) is None # Test for service accounts with no corp type authorization = Authorization.get_user_authorizations_for_entity( { 'loginSource': '', 'realm_access': { 'roles': ['system'] } }, entity.business_identifier) assert bool(authorization) is False assert authorization.get('orgMembership', None) is None
def test_create_task_org(session, keycloak_mock): # pylint:disable=unused-argument """Assert that a task can be created.""" user = factory_user_model() test_org = factory_org_model() task_type_new_account = TaskTypePrefix.NEW_ACCOUNT_STAFF_REVIEW.value test_task_info = { 'name': test_org.name, 'relationshipId': test_org.id, 'relatedTo': user.id, 'dateSubmitted': datetime.today(), 'relationshipType': TaskRelationshipType.ORG.value, 'type': task_type_new_account, 'status': TaskStatus.OPEN.value, 'relationship_status': TaskRelationshipStatus.PENDING_STAFF_REVIEW.value } task = TaskService.create_task(test_task_info) assert task dictionary = task.as_dict() assert dictionary['name'] == test_org.name
def test_reset_bceid_user(session, auth_mock): # pylint: disable=unused-argument """Assert that reset data from a bceid user.""" keycloak_service = KeycloakService() request = KeycloakScenario.create_user_by_user_info( TestJwtClaims.tester_bceid_role) keycloak_service.add_user(request, return_if_exists=True) user = keycloak_service.get_user_by_username(request.user_name) assert user is not None user_id = user.id user_with_token = TestUserInfo.user_bceid_tester user_with_token['keycloak_guid'] = user_id user = factory_user_model(user_info=user_with_token) org = factory_org_model(user_id=user.id) response = ResetDataService.reset( TestJwtClaims.get_test_user(user_id, 'BCEID')) assert response is None found_org = OrgService.find_by_org_id(org.id) assert found_org is None
def test_add_back_a_delete_bcros(client, jwt, session, keycloak_mock): """Assert different conditions of user deletion.""" org = factory_org_model(org_info=TestOrgInfo.org_anonymous) user = factory_user_model(user_info=TestUserInfo.user_bcros_active) factory_membership_model(user.id, org.id) owner_claims = TestJwtClaims.get_test_real_user(user.keycloak_guid) member = TestAnonymousMembership.generate_random_user(MEMBER) membership = [member, TestAnonymousMembership.generate_random_user(ADMIN)] UserService.create_user_and_add_membership(membership, org.id, token_info=owner_claims) headers = factory_auth_header(jwt=jwt, claims=owner_claims) member_user_id = IdpHint.BCROS.value + '/' + member.get('username') rv = client.delete(f'/api/v1/users/{member_user_id}', headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_204_NO_CONTENT kc_user = KeycloakService.get_user_by_username(member.get('username')) assert kc_user.enabled is False user_model = UserService.find_by_username(member_user_id) assert user_model.as_dict().get('userStatus') == UserStatus.INACTIVE.value membership = MembershipModel.find_membership_by_userid(user_model.identifier) assert membership.status == Status.INACTIVE.value
def test_get_user_authorizations_for_entity(session, monkeypatch): # pylint:disable=unused-argument """Assert that user authorizations for entity is working.""" user = factory_user_model() org = factory_org_model() membership = factory_membership_model(user.id, org.id) entity = factory_entity_model() factory_affiliation_model(entity.id, org.id) patch_token_info({ 'sub': str(user.keycloak_guid), 'realm_access': { 'roles': ['basic'] }}, monkeypatch) authorization = Authorization.get_user_authorizations_for_entity(entity.business_identifier) assert authorization is not None assert authorization.get('orgMembership', None) == membership.membership_type_code # Test with invalid user patch_token_info({'sub': str(uuid.uuid4()), 'realm_access': { 'roles': ['basic'] }}, monkeypatch) authorization = Authorization.get_user_authorizations_for_entity(entity.business_identifier) assert authorization is not None assert authorization.get('orgMembership', None) is None # Test for passcode users with invalid username patch_token_info({'loginSource': 'PASSCODE', 'username': '******', 'realm_access': { 'roles': ['basic'] }}, monkeypatch) authorization = Authorization.get_user_authorizations_for_entity(entity.business_identifier) assert authorization is not None assert authorization.get('orgMembership', None) is None # Test for staff users patch_token_info( {'loginSource': '', 'realm_access': {'roles': ['staff']}}, monkeypatch) authorization = Authorization.get_user_authorizations_for_entity(entity.business_identifier) assert authorization is not None assert authorization.get('orgMembership', None) is None
def test_get_user_authorizations_for_org(session): # pylint:disable=unused-argument """Assert that user authorizations for entity is working.""" user = factory_user_model() org = factory_org_model() membership = factory_membership_model(user.id, org.id) authorization = Authorization.get_account_authorizations_for_org( { 'sub': str(user.keycloak_guid), 'realm_access': { 'roles': ['basic'] } }, org.id, ProductCode.BUSINESS.value) assert authorization is not None assert authorization.get('orgMembership', None) == membership.membership_type_code assert authorization.get('roles') is not None authorization = Authorization.get_account_authorizations_for_org( { 'sub': str(user.keycloak_guid), 'realm_access': { 'roles': ['basic'] } }, org.id, ProductCode.NAMES_REQUEST.value) assert authorization is not None assert authorization.get('orgMembership', None) == membership.membership_type_code assert authorization.get('roles') is not None authorization = Authorization.get_account_authorizations_for_org( { 'sub': str(user.keycloak_guid), 'realm_access': { 'roles': ['basic'] } }, org.id, ProductCode.VS.value) assert authorization is not None assert authorization.get('orgMembership') is None assert len(authorization.get('roles')) == 0
def test_create_user_and_add_transaction_membership_1(session, auth_mock, keycloak_mock): # pylint:disable=unused-argument """Assert transactions works fine.""" org = factory_org_model(org_info=TestOrgInfo.org_anonymous) membership = [TestAnonymousMembership.generate_random_user(ADMIN)] with patch('auth_api.models.User.flush', side_effect=Exception('mocked error')): users = UserService.create_user_and_add_membership(membership, org.id, single_mode=True) user_name = IdpHint.BCROS.value + '/' + membership[0]['username'] assert len(users['users']) == 1 assert users['users'][0]['username'] == membership[0]['username'] assert users['users'][0]['http_status'] == 500 assert users['users'][0]['error'] == 'Adding User Failed' # make sure no records are created user = UserModel.find_by_username(user_name) assert user is None user = UserModel.find_by_username(membership[0]['username']) assert user is None members = MembershipModel.find_members_by_org_id(org.id) # only one member should be there since its a STAFF created org assert len(members) == 0
def test_authorizations_expanded_for_staff(client, jwt, session): # pylint:disable=unused-argument """Assert expanded authorizations for staff user returns result.""" user = factory_user_model() org = factory_org_model() factory_membership_model(user.id, org.id) entity = factory_entity_model() factory_affiliation_model(entity.id, org.id) claims = copy.deepcopy(TestJwtClaims.edit_user_role.value) claims['sub'] = str(user.keycloak_guid) headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.staff_role) rv = client.get( f'/api/v1/entities/{entity.business_identifier}/authorizations?expanded=true', headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_200_OK assert rv.json.get('account') is not None assert rv.json.get('account').get('name') == org.name assert rv.json.get('business').get('name') == entity.name assert rv.json.get('business').get('folioNumber') == entity.folio_number
def test_add_user_adds_to_account_holders_group(client, jwt, session): # pylint:disable=unused-argument """Assert that a user gets added to account_holders group if the user has any active account.""" # Create a user in keycloak request = KeycloakScenario.create_user_request() KEYCLOAK_SERVICE.add_user(request, return_if_exists=True) user = KEYCLOAK_SERVICE.get_user_by_username(request.user_name) user_id = user.id # Create user, org and membserhip in DB user = factory_user_model(TestUserInfo.get_user_with_kc_guid(user_id)) org = factory_org_model(org_status_info=None) factory_membership_model(user.id, org.id) # Login as that user headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.get_test_user(user_id, source='BCSC')) client.post('/api/v1/users', headers=headers, content_type='application/json') user_groups = KEYCLOAK_SERVICE.get_user_groups(user_id=user_id) groups = [] for group in user_groups: groups.append(group.get('name')) assert GROUP_ACCOUNT_HOLDERS in groups
def test_reset(session, auth_mock): # pylint: disable=unused-argument """Assert that can be reset data by the provided token.""" user_with_token = TestUserInfo.user_tester user_with_token['keycloak_guid'] = TestJwtClaims.tester_role['sub'] user = factory_user_model(user_info=user_with_token) org = factory_org_model(user_id=user.id) factory_membership_model(user.id, org.id) entity = factory_entity_model(user_id=user.id) ResetDataService.reset(TestJwtClaims.tester_role) with pytest.raises(BusinessException) as exception: UserService.find_by_jwt_token(user_with_token) assert exception.value.code == Error.DATA_NOT_FOUND.name found_org = OrgService.find_by_org_id(org.id) assert found_org is None found_entity = EntityService.find_by_entity_id(entity.id) assert found_entity is None found_memeber = MembershipService.get_members_for_org(org.id) assert found_memeber is None
def test_user_authorizations_returns_200(client, jwt, session): # pylint:disable=unused-argument """Assert authorizations for users returns 200.""" user = factory_user_model() org = factory_org_model() factory_membership_model(user.id, org.id) entity = factory_entity_model() factory_affiliation_model(entity.id, org.id) claims = copy.deepcopy(TestJwtClaims.public_user_role.value) claims['sub'] = str(user.keycloak_guid) headers = factory_auth_header(jwt=jwt, claims=claims) rv = client.get('/api/v1/users/authorizations', headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_200_OK assert rv.json.get('authorizations')[0].get('orgMembership') == 'ADMIN' # Test with invalid user claims['sub'] = str(uuid.uuid4()) headers = factory_auth_header(jwt=jwt, claims=claims) rv = client.get('/api/v1/users/authorizations', headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_200_OK assert len(rv.json.get('authorizations')) == 0
def test_check_auth(session, monkeypatch): # pylint:disable=unused-argument """Assert that check_auth is working as expected.""" user = factory_user_model() org = factory_org_model() factory_membership_model(user.id, org.id) factory_product_model(org.id, product_code=ProductCode.BUSINESS.value) entity = factory_entity_model() factory_affiliation_model(entity.id, org.id) # Test if staff admin can access to STAFF only method patch_token_info({'realm_access': {'roles': ['staff', 'create_accounts']}, 'sub': str(user.keycloak_guid)}, monkeypatch) check_auth(one_of_roles=[STAFF]) # Test for staff admin role to only STAFF patch_token_info({'realm_access': {'roles': ['staff', 'create_accounts']}, 'sub': str(user.keycloak_guid)}, monkeypatch) check_auth(equals_role=STAFF) # Test for staff role patch_token_info({'realm_access': {'roles': ['staff']}, 'sub': str(user.keycloak_guid), 'product_code': ProductCode.BUSINESS.value}, monkeypatch) check_auth(one_of_roles=[STAFF]) # Test for owner role patch_token_info({'realm_access': {'roles': ['public']}, 'sub': str(user.keycloak_guid), 'product_code': ProductCode.BUSINESS.value}, monkeypatch) check_auth(one_of_roles=[ADMIN], business_identifier=entity.business_identifier) # Test for owner role with org id patch_token_info({'realm_access': {'roles': ['public']}, 'sub': str(user.keycloak_guid), 'product_code': ProductCode.BUSINESS.value}, monkeypatch) check_auth(one_of_roles=[ADMIN], org_id=org.id) # Test for exception, check for auth if resource is available for STAFF users with pytest.raises(HTTPException) as excinfo: patch_token_info({'realm_access': {'roles': ['public']}, 'sub': str(user.keycloak_guid)}, monkeypatch) check_auth(one_of_roles=[STAFF], business_identifier=entity.business_identifier) assert excinfo.exception.code == 403 # Test auth where STAFF role is in disabled role list with pytest.raises(HTTPException) as excinfo: patch_token_info({'realm_access': {'roles': ['staff']}, 'sub': str(user.keycloak_guid)}, monkeypatch) check_auth(disabled_roles=[STAFF], business_identifier=entity.business_identifier) assert excinfo.exception.code == 403 # Test auth where STAFF role is exact match with pytest.raises(HTTPException) as excinfo: patch_token_info({'realm_access': {'roles': ['public']}, 'sub': str(user.keycloak_guid)}, monkeypatch) check_auth(equals_role=USER, business_identifier=entity.business_identifier) assert excinfo.exception.code == 403 # Test auth where STAFF role is exact match with pytest.raises(HTTPException) as excinfo: patch_token_info({'realm_access': {'roles': ['public']}, 'sub': str(user.keycloak_guid)}, monkeypatch) check_auth(equals_role=USER, org_id=org.id) assert excinfo.exception.code == 403 # Test auth where STAFF role is exact match with pytest.raises(HTTPException) as excinfo: patch_token_info({'realm_access': {'roles': ['staff', 'create_accounts']}, 'sub': str(user.keycloak_guid)}, monkeypatch) check_auth(equals_role=USER, org_id=org.id) assert excinfo.exception.code == 403
def test_reset_password(client, jwt, session, keycloak_mock): # pylint:disable=unused-argument """Assert that an anonymous admin can be Patched.""" org = factory_org_model(org_info=TestOrgInfo.org_anonymous) user = factory_user_model(user_info=TestUserInfo.user_bcros_active) factory_membership_model(user.id, org.id) factory_product_model(org.id, product_code=ProductCode.DIR_SEARCH.value) owner_claims = TestJwtClaims.get_test_real_user(user.keycloak_guid) member = TestAnonymousMembership.generate_random_user(USER) admin = TestAnonymousMembership.generate_random_user(COORDINATOR) membership = [member, admin] UserService.create_user_and_add_membership(membership, org.id, token_info=owner_claims) owner_headers = factory_auth_header(jwt=jwt, claims=owner_claims) member_username = IdpHint.BCROS.value + '/' + member['username'] admin_username = IdpHint.BCROS.value + '/' + admin['username'] admin_claims = TestJwtClaims.get_test_real_user( uuid.uuid4(), admin_username, access_ype=AccessType.ANONYMOUS.value, roles=[Role.ANONYMOUS_USER.value]) admin_headers = factory_auth_header(jwt=jwt, claims=admin_claims) member_claims = TestJwtClaims.get_test_real_user( uuid.uuid4(), member_username, access_ype=AccessType.ANONYMOUS.value, roles=[Role.ANONYMOUS_USER.value]) member_headers = factory_auth_header(jwt=jwt, claims=member_claims) # set up JWTS for member and admin client.post('/api/v1/users', headers=admin_headers, content_type='application/json') client.post('/api/v1/users', headers=member_headers, content_type='application/json') # reset password of admin by owner input_data = json.dumps({ 'username': admin_username, 'password': '******' }) rv = client.patch(f'/api/v1/users/{admin_username}', headers=owner_headers, data=input_data, content_type='application/json') assert rv.status_code == http_status.HTTP_204_NO_CONTENT # member cant reset password rv = client.patch(f'/api/v1/users/{admin_username}', headers=member_headers, data=input_data, content_type='application/json') assert rv.status_code == http_status.HTTP_403_FORBIDDEN # admin cant reset password rv = client.patch(f'/api/v1/users/{admin_username}', headers=admin_headers, data=input_data, content_type='application/json') assert rv.status_code == http_status.HTTP_403_FORBIDDEN
def test_check_auth(session): # pylint:disable=unused-argument """Assert that check_auth is working as expected.""" user = factory_user_model() org = factory_org_model() factory_membership_model(user.id, org.id) entity = factory_entity_model() factory_affiliation_model(entity.id, org.id) # Test if staff admin can access to STAFF only method check_auth( { 'realm_access': { 'roles': ['staff_admin'] }, 'sub': str(user.keycloak_guid) }, one_of_roles=[STAFF]) # Test for staff admin can access to STAFF_ADMIN method check_auth( { 'realm_access': { 'roles': ['staff_admin'] }, 'sub': str(user.keycloak_guid) }, one_of_roles=[STAFF_ADMIN]) # Test for staff admin role can access to STAFF_ADMIN and STAFF method check_auth( { 'realm_access': { 'roles': ['staff_admin'] }, 'sub': str(user.keycloak_guid) }, one_of_roles=[STAFF_ADMIN, STAFF]) # Test for staff admin role can access to only STAFF_ADMIN check_auth( { 'realm_access': { 'roles': ['staff_admin'] }, 'sub': str(user.keycloak_guid) }, equals_role=STAFF_ADMIN) # Test for staff admin role to only STAFF check_auth( { 'realm_access': { 'roles': ['staff_admin'] }, 'sub': str(user.keycloak_guid) }, equals_role=STAFF) # Test for staff role check_auth( { 'realm_access': { 'roles': ['staff'] }, 'sub': str(user.keycloak_guid) }, one_of_roles=[STAFF]) # Test for owner role check_auth( { 'realm_access': { 'roles': ['public'] }, 'sub': str(user.keycloak_guid) }, one_of_roles=[OWNER], business_identifier=entity.business_identifier) # Test for owner role with org id check_auth( { 'realm_access': { 'roles': ['public'] }, 'sub': str(user.keycloak_guid) }, one_of_roles=[OWNER], org_id=org.id) # Test for exception, check for auth if resource is available for STAFF users with pytest.raises(HTTPException) as excinfo: check_auth( { 'realm_access': { 'roles': ['public'] }, 'sub': str(user.keycloak_guid) }, one_of_roles=[STAFF], business_identifier=entity.business_identifier) assert excinfo.exception.code == 403 # Test auth where STAFF role is in disabled role list with pytest.raises(HTTPException) as excinfo: check_auth( { 'realm_access': { 'roles': ['staff'] }, 'sub': str(user.keycloak_guid) }, disabled_roles=[STAFF], business_identifier=entity.business_identifier) assert excinfo.exception.code == 403 # Test auth where STAFF role is exact match with pytest.raises(HTTPException) as excinfo: check_auth( { 'realm_access': { 'roles': ['public'] }, 'sub': str(user.keycloak_guid) }, equals_role=MEMBER, business_identifier=entity.business_identifier) assert excinfo.exception.code == 403 # Test auth where STAFF role is exact match with pytest.raises(HTTPException) as excinfo: check_auth( { 'realm_access': { 'roles': ['public'] }, 'sub': str(user.keycloak_guid) }, equals_role=MEMBER, org_id=org.id) assert excinfo.exception.code == 403 # Test auth where STAFF role is exact match with pytest.raises(HTTPException) as excinfo: check_auth( { 'realm_access': { 'roles': ['staff_admin'] }, 'sub': str(user.keycloak_guid) }, equals_role=MEMBER, org_id=org.id) assert excinfo.exception.code == 403
def test_create_user_add_membership_reenable(session, auth_mock, keycloak_mock): # pylint:disable=unused-argument """Assert that an admin can add a member.""" org = factory_org_model(org_info=TestOrgInfo.org_anonymous) user = factory_user_model() factory_membership_model(user.id, org.id) claims = TestJwtClaims.get_test_real_user(user.keycloak_guid) anon_member = TestAnonymousMembership.generate_random_user(MEMBER) membership = [anon_member] users = UserService.create_user_and_add_membership(membership, org.id, token_info=claims) user_name = IdpHint.BCROS.value + '/' + membership[0]['username'] assert len(users['users']) == 1 assert users['users'][0]['username'] == user_name assert users['users'][0]['type'] == 'ANONYMOUS' members = MembershipModel.find_members_by_org_id(org.id) # staff didnt create members..so count is count of owner+other 1 member assert len(members) == 2 # assert cant be readded users = UserService.create_user_and_add_membership(membership, org.id, token_info=claims) assert users['users'][0]['http_status'] == 409 assert users['users'][0]['error'] == 'The username is already taken' # deactivate everything and try again anon_user = UserModel.find_by_username(user_name) anon_user.status = Status.INACTIVE.value anon_user.save() membership_model = MembershipModel.find_membership_by_userid(anon_user.id) membership_model.status = Status.INACTIVE.value update_user_request = KeycloakUser() update_user_request.user_name = membership[0]['username'] update_user_request.enabled = False KeycloakService.update_user(update_user_request) org2 = factory_org_model(org_info=TestOrgInfo.org_anonymous_2, org_type_info={'code': 'BASIC'}, org_status_info=None, payment_type_info=None) factory_membership_model(user.id, org2.id) users = UserService.create_user_and_add_membership(membership, org2.id, token_info=claims) assert users['users'][0]['http_status'] == 409 assert users['users'][0]['error'] == 'The username is already taken' # add to same org.Should work users = UserService.create_user_and_add_membership(membership, org.id, token_info=claims) assert len(users['users']) == 1 assert users['users'][0][ 'username'] == IdpHint.BCROS.value + '/' + membership[0]['username'] assert users['users'][0]['type'] == 'ANONYMOUS'
def test_delete_otp_for_user(client, jwt, session): # pylint:disable=unused-argument """Assert that a user can be POSTed.""" # ADMIN admin_user = factory_user_model(user_info=TestUserInfo.user1) org = factory_org_model(org_info=TestOrgInfo.org_regular_bceid) factory_membership_model(admin_user.id, org.id) admin_claims = TestJwtClaims.get_test_real_user(admin_user.keycloak_guid) admin_headers = factory_auth_header(jwt=jwt, claims=admin_claims) # COORDINATOR coordinator_user = factory_user_model(user_info=TestUserInfo.user2) factory_membership_model(coordinator_user.id, org.id, member_type=COORDINATOR) coordinator_claims = TestJwtClaims.get_test_real_user(coordinator_user.keycloak_guid) coordinator_headers = factory_auth_header(jwt=jwt, claims=coordinator_claims) # just a member member_user = factory_user_model(user_info=TestUserInfo.user3) factory_membership_model(member_user.id, org.id, member_type=USER) user_claims = TestJwtClaims.get_test_real_user(member_user.keycloak_guid) user_headers = factory_auth_header(jwt=jwt, claims=user_claims) request = KeycloakScenario.create_user_by_user_info(user_info=TestJwtClaims.tester_bceid_role) KEYCLOAK_SERVICE.add_user(request, return_if_exists=True) user = KEYCLOAK_SERVICE.get_user_by_username(request.user_name) assert 'CONFIGURE_TOTP' not in json.loads(user.value()).get('requiredActions', None) user_id = user.id # Create user, org and membserhip in DB user = factory_user_model(TestUserInfo.get_bceid_user_with_kc_guid(user_id)) factory_membership_model(user.id, org.id) # staff with manage accounts otp reset headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.staff_manage_accounts_role) rv = client.delete(f'api/v1/users/{user.username}/otp', headers=headers) assert rv.status_code == http_status.HTTP_204_NO_CONTENT user1 = KEYCLOAK_SERVICE.get_user_by_username(request.user_name) assert 'CONFIGURE_TOTP' in json.loads(user1.value()).get('requiredActions') # staff with basic access cant do otp reset headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.staff_role) rv = client.delete(f'api/v1/users/{user.username}/otp', headers=headers) assert rv.status_code == http_status.HTTP_401_UNAUTHORIZED # admin can do otp reset rv = client.delete(f'api/v1/users/{user.username}/otp', headers=admin_headers) assert rv.status_code == http_status.HTTP_204_NO_CONTENT # coordinator can do otp reset rv = client.delete(f'api/v1/users/{user.username}/otp', headers=coordinator_headers) assert rv.status_code == http_status.HTTP_204_NO_CONTENT # user can not do otp reset rv = client.delete(f'api/v1/users/{user.username}/otp', headers=user_headers) assert rv.status_code == http_status.HTTP_403_FORBIDDEN # another org admin cant do admin_user1 = factory_user_model(user_info=TestUserInfo.user_test) org1 = factory_org_model(org_info=TestOrgInfo.org2, org_type_info=TestOrgTypeInfo.implicit, org_status_info=None, payment_type_info=None) factory_membership_model(admin_user1.id, org1.id) admin_claims = TestJwtClaims.get_test_real_user(admin_user1.keycloak_guid) admin1_headers = factory_auth_header(jwt=jwt, claims=admin_claims) rv = client.delete(f'api/v1/users/{user.username}/otp', headers=admin1_headers) assert rv.status_code == http_status.HTTP_403_FORBIDDEN
def test_delete_bcros_valdiations(client, jwt, session, keycloak_mock, monkeypatch): """Assert different conditions of user deletion.""" admin_user = TestUserInfo.user_bcros_active org = factory_org_model(org_info=TestOrgInfo.org_anonymous) user = factory_user_model(user_info=TestUserInfo.user_bcros_active) factory_membership_model(user.id, org.id) factory_product_model(org.id, product_code=ProductCode.DIR_SEARCH.value) owner_claims = TestJwtClaims.get_test_real_user(user.keycloak_guid) patch_token_info(owner_claims, monkeypatch) member = TestAnonymousMembership.generate_random_user(USER) admin = TestAnonymousMembership.generate_random_user(COORDINATOR) membership = [member, admin] UserService.create_user_and_add_membership(membership, org.id) owner_headers = factory_auth_header(jwt=jwt, claims=owner_claims) member_username = IdpHint.BCROS.value + '/' + member['username'] admin_username = IdpHint.BCROS.value + '/' + admin['username'] admin_claims = TestJwtClaims.get_test_real_user(uuid.uuid4(), admin_username, access_ype=AccessType.ANONYMOUS.value, roles=[Role.ANONYMOUS_USER.value]) admin_headers = factory_auth_header(jwt=jwt, claims=admin_claims) member_claims = TestJwtClaims.get_test_real_user(uuid.uuid4(), member_username, access_ype=AccessType.ANONYMOUS.value, roles=[Role.ANONYMOUS_USER.value]) member_headers = factory_auth_header(jwt=jwt, claims=member_claims) # set up JWTS for member and admin patch_token_info(admin_claims, monkeypatch) client.post('/api/v1/users', headers=admin_headers, content_type='application/json', data=json.dumps({'isLogin': True})) patch_token_info(member_claims, monkeypatch) client.post('/api/v1/users', headers=member_headers, content_type='application/json', data=json.dumps({'isLogin': True})) patch_token_info(owner_claims, monkeypatch) # delete only owner ;failure rv = client.delete(f"/api/v1/users/{admin_user['username']}", headers=owner_headers, content_type='application/json') assert rv.status_code == http_status.HTTP_401_UNAUTHORIZED # admin trying to delete member: Failure patch_token_info(admin_claims, monkeypatch) rv = client.delete(f'/api/v1/users/{member_username}', headers=admin_headers, content_type='application/json') assert rv.status_code == http_status.HTTP_401_UNAUTHORIZED # member delete admin: failure patch_token_info(member_claims, monkeypatch) rv = client.delete(f'/api/v1/users/{admin_username}', headers=member_headers, content_type='application/json') assert rv.status_code == http_status.HTTP_401_UNAUTHORIZED # a self delete ;should work ;mimics leave team for anonymous user patch_token_info(member_claims, monkeypatch) rv = client.delete(f'/api/v1/users/{member_username}', headers=member_headers, content_type='application/json') assert rv.status_code == http_status.HTTP_204_NO_CONTENT patch_token_info(admin_claims, monkeypatch) rv = client.delete(f'/api/v1/users/{admin_username}', headers=admin_headers, content_type='application/json') assert rv.status_code == http_status.HTTP_204_NO_CONTENT # add one more admin patch_token_info(owner_claims, monkeypatch) new_owner = TestAnonymousMembership.generate_random_user(ADMIN) membership = [new_owner] UserService.create_user_and_add_membership(membership, org.id) patch_token_info(owner_claims, monkeypatch) rv = client.delete(f"/api/v1/users/{IdpHint.BCROS.value + '/' + new_owner['username']}", headers=owner_headers, content_type='application/json') assert rv.status_code == http_status.HTTP_204_NO_CONTENT
def test_delete_bcros_valdiations(client, jwt, session, keycloak_mock): """Assert different conditions of user deletion.""" admin_user = TestUserInfo.user_bcros_active org = factory_org_model(org_info=TestOrgInfo.org_anonymous) user = factory_user_model(user_info=TestUserInfo.user_bcros_active) factory_membership_model(user.id, org.id) owner_claims = TestJwtClaims.get_test_real_user(user.keycloak_guid) member = TestAnonymousMembership.generate_random_user(MEMBER) admin = TestAnonymousMembership.generate_random_user(ADMIN) membership = [member, admin] UserService.create_user_and_add_membership(membership, org.id, token_info=owner_claims) owner_headers = factory_auth_header(jwt=jwt, claims=owner_claims) member_username = IdpHint.BCROS.value + '/' + member['username'] admin_username = IdpHint.BCROS.value + '/' + admin['username'] admin_claims = TestJwtClaims.get_test_real_user( uuid.uuid4(), admin_username, access_ype=AccessType.ANONYMOUS.value) admin_headers = factory_auth_header(jwt=jwt, claims=admin_claims) member_claims = TestJwtClaims.get_test_real_user( uuid.uuid4(), member_username, access_ype=AccessType.ANONYMOUS.value) member_headers = factory_auth_header(jwt=jwt, claims=member_claims) # set up JWTS for member and admin client.post('/api/v1/users', headers=admin_headers, content_type='application/json') client.post('/api/v1/users', headers=member_headers, content_type='application/json') # delete only owner ;failure rv = client.delete(f"/api/v1/users/{admin_user['username']}", headers=owner_headers, content_type='application/json') assert rv.status_code == http_status.HTTP_401_UNAUTHORIZED # admin trying to delete member: Failure rv = client.delete(f'/api/v1/users/{member_username}', headers=admin_headers, content_type='application/json') assert rv.status_code == http_status.HTTP_401_UNAUTHORIZED # member delete admin: failure rv = client.delete(f'/api/v1/users/{admin_username}', headers=member_headers, content_type='application/json') assert rv.status_code == http_status.HTTP_401_UNAUTHORIZED # a self delete ;should work ;mimics leave team for anonymous user rv = client.delete(f'/api/v1/users/{member_username}', headers=member_headers, content_type='application/json') assert rv.status_code == http_status.HTTP_204_NO_CONTENT rv = client.delete(f'/api/v1/users/{admin_username}', headers=admin_headers, content_type='application/json') assert rv.status_code == http_status.HTTP_204_NO_CONTENT # add one more admin new_owner = TestAnonymousMembership.generate_random_user(OWNER) membership = [new_owner] UserService.create_user_and_add_membership(membership, org.id, token_info=owner_claims) rv = client.delete( f"/api/v1/users/{IdpHint.BCROS.value + '/' + new_owner['username']}", headers=owner_headers, content_type='application/json') assert rv.status_code == http_status.HTTP_204_NO_CONTENT