def delete_user(): """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() 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')
def send_notification_to_member(self, origin_url, notification_type): """Send member notification.""" current_app.logger.debug(f'<send {notification_type} notification') org_name = self._model.org.name template_name = '' params = {} if notification_type == NotificationType.ROLE_CHANGED.value: subject = '[BC Registries & Online Services] Your Role has been changed' template_name = 'role_changed_notification_email.html' params = {'org_name': org_name, 'role': self._model.membership_type.code, 'label': self._model.membership_type.label} elif notification_type == NotificationType.MEMBERSHIP_APPROVED.value: subject = '[BC Registries & Online Services] Welcome to the team {}'. \ format(org_name) template_name = 'membership_approved_notification_email.html' params = {'org_name': org_name} sender = CONFIG.MAIL_FROM_ID template = ENV.get_template(f'email_templates/{template_name}') context_path = CONFIG.AUTH_WEB_TOKEN_CONFIRM_PATH app_url = '{}/{}'.format(origin_url, context_path) sent_response = send_email(subject, sender, self._model.user.contacts[0].contact.email, template.render(url=app_url, params=params, logo_url=f'{app_url}/{CONFIG.REGISTRIES_LOGO_IMAGE_NAME}')) current_app.logger.debug('<send_approval_notification_to_member') if not sent_response: # invitation.invitation_status_code = 'FAILED' # invitation.save() current_app.logger.error('<send_notification_to_member failed') raise BusinessException(Error.FAILED_NOTIFICATION, None)
def send_approved_rejected_notification(receipt_admin_email, org_name, org_id, org_status: OrgStatus, origin_url): """Send Approved/Rejected notification to the user.""" current_app.logger.debug('<send_approved_rejected_notification') if org_status == OrgStatus.ACTIVE.value: notification_type = 'nonbcscOrgApprovedNotification' elif org_status == OrgStatus.REJECTED.value: notification_type = 'nonbcscOrgRejectedNotification' else: return # Don't send mail for any other status change app_url = f"{origin_url}/{current_app.config.get('AUTH_WEB_TOKEN_CONFIRM_PATH')}" data = { 'accountId': org_id, 'emailAddresses': receipt_admin_email, 'contextUrl': app_url, 'orgName': org_name } try: publish_to_mailer(notification_type, org_id=org_id, data=data) current_app.logger.debug('<send_approved_rejected_notification') except Exception as e: # noqa=B901 current_app.logger.error( '<send_approved_rejected_notification failed') raise BusinessException(Error.FAILED_NOTIFICATION, None) from e
def search_orgs(search: OrgSearch): # pylint: disable=too-many-locals """Search for orgs based on input parameters.""" orgs_result = { 'orgs': [], 'page': search.page, 'limit': search.limit, 'total': 0 } include_invitations: bool = False search.access_type, is_staff_admin = Org.refine_access_type( search.access_type) if search.statuses and OrgStatus.PENDING_ACTIVATION.value in search.statuses: # only staff admin can see director search accounts if not is_staff_admin: raise BusinessException(Error.INVALID_USER_CREDENTIALS, None) org_models, orgs_result[ 'total'] = OrgModel.search_pending_activation_orgs( name=search.name) include_invitations = True else: org_models, orgs_result['total'] = OrgModel.search_org(search) for org in org_models: orgs_result['orgs'].append({ **Org(org).as_dict(), 'contacts': [ ContactSchema(exclude=('links', )).dump( org.contacts[0].contact, many=False) ] if org.contacts else [], 'invitations': [ InvitationSchema(exclude=('membership', )).dump( org.invitations[0].invitation, many=False) ] if include_invitations and org.invitations else [], }) return orgs_result
def get_bcol_details(bcol_credential: Dict, org_id=None): """Retrieve and validate BC Online credentials.""" arg_dict = {'bcol_credential': bcol_credential, 'org_id': org_id} validator_obj = bcol_credentials_validate(**arg_dict) if not validator_obj.is_valid: raise BusinessException(validator_obj.error[0], None) return validator_obj.info.get('bcol_response', None)
def create_invitation(invitation_info: Dict, user, token_info: Dict, invitation_origin): """Create a new invitation.""" # Ensure that the current user is ADMIN or COORDINATOR on each org being invited to context_path = CONFIG.AUTH_WEB_TOKEN_CONFIRM_PATH org_id = invitation_info['membership'][0]['orgId'] # get the org and check the access_type org = OrgModel.find_by_org_id(org_id) if not org: raise BusinessException(Error.DATA_NOT_FOUND, None) check_auth(token_info, org_id=org_id, one_of_roles=(ADMIN, COORDINATOR, STAFF)) org_name = org.name invitation_type = InvitationType.DIRECTOR_SEARCH.value if org.access_type == AccessType.ANONYMOUS.value \ else InvitationType.STANDARD.value if org.access_type == AccessType.ANONYMOUS.value: # anonymous account never get bceid or bcsc choices mandatory_login_source = LoginSource.BCROS.value else: default_login_option_based_on_accesstype = LoginSource.BCSC.value if \ org.access_type == AccessType.REGULAR.value else LoginSource.BCEID.value role = invitation_info['membership'][0]['membershipType'] account_login_options = AccountLoginOptionsModel.find_active_by_org_id(org.id) mandatory_login_source = LoginSource.BCSC.value if \ role == ADMIN else getattr(account_login_options, 'login_source', default_login_option_based_on_accesstype) invitation = InvitationModel.create_from_dict(invitation_info, user.identifier, invitation_type) confirmation_token = Invitation.generate_confirmation_token(invitation.id, invitation.type) invitation.token = confirmation_token invitation.login_source = mandatory_login_source invitation.save() Invitation.send_invitation(invitation, org_name, user.as_dict(), '{}/{}'.format(invitation_origin, context_path), mandatory_login_source) return Invitation(invitation)
def test_add_entity_invalid_returns_exception(client, jwt, session): # pylint:disable=unused-argument """Assert that POSTing an invalid entity returns an exception.""" headers = factory_auth_header(jwt, claims=TestJwtClaims.system_role) with patch.object(EntityService, 'save_entity', side_effect=BusinessException(Error.DATA_ALREADY_EXISTS, None)): rv = client.post('/api/v1/entities', data=json.dumps(TestEntityInfo.entity1), headers=headers, content_type='application/json') assert rv.status_code == 400
def __remove_org_membership(org, user_id): is_user_an_owner: bool = False org_has_other_owners: bool = False user_membership: MembershipModel = None for member in MembershipModel.find_members_by_org_id(org.id): if member.user_id == user_id: user_membership = member if member.membership_type_code == ADMIN: is_user_an_owner = True elif member.membership_type_code == ADMIN: org_has_other_owners = True current_app.logger.info( f'Org :{org.name} --> User Owner : {is_user_an_owner},Has other owners :{org_has_other_owners}' ) if is_user_an_owner and not org_has_other_owners: current_app.logger.info('Affiliated entities : {}'.format( len(org.affiliated_entities))) if len(org.affiliated_entities) == 0: org.status_code = OrgStatus.INACTIVE.value org.flush() else: # Roll back the transaction as there could be situation where a change in one org # membership is flushed, but the next one fails. In this case roll back whole transaction org.rollback() raise BusinessException(Error.DELETE_FAILED_ONLY_OWNER, None) else: user_membership.status = Status.INACTIVE.value user_membership.flush()
def find_by_jwt_token(cls, **kwargs): """Find user from database by user token.""" user_from_context: UserContext = kwargs['user_context'] if not user_from_context.token_info: return None user_model = UserModel.find_by_jwt_token() if not user_model: if kwargs.get('silent_mode', False): return None raise BusinessException(Error.DATA_NOT_FOUND, None) is_anonymous_user = user_from_context.token_info.get('accessType', None) == AccessType.ANONYMOUS.value is_govm_user = user_from_context.login_source == LoginSource.STAFF.value # If terms accepted , double check if there is a new TOS in place. If so, update the flag to false. if user_model.is_terms_of_use_accepted: if is_anonymous_user: document_type = DocumentType.TERMS_OF_USE_DIRECTOR_SEARCH.value elif is_govm_user: document_type = DocumentType.TERMS_OF_USE_GOVM.value else: document_type = DocumentType.TERMS_OF_USE.value # get the digit version of the terms of service..ie d1 gives 1 ; d2 gives 2..for proper comparison latest_version = util.digitify(DocumentService.find_latest_version_by_type(document_type)) current_version = util.digitify(user_model.terms_of_use_accepted_version) if latest_version > current_version: user_model.is_terms_of_use_accepted = False return User(user_model)
def send_staff_review_account_reminder(user, org_id, origin_url): """Send staff review account reminder notification.""" current_app.logger.debug('<send_staff_review_account_reminder') recipient = current_app.config.get('STAFF_ADMIN_EMAIL') context_path = f'review-account/{org_id}' app_url = '{}/{}'.format( origin_url, current_app.config.get('AUTH_WEB_TOKEN_CONFIRM_PATH')) review_url = '{}/{}'.format(app_url, context_path) first_name = '' last_name = '' if user: first_name = user.firstname last_name = user.lastname data = { 'accountId': org_id, 'emailAddresses': recipient, 'contextUrl': review_url, 'userFirstName': first_name, 'userLastName': last_name } try: publish_to_mailer('staffReviewAccount', org_id=org_id, data=data) current_app.logger.debug('<send_staff_review_account_reminder') except: # noqa=B901 current_app.logger.error( '<send_staff_review_account_reminder failed') raise BusinessException(Error.FAILED_NOTIFICATION, None)
def _validate_and_get_payment_method(selected_payment_type: str, org_type: OrgType, access_type=None) -> str: # TODO whats a better place for this org_payment_method_mapping = { OrgType.BASIC: (PaymentMethod.CREDIT_CARD.value, PaymentMethod.DIRECT_PAY.value, PaymentMethod.ONLINE_BANKING.value), OrgType.PREMIUM: (PaymentMethod.CREDIT_CARD.value, PaymentMethod.DIRECT_PAY.value, PaymentMethod.PAD.value, PaymentMethod.BCOL.value) } if access_type == AccessType.GOVM.value: payment_type = PaymentMethod.EJV.value elif selected_payment_type: valid_types = org_payment_method_mapping.get(org_type, []) if selected_payment_type in valid_types: payment_type = selected_payment_type else: raise BusinessException(Error.INVALID_INPUT, None) else: payment_type = PaymentMethod.BCOL.value if \ org_type == OrgType.PREMIUM else Org._get_default_payment_method_for_creditcard() return payment_type
def update_entity(business_identifier: str, entity_info: dict, **kwargs): """Update an entity from the given dictionary. Completely replaces the entity including the business identifier """ if not entity_info or not business_identifier: return None user_from_context: UserContext = kwargs['user_context'] # todo No memberhsip created at this point. check_auth wont work.ideally we shud put the logic in here # check_auth(token_info, one_of_roles=allowed_roles, business_identifier=business_identifier) entity = EntityModel.find_by_business_identifier(business_identifier) if entity is None or entity.corp_type_code is None: raise BusinessException(Error.DATA_NOT_FOUND, None) # if entity.corp_type_code != token_info.get('corp_type', None): # raise BusinessException(Error.INVALID_USER_CREDENTIALS, None) if user_from_context.is_system(): if entity_info.get('passCode') is not None: entity_info['passCode'] = passcode_hash(entity_info['passCode']) # Small mapping from state -> status. EX in LEAR: Business.State.HISTORICAL if 'state' in entity_info: entity_info['status'] = entity_info['state'] del entity_info['state'] entity.update_from_dict(**camelback2snake(entity_info)) entity.commit() entity = Entity(entity) return entity
def create_affidavit(token_info: Dict, affidavit_info: Dict): """Create a new affidavit record.""" current_app.logger.debug('<create_affidavit ') user = UserService.find_by_jwt_token(token=token_info) # If the user already have a pending affidavit, raise error existing_affidavit = AffidavitModel.find_pending_by_user_id( user_id=user.identifier) if existing_affidavit is not None: raise BusinessException(Error.ACTIVE_AFFIDAVIT_EXISTS, None) contact = affidavit_info.pop('contact') affidavit_model = AffidavitModel( issuer=affidavit_info.get('issuer'), document_id=affidavit_info.get('documentId'), status_code=AffidavitStatus.PENDING.value, user_id=user.identifier) affidavit_model.add_to_session() # Save contact for the affidavit if contact: contact = ContactModel(**camelback2snake(contact)) contact.add_to_session() contact_link = ContactLinkModel() contact_link.affidavit = affidavit_model contact_link.contact = contact contact_link.add_to_session() affidavit_model.save() return Affidavit(affidavit_model)
def update_org( self, org_info, token_info: Dict = None, # pylint: disable=too-many-locals bearer_token: str = None): """Update the passed organization with the new info.""" current_app.logger.debug('<update_org ') has_org_updates: bool = False # update the org table if this variable is set true is_name_getting_updated = 'name' in org_info if is_name_getting_updated: existing_similar__org = OrgModel.find_similar_org_by_name( org_info['name'], self._model.id) if existing_similar__org is not None: raise BusinessException(Error.DATA_CONFLICT, None) has_org_updates = True # If the account is created using BCOL credential, verify its valid bc online account # If it's a valid account disable the current one and add a new one if bcol_credential := org_info.pop('bcOnlineCredential', None): bcol_response = Org.get_bcol_details(bcol_credential, bearer_token, self._model.id).json() Org._map_response_to_org(bcol_response, org_info) has_org_updates = True
def logout(refresh_token): """Logout user by refresh-token.""" try: response = KEYCLOAK_OPENID.logout(refresh_token) return response except Exception as err: raise BusinessException(Error.INVALID_REFRESH_TOKEN, err)
def find_by_jwt_token(cls, token: dict = None): """Find user from database by user token.""" if not token: return None user_model = UserModel.find_by_jwt_token(token) if not user_model: raise BusinessException(Error.DATA_NOT_FOUND, None) is_anonymous_user = token.get('accessType', None) == AccessType.ANONYMOUS.value # If terms accepted , double check if there is a new TOS in place. If so, update the flag to false. if user_model.is_terms_of_use_accepted: document_type = DocumentType.TERMS_OF_USE_DIRECTOR_SEARCH.value if is_anonymous_user \ else DocumentType.TERMS_OF_USE.value # get the digit version of the terms of service..ie d1 gives 1 ; d2 gives 2..for proper comparison latest_version = util.digitify( DocumentService.find_latest_version_by_type(document_type)) current_version = util.digitify( user_model.terms_of_use_accepted_version) if latest_version > current_version: user_model.is_terms_of_use_accepted = False return User(user_model)
def get_user_by_username(username): """Get user from Keycloak by username.""" try: # Get user id user_id_keycloak = KEYCLOAK_ADMIN.get_user_id(username) except Exception as err: raise BusinessException(Error.UNDEFINED_ERROR, err) # Get User if user_id_keycloak is not None: try: user = KEYCLOAK_ADMIN.get_user(user_id_keycloak) return user except Exception as err: raise BusinessException(Error.UNDEFINED_ERROR, err) else: raise BusinessException(Error.DATA_NOT_FOUND, None)
def update_terms_of_use(token, is_terms_accepted, terms_of_use_version): """Update terms of use for an existing user.""" current_app.logger.debug('update_terms_of_use') if token is None: raise BusinessException(Error.DATA_NOT_FOUND, None) user = UserModel.update_terms_of_use(token, is_terms_accepted, terms_of_use_version) return User(user)
def send_invitation(invitation: InvitationModel, org_name, user, app_url): """Send the email notification.""" current_app.logger.debug('<send_invitation') mail_configs = Invitation.get_invitation_configs( invitation.type, org_name) subject = mail_configs.get('subject').format(user['firstname'], user['lastname']) sender = CONFIG.MAIL_FROM_ID recipient = invitation.recipient_email token_confirm_url = '{}/{}/{}'.format( app_url, mail_configs.get('token_confirm_path'), invitation.token) template = ENV.get_template( f"email_templates/{mail_configs.get('template_name')}.html") sent_response = send_email( subject, sender, recipient, template.render( invitation=invitation, url=token_confirm_url, user=user, org_name=org_name, logo_url=f'{app_url}/{CONFIG.REGISTRIES_LOGO_IMAGE_NAME}')) if not sent_response: invitation.invitation_status_code = 'FAILED' invitation.save() current_app.logger.debug('>send_invitation failed') raise BusinessException(Error.FAILED_INVITATION, None) current_app.logger.debug('>send_invitation')
def fetch_codes(cls, code_type: str = None) -> []: """Return values from code table.""" try: data: [] = None if code_type: code_model = Codes.fetch_data_model(code_type.lower()) if code_model: codes = code_model.query.all() data = [] # transform each of entry to a dictionary base on schema. for entry in codes: module_name = f'auth_api.schemas.{entry.__tablename__}' class_name = f'{entry.__class__.__name__}Schema' try: schema = getattr( importlib.import_module(module_name), class_name) except ModuleNotFoundError: schema = getattr( importlib.import_module( 'auth_api.schemas.basecode_type'), 'BaseCodeSchema') code_schema = schema() data.append(code_schema.dump(entry, many=False)) return data return None except Exception as exception: # NOQA # pylint: disable=broad-except raise BusinessException(Error.UNDEFINED_ERROR, exception)
def update_user(user: KeycloakUser): """Add user to Keycloak.""" config = current_app.config # Add user and set password admin_token = KeycloakService._get_admin_token(upstream=True) base_url = config.get('KEYCLOAK_BCROS_BASE_URL') realm = config.get('KEYCLOAK_BCROS_REALMNAME') existing_user = KeycloakService.get_user_by_username( user.user_name, admin_token=admin_token) if not existing_user: raise BusinessException(Error.DATA_NOT_FOUND, None) headers = { 'Content-Type': ContentType.JSON.value, 'Authorization': f'Bearer {admin_token}' } update_user_url = f'{base_url}/auth/admin/realms/{realm}/users/{existing_user.id}' response = requests.put(update_user_url, data=user.value(), headers=headers) response.raise_for_status() return KeycloakService.get_user_by_username(user.user_name, admin_token)
def send_invitation(invitation: InvitationModel, org_name, user, app_url): """Send the email notification.""" current_app.logger.debug('<send_invitation') subject = '[BC Registries & Online Services] {} {} has invited you to join a team'.format( user['firstname'], user['lastname']) sender = CONFIG.MAIL_FROM_ID recipient = invitation.recipient_email token_confirm_url = '{}/validatetoken/{}'.format( app_url, invitation.token) template = ENV.get_template( 'email_templates/business_invitation_email.html') sent_response = send_email( subject, sender, recipient, template.render( invitation=invitation, url=token_confirm_url, user=user, org_name=org_name, logo_url=f'{app_url}/{CONFIG.REGISTRIES_LOGO_IMAGE_NAME}')) if not sent_response: invitation.invitation_status_code = 'FAILED' invitation.save() current_app.logger.debug('>send_invitation failed') raise BusinessException(Error.FAILED_INVITATION, None) current_app.logger.debug('>send_invitation')
def add_user(user: KeycloakUser, return_if_exists: bool = False, throw_error_if_exists: bool = False): """Add user to Keycloak.""" config = current_app.config # Add user and set password admin_token = KeycloakService._get_admin_token(upstream=True) base_url = config.get('KEYCLOAK_BCROS_BASE_URL') realm = config.get('KEYCLOAK_BCROS_REALMNAME') # Check if the user exists if return_if_exists or throw_error_if_exists: existing_user = KeycloakService.get_user_by_username(user.user_name, admin_token=admin_token) if existing_user: if not throw_error_if_exists: return existing_user raise BusinessException(Error.USER_ALREADY_EXISTS_IN_KEYCLOAK, None) # Add user to the keycloak group '$group_name' headers = { 'Content-Type': ContentType.JSON.value, 'Authorization': f'Bearer {admin_token}' } add_user_url = f'{base_url}/auth/admin/realms/{realm}/users' response = requests.post(add_user_url, data=user.value(), headers=headers) response.raise_for_status() return KeycloakService.get_user_by_username(user.user_name, admin_token)
def _notify_admin_about_hold(task_model, org: OrgModel = None, is_new_bceid_admin_request: bool = False, membership_id: int = None, user: UserModel = None): if is_new_bceid_admin_request: create_account_signin_route = urllib.parse.quote_plus( f"{current_app.config.get('BCEID_ADMIN_SETUP_ROUTE')}/" f'{task_model.account_id}/' f'{membership_id}') admin_email = user.contacts[0].contact.email account_id = task_model.account_id mailer_type = 'resubmitBceidAdmin' else: create_account_signin_route = urllib.parse. \ quote_plus(f"{current_app.config.get('BCEID_ACCOUNT_SETUP_ROUTE')}/" f'{org.id}') admin_email = ContactLinkModel.find_by_user_id(org.members[0].user.id).contact.email account_id = org.id mailer_type = 'resubmitBceidOrg' data = { 'remarks': task_model.remarks, 'applicationDate': f"{task_model.created.strftime('%m/%d/%Y')}", 'accountId': account_id, 'emailAddresses': admin_email, 'contextUrl': f"{current_app.config.get('WEB_APP_URL')}" f"/{current_app.config.get('BCEID_SIGNIN_ROUTE')}/" f'{create_account_signin_route}' } try: publish_to_mailer(mailer_type, org_id=account_id, data=data) current_app.logger.debug('<send_approval_notification_to_member') except Exception as e: # noqa=B901 current_app.logger.error('<send_notification_to_member failed') raise BusinessException(Error.FAILED_NOTIFICATION, None) from e
def update_login_option(org_id, login_source): """Create a new contact for this org.""" # check for existing contact (only one contact per org for now) current_app.logger.debug('>update_login_option') org = OrgModel.find_by_org_id(org_id) if org is None: raise BusinessException(Error.DATA_NOT_FOUND, None) check_auth(one_of_roles=ADMIN, org_id=org_id) existing_login_option = AccountLoginOptionsModel.find_active_by_org_id( org_id) if existing_login_option is not None: existing_login_option.is_active = False existing_login_option.add_to_session() login_option = AccountLoginOptionsModel(login_source=login_source, org_id=org_id) login_option.save() ActivityLogPublisher.publish_activity( Activity(org_id, ActivityAction.AUTHENTICATION_METHOD_CHANGE.value, name=org.name, value=login_source, id=login_option.id)) return login_option
def delete_user_by_username(username): """Delete user from Keycloak by username.""" try: # Get user id user_id_keycloak = KEYCLOAK_ADMIN.get_user_id(username) except Exception as err: raise BusinessException(Error.UNDEFINED_ERROR, err) # Delete User if user_id_keycloak is not None: try: response = KEYCLOAK_ADMIN.delete_user(user_id_keycloak) return response except Exception as err: raise BusinessException(Error.UNDEFINED_ERROR, err) else: raise BusinessException(Error.DATA_NOT_FOUND, None)
def send_staff_review_account_reminder( relationship_id, task_relationship_type=TaskRelationshipType.ORG.value): """Send staff review account reminder notification.""" current_app.logger.debug('<send_staff_review_account_reminder') user: UserModel = UserModel.find_by_jwt_token() recipient = current_app.config.get('STAFF_ADMIN_EMAIL') # Get task id that is related with the task. Task Relationship Type can be ORG, PRODUCT etc. task = TaskModel.find_by_task_relationship_id( task_relationship_type=task_relationship_type, relationship_id=relationship_id) context_path = f'review-account/{task.id}' app_url = f"{g.get('origin_url', '')}/{current_app.config.get('AUTH_WEB_TOKEN_CONFIRM_PATH')}" review_url = f'{app_url}/{context_path}' first_name = user.firstname last_name = user.lastname data = { 'emailAddresses': recipient, 'contextUrl': review_url, 'userFirstName': first_name, 'userLastName': last_name } try: publish_to_mailer('staffReviewAccount', org_id=relationship_id, data=data) current_app.logger.debug('<send_staff_review_account_reminder') except Exception as e: # noqa=B901 current_app.logger.error( '<send_staff_review_account_reminder failed') raise BusinessException(Error.FAILED_NOTIFICATION, None) from e
def get_token(username, password): """Get user access token by username and password.""" try: response = KEYCLOAK_OPENID.token(username, password) return response except Exception as err: raise BusinessException(Error.INVALID_USER_CREDENTIALS, err)
def update_entity(business_identifier: str, entity_info: dict, token_info: Dict = None): """Update an entity from the given dictionary. Completely replaces the entity including the business identifier """ if not entity_info or not business_identifier: return None # todo No memberhsip created at this point. check_auth wont work.ideally we shud put the logic in here # check_auth(token_info, one_of_roles=allowed_roles, business_identifier=business_identifier) entity = EntityModel.find_by_business_identifier(business_identifier) if entity is None or entity.corp_type_code is None: raise BusinessException(Error.DATA_NOT_FOUND, None) # if entity.corp_type_code != token_info.get('corp_type', None): # raise BusinessException(Error.INVALID_USER_CREDENTIALS, None) is_system = token_info and Role.SYSTEM.value in token_info.get( 'realm_access').get('roles') if is_system: if entity_info.get('passCode') is not None: entity_info['passCode'] = passcode_hash( entity_info['passCode']) entity.update_from_dict(**camelback2snake(entity_info)) entity.commit() entity = Entity(entity) return entity
def validate(is_fatal=False, **kwargs) -> ValidatorResponse: """Validate and return correct access type.""" selected_payment_method: str = kwargs.get('selected_payment_method') access_type: str = kwargs.get('access_type') org_type: str = kwargs.get('org_type') default_cc_method = PaymentMethod.DIRECT_PAY.value if current_app.config.get( 'DIRECT_PAY_ENABLED') else PaymentMethod.CREDIT_CARD.value validator_response = ValidatorResponse() org_payment_method_mapping = { OrgType.BASIC: ( PaymentMethod.CREDIT_CARD.value, PaymentMethod.DIRECT_PAY.value, PaymentMethod.ONLINE_BANKING.value), OrgType.PREMIUM: ( PaymentMethod.CREDIT_CARD.value, PaymentMethod.DIRECT_PAY.value, PaymentMethod.PAD.value, PaymentMethod.BCOL.value) } if access_type == AccessType.GOVM.value: payment_type = PaymentMethod.EJV.value elif selected_payment_method: valid_types = org_payment_method_mapping.get(org_type, []) if selected_payment_method in valid_types: payment_type = selected_payment_method else: validator_response.add_error( Error.INVALID_INPUT) if is_fatal: raise BusinessException(Error.INVALID_INPUT, None) else: payment_type = PaymentMethod.BCOL.value if \ org_type == OrgType.PREMIUM else default_cc_method validator_response.add_info({'payment_type': payment_type}) return validator_response