def upgrade(): # Query all orgs which are linked to BCOL. conn = op.get_bind() org_res = conn.execute( "select o.id, o.bcol_user_id from orgs o where bcol_user_id is not null and bcol_account_id is not null and status_code in ('ACTIVE', 'PENDING_STAFF_REVIEW');" ) orgs = org_res.fetchall() print('starting migration for BCOL products') if len(orgs) > 0: token = RestService.get_service_account_token() for org_id in orgs: try: print('Getting bcol profile for ', org_id[0], org_id[1]) bcol_response = RestService.get( endpoint=current_app.config.get('BCOL_API_URL') + f'/profiles/{org_id[1]}', token=token) print('BCOL Response', bcol_response.json()) Product.create_subscription_from_bcol_profile( org_id[0], bcol_response.json().get('profileFlags')) except Exception as exc: print('Profile Error') print(exc) raise exc db.session.commit()
def _create_sandbox_pay_account(cls, pay_request, user): current_app.logger.info('Creating Sandbox Payload %s', pay_request) pay_sandbox_accounts_endpoint = f"{current_app.config.get('PAY_API_SANDBOX_URL')}/accounts?sandbox=true" RestService.post(endpoint=pay_sandbox_accounts_endpoint, token=user.bearer_token, data=pay_request, raise_for_status=True)
def revoke_key(cls, org_id: int, api_key: str): """Revoke api key.""" current_app.logger.debug('<revoke_key ') consumer_endpoint: str = current_app.config.get('API_GW_CONSUMERS_API_URL') gw_api_key: str = current_app.config.get('API_GW_KEY') email_id = cls._get_email_id(org_id) RestService.patch( f'{consumer_endpoint}/mc/v1/consumers/{email_id}/apiKeys/{api_key}?action=removeAccess', additional_headers={'x-apikey': gw_api_key}, data=dict(apiAccess='ALL_API'), generate_token=False )
def create_key(cls, org_id: int, request_json: Dict[str, str]): """Create a key for the account.""" current_app.logger.debug('<create_key ') env = request_json.get('environment', 'sandbox') name = request_json.get('keyName') org: OrgModel = OrgModel.find_by_id(org_id) # first find if there is a consumer created for this account. consumer_endpoint: str = current_app.config.get('API_GW_CONSUMERS_API_URL') gw_api_key = current_app.config.get('API_GW_KEY') if env == 'prod' else current_app.config.get( 'API_GW_NON_PROD_KEY') email = cls._get_email_id(org_id) if not org.has_api_access: # If the account doesn't have api access, add it client_rep = generate_client_representation(org_id, current_app.config.get('API_GW_KC_CLIENT_ID_PATTERN')) KeycloakService.create_client(client_rep) service_account = KeycloakService.get_service_account_user(client_rep.get('id')) KeycloakService.add_user_to_group(service_account.get('id'), GROUP_API_GW_USERS) KeycloakService.add_user_to_group(service_account.get('id'), GROUP_ACCOUNT_HOLDERS) # Create a consumer with the keycloak client id and secret create_consumer_payload = dict(email=email, firstName=org.name, lastName=org.branch_name or 'BCR', userName=org.name, clientId=client_rep.get('clientId'), clientSecret=client_rep.get('secret'), apiAccess=['ALL_API'], apiKeyName=name) api_key_response = RestService.post( f'{consumer_endpoint}/mc/v1/consumers', additional_headers={'x-apikey': gw_api_key}, data=create_consumer_payload, generate_token=False ) org.has_api_access = True org.save() else: # Create additional API Key if a consumer exists api_key_response = RestService.post( f'{consumer_endpoint}/mc/v1/consumers/{email}/apikeys', additional_headers={'x-apikey': gw_api_key}, data=dict( apiAccess=['ALL_API'], apiKeyName=name ), generate_token=False ) return api_key_response.json()
def _consumer_exists(cls, email, env): """Return if customer exists with this email.""" consumer_endpoint: str = cls._get_api_consumer_endpoint(env) gw_api_key: str = cls._get_api_gw_key(env) try: RestService.get( f'{consumer_endpoint}/mc/v1/consumers/{email}', additional_headers={'x-apikey': gw_api_key} ) except HTTPError as exc: if exc.response.status_code == 404: # If consumer doesn't exist return False raise exc return True
def validate(is_fatal=False, **kwargs) -> ValidatorResponse: """Validate bcol credentials.""" bcol_credential = kwargs.get('bcol_credential') org_id = kwargs.get('org_id', None) user: UserContext = kwargs['user'] validator_response = ValidatorResponse() bcol_response = RestService.post( endpoint=current_app.config.get('BCOL_API_URL') + '/profiles', data=bcol_credential, token=user.bearer_token, raise_for_status=False) if bcol_response.status_code != http_status.HTTP_200_OK: error = json.loads(bcol_response.text) validator_response.add_error( CustomException(error['detail'], bcol_response.status_code)) if is_fatal: raise BusinessException( CustomException(error['detail'], bcol_response.status_code), None) else: bcol_account_number = bcol_response.json().get('accountNumber') from auth_api.services.org import Org as OrgService # pylint:disable=cyclic-import, import-outside-toplevel if OrgService.bcol_account_link_check(bcol_account_number, org_id): validator_response.add_error(Error.BCOL_ACCOUNT_ALREADY_LINKED) if is_fatal: raise BusinessException(Error.BCOL_ACCOUNT_ALREADY_LINKED, None) else: validator_response.add_info({'bcol_response': bcol_response}) return validator_response
def _create_consumer(cls, name, org, env): """Create an API Gateway consumer.""" consumer_endpoint: str = cls._get_api_consumer_endpoint(env) gw_api_key = cls._get_api_gw_key(env) email = cls._get_email_id(org.id, env) client_rep = generate_client_representation(org.id, current_app.config.get('API_GW_KC_CLIENT_ID_PATTERN'), env) KeycloakService.create_client(client_rep) service_account = KeycloakService.get_service_account_user(client_rep.get('id')) KeycloakService.add_user_to_group(service_account.get('id'), GROUP_API_GW_USERS if env == 'prod' else GROUP_API_GW_SANDBOX_USERS) KeycloakService.add_user_to_group(service_account.get('id'), GROUP_ACCOUNT_HOLDERS) # Create a consumer with the keycloak client id and secret create_consumer_payload = dict(email=email, firstName=org.name, lastName=org.branch_name or 'BCR', userName=org.name, clientId=client_rep.get('clientId'), clientSecret=client_rep.get('secret'), apiAccess=['ALL_API'], apiKeyName=name) api_key_response = RestService.post( f'{consumer_endpoint}/mc/v1/consumers', additional_headers={'x-apikey': gw_api_key}, data=create_consumer_payload, generate_token=False ) return api_key_response
def _get_pad_confirmation_report_pdf(email_msg, token): current_time = datetime.datetime.now() mailing_address = _get_address(email_msg.get('accountId')) template_vars = { **email_msg, 'generatedDate': current_time.strftime('%m-%d-%Y'), 'accountAddress': mailing_address } filled_template = generate_template( current_app.config.get('PDF_TEMPLATE_PATH'), 'pad_confirmation') template_b64 = "'" + base64.b64encode(bytes(filled_template, 'utf-8')).decode() + "'" pdf_payload = { 'reportName': 'PAD_Confirmation_Letter', 'template': template_b64, 'templateVars': template_vars, 'populatePageNumber': True, } report_response = RestService.post( endpoint=current_app.config.get('REPORT_API_BASE_URL'), token=token, auth_header_type=AuthHeaderType.BEARER, content_type=ContentType.JSON, data=pdf_payload, raise_for_status=True, additional_headers={'Accept': 'application/pdf'}) pdf_attachment = None if report_response.status_code != 200: logger.error('Failed to get pdf') else: pdf_attachment = base64.b64encode(report_response.content) return pdf_attachment
def send_email(notify_body: dict ,token:str): # pylint:disable=unused-argument """Send the email asynchronously, using the given details.""" current_app.logger.info(f'send_email to {notify_body.get("recipients")}') notify_url = current_app.config.get('NOTIFY_API_URL') + '/notify/' notify_response = RestService.post(notify_url, token=token, data=notify_body) current_app.logger.info('send_email notify_response') if notify_response: response_json = json.loads(notify_response.text) if response_json['notifyStatus']['code'] != 'FAILURE': return True return False
def revoke_key(cls, org_id: int, api_key: str): """Revoke api key.""" current_app.logger.debug('<revoke_key ') check_auth(one_of_roles=(ADMIN, STAFF), org_id=org_id) # Find the environment for this key, based on it consumer changes. email_id: str = None for key in cls.get_api_keys(org_id)['consumer']['consumerKey']: if key['apiKey'] == api_key: email_id = key['email'] break if not email_id: raise BusinessException(Error.DATA_NOT_FOUND, Exception()) env = 'sandbox' if email_id == cls._get_email_id(org_id, 'prod'): env = 'prod' consumer_endpoint = cls._get_api_consumer_endpoint(env) gw_api_key = cls._get_api_gw_key(env) RestService.patch( f'{consumer_endpoint}/mc/v1/consumers/{email_id}/apikeys/{api_key}?action=revoke', additional_headers={'x-apikey': gw_api_key}, data=dict(apiAccess='ALL_API'), generate_token=False )
def get_api_keys(cls, org_id: int) -> List[Dict[str, any]]: """Get all api keys.""" current_app.logger.debug('<get_api_keys ') consumer_endpoint: str = current_app.config.get('API_GW_CONSUMERS_API_URL') gw_api_key: str = current_app.config.get('API_GW_KEY') email_id = cls._get_email_id(org_id) try: consumers_response = RestService.get( f'{consumer_endpoint}/mc/v1/consumers/{email_id}', additional_headers={'x-apikey': gw_api_key} ) api_keys = consumers_response.json() except HTTPError as exc: if exc.response.status_code == 404: api_keys = {} else: raise exc return api_keys
def create_key(cls, org_id: int, request_json: Dict[str, str]): """Create a key for the account. Steps: A - If consumer doesn't exist, 1 - Create a consumer for PROD and one for SANDBOX 2 - Keycloak Client created for Sandbox consumer added to sandbox group (new role for sandbox) 3 - Keycloak client created for PROD consumer added to prod group B - If consumer already exists, 1 - Create key for specific environment. """ current_app.logger.debug('<create_key ') env = request_json.get('environment', 'sandbox') name = request_json.get('keyName') org: OrgModel = OrgModel.find_by_id(org_id) # first find if there is a consumer created for this account. consumer_endpoint: str = cls._get_api_consumer_endpoint(env) gw_api_key = cls._get_api_gw_key(env) email = cls._get_email_id(org_id, env) if not cls._consumer_exists(email, env): # If the account doesn't have api access, add it # If env is sandbox; then create a sandbox payment account. if env != 'prod': cls._create_payment_account(org) cls._create_consumer(name, org, env=env) org.has_api_access = True org.save() response = cls.get_api_keys(org_id) else: # Create additional API Key if a consumer exists api_key_response = RestService.post( f'{consumer_endpoint}/mc/v1/consumers/{email}/apikeys', additional_headers={'x-apikey': gw_api_key}, data=dict( apiAccess=['ALL_API'], apiKeyName=name ), generate_token=False ) response = api_key_response.json() return response
def get_api_keys(cls, org_id: int) -> List[Dict[str, any]]: """Get all api keys.""" current_app.logger.debug('<get_api_keys ') check_auth(one_of_roles=(ADMIN, STAFF), org_id=org_id) api_keys_response = {'consumer': {'consumerKey': []}} for env in ('sandbox', 'prod'): email = cls._get_email_id(org_id, env) consumer_endpoint: str = cls._get_api_consumer_endpoint(env) gw_api_key: str = cls._get_api_gw_key(env) try: consumers_response = RestService.get( f'{consumer_endpoint}/mc/v1/consumers/{email}', additional_headers={'x-apikey': gw_api_key} ) keys = consumers_response.json()['consumer']['consumerKey'] cls._filter_and_add_keys(api_keys_response, keys, email) except HTTPError as exc: if exc.response.status_code != 404: # If consumer doesn't exist raise exc return api_keys_response
async def process_event(event_message: dict, flask_app): """Process the incoming queue event message.""" if not flask_app: raise QueueException('Flask App not available.') with flask_app.app_context(): message_type = event_message.get('type', None) email_msg = None email_dict = None token = RestService.get_service_account_token() if message_type == 'account.mailer': email_msg = json.loads(event_message.get('data')) email_dict = payment_completed.process(email_msg) elif message_type == 'bc.registry.payment.refundRequest': email_msg = event_message.get('data') email_dict = refund_requested.process(email_msg) elif event_message.get('type', None) == 'bc.registry.payment.padAccountCreate': email_msg = event_message.get('data') email_dict = pad_confirmation.process(email_msg, token) logger.debug('Extracted email msg: %s', email_dict) process_email(email_dict, FLASK_APP, token)
async def process_event(event_message: dict, flask_app): """Process the incoming queue event message.""" if not flask_app: raise QueueException('Flask App not available.') with flask_app.app_context(): message_type = event_message.get('type', None) email_msg = event_message.get('data') email_msg['logo_url'] = minio_service.MinioService.get_minio_public_url('bc_logo_for_email.png') email_dict = None token = RestService.get_service_account_token() logger.debug('message_type recieved %s', message_type) if message_type == 'account.mailer': email_dict = payment_completed.process(email_msg) elif message_type == MessageType.REFUND_REQUEST.value: email_dict = refund_requested.process(email_msg) elif message_type == MessageType.PAD_ACCOUNT_CREATE.value: email_msg['registry_logo_url'] = minio_service.MinioService.get_minio_public_url('bc_registry_logo_pdf.svg') email_dict = pad_confirmation.process(email_msg, token) elif message_type == MessageType.NSF_LOCK_ACCOUNT.value: logger.debug('lock account message recieved:') template_name = TemplateType.NSF_LOCK_ACCOUNT_TEMPLATE_NAME.value org_id = email_msg.get('accountId') admin_coordinator_emails = get_member_emails(org_id, (ADMIN, COORDINATOR)) subject = SubjectType.NSF_LOCK_ACCOUNT_SUBJECT.value logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, subject, logo_url=logo_url) elif message_type == MessageType.NSF_UNLOCK_ACCOUNT.value: logger.debug('unlock account message recieved') template_name = TemplateType.NSF_UNLOCK_ACCOUNT_TEMPLATE_NAME.value org_id = email_msg.get('accountId') admin_coordinator_emails = get_member_emails(org_id, (ADMIN, COORDINATOR)) subject = SubjectType.NSF_UNLOCK_ACCOUNT_SUBJECT.value logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, subject, logo_url=logo_url) elif message_type == MessageType.ACCOUNT_CONFIRMATION_PERIOD_OVER.value: template_name = TemplateType.ACCOUNT_CONF_OVER_TEMPLATE_NAME.value org_id = email_msg.get('accountId') nsf_fee = email_msg.get('nsfFee') admin_coordinator_emails = get_member_emails(org_id, (ADMIN,)) subject = SubjectType.ACCOUNT_CONF_OVER_SUBJECT.value logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, subject, nsf_fee=nsf_fee, logo_url=logo_url) elif message_type in (MessageType.TEAM_MODIFIED.value, MessageType.TEAM_MEMBER_INVITED.value): logger.debug('Team Modified message received') template_name = TemplateType.TEAM_MODIFIED_TEMPLATE_NAME.value org_id = email_msg.get('accountId') admin_coordinator_emails = get_member_emails(org_id, (ADMIN,)) subject = SubjectType.TEAM_MODIFIED_SUBJECT.value logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, subject, logo_url=logo_url) elif message_type == MessageType.ADMIN_REMOVED.value: logger.debug('ADMIN_REMOVED message received') template_name = TemplateType.ADMIN_REMOVED_TEMPLATE_NAME.value org_id = email_msg.get('accountId') recipient_email = email_msg.get('recipientEmail') subject = SubjectType.ADMIN_REMOVED_SUBJECT.value logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, recipient_email, template_name, subject, logo_url=logo_url) elif message_type == MessageType.PAD_INVOICE_CREATED.value: template_name = TemplateType.PAD_INVOICE_CREATED_TEMPLATE_NAME.value org_id = email_msg.get('accountId') admin_coordinator_emails = get_member_emails(org_id, (ADMIN,)) subject = SubjectType.PAD_INVOICE_CREATED.value args = { 'nsf_fee': email_msg.get('nsfFee'), 'invoice_total': email_msg.get('invoice_total'), } logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, subject, logo_url=logo_url, **args) elif message_type in (MessageType.ONLINE_BANKING_OVER_PAYMENT.value, MessageType.ONLINE_BANKING_UNDER_PAYMENT.value, MessageType.ONLINE_BANKING_PAYMENT.value): if message_type == MessageType.ONLINE_BANKING_OVER_PAYMENT.value: template_name = TemplateType.ONLINE_BANKING_OVER_PAYMENT_TEMPLATE_NAME.value elif message_type == MessageType.ONLINE_BANKING_UNDER_PAYMENT.value: template_name = TemplateType.ONLINE_BANKING_UNDER_PAYMENT_TEMPLATE_NAME.value else: template_name = TemplateType.ONLINE_BANKING_PAYMENT_TEMPLATE_NAME.value org_id = email_msg.get('accountId') admin_emails = get_member_emails(org_id, (ADMIN,)) subject = SubjectType.ONLINE_BANKING_PAYMENT_SUBJECT.value args = { 'title': subject, 'paid_amount': email_msg.get('amount'), 'credit_amount': email_msg.get('creditAmount'), } logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, admin_emails, template_name, subject, logo_url=logo_url, **args) elif message_type == MessageType.PAD_SETUP_FAILED.value: template_name = TemplateType.PAD_SETUP_FAILED_TEMPLATE_NAME.value org_id = email_msg.get('accountId') admin_coordinator_emails = get_member_emails(org_id, (ADMIN,)) subject = SubjectType.PAD_SETUP_FAILED.value args = { 'accountId': email_msg.get('accountId'), } logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, subject, logo_url=logo_url, **args) elif message_type == MessageType.PAYMENT_PENDING.value: template_name = TemplateType.PAYMENT_PENDING_TEMPLATE_NAME.value org_id = email_msg.get('accountId') admin_coordinator_emails = get_member_emails(org_id, (ADMIN,)) subject = SubjectType.PAYMENT_PENDING.value args = { 'accountId': email_msg.get('accountId'), 'cfsAccountId': email_msg.get('cfsAccountId'), 'transactionAmount': email_msg.get('transactionAmount'), } logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, subject, logo_url=logo_url, **args) elif message_type == MessageType.EJV_FAILED.value: email_dict = ejv_failures.process(email_msg) if email_dict: logger.debug('Extracted email msg Recipient: %s ', email_dict.get('recipients', '')) process_email(email_dict, FLASK_APP, token) else: # TODO probably an unhandled event.handle better logger.error('No email content generated')
async def process_name_events(event_message: Dict[str, any]): """Process name events. 1. Check if the NR already exists in entities table, if yes apply changes. If not create entity record. 2. Check if new status is DRAFT, if yes call pay-api and get the account details for the payments against the NR. 3. If an account is found, affiliate to that account. Args: event_message (object): cloud event message, sample below. { 'specversion': '1.0.1', 'type': 'bc.registry.names.events', 'source': '/requests/6724165', 'id': id, 'time': '', 'datacontenttype': 'application/json', 'identifier': '781020202', 'data': { 'request': { 'nrNum': 'NR 5659951', 'newState': 'APPROVED', 'previousState': 'DRAFT' } } } """ logger.debug('>>>>>>>process_name_events>>>>>') request_data = event_message.get('data').get('request') nr_number = request_data['nrNum'] nr_status = request_data['newState'] nr_entity = EntityModel.find_by_business_identifier(nr_number) if nr_entity is None: logger.info('Entity doesn' 't exist, creating a new entity.') nr_entity = EntityModel(business_identifier=nr_number, corp_type_code=CorpType.NR.value) nr_entity.status = nr_status nr_entity.name = request_data.get( 'name', '') # its not part of event now, this is to handle if they include it. nr_entity.last_modified_by = None # TODO not present in event message. nr_entity.last_modified = parser.parse(event_message.get('time')) if nr_status == 'DRAFT' and AffiliationModel.find_affiliations_by_business_identifier( nr_number) is None: logger.info('Status is DRAFT, getting invoices for account') # Find account details for the NR. invoices = RestService.get( f'{APP_CONFIG.PAY_API_URL}/payment-requests?businessIdentifier={nr_number}', token=RestService.get_service_account_token()).json() # Ideally there should be only one or two (priority fees) payment request for the NR. if invoices and (auth_account_id := invoices['invoices'][0].get('paymentAccount').get('accountId')) \ and str(auth_account_id).isnumeric(): logger.info('Account ID received : %s', auth_account_id) # Auth account id can be service account value too, so doing a query lookup than find_by_id org: OrgModel = db.session.query(OrgModel).filter( OrgModel.id == auth_account_id).one_or_none() if org: nr_entity.pass_code_claimed = True # Create an affiliation. logger.info( 'Creating affiliation between Entity : %s and Org : %s', nr_entity, org) affiliation: AffiliationModel = AffiliationModel( entity=nr_entity, org=org) affiliation.flush()
async def process_event(event_message: dict, flask_app): """Process the incoming queue event message.""" if not flask_app: raise QueueException('Flask App not available.') with flask_app.app_context(): message_type = event_message.get('type', None) email_msg = event_message.get('data') email_msg[ 'logo_url'] = minio_service.MinioService.get_minio_public_url( 'bc_logo_for_email.png') email_dict = None token = RestService.get_service_account_token() logger.debug('message_type recieved %s', message_type) if message_type == 'account.mailer': email_dict = payment_completed.process(email_msg) elif message_type in ([ MessageType.REFUND_DIRECT_PAY_REQUEST.value, MessageType.REFUND_DRAWDOWN_REQUEST.value ]): email_dict = refund_requested.process(event_message) elif message_type == MessageType.PAD_ACCOUNT_CREATE.value: email_msg[ 'registry_logo_url'] = minio_service.MinioService.get_minio_public_url( 'bc_registry_logo_pdf.svg') email_dict = pad_confirmation.process(email_msg, token) elif message_type == MessageType.NSF_LOCK_ACCOUNT.value: logger.debug('lock account message recieved:') template_name = TemplateType.NSF_LOCK_ACCOUNT_TEMPLATE_NAME.value org_id = email_msg.get('accountId') admin_coordinator_emails = get_member_emails( org_id, (ADMIN, COORDINATOR)) subject = SubjectType.NSF_LOCK_ACCOUNT_SUBJECT.value logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, subject, logo_url=logo_url) elif message_type == MessageType.NSF_UNLOCK_ACCOUNT.value: logger.debug('unlock account message recieved') template_name = TemplateType.NSF_UNLOCK_ACCOUNT_TEMPLATE_NAME.value org_id = email_msg.get('accountId') admin_coordinator_emails = get_member_emails( org_id, (ADMIN, COORDINATOR)) subject = SubjectType.NSF_UNLOCK_ACCOUNT_SUBJECT.value logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, subject, logo_url=logo_url) elif message_type == MessageType.ACCOUNT_CONFIRMATION_PERIOD_OVER.value: template_name = TemplateType.ACCOUNT_CONF_OVER_TEMPLATE_NAME.value org_id = email_msg.get('accountId') nsf_fee = email_msg.get('nsfFee') admin_coordinator_emails = get_member_emails(org_id, (ADMIN, )) subject = SubjectType.ACCOUNT_CONF_OVER_SUBJECT.value logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, subject, nsf_fee=nsf_fee, logo_url=logo_url) elif message_type in (MessageType.TEAM_MODIFIED.value, MessageType.TEAM_MEMBER_INVITED.value): logger.debug('Team Modified message received') template_name = TemplateType.TEAM_MODIFIED_TEMPLATE_NAME.value org_id = email_msg.get('accountId') admin_coordinator_emails = get_member_emails(org_id, (ADMIN, )) subject = SubjectType.TEAM_MODIFIED_SUBJECT.value logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, subject, logo_url=logo_url) elif message_type == MessageType.ADMIN_REMOVED.value: logger.debug('ADMIN_REMOVED message received') template_name = TemplateType.ADMIN_REMOVED_TEMPLATE_NAME.value org_id = email_msg.get('accountId') recipient_email = email_msg.get('recipientEmail') subject = SubjectType.ADMIN_REMOVED_SUBJECT.value logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, recipient_email, template_name, subject, logo_url=logo_url) elif message_type == MessageType.PAD_INVOICE_CREATED.value: template_name = TemplateType.PAD_INVOICE_CREATED_TEMPLATE_NAME.value org_id = email_msg.get('accountId') admin_coordinator_emails = get_member_emails(org_id, (ADMIN, )) subject = SubjectType.PAD_INVOICE_CREATED.value invoice_process_date = datetime.fromisoformat( email_msg.get('invoice_process_date')) args = { 'nsf_fee': email_msg.get('nsfFee'), 'invoice_total': email_msg.get('invoice_total'), 'invoice_process_date': get_local_formatted_date(invoice_process_date, '%m-%d-%Y') } logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, subject, logo_url=logo_url, **args) elif message_type in (MessageType.ONLINE_BANKING_OVER_PAYMENT.value, MessageType.ONLINE_BANKING_UNDER_PAYMENT.value, MessageType.ONLINE_BANKING_PAYMENT.value): if message_type == MessageType.ONLINE_BANKING_OVER_PAYMENT.value: template_name = TemplateType.ONLINE_BANKING_OVER_PAYMENT_TEMPLATE_NAME.value elif message_type == MessageType.ONLINE_BANKING_UNDER_PAYMENT.value: template_name = TemplateType.ONLINE_BANKING_UNDER_PAYMENT_TEMPLATE_NAME.value else: template_name = TemplateType.ONLINE_BANKING_PAYMENT_TEMPLATE_NAME.value org_id = email_msg.get('accountId') admin_emails = get_member_emails(org_id, (ADMIN, )) subject = SubjectType.ONLINE_BANKING_PAYMENT_SUBJECT.value args = { 'title': subject, 'paid_amount': email_msg.get('amount'), 'credit_amount': email_msg.get('creditAmount'), } logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, admin_emails, template_name, subject, logo_url=logo_url, **args) elif message_type == MessageType.PAD_SETUP_FAILED.value: template_name = TemplateType.PAD_SETUP_FAILED_TEMPLATE_NAME.value org_id = email_msg.get('accountId') admin_coordinator_emails = get_member_emails(org_id, (ADMIN, )) subject = SubjectType.PAD_SETUP_FAILED.value args = { 'accountId': email_msg.get('accountId'), } logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, subject, logo_url=logo_url, **args) elif message_type == MessageType.PAYMENT_PENDING.value: template_name = TemplateType.PAYMENT_PENDING_TEMPLATE_NAME.value org_id = email_msg.get('accountId') admin_coordinator_emails = get_member_emails(org_id, (ADMIN, )) subject = SubjectType.PAYMENT_PENDING.value args = { 'accountId': email_msg.get('accountId'), 'cfsAccountId': email_msg.get('cfsAccountId'), 'transactionAmount': email_msg.get('transactionAmount'), } logo_url = email_msg.get('logo_url') email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, subject, logo_url=logo_url, **args) elif message_type == MessageType.EJV_FAILED.value: email_dict = ejv_failures.process(email_msg) elif message_type == MessageType.RESET_PASSCODE.value: template_name = TemplateType.RESET_PASSCODE_TEMPLATE_NAME.value subject = SubjectType.RESET_PASSCODE.value email_msg.update({'header': Constants.RESET_PASSCODE_HEADER.value}) email_dict = common_mailer.process( org_id=None, recipients=email_msg.get('emailAddresses'), template_name=template_name, subject=subject, **email_msg) else: if any(x for x in MessageType if x.value == message_type): title = TitleType[MessageType(message_type).name].value subject = SubjectType[MessageType(message_type).name].value\ .format(user_first_name=email_msg.get('userFirstName'), user_last_name=email_msg.get('userLastName'), product_name=email_msg.get('productName'), account_name=email_msg.get('orgName') ) template_name = TemplateType[ f'{MessageType(message_type).name}_TEMPLATE_NAME'].value else: return kwargs = { 'title': title, 'user_first_name': email_msg.get('userFirstName'), 'user_last_name': email_msg.get('userLastName'), 'context_url': email_msg.get('contextUrl'), 'role': email_msg.get('role'), 'label': email_msg.get('label'), 'product_name': email_msg.get('productName'), 'remarks': email_msg.get('remarks'), 'applicationDate': email_msg.get('applicationDate') } org_id = email_msg.get('accountId') logo_url = email_msg.get('logo_url') email_dict = common_mailer.process( org_id=org_id, recipients=email_msg.get('emailAddresses'), template_name=template_name, logo_url=logo_url, subject=subject, **kwargs) if email_dict: logger.debug('Extracted email msg Recipient: %s ', email_dict.get('recipients', '')) process_email(email_dict, FLASK_APP, token) else: # TODO probably an unhandled event.handle better logger.error('No email content generated')
def send_email(notify_body: dict, token: str): # pylint:disable=unused-argument """Send the email asynchronously, using the given details.""" current_app.logger.info(f'send_email to {notify_body.get("recipients")}') notify_url = current_app.config.get('NOTIFY_API_URL') + '/notify/' RestService.post(notify_url, token=token, data=notify_body) current_app.logger.info(f'Email sent to {notify_body.get("recipients")}')
def upgrade(): # ### commands auto generated by Alembic - please adjust! ### op.add_column( 'org', sa.Column('bcol_account_id', sa.String(length=20), nullable=True)) op.add_column( 'org', sa.Column('bcol_user_id', sa.String(length=20), nullable=True)) op.add_column( 'org_version', sa.Column('bcol_account_id', sa.String(length=20), autoincrement=False, nullable=True)) op.add_column( 'org_version', sa.Column('bcol_user_id', sa.String(length=20), autoincrement=False, nullable=True)) # iterate over each org and invoke payment api to create payment records conn = op.get_bind() org_res = conn.execute( f"select * from org o where status_code = 'ACTIVE';") org_list: List[Org] = org_res.fetchall() acc_res = conn.execute( f"select * from account_payment_settings where is_active;") account_payment_list: List[ AccountPaymentSettingsDeprecated] = acc_res.fetchall() account_payment_dict: Dict[int, AccountPaymentSettingsDeprecated] = { account_payment.org_id: account_payment for account_payment in account_payment_list } pay_url = current_app.config.get('PAY_API_URL') default_type = PaymentMethod.DIRECT_PAY.value if current_app.config.get( 'DIRECT_PAY_ENABLED') else PaymentMethod.CREDIT_CARD.value if len(org_list) > 0: token = RestService.get_service_account_token() for org in org_list: # invoke pay-api for each org account_payment_detail = account_payment_dict.get(org.id) pay_request = { 'accountId': org.id, 'accountName': org.name, 'paymentInfo': { 'methodOfPayment': getattr(account_payment_detail, 'preferred_payment_code', default_type), 'billable': org.billable } } if is_premium := org.type_code == OrgType.PREMIUM.value: bcol_account_number = getattr(account_payment_detail, 'bcol_account_id', '') bcol_user_id = getattr(account_payment_detail, 'bcol_user_id', '') pay_request['bcolAccountNumber'] = bcol_account_number pay_request['bcolUserId'] = bcol_user_id accounts_url = f'{pay_url}/accounts/{org.id}' RestService.put(endpoint=accounts_url, data=pay_request, token=token, raise_for_status=False) if is_premium: op.execute( f"update org set bcol_account_id = '{bcol_account_number}' , " f"bcol_user_id = '{bcol_user_id}' where id={org.id}")
def _get_pay_account(cls, org, user): pay_accounts_endpoint = f"{current_app.config.get('PAY_API_URL')}/accounts/{org.id}" pay_account = RestService.get(endpoint=pay_accounts_endpoint, token=user.bearer_token).json() return pay_account