def reset_password_for_anon_user(user_info: dict, user_name, token_info: Dict = None): """Reset the password of the user.""" user = UserModel.find_by_username(user_name) membership = MembershipModel.find_membership_by_userid(user.id) org_id = membership.org_id org = OrgModel.find_by_org_id(org_id) if not org or org.access_type != AccessType.ANONYMOUS.value: raise BusinessException(Error.INVALID_INPUT, None) check_auth(org_id=org_id, token_info=token_info, one_of_roles=(ADMIN, STAFF)) update_user_request = KeycloakUser() update_user_request.user_name = user_name.replace( IdpHint.BCROS.value + '/', '') update_user_request.password = user_info['password'] update_user_request.update_password_on_login() try: kc_user = KeycloakService.update_user(update_user_request) except HTTPError as err: current_app.logger.error('update_user in keycloak failed {}', err) raise BusinessException(Error.UNDEFINED_ERROR, err) return kc_user
def _create_kc_user(membership): create_user_request = KeycloakUser() create_user_request.first_name = membership['username'] create_user_request.user_name = membership['username'] create_user_request.password = membership['password'] create_user_request.enabled = True create_user_request.attributes = {'access_type': AccessType.ANONYMOUS.value} return create_user_request
def test_create_user_add_membership_reenable(session, auth_mock, keycloak_mock, monkeypatch): # 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) patch_token_info(claims, monkeypatch) anon_member = TestAnonymousMembership.generate_random_user(USER) membership = [anon_member] users = UserService.create_user_and_add_membership(membership, org.id) 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'] == 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 # assert cant be readded users = UserService.create_user_and_add_membership(membership, org.id) 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) factory_product_model(org2.id, product_code=ProductCode.DIR_SEARCH.value) users = UserService.create_user_and_add_membership(membership, org2.id) 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) 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
def create_user_by_user_info(user_info: dict): """Return create user request.""" create_user_request = KeycloakUser() create_user_request.user_name = user_info['preferred_username'] create_user_request.password = '******' create_user_request.first_name = user_info['firstname'] create_user_request.last_name = user_info['lastname'] create_user_request.attributes = {'source': user_info['loginSource']} create_user_request.enabled = True return create_user_request
def create_user_and_add_membership(memberships: List[dict], org_id, token_info: Dict = None, skip_auth: bool = False): """ Create user(s) in the DB and upstream keycloak. accepts a list of memberships ie.a list of objects with username,password and membershipTpe skip_auth can be used if called method already perfomed the authenticaiton skip_auth= true is used now incase of invitation for admin users scenarion other cases should be invoked with skip_auth=false """ if skip_auth: # make sure no bulk operation and only owner is created using if no auth if len(memberships) > 1 or memberships[0].get('membershipType') not in [OWNER, ADMIN]: raise BusinessException(Error.INVALID_USER_CREDENTIALS, None) else: check_auth(org_id=org_id, token_info=token_info, one_of_roles=(ADMIN, OWNER)) # check if anonymous org ;these actions cannot be performed on normal orgs org = OrgModel.find_by_org_id(org_id) if not org or org.access_type != AccessType.ANONYMOUS.value: raise BusinessException(Error.INVALID_INPUT, None) current_app.logger.debug('create_user') users = [] for membership in memberships: create_user_request = KeycloakUser() current_app.logger.debug(f"create user username: {membership['username']}") create_user_request.first_name = membership['username'] create_user_request.user_name = membership['username'] create_user_request.password = membership['password'] create_user_request.enabled = True create_user_request.attributes = {'access_type': AccessType.ANONYMOUS.value} if membership.get('update_password_on_login', True): # by default , reset needed create_user_request.update_password_on_login() try: # TODO may be this method itself throw the business exception;can handle different exceptions? kc_user = KeycloakService.add_user(create_user_request) except HTTPError as err: current_app.logger.error('create_user in keycloak failed', err) raise BusinessException(Error.FAILED_ADDING_USER_IN_KEYCLOAK, None) username = IdpHint.BCROS.value + '/' + membership['username'] existing_user = UserModel.find_by_username(username) if existing_user: current_app.logger.debug('Existing users found in DB') raise BusinessException(Error.DATA_ALREADY_EXISTS, None) user_model: UserModel = UserModel(username=username, # BCROS is temporary value.Will be overwritten when user logs in is_terms_of_use_accepted=False, status=Status.ACTIVE.value, type=AccessType.ANONYMOUS.value, email=membership.get('email', None), firstname=kc_user.first_name, lastname=kc_user.last_name) user_model.save() User._add_org_membership(org_id, user_model.id, membership['membershipType']) users.append(User(user_model).as_dict()) return {'users': users}
def create_user_request(): """Return create user request.""" create_user_request = KeycloakUser() create_user_request.user_name = 'testuser1' create_user_request.password = '******' create_user_request.first_name = 'test_first' create_user_request.last_name = 'test_last' create_user_request.email = '*****@*****.**' create_user_request.attributes = {'corp_type': 'CP', 'source': 'BCSC'} create_user_request.enabled = True return create_user_request
def create_user_request(): """Return create user request.""" create_user_request = KeycloakUser() user_name = ''.join(choice(ascii_lowercase) for i in range(5)) create_user_request.user_name = user_name create_user_request.password = '******' create_user_request.first_name = 'test_first' create_user_request.last_name = 'test_last' create_user_request.email = f'{user_name}@gov.bc.ca' create_user_request.attributes = {'corp_type': 'CP', 'source': 'BCSC'} create_user_request.enabled = True return create_user_request
def delete_anonymous_user(user_name, token_info: Dict = None): """ Delete User Profile. 1) check if the token user is admin/owner of the current user 2) disable the user from kc 3) set user status as INACTIVE 4) set membership as inactive """ admin_user: UserModel = UserModel.find_by_jwt_token(token_info) if not admin_user: raise BusinessException(Error.DATA_NOT_FOUND, None) if admin_user.status == UserStatus.INACTIVE.value: raise BusinessException(Error.DELETE_FAILED_INACTIVE_USER, None) # handle validations. user = UserModel.find_by_username(user_name) membership = MembershipModel.find_membership_by_userid(user.id) org_id = membership.org_id is_valid_action = False # admin/owner deleteion admin_user_membership = MembershipModel.find_membership_by_user_and_org( admin_user.id, org_id) if admin_user_membership.membership_type_code in [ADMIN]: is_valid_action = True # staff admin deleteion is_staff_admin = token_info and Role.STAFF_CREATE_ACCOUNTS.value in token_info.get( 'realm_access').get('roles') if is_staff_admin: is_valid_action = True # self deletion if user.keycloak_guid == admin_user.keycloak_guid: is_valid_action = True # is the only owner getting deleted if is_valid_action and membership.membership_type_code == ADMIN: count_of_owners = MembershipModel.get_count_active_owner_org_id( org_id) if count_of_owners == 1: is_valid_action = False if not is_valid_action: raise BusinessException(Error.INVALID_USER_CREDENTIALS, None) user.is_terms_of_use_accepted = False user.status = UserStatus.INACTIVE.value user.save() membership.status = Status.INACTIVE.value membership.save() update_user_request = KeycloakUser() update_user_request.user_name = user_name.replace( IdpHint.BCROS.value + '/', '') update_user_request.enabled = False KeycloakService.update_user(update_user_request)
def _update_user_in_kc(create_user_request): update_user_request = KeycloakUser() update_user_request.user_name = create_user_request.user_name update_user_request.enabled = False KeycloakService.update_user(update_user_request)