def get(self, kyc_application_id): user_id = request.args.get('user_id') trulioo_countries = request.args.get('trulioo_countries', None) trulioo_documents = request.args.get('trulioo_documents', None) country = request.args.get('country', None) if trulioo_countries: trulioo_countries = supported_countries return make_response(jsonify({'message': 'Trulioo Countries', 'data': {'kyc_application': {'trulioo_countries': trulioo_countries}}})), 200 if trulioo_documents: trulioo_documents = {country: supported_documents[country]} return make_response(jsonify({'message': 'Trulioo Countries', 'data': {'kyc_application': {'trulioo_documents': trulioo_documents}}})), 200 if AccessControl.has_suffient_role(g.user.roles, {'ADMIN': 'subadmin'}): if user_id: # user account KYC kyc_details = KycApplication.query.filter_by(user_id=user_id).first() else: # main organisation KYC kyc_details = KycApplication.query.filter_by(organisation_id=g.active_organisation.id).first() if kyc_details is None: response_object = { 'message': 'No business verification details found' } return make_response(jsonify(response_object)), 404 if user_id and AccessControl.has_suffient_role(g.user.roles, {'ADMIN': 'admin'}): response_object = { 'message': 'Successfully loaded business verification details', 'data': {'kyc_application': kyc_application_schema.dump(kyc_details).data} } return make_response(jsonify(response_object)), 200 else: # must be an individual (mobile) user account kyc_details = KycApplication.query.filter_by(user_id=g.user.id).first() if kyc_details is None: return make_response(jsonify({'message': 'No KYC object found for user.', 'data': {'kyc_application': {}}})) # displays kyc_status and kyc_actions state only. response_object = { 'message': 'Loaded KYC details', 'data': {'kyc_application': kyc_application_state_schema.dump(kyc_details).data} } return make_response(jsonify(response_object)), 200
def get(self): user = g.user if AccessControl.has_suffient_role(user.roles, {'ADMIN': 'subadmin', 'VENDOR': 'supervendor'}): # admins and supervendors see all transfers for that transfer account transfer_account = user.transfer_account transfers_query = CreditTransfer.query.filter( or_(CreditTransfer.recipient_transfer_account_id == transfer_account.id, CreditTransfer.sender_transfer_account_id == transfer_account.id)) else: # other users only see transfers involving themselves transfers_query = CreditTransfer.query.filter( or_(CreditTransfer.recipient_user_id == user.id, CreditTransfer.sender_user_id == user.id)) transfers, total_items, total_pages = paginate_query(transfers_query, CreditTransfer) transfer_list = me_credit_transfers_schema.dump(transfers).data response_object = { 'message': 'Successfully Loaded.', 'items': total_items, 'pages': total_pages, 'data': { 'credit_transfers': transfer_list, } } return make_response(jsonify(response_object)), 201
def resolve_as_complete(self, batch_uuid=None): if self.transfer_status not in [None, TransferStatusEnum.PENDING]: raise Exception(f'Resolve called multiple times for transfer {self.id}') try: self.check_sender_transfer_limits() except TransferLimitError as e: # Sempo admins can always bypass limits, allowing for things like emergency moving of funds etc if hasattr(g, 'user') and AccessControl.has_suffient_role(g.user.roles, {'ADMIN': 'sempoadmin'}): self.add_message(f'Warning: {e}') else: raise e self.resolved_date = datetime.datetime.utcnow() self.transfer_status = TransferStatusEnum.COMPLETE self.update_balances() if self.transfer_type == TransferTypeEnum.PAYMENT and self.transfer_subtype == TransferSubTypeEnum.DISBURSEMENT: if self.recipient_user and self.recipient_user.transfer_card: self.recipient_user.transfer_card.update_transfer_card() if batch_uuid: self.batch_uuid = batch_uuid if self.fiat_ramp and self.transfer_type in [TransferTypeEnum.DEPOSIT, TransferTypeEnum.WITHDRAWAL]: self.fiat_ramp.resolve_as_complete()
def post(self): reference = None kyc_application_id = None if 'kyc_application_id' in request.form: kyc_application_id = request.form['kyc_application_id'] if 'document' not in request.files: return make_response(jsonify({'message': 'No File'})), 400 document = request.files['document'] filename = document.filename if kyc_application_id is None: return make_response(jsonify({'message': 'You must append documents to a business profile'})), 400 business_details = KycApplication.query.filter_by(id=kyc_application_id).first() if not business_details: return make_response(jsonify({'message': 'Cannot find kyc for id {}'.format(kyc_application_id)})), 404 if business_details.organisation_id and AccessControl.has_suffient_role(g.user.roles, {'ADMIN': 'superadmin'}) is not True: return make_response(jsonify({'message': 'Must be a superadmin to edit admin org KYC object'})), 401 if filename == '': return make_response(jsonify({'message': 'No File'})), 400 if not allowed_file(filename): return make_response(jsonify({'message': 'Must be JPG, JPEG, PNG or PDF'})), 400 file_type = filename.rsplit('.', 1)[1].lower() new_filename = generate_new_filename(filename, file_type) saved_document = UploadedResource.query.filter_by(filename=new_filename).first() if saved_document: return make_response(jsonify({'message': 'Document already exists'})), 400 save_to_s3_from_document(document=document, new_filename=new_filename) if 'reference' in request.form: reference = request.form['reference'] uploaded_document = UploadedResource(filename=new_filename, file_type=file_type, reference=reference, user_filename=filename) db.session.add(uploaded_document) # tie document to kyc application uploaded_document.kyc_application_id = business_details.id response_object = { 'message': 'Document uploaded', 'data': {'kyc_application': kyc_application_schema.dump(business_details).data} } return make_response(jsonify(response_object)), 201
def put(self, bank_account_id): put_data = request.get_json() kyc_application_id = put_data.get('kyc_application_id') bank_country = put_data.get('bank_country') routing_number = put_data.get('routing_number') account_number = put_data.get('account_number') currency = put_data.get('currency') if bank_account_id is None: return make_response( jsonify({'message': 'You need to provide a bank account ID'})), 400 bank_account = BankAccount.query.filter_by(id=bank_account_id).first() if kyc_application_id is None: kyc_application_id = bank_account.kyc_application_id business_details = KycApplication.query.filter_by( id=kyc_application_id).first() if not business_details: return make_response( jsonify({ 'message': 'Cannot find kyc for id {}'.format(kyc_application_id) })), 404 if business_details.organisation_id and AccessControl.has_suffient_role( g.user.roles, {'ADMIN': 'superadmin'}) is not True: return make_response( jsonify({ 'message': 'Must be a superadmin to edit admin org KYC object' })), 401 if bank_account: bank_account.kyc_application_id = kyc_application_id bank_account.bank_country = bank_country bank_account.routing_number = routing_number bank_account.account_number = account_number bank_account.currency = currency response_object = { 'message': 'Bank account edited', 'data': { 'kyc_application': kyc_application_schema.dump(business_details).data } } return make_response(jsonify(response_object)), 200
def post(self, bank_account_id): post_data = request.get_json() kyc_application_id = post_data.get('kyc_application_id') bank_country = post_data.get('bank_country') routing_number = post_data.get('routing_number') account_number = post_data.get('account_number') currency = post_data.get('currency') business_details = KycApplication.query.filter_by(id=kyc_application_id).first() if not business_details: return make_response(jsonify({'message': 'Cannot find kyc for id {}'.format(kyc_application_id)})), 404 if business_details.organisation_id and AccessControl.has_suffient_role(g.user.roles, {'ADMIN': 'superadmin'}) is not True: return make_response(jsonify({'message': 'Must be a superadmin to edit admin org KYC object'})), 401 if routing_number is None or account_number is None or bank_country is None or currency is None or kyc_application_id is None: response_object = { 'message': 'Need routing_number, account_number, bank_country, currency and business profile id', } return make_response(jsonify(response_object)), 400 # can't create a duplicate bank account at present bank_account = BankAccount.query.filter_by(routing_number=routing_number, account_number=account_number).first() if bank_account: response_object = { 'message': 'Bank account already exists', } return make_response(jsonify(response_object)), 400 # create new bank account create_bank_account = BankAccount( bank_country=bank_country, routing_number=routing_number, account_number=account_number, currency=currency, ) create_bank_account.kyc_application = business_details db.session.add(create_bank_account) response_object = { 'message': 'Bank account added', 'data': {'kyc_application': kyc_application_schema.dump(business_details).data} } return make_response(jsonify(response_object)), 201
def wrapper(*args, **kwargs): # ----- FIRST GET AUTH VALUES ----- # Query string auth needs to be explicity allowed for an endpoint since it can lead to security vulnerabilities # if used incorrectly by the client (for example credentials getting logged by website trackers). # We get credentials with it first, meaning any values will be overwritten by a present header auth if allow_query_string_auth: username = request.args.get('username', None) password = request.args.get('password', None) auth_token = request.args.get('auth_token', None) tfa_token = request.args.get('tfa_token', None) else: username = None password = None auth_token = None tfa_token = None # Next get basic auth, which we parse using flask's built-in process, if present overwriting query string values auth = request.authorization if auth and auth.type == 'basic': username = auth.username or username password = auth.password or password # Lastly, get any custom set Sempo auth headers, if present overwriting query string values auth_header = request.headers.get('Authorization') if auth_header: split_header = auth_header.split("|") auth_token = split_header[0] try: tfa_token = split_header[1] except IndexError: # Auth header does not contain a TFA token, try getting it from explicit header instead # (dev convenience) tfa_token = request.headers.get( 'TFA_Authorization') or tfa_token # ----- THEN ATTEMPT AUTHORIZATION ----- # If username as password attempt basic auth if username and password: # Make sure basic auth is allowed if len(allowed_basic_auth_types) == 0: response_object = {'message': 'basic auth not allowed'} return make_response(jsonify(response_object)), 401 # Try to find a matching password and auth type for the username, checking orgs first and then config # Check if username belongs to an org org = Organisation.query.filter_by( external_auth_username=username).first() if org: auth_type = 'external' required_password = org.external_auth_password # Otherwise, check if it is one of the allowed BASIC_AUTH_CREDENTIALS else: try: (required_password, auth_type ) = current_app.config['BASIC_AUTH_CREDENTIALS'][username] except KeyError: required_password = None auth_type = None g.auth_type = auth_type if required_password is None or required_password != password: response_object = { 'message': 'invalid basic auth username or password' } return make_response(jsonify(response_object)), 401 if (auth_type not in allowed_basic_auth_types) or (auth_type is None): response_object = { 'message': 'Basic Auth type is {}. Must be: {}'.format( auth_type, allowed_basic_auth_types) } return make_response(jsonify(response_object)), 401 g.active_organisation = org return f(*args, **kwargs) if auth_token: resp = User.decode_auth_token(auth_token) if not isinstance(resp, str): user = User.query.filter_by(id=resp['id']).execution_options( show_all=True).first() if not user: response_object = { 'status': 'fail', 'message': 'user not found' } return make_response(jsonify(response_object)), 401 if not user.is_activated: response_object = { 'status': 'fail', 'message': 'user not activated' } return make_response(jsonify(response_object)), 401 if user.is_disabled: response_object = { 'status': 'fail', 'message': 'user has been disabled' } return make_response(jsonify(response_object)), 401 tfa_response_object = tfa_logic(user, tfa_token, ignore_tfa_requirement) if tfa_response_object: return make_response(jsonify(tfa_response_object)), 401 if len(allowed_roles) > 0: held_roles = resp.get('roles', {}) if not AccessControl.has_suffient_role( held_roles, allowed_roles): response_object = { 'message': 'user does not have any of the allowed roles: ' + str(allowed_roles), } return make_response(jsonify(response_object)), 403 # ----- AUTH PASSED, DO FINAL SETUP ----- g.user = user g.member_organisations = [org.id for org in user.organisations] try: g.active_organisation = None # First try to set the active org from the query query_org = request.args.get('org', None) if query_org is not None: try: query_org = int(query_org) if query_org in g.member_organisations: g.active_organisation = Organisation.query.get( query_org) except ValueError: pass # Then get the fallback organisation if g.active_organisation is None: g.active_organisation = user.fallback_active_organisation( ) # Check for query_organisations as well. These are stored in g and used for operations which # are allowed to be run against multiple orgs. Submitted as a CSV # E.g. GET metrics, user list, transfer list should be gettable with ?query_organisations=1,2,3 query_organisations = request.args.get( 'query_organisations', None) if query_organisations: g.query_organisations = [] try: query_organisations = [ int(q) for q in query_organisations.split(',') ] if set(query_organisations).issubset( set(g.member_organisations)): g.query_organisations = query_organisations except ValueError: pass except NotImplementedError: g.active_organisation = None proxies = request.headers.getlist("X-Forwarded-For") check_ip(proxies, user, num_proxy=1) # updates the validated user last seen timestamp user.update_last_seen_ts() #This is the point where you've made it through ok and you can return the top method return f(*args, **kwargs) response_object = {'status': 'fail', 'message': resp} return make_response(jsonify(response_object)), 401 response_object = { 'status': 'fail', 'message': 'Provide a valid auth token.' } return make_response(jsonify(response_object)), 401
def get(self, user_id): can_see_full_details = AccessControl.has_suffient_role( g.user.roles, {'ADMIN': 'admin'}) if not can_see_full_details: public_serial_number = request.args.get('public_serial_number') if public_serial_number: user = User.query.filter_by( public_serial_number=public_serial_number.strip()).first() if user: if user.default_transfer_account: response_object = { 'message': 'Successfully found transfer account!', 'data': { 'balance': user.default_transfer_account.balance } } return make_response(jsonify(response_object)), 201 response_object = { 'message': 'No transfer_account for user: {}'.format(user), } return make_response(jsonify(response_object)), 400 response_object = { 'message': 'No user for public serial number: {}'.format( public_serial_number), } return make_response(jsonify(response_object)), 400 response_object = { 'message': 'No public_serial_number provided', } return make_response(jsonify(response_object)), 400 account_type_filter = request.args.get('account_type') if account_type_filter: account_type_filter = account_type_filter.lower() if user_id: user = User.query.get(user_id) # # user.cashout_authorised() if user is None: response_object = { 'message': 'No such user: {}'.format(user_id), } return make_response(jsonify(response_object)), 400 response_object = { 'status': 'success', 'message': 'Successfully Loaded.', 'data': { 'user': user_schema.dump(user).data } } return make_response(jsonify(response_object)), 200 else: if account_type_filter == 'beneficiary': user_query = User.query.filter(User.has_beneficiary_role) elif account_type_filter == 'vendor': user_query = User.query.filter(User.has_vendor_role) elif account_type_filter == 'admin': user_query = User.query.filter(User.has_admin_role).order_by( User.created.desc()) else: user_query = User.query users, total_items, total_pages = paginate_query(user_query, User) if users is None: response_object = { 'message': 'No users', } return make_response(jsonify(response_object)), 400 user_list = users_schema.dump(users).data response_object = { 'message': 'Successfully Loaded.', 'pages': total_pages, 'items': total_items, 'data': { 'users': user_list, } } return make_response(jsonify(response_object)), 200
def post(self, kyc_application_id): post_data = request.get_json() is_mobile = post_data.get('is_mobile') user_id = post_data.get( 'user_id' ) # should only be defined when an admin is adding user KYC data (not their own) type = post_data.get('account_type', 'BUSINESS').upper() first_name = post_data.get('first_name') last_name = post_data.get('last_name') phone = post_data.get('phone') business_legal_name = post_data.get('business_legal_name') business_type = post_data.get('business_type') tax_id = post_data.get('tax_id') website = post_data.get('website') date_established = post_data.get('date_established') country = post_data.get('country') street_address = post_data.get('street_address') street_address_2 = post_data.get('street_address_2') city = post_data.get('city') region = post_data.get('region') postal_code = post_data.get('postal_code') beneficial_owners = post_data.get('beneficial_owners') document_type = post_data.get('document_type') document_country = post_data.get('document_country') document_front_base64 = post_data.get('document_front_base64') # image document_back_base64 = post_data.get('document_back_base64') # image selfie_base64 = post_data.get('selfie_base64') # image if is_mobile or user_id: # creation logic is handled after kyc object creation. kyc_details = KycApplication.query.filter_by( user_id=user_id or g.user.id).first() if kyc_details is not None: return make_response( jsonify({'message': 'KYC details already exist'})), 400 if not user_id and (document_type is None or document_country is None or document_front_base64 is None or selfie_base64 is None): return make_response( jsonify({'message': 'Must provide correct parameters'})), 400 if not is_mobile and type == 'BUSINESS': if user_id and AccessControl.has_suffient_role( g.user.roles, {'ADMIN': 'subadmin'}) is not True: return make_response( jsonify({ 'message': 'Must be superadmin to create any KYC profile' })), 401 elif AccessControl.has_suffient_role( g.user.roles, {'ADMIN': 'superadmin'}) is not True: return make_response( jsonify({ 'message': 'Must be superadmin to create org business KYC profile' })), 401 # check for existing business based on Legal Name and Tax ID. business_details = KycApplication.query.filter_by( business_legal_name=business_legal_name, tax_id=tax_id).first() if business_details is not None: response_object = { 'message': 'Business Verification profile already exists for business name: {} and tax ID: {}' .format(business_legal_name, tax_id) } return make_response(jsonify(response_object)), 400 if not is_mobile and (business_legal_name is None and tax_id is None) and not user_id: # not mobile, not a org profile, thus user_id cannot be None return make_response( jsonify({ 'message': 'Must provide a user id to create a user KYC profile' })), 400 if beneficial_owners is not None: # filter empty beneficial owners beneficial_owners = [ owner for owner in beneficial_owners if (owner['full_name'].strip(' ', ) != '') ] create_kyc_application = KycApplication( type=type, user=g.user, first_name=first_name or g.user.first_name, last_name=last_name or g.user.last_name, phone=phone or g.user.phone, business_legal_name=business_legal_name, business_type=business_type, tax_id=tax_id, website=website, date_established=date_established, country=country or document_country, street_address=street_address, street_address_2=street_address_2, city=city, region=region, postal_code=postal_code, beneficial_owners=beneficial_owners, ) if user_id: user = User.query.get(user_id) create_kyc_application.user = user or g.user if not is_mobile: # not mobile if not user_id and type == 'BUSINESS': # not a admin applying for another user # ngo organisation create_kyc_application.organisation = g.active_organisation else: # admin applying for another user (individual or business) create_kyc_application.kyc_status = 'INCOMPLETE' db.session.add(create_kyc_application) db.session.flush() # need this to create an ID if is_mobile: # handle document upload to s3 handle_kyc_documents(data=post_data, document_country=document_country, document_type=document_type, kyc_details=create_kyc_application) # Post verification message to slack post_verification_message(user=g.user) response_object = { 'message': 'KYC Application created', 'data': { 'kyc_application': kyc_application_state_schema.dump(create_kyc_application).data } } return make_response(jsonify(response_object)), 201
def put(self, kyc_application_id): put_data = request.get_json() is_mobile = put_data.get('is_mobile') document_type = put_data.get('document_type') document_country = put_data.get('document_country') document_front_base64 = put_data.get('document_front_base64') # image document_back_base64 = put_data.get('document_back_base64') # image selfie_base64 = put_data.get('selfie_base64') # image kyc_status = put_data.get('kyc_status') first_name = put_data.get('first_name') last_name = put_data.get('last_name') phone = put_data.get('phone') business_legal_name = put_data.get('business_legal_name') business_type = put_data.get('business_type') tax_id = put_data.get('tax_id') website = put_data.get('website') date_established = put_data.get('date_established') country = put_data.get('country') street_address = put_data.get('street_address') street_address_2 = put_data.get('street_address_2') city = put_data.get('city') region = put_data.get('region') postal_code = put_data.get('postal_code') beneficial_owners = put_data.get('beneficial_owners') kyc_details = None if is_mobile: if document_type is None or document_country is None or document_front_base64 is None or selfie_base64 is None: return make_response( jsonify({'message': 'Must provide correct parameters'})), 400 kyc_details = KycApplication.query.filter_by( user_id=g.user.id).first() if kyc_details is None: return make_response( jsonify({'message': 'No KYC object found'})), 400 kyc_details.kyc_attempts = kyc_details.kyc_attempts + 1 if kyc_details.kyc_attempts > 2: # only allow two attempts kyc_details.kyc_status = 'REJECTED' db.session.commit() return make_response( jsonify( {'message': 'KYC attempts exceeded. Contact Support.'})), 400 kyc_details.kyc_status = 'PENDING' # handle document upload to s3 handle_kyc_documents(data=put_data, document_country=document_country, document_type=document_type, kyc_details=kyc_details) # Post verification message to slack post_verification_message(user=g.user) response_object = { 'message': 'Successfully Updated KYC Application.', 'data': { 'kyc_application': kyc_application_schema.dump(kyc_details).data } } return make_response(jsonify(response_object)), 200 if not is_mobile: if kyc_application_id is None: response_object = { 'message': 'Must provide business profile ID' } return make_response(jsonify(response_object)), 400 kyc_details = KycApplication.query.get(kyc_application_id) if not kyc_details: response_object = { 'message': 'Business Verification Profile not found' } return make_response(jsonify(response_object)), 404 if kyc_details.organisation_id and AccessControl.has_suffient_role( g.user.roles, {'ADMIN': 'superadmin'}) is not True: return make_response( jsonify({ 'message': 'Must be a superadmin to edit admin org KYC object' })), 401 if AccessControl.has_suffient_role( g.user.roles, {'ADMIN': 'subadmin'}) is not True: return make_response( jsonify({ 'message': 'Must be a subadmin to edit any KYC object' })), 401 # update business profile if kyc_status: kyc_details.kyc_status = kyc_status if first_name: kyc_details.first_name = first_name if last_name: kyc_details.last_name = last_name if phone: kyc_details.phone = phone if business_legal_name: kyc_details.business_legal_name = business_legal_name if business_type: kyc_details.business_type = business_type if tax_id: kyc_details.tax_id = tax_id if website: kyc_details.website = website if date_established: kyc_details.date_established = date_established if country: kyc_details.country = country if street_address: kyc_details.street_address = street_address if street_address_2: kyc_details.street_address_2 = street_address_2 if city: kyc_details.city = city if region: kyc_details.region = region if postal_code: kyc_details.postal_code = postal_code if beneficial_owners is not None: # filter empty beneficial owners beneficial_owners = [ owner for owner in beneficial_owners if (owner['full_name'].strip(' ', ) != '') ] if beneficial_owners: kyc_details.beneficial_owners = beneficial_owners if kyc_status == 'PENDING': # Final web submission. Post verification message to slack post_verification_message(user=kyc_details.user) response_object = { 'message': 'Successfully Updated KYC Application.', 'data': { 'kyc_application': kyc_application_schema.dump(kyc_details).data } } return make_response(jsonify(response_object)), 200
def post(self, organisation_id): post_data = request.get_json() organisation_name = post_data.get('organisation_name') custom_welcome_message_key = post_data.get( 'custom_welcome_message_key') timezone = post_data.get('timezone') country_code = post_data.get('country_code') default_disbursement = post_data.get('default_disbursement') minimum_vendor_payout_withdrawal = post_data.get( 'minimum_vendor_payout_withdrawal') require_transfer_card = post_data.get('require_transfer_card') default_lat = post_data.get('default_lat') default_lng = post_data.get('default_lng') account_types = post_data.get('account_types', []) token_id = post_data.get('token_id') deploy_cic = post_data.get('deploy_cic', False) for at in account_types: if at not in ASSIGNABLE_TIERS.keys(): raise Exception(f'{at} not an assignable role') if organisation_name is None or country_code is None or timezone is None: return make_response( jsonify({ 'message': 'Must provide organisation_name, country_code and timezone to create organisation.' })), 400 existing_organisation = Organisation.query.filter_by( name=organisation_name).execution_options(show_all=True).first() if existing_organisation is not None: return make_response( jsonify({ 'message': 'Must be unique name. Organisation already exists for name: {}' .format(organisation_name), 'data': { 'organisation': organisation_schema.dump(existing_organisation).data } })), 400 try: new_organisation = Organisation( name=organisation_name, custom_welcome_message_key=custom_welcome_message_key, timezone=timezone, country_code=country_code, default_disbursement=default_disbursement, minimum_vendor_payout_withdrawal= minimum_vendor_payout_withdrawal, require_transfer_card=require_transfer_card, default_lat=default_lat, default_lng=default_lng, valid_roles=account_types) except Exception as e: response_object = { 'message': str(e), } return make_response(jsonify(response_object)), 400 db.session.add(new_organisation) db.session.flush() response_object = { 'message': 'Created Project', 'data': { 'organisation': organisation_schema.dump(new_organisation).data }, } if token_id: token = Token.query.get(token_id) if token is None: return make_response(jsonify({'message': 'Token not found'})), 404 new_organisation.bind_token(token) elif deploy_cic: cic_response_object, cic_response_code = deploy_cic_token( post_data, new_organisation) if cic_response_code == 201: response_object['data']['token_id'] = cic_response_object[ 'data']['token_id'] else: return make_response( jsonify(cic_response_object)), cic_response_code if AccessControl.has_suffient_role(g.user.roles, {'ADMIN': 'superadmin'}): g.user.add_user_to_organisation(new_organisation, is_admin=True) return make_response(jsonify(response_object)), 201