def create_user_credential(accountname, username, credential): """ POST /accounts/{accountname}/users/{username}/credentials :param accountname: str account id for account account record :param username: str username :param credential: json object of the credential type :return: credential json object """ try: with session_scope() as session: mgr = manager_factory.for_session(session) usr = mgr.get_user(username) if not usr or usr['account_name'] != accountname: return make_response_error('Username not found in account'), 404 # For now, only support passwords via the api if credential['type'] != 'password': return make_response_error('Invalid credential type'), 400 if not credential.get('value'): return make_response_error('Invalid credential value, must be non-null and non-empty'), 400 try: cred_type = UserAccessCredentialTypes(credential['type']) except: return make_response_error(errmsg='Invalid credential type'), 400 cred = mgr.add_user_credential(session, creator_name=ApiRequestContextProxy.user(), username=username, credential_type=cred_type, value=credential['value']) return credential_db_to_msg(cred), 200 except Exception as ex: logger.exception('API Error') return make_response_error(errmsg=str(ex)), 500
def delete_user_credential(accountname, username, credential_type): """ DELETE /accounts/{accountname}/users/{username}/credentials?credential_type=password :param username: :param credential_type: :return: """ if not credential_type: return make_response_error('credential type must be specified', in_httpcode=400), 400 try: with session_scope() as session: mgr = manager_factory.for_session(session) usr = verify_user(username, accountname, mgr) if credential_type != 'password': return make_response_error('Invalid credential type', in_httpcode=400), 400 if username == ApiRequestContextProxy.identity().username: return make_response_error( 'Cannot delete credential of authenticated user', in_httpcode=400), 400 resp = mgr.delete_user_credential(username, credential_type) return None, 204 except UserNotFoundError as ex: return make_response_error('User not found', in_httpcode=404), 404 except AccountNotFoundError as ex: return make_response_error('Account not found', in_httpcode=404), 404 except Exception as ex: logger.exception('Api Error') return make_response_error(errmsg=str(ex), in_httpcode=500), 500
def delete_user(accountname, username): """ DELETE /accounts/{accountname}/users/{username} :param accountname: :param username: the user to delete :return: """ try: with session_scope() as session: mgr = manager_factory.for_session(session) verify_user(username, accountname, mgr) if ApiRequestContextProxy.identity().username == username: return make_response_error( 'Cannot delete credential used for authentication of the request', in_httpcode=400), 400 if mgr.delete_user(username): return None, 204 else: return make_response_error( 'Failed to delete user: {}'.format(username), in_httpcode=500), 500 except (UserNotFoundError, AccountNotFoundError): return make_response_error('User not found', in_httpcode=404), 404 except Exception as e: logger.exception('API Error') return make_response_error( 'Internal error deleting user {}'.format(username), in_httpcode=500), 500
def create_client(client_definition): """ POST /create_client :return: """ with session_scope() as db: # Use for handling form-urlencoded input instead of json if not request.is_json: logger.debug('Using non-json handler for defining the client') client_definition = request.form.to_dict(flat=True) logger.debug('Saving client from form: {}'.format(client_definition)) user = client_definition.get( 'user_id', ApiRequestContextProxy.identity().username) if not client_definition.get('user_id'): client_definition['user_id'] = user client = OAuth2Client(**client_definition) client.user_id = user client.client_id = gen_salt(24) if client.token_endpoint_auth_method == 'none': client.client_secret = '' else: client.client_secret = gen_salt(48) db.add(client) return { 'client_id': client.client_id, 'client_secret': client.client_secret }, 200
def create_user(accountname, user): """ POST /accounts/{accountname}/users :param accountname: :param user: :return: """ try: with session_scope() as session: mgr = manager_factory.for_session(session) verify_account(accountname, mgr) usr = mgr.create_user( account_name=accountname, username=user['username'], creator_name=ApiRequestContextProxy.identity().username, password=user['password']) return user_db_to_msg(usr), 200 except UserAlreadyExistsError as ex: return make_response_error('User already exists', in_httpcode=400), 400 except AccountNotFoundError as ex: return make_response_error('Account not found', in_httpcode=404), 404 except Exception as e: logger.exception('API Error') return make_response_error( 'Internal error deleting account {}'.format(accountname)), 500
def get_oauth_token(): """ POST /oauth/token Requires the resource-owners credentials in the Authorization Header. This is a bit of a mix of the ResourceOwnerPasswordGrant flow and the ImplicitGrant flow since this function will populate the necessary fields to perform a password grant if the Authorization header is set and no content body is provided :return: """ authz = ApiRequestContextProxy.get_service()._oauth_app if authz is None: # oauth is not enabled and not supported based on configuration return make_response_error(errmsg='Oauth not enabled in configuration', in_httpcode=500), 500 # Add some default properties if not set in the request try: if request.content_length == 0 or not request.form: logger.debug('Handling converting empty body into form-based grant request') if not request.data and not request.form: setattr(request, 'form', ImmutableMultiDict([('username', request.authorization.username), ('password', request.authorization.password), ('grant_type', 'password'), ('client_id', 'anonymous')])) resp = authz.create_token_response() logger.debug('Token resp: {}'.format(resp)) return resp except: logger.debug_exception('Error authenticating') raise
def create_account(account): """ POST /accounts :param account: :return: """ try: if account.get('type') != AccountTypes.user.value: return make_response_error( 'Invalid account type: {}. Only valid value is "user"'.format( account.get('type')), in_httpcode=400), 400 with session_scope() as session: mgr = manager_factory.for_session(session) resp = mgr.create_account( account_name=account['name'], account_type=account.get('type', AccountTypes.user.value), email=account.get('email'), creator=ApiRequestContextProxy.identity().username) return account_db_to_msg(resp), 200 except AccountAlreadyExistsError as ex: return make_response_error(errmsg='Account already exists', in_httpcode=400), 400 except Exception as ex: logger.exception('Unexpected Error creating account') return make_response_error('Error creating account', in_httpcode=500), 500
def delete_user(accountname, username): """ DELETE /accounts/{accountname}/users/{username} :param accountname: :param username: the user to delete :return: """ try: with session_scope() as session: mgr = manager_factory.for_session(session) usr = verify_user(username, accountname, mgr) if not can_delete_user(usr): return make_response_error('User not allowed to be deleted due to system constraints', in_httpcode=400), 400 elif ApiRequestContextProxy.identity().username == username: return make_response_error('Cannot delete credential used for authentication of the request', in_httpcode=400), 400 else: if mgr.delete_user(username): # Flush from authz system if necessary, will rollback if this fails, but rely on the db state checks first to gate this authorizer.notify(NotificationTypes.principal_deleted, username) return None, 204 else: return make_response_error('Failed to delete user: {}'.format(username), in_httpcode=500), 500 except (UserNotFoundError, AccountNotFoundError): return make_response_error('User not found', in_httpcode=404), 404 except Exception as e: logger.exception('API Error') return make_response_error('Internal error deleting user {}'.format(username), in_httpcode=500), 500
def get_users_account(): """ GET /account :return: """ try: with session_scope() as session: mgr = manager_factory.for_session(session) account = mgr.get_account(ApiRequestContextProxy.namespace()) return account_db_to_msg(account), 200 except Exception as ex: logger.exception("API Error") return make_response_error(errmsg=str(ex)), 500
def create_user_credential(accountname, username, credential): """ POST /accounts/{accountname}/users/{username}/credentials :param accountname: str account id for account account record :param username: str username :param credential: json object of the credential type :return: credential json object """ try: with session_scope() as session: mgr = manager_factory.for_session(session) user = verify_user(username, accountname, mgr) # For now, only support passwords via the api if credential['type'] != 'password': return make_response_error('Invalid credential type', in_httpcode=404), 404 if not credential.get('value'): return make_response_error( 'Invalid credential value, must be non-null and non-empty', in_httpcode=400), 400 try: cred_type = UserAccessCredentialTypes(credential['type']) except: return make_response_error(errmsg='Invalid credential type', in_httpcode=400), 400 cred = mgr.add_user_credential( username=username, creator_name=ApiRequestContextProxy.identity().username, credential_type=cred_type, value=credential['value']) return credential_db_to_msg(cred), 200 except UserNotFoundError as ex: return make_response_error('User not found', in_httpcode=404), 404 except AccountNotFoundError as ex: return make_response_error('Account not found', in_httpcode=404), 404 except Exception as e: logger.exception('API Error') return make_response_error( 'Internal error creating credential {}'.format(accountname)), 500
def create_user(accountname, user): """ POST /accounts/{accountname}/users :param accountname: :param user: :return: """ try: with session_scope() as session: mgr = manager_factory.for_session(session) usr = mgr.create_user(account_name=accountname, username=user['username'], creator_name=ApiRequestContextProxy.user(), password=user['password']) return user_db_to_msg(usr), 200 except Exception as ex: logger.exception('API Error') return make_response_error(errmsg=str(ex)), 500