def post(org_id): """Create a new contact for the specified org.""" request_json = request.get_json() valid_format, errors = schema_utils.validate(request_json, 'contact') if not valid_format: return { 'message': schema_utils.serialize(errors) }, http_status.HTTP_400_BAD_REQUEST try: response, status = OrgService.add_contact( org_id, request_json).as_dict(), http_status.HTTP_201_CREATED except BusinessException as exception: response, status = { 'code': exception.code, 'message': exception.message }, exception.status_code return response, status
def test_add_contact(client, jwt, session): # pylint:disable=unused-argument """Assert that a contact can be added (POST) to an existing user.""" # POST a test user headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.public_user_role) rv = client.post('/api/v1/users', headers=headers, content_type='application/json') # POST a contact to test user rv = client.post('/api/v1/users/contacts', data=json.dumps(TestContactInfo.contact1), headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_201_CREATED assert schema_utils.validate(rv.json, 'contact_response')[0] contact = json.loads(rv.data) assert contact['email'] == '*****@*****.**'
def test_authorizations_for_account_with_search_returns_200(client, jwt, session): # pylint:disable=unused-argument """Assert authorizations for product returns 200.""" product_code = 'PPR' user = factory_user_model() org = factory_org_model() factory_membership_model(user.id, org.id) factory_product_model(org.id) claims = copy.deepcopy(TestJwtClaims.public_user_role.value) claims['sub'] = str(user.keycloak_guid) headers = factory_auth_header(jwt=jwt, claims=claims) rv = client.get(f'/api/v1/accounts/{org.id}/products/{product_code}/authorizations', headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_200_OK assert schema_utils.validate(rv.json, 'account_response')[0] assert len(rv.json.get('roles')) > 0
def post(org_id): """Create new api key for the org.""" request_json = request.get_json() valid_format, errors = schema_utils.validate(request_json, 'api_key') if not valid_format: return { 'message': schema_utils.serialize(errors) }, http_status.HTTP_400_BAD_REQUEST try: response, status = ApiGatewayService.create_key( org_id, request_json), http_status.HTTP_201_CREATED except BusinessException as exception: response, status = { 'code': exception.code, 'message': exception.message }, exception.status_code return response, status
def put(business_identifier): """Update the business contact for the Entity identified by the provided id.""" request_json = request.get_json() valid_format, errors = schema_utils.validate(request_json, 'contact') if not valid_format: return {'message': schema_utils.serialize(errors)}, http_status.HTTP_400_BAD_REQUEST try: entity = EntityService.find_by_business_identifier(business_identifier, token_info=g.jwt_oidc_token_info, allowed_roles=ALL_ALLOWED_ROLES) if entity: response, status = entity.update_contact(request_json).as_dict(), \ http_status.HTTP_200_OK else: response, status = {'message': 'The requested business could not be found.'}, \ http_status.HTTP_404_NOT_FOUND except BusinessException as exception: response, status = {'code': exception.code, 'message': exception.message}, exception.status_code return response, status
def test_add_user_admin_valid_bcros(client, jwt, session, keycloak_mock): # pylint:disable=unused-argument """Assert that an anonymous admin can be POSTed.""" headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.staff_admin_dir_search_role) rv = client.post('/api/v1/users', headers=headers, content_type='application/json') rv = client.post('/api/v1/orgs', data=json.dumps(TestOrgInfo.org_anonymous), headers=headers, content_type='application/json') dictionary = json.loads(rv.data) org_id = dictionary['id'] rv = client.post('/api/v1/invitations', data=json.dumps(factory_invitation_anonymous(org_id=org_id)), headers=headers, content_type='application/json') dictionary = json.loads(rv.data) assert dictionary.get('token') is not None assert rv.status_code == http_status.HTTP_201_CREATED rv = client.post('/api/v1/users/bcros', data=json.dumps(TestUserInfo.user_anonymous_1), headers={'invitation_token': dictionary.get('token')}, content_type='application/json') dictionary = json.loads(rv.data) assert rv.status_code == http_status.HTTP_201_CREATED assert dictionary['users'][0].get('username') == IdpHint.BCROS.value + '/' + TestUserInfo.user_anonymous_1[ 'username'] assert dictionary['users'][0].get('password') is None assert dictionary['users'][0].get('type') == Role.ANONYMOUS_USER.name assert schema_utils.validate(rv.json, 'anonymous_user_response')[0] # different error scenarios # check expired invitation rv = client.post('/api/v1/users/bcros', data=json.dumps(TestUserInfo.user_anonymous_1), headers={'invitation_token': dictionary.get('token')}, content_type='application/json') dictionary = json.loads(rv.data) assert dictionary['code'] == 'EXPIRED_INVITATION' rv = client.post('/api/v1/invitations', data=json.dumps(factory_invitation_anonymous(org_id=org_id)), headers=headers, content_type='application/json') dictionary = json.loads(rv.data) # check duplicate user rv = client.post('/api/v1/users/bcros', data=json.dumps(TestUserInfo.user_anonymous_1), headers={'invitation_token': dictionary.get('token')}, content_type='application/json') dictionary = json.loads(rv.data) assert dictionary['code'] == 409 assert dictionary['message'] == 'The username is already taken'
def post(): """Create a new contact for the user associated with the JWT in the authorization header.""" token = g.jwt_oidc_token_info request_json = request.get_json() valid_format, errors = schema_utils.validate(request_json, 'contact') if not valid_format: return { 'message': schema_utils.serialize(errors) }, http_status.HTTP_400_BAD_REQUEST try: response, status = UserService.add_contact( token, request_json).as_dict(), http_status.HTTP_201_CREATED except BusinessException as exception: response, status = { 'code': exception.code, 'message': exception.message }, exception.status_code return response, status
def post(): """Post a new user using the request body who has a proper invitation.""" try: request_json = request.get_json() invitation_token = request.headers.get('invitation_token', None) invitation = InvitationService.validate_token( invitation_token).as_dict() valid_format, errors = schema_utils.validate( request_json, 'anonymous_user') if not valid_format: return { 'message': schema_utils.serialize(errors) }, http_status.HTTP_400_BAD_REQUEST membership_details = { 'email': invitation['recipientEmail'], 'membershipType': invitation['membership'][0]['membershipType'], 'update_password_on_login': False } membership_details.update(request_json) user = UserService.create_user_and_add_membership( [membership_details], invitation['membership'][0]['org']['id'], single_mode=True) user_dict = user['users'][0] if user_dict['http_status'] != http_status.HTTP_201_CREATED: response, status = { 'code': user_dict['http_status'], 'message': user_dict['error'] }, user_dict['http_status'] else: InvitationService.accept_invitation(invitation['id'], None, None, False) response, status = user, http_status.HTTP_201_CREATED except BusinessException as exception: response, status = { 'code': exception.code, 'message': exception.message }, exception.status_code return response, status
def post(): """Post a new Entity using the request body.""" request_json = request.get_json() valid_format, errors = schema_utils.validate(request_json, 'entity') if not valid_format: return { 'message': schema_utils.serialize(errors) }, http_status.HTTP_400_BAD_REQUEST try: response, status = EntityService.save_entity( request_json).as_dict(), http_status.HTTP_201_CREATED except BusinessException as exception: response, status = { 'code': exception.code, 'message': exception.message }, exception.status_code return response, status
def test_get_user_settings(client, jwt, session, keycloak_mock): # pylint:disable=unused-argument """Assert that get works and adhere to schema.""" user_model = factory_user_model(user_info=TestUserInfo.user_test) contact = factory_contact_model() contact_link = ContactLinkModel() contact_link.contact = contact contact_link.user = user_model contact_link.commit() kc_id = user_model.keycloak_guid OrgService.create_org(TestOrgInfo.org1, user_id=user_model.id) claims = copy.deepcopy(TestJwtClaims.updated_test.value) claims['sub'] = str(kc_id) # post token with updated claims headers = factory_auth_header(jwt=jwt, claims=claims) rv = client.get(f'/api/v1/users/{kc_id}/settings', headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_200_OK assert schema_utils.validate(rv.json, 'user_settings_response')
def test_update_invitation(client, jwt, session, keycloak_mock): # pylint:disable=unused-argument """Assert that an invitation can be updated.""" headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.public_user_role) rv = client.post('/api/v1/users', headers=headers, content_type='application/json') rv = client.post('/api/v1/orgs', data=json.dumps(TestOrgInfo.org1), headers=headers, content_type='application/json') dictionary = json.loads(rv.data) org_id = dictionary['id'] rv = client.post('/api/v1/invitations', data=json.dumps(factory_invitation(org_id=org_id)), headers=headers, content_type='application/json') invitation_dictionary = json.loads(rv.data) invitation_id = invitation_dictionary['id'] updated_invitation = {} rv = client.patch('/api/v1/invitations/{}'.format(invitation_id), data=json.dumps(updated_invitation), headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_200_OK assert schema_utils.validate(rv.json, 'invitation_response')[0] dictionary = json.loads(rv.data) assert dictionary['status'] == 'PENDING'
def post(): """Post a new Entity using the request body.""" request_json = request.get_json() # If the record exists, just return existing record. entity = EntityService.find_by_business_identifier(request_json.get('businessIdentifier'), allowed_roles=ALL_ALLOWED_ROLES) if entity: return entity.as_dict(), http_status.HTTP_202_ACCEPTED valid_format, errors = schema_utils.validate(request_json, 'entity') if not valid_format: return {'message': schema_utils.serialize(errors)}, http_status.HTTP_400_BAD_REQUEST try: response, status = EntityService.save_entity(request_json).as_dict(), http_status.HTTP_201_CREATED except BusinessException as exception: response, status = {'code': exception.code, 'message': exception.message}, exception.status_code return response, status
def test_documents_returns_200(client, jwt, session): # pylint:disable=unused-argument """Assert get documents endpoint returns 200.""" headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.public_user_role) rv = client.get('/api/v1/documents/termsofuse', headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_200_OK assert rv.json.get('versionId') == '4' headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.anonymous_bcros_role) rv = client.get('/api/v1/documents/termsofuse', headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_200_OK assert schema_utils.validate(rv.json, 'document')[0] assert rv.json.get('versionId') == 'd1'
def test_staff_get_user(client, jwt, session): # pylint:disable=unused-argument """Assert that a staff user can GET a user by id.""" # POST a test user headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.public_user_role) rv = client.post('/api/v1/users', headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_201_CREATED # GET the test user as a staff user headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.staff_role) rv = client.get('/api/v1/users/{}'.format( TestJwtClaims.public_user_role['preferred_username']), headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_200_OK assert schema_utils.validate(rv.json, 'user_response')[0] user = json.loads(rv.data) assert user['firstname'] is not None
def post(): """Post a new org using the request body. If the org already exists, update the attributes. """ request_json = request.get_json() valid_format, errors = schema_utils.validate(request_json, 'org') if not valid_format: return {'message': schema_utils.serialize(errors)}, http_status.HTTP_400_BAD_REQUEST try: user = UserService.find_by_jwt_token() if user is None: response, status = {'message': 'Not authorized to perform this action'}, \ http_status.HTTP_401_UNAUTHORIZED return response, status response, status = OrgService.create_org(request_json, user.identifier).as_dict(), http_status.HTTP_201_CREATED except BusinessException as exception: response, status = {'code': exception.code, 'message': exception.message}, exception.status_code return response, status
def test_authorizations_for_affiliated_users_returns_200(client, jwt, session): # pylint:disable=unused-argument """Assert authorizations for affiliated users returns 200.""" user = factory_user_model() org = factory_org_model() factory_membership_model(user.id, org.id) entity = factory_entity_model() factory_affiliation_model(entity.id, org.id) claims = copy.deepcopy(TestJwtClaims.edit_user_role.value) claims['sub'] = str(user.keycloak_guid) headers = factory_auth_header(jwt=jwt, claims=claims) rv = client.get( f'/api/v1/entities/{entity.business_identifier}/authorizations', headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_200_OK assert schema_utils.validate(rv.json, 'account_response')[0] assert rv.json.get('orgMembership') == 'ADMIN'
def test_add_invitation(client, jwt, session, keycloak_mock): # pylint:disable=unused-argument """Assert that an invitation can be POSTed.""" headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.public_user_role) rv = client.post('/api/v1/users', headers=headers, content_type='application/json') rv = client.post('/api/v1/orgs', data=json.dumps(TestOrgInfo.org1), headers=headers, content_type='application/json') dictionary = json.loads(rv.data) org_id = dictionary['id'] rv = client.post('/api/v1/invitations', data=json.dumps(factory_invitation(org_id=org_id)), headers=headers, content_type='application/json') dictionary = json.loads(rv.data) assert dictionary.get('token') is not None assert rv.status_code == http_status.HTTP_201_CREATED assert schema_utils.validate(rv.json, 'invitation_response')[0]
def test_add_contact(client, jwt, session): # pylint:disable=unused-argument """Assert that a contact can be added to an entity.""" headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.system_role) rv = client.post('/api/v1/entities', data=json.dumps(TestEntityInfo.entity1), headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_201_CREATED headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.system_role) rv = client.post('/api/v1/entities/{}/contacts'.format( TestEntityInfo.entity1['businessIdentifier']), headers=headers, data=json.dumps(TestContactInfo.contact1), content_type='application/json') assert rv.status_code == http_status.HTTP_201_CREATED assert schema_utils.validate(rv.json, 'business')[0] dictionary = json.loads(rv.data) assert len(dictionary['contacts']) == 1 assert dictionary['contacts'][0]['email'] == TestContactInfo.contact1[ 'email']
def test_add_single_org_product(client, jwt, session, keycloak_mock): # pylint:disable=unused-argument """Assert that an org can be POSTed.""" headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.staff_admin_role) rv = client.post('/api/v1/users', headers=headers, content_type='application/json') rv = client.post('/api/v1/orgs', data=json.dumps(TestOrgInfo.org1), headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_201_CREATED dictionary = json.loads(rv.data) rv_products = client.post(f"/api/v1/orgs/{dictionary.get('id')}/products", data=json.dumps( TestOrgProductsInfo.org_products1), headers=headers, content_type='application/json') assert rv_products.status_code == http_status.HTTP_201_CREATED assert schema_utils.validate(rv_products.json, 'org_product_subscriptions_response')[0]
def put(org_id): """Update the org specified by the provided id with the request body.""" request_json = request.get_json() action = request.args.get('action', '').upper() valid_format, errors = schema_utils.validate(request_json, 'org') toke_info = g.jwt_oidc_token_info bearer_token = request.headers['Authorization'].replace('Bearer ', '') origin = request.environ.get('HTTP_ORIGIN', 'localhost') if not valid_format: return { 'message': schema_utils.serialize(errors) }, http_status.HTTP_400_BAD_REQUEST try: org = OrgService.find_by_org_id(org_id, g.jwt_oidc_token_info, allowed_roles=(*CLIENT_ADMIN_ROLES, STAFF)) if org and org.as_dict().get('accessType', None) == AccessType.ANONYMOUS.value and \ Role.STAFF_CREATE_ACCOUNTS.value not in toke_info.get('realm_access').get('roles'): return {'message': 'The organisation can only be updated by a staff admin.'}, \ http_status.HTTP_401_UNAUTHORIZED if org: if action in (ChangeType.DOWNGRADE.value, ChangeType.UPGRADE.value): response, status = org.change_org_ype( request_json, action, bearer_token).as_dict(), http_status.HTTP_200_OK else: response, status = org.update_org(org_info=request_json, token_info=toke_info, bearer_token=bearer_token, origin_url=origin).as_dict(), \ http_status.HTTP_200_OK else: response, status = {'message': 'The requested organization could not be found.'}, \ http_status.HTTP_404_NOT_FOUND except BusinessException as exception: response, status = { 'code': exception.code, 'message': exception.message }, exception.status_code return response, status
def post(org_id): """Post a new product subscription to the org using the request body.""" request_json = request.get_json() valid_format, errors = schema_utils.validate( request_json, 'org_product_subscription') if not valid_format: return { 'message': schema_utils.serialize(errors) }, http_status.HTTP_400_BAD_REQUEST try: subscriptions = ProductService.create_product_subscription( org_id, request_json) response, status = { 'subscriptions': subscriptions }, http_status.HTTP_201_CREATED except BusinessException as exception: response, status = { 'code': exception.code, 'message': exception.message }, exception.status_code return response, status
def put(org_id): """Update the org specified by the provided id with the request body.""" request_json = request.get_json() valid_format, errors = schema_utils.validate(request_json, 'org') token_info = g.jwt_oidc_token_info if not valid_format: return {'message': schema_utils.serialize(errors)}, http_status.HTTP_400_BAD_REQUEST try: org = OrgService.find_by_org_id(org_id, allowed_roles=(*CLIENT_ADMIN_ROLES, STAFF)) if org and org.as_dict().get('accessType', None) == AccessType.ANONYMOUS.value and \ Role.STAFF_CREATE_ACCOUNTS.value not in token_info.get('realm_access').get('roles'): return {'message': 'The organisation can only be updated by a staff admin.'}, \ http_status.HTTP_401_UNAUTHORIZED if org: response, status = org.update_org(org_info=request_json).as_dict(), \ http_status.HTTP_200_OK else: response, status = {'message': 'The requested organization could not be found.'}, \ http_status.HTTP_404_NOT_FOUND except BusinessException as exception: response, status = {'code': exception.code, 'message': exception.message}, exception.status_code return response, status
def test_get_entity(client, jwt, session): # pylint:disable=unused-argument """Assert that an entity can be retrieved via GET.""" headers_system = factory_auth_header(jwt=jwt, claims=TestJwtClaims.system_role) rv_create = client.post('/api/v1/entities', data=json.dumps(TestEntityInfo.entity1), headers=headers_system, content_type='application/json') assert rv_create.status_code == http_status.HTTP_201_CREATED headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.system_role) rv = client.get('/api/v1/entities/{}'.format( TestEntityInfo.entity1['businessIdentifier']), headers=headers, content_type='application/json') assert rv.status_code == http_status.HTTP_200_OK assert schema_utils.validate(rv.json, 'business')[0] dictionary = json.loads(rv.data) assert dictionary['businessIdentifier'] == TestEntityInfo.entity1[ 'businessIdentifier']
def test_user_post_during_login(client, jwt, session): # pylint:disable=unused-argument """Assert that a user can be POSTed.""" # Create a user by POST, then create same user with login flag and make sure the login date is different headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.public_user_role) rv = client.post('/api/v1/users', headers=headers, content_type='application/json') login_time = rv.json.get('loginTime') # Call the same endpoint again and confirm logn time is same rv = client.post('/api/v1/users', headers=headers, content_type='application/json') assert login_time == rv.json.get('loginTime') # Call same endpoint with login flag and assert login time is different rv = client.post('/api/v1/users', headers=headers, data=json.dumps({'isLogin': True}), content_type='application/json') assert schema_utils.validate(rv.json, 'user_response')[0] assert login_time != rv.json.get('loginTime')
def patch(): """Update terms of service for the user.""" request_json = request.get_json() valid_format, errors = schema_utils.validate(request_json, 'termsofuse') if not valid_format: return { 'message': schema_utils.serialize(errors) }, http_status.HTTP_400_BAD_REQUEST version = request_json['termsversion'] is_terms_accepted = request_json['istermsaccepted'] try: response, status = UserService.update_terms_of_use(is_terms_accepted, version).as_dict(), \ http_status.HTTP_200_OK except BusinessException as exception: response, status = { 'code': exception.code, 'message': exception.message }, exception.status_code return response, status
def put(): """Update an existing contact for the user associated with the JWT in the authorization header.""" token = g.jwt_oidc_token_info request_json = request.get_json() valid_format, errors = schema_utils.validate(request_json, 'contact') if not token: return { 'message': 'Authorization required.' }, http_status.HTTP_401_UNAUTHORIZED if not valid_format: return { 'message': schema_utils.serialize(errors) }, http_status.HTTP_400_BAD_REQUEST try: response, status = UserService.update_contact( token, request_json).as_dict(), http_status.HTTP_200_OK except BusinessException as exception: response, status = { 'code': exception.code, 'message': exception.message }, exception.status_code return response, status
def post(user_guid): """Create affidavit record for the user.""" token = g.jwt_oidc_token_info request_json = request.get_json() if token.get('sub', None) != user_guid: abort(403) valid_format, errors = schema_utils.validate(request_json, 'affidavit') if not valid_format: return { 'message': schema_utils.serialize(errors) }, http_status.HTTP_400_BAD_REQUEST try: response, status = AffidavitService.create_affidavit( token, request_json).as_dict(), http_status.HTTP_200_OK except BusinessException as exception: response, status = { 'code': exception.code, 'message': exception.message }, exception.status_code return response, status
def post(): """Send a new invitation using the details in request and saves the invitation.""" token = g.jwt_oidc_token_info origin = request.environ.get('HTTP_ORIGIN', 'localhost') request_json = request.get_json() valid_format, errors = schema_utils.validate(request_json, 'invitation') if not valid_format: return { 'message': schema_utils.serialize(errors) }, http_status.HTTP_400_BAD_REQUEST try: user = UserService.find_by_jwt_token(token) response, status = InvitationService.create_invitation( request_json, user, token, origin).as_dict(), http_status.HTTP_201_CREATED except BusinessException as exception: response, status = { 'code': exception.code, 'message': exception.message }, exception.status_code return response, status
def post(): """Post a new user using the request body (which will contain a JWT). If the user already exists, update the name. """ token = g.jwt_oidc_token_info try: request_json = request.get_json(silent=True) # For BCeID users validate schema. if token.get( 'loginSource', None ) == LoginSource.BCEID.value and request_json is not None: valid_format, errors = schema_utils.validate( request_json, 'user') if not valid_format: return { 'message': schema_utils.serialize(errors) }, http_status.HTTP_400_BAD_REQUEST user = UserService.save_from_jwt_token(token, request_json) response, status = user.as_dict(), http_status.HTTP_201_CREATED # Add the user to public_users group if the user doesn't have public_user group if token.get('loginSource', '') != LoginSource.STAFF.value: KeycloakService.join_users_group(token) # For anonymous users, there are no invitation process for members, # so whenever they login perform this check and add them to corresponding groups if token.get('loginSource', '') == LoginSource.BCROS.value: if len( OrgService.get_orgs(user.identifier, [Status.ACTIVE.value])) > 0: KeycloakService.join_account_holders_group() except BusinessException as exception: response, status = { 'code': exception.code, 'message': exception.message }, exception.status_code return response, status
def post(org_id): """Post a new Affiliation for an org using the request body.""" request_json = request.get_json() valid_format, errors = schema_utils.validate(request_json, 'affiliation') bearer_token = request.headers['Authorization'].replace('Bearer ', '') is_new_business = request.args.get('newBusiness', 'false').lower() == 'true' if not valid_format: return { 'message': schema_utils.serialize(errors) }, http_status.HTTP_400_BAD_REQUEST try: if is_new_business: response, status = AffiliationService.create_new_business_affiliation( org_id, request_json.get('businessIdentifier'), request_json.get('email'), request_json.get('phone'), token_info=g.jwt_oidc_token_info, bearer_token=bearer_token).as_dict( ), http_status.HTTP_201_CREATED else: response, status = AffiliationService.create_affiliation( org_id, request_json.get('businessIdentifier'), request_json.get('passCode'), token_info=g.jwt_oidc_token_info).as_dict( ), http_status.HTTP_201_CREATED except BusinessException as exception: response, status = { 'code': exception.code, 'message': exception.message }, exception.status_code return response, status