def _verify_token(self, token, user): if not self.token_verified_cache.get_verify_hash_result(token, user.id): if not verify_hash(compare_data=user.password, hashed_data=token): raise_unauthorized_user_error( 'Authentication failed for {0}'.format(user) ) else: self.token_verified_cache.cache_verify_hash_result(token, user.id)
def _check_if_user_is_locked(self, user, auth): if self.external_auth_configured: return user if not user: raise_unauthorized_user_error('Authentication failed for ' '<User username=`{0}`>'.format( auth.username)) if user.is_locked: raise_unauthorized_user_error( 'Authentication failed for {0}.' ' Bad credentials or locked account'.format(user))
def _check_if_user_is_locked(self, user, auth): if self.external_auth_configured: return user if not user: raise_unauthorized_user_error( 'Authentication failed for ' '<User username=`{0}`>'.format(auth.username) ) if user.is_locked: raise_unauthorized_user_error( 'Authentication failed for {0}.' ' Bad credentials or locked account'.format(user))
def _authenticate_token(self, token): """Make sure that the token passed exists, is valid, is not expired, and that the user contained within it exists in the DB :param token: An authentication token :return: A tuple: (A user object, its hashed password) """ self.logger.debug('Authenticating token') expired, invalid, user, data, error = \ user_handler.get_token_status(token) if expired: raise_unauthorized_user_error('Token is expired') elif invalid or (not isinstance(data, list) or len(data) != 2): raise_unauthorized_user_error( 'Authentication token is invalid:\n{0}'.format(error) ) elif not user: raise_unauthorized_user_error('No authentication info provided') elif md5(user.password) != data[1]: raise_unauthorized_user_error( 'Authentication failed for {0}'.format(user) ) return user
def authorize(self, user, request): """Assert that the user is allowed to access a certain endpoint via a certain method :param user: A valid user object :param request: A flask request """ # TODO: See if this is still relevant after the roles redesign self._role = user.role self._method = request.method self._endpoint = request.path if not user.active: raise_unauthorized_user_error('{0} is not active'.format(user))
def authenticate(self, request): user = self._internal_auth(request) is_bootstrap_admin = user and user.is_bootstrap_admin if self.external_auth \ and not is_bootstrap_admin \ and not self.token_based_auth: self.logger.debug('using external auth') user = user_handler.get_user_from_auth(request.authorization) user = self.external_auth.authenticate(request, user) if not user: raise_unauthorized_user_error('No authentication info provided') self.logger.info('Authenticated user: {0}'.format(user)) user.last_login_at = datetime.now() user_datastore.commit() return user
def _internal_auth(self, request): user = None auth = request.authorization token = user_handler.get_token_from_request(request) api_token = user_handler.get_api_token_from_request(request) self.token_based_auth = token or api_token if auth: # Basic authentication (User + Password) user = user_handler.get_user_from_auth(auth) user = self._authenticate_password(user, auth) elif token: # Token authentication user = self._authenticate_token(token) elif api_token: # API token authentication user, user_token_key = user_handler.extract_api_token(api_token) if not user or user.api_token_key != user_token_key: raise_unauthorized_user_error( 'API token authentication failed') return user
def _http_auth(self, user, username, password): """Perform basic user authentication - Check that the password that was passed in the request can be verified against the password stored in the DB :param user: The DB user object :param username: The username from the request :param password: The password from the request :return: The DB user object """ self.logger.debug('Running basic HTTP authentication') if not user: raise_unauthorized_user_error( 'Authentication failed for ' '<User username=`{0}`>'.format(username)) if not verify_password(password, user.password): raise_unauthorized_user_error( 'Authentication failed for {0}'.format(user)) return user
def authenticate(self, request): auth = request.authorization token = user_handler.get_token_from_request(request) api_token = user_handler.get_api_token_from_request(request) if auth: # User + Password authentication user = user_handler.get_user_from_auth(auth) user = self._authenticate_password(user, auth) elif token: # Token authentication user = self._authenticate_token(token) elif api_token: # API token authentication user, user_token_key = user_handler.extract_api_token(api_token) if not user or user.api_token_key != user_token_key: raise_unauthorized_user_error( 'API token authentication failed') else: raise_unauthorized_user_error('No authentication ' 'info provided') user.last_login_at = datetime.now() user_datastore.commit() return user
def _internal_auth(self, request): user = None auth = request.authorization token = user_handler.get_token_from_request(request) api_token = user_handler.get_api_token_from_request(request) execution_token = get_execution_token_from_request(request) self.token_based_auth = token or api_token or execution_token if auth: # Basic authentication (User + Password) user = user_handler.get_user_from_auth(auth) self._check_if_user_is_locked(user, auth) user = self._authenticate_password(user, auth) elif execution_token: # Execution Token authentication user = self._authenticate_execution_token() elif token: # Token authentication user = self._authenticate_token(token) elif api_token: # API token authentication user, user_token_key = user_handler.extract_api_token(api_token) if not user or user.api_token_key != user_token_key: raise_unauthorized_user_error( 'API token authentication failed') return user
def post(self): """ Enable/Disable SSL """ if not current_user.is_admin: raise_unauthorized_user_error( '{0} does not have privileges to set SSL mode'.format( current_user)) request_dict = rest_utils.get_json_and_verify_params({'state'}) state = rest_utils.verify_and_convert_bool('state', request_dict.get('state')) status = 'enabled' if state else 'disabled' if state == SSLConfig._is_enabled(): return 'SSL is already {0} on the manager'.format(status) source = HTTP_PATH if state else HTTPS_PATH target = HTTPS_PATH if state else HTTP_PATH cmd = 'sudo sed -i "s~{0}~{1}~g" {2}'.format(source, target, DEFAULT_CONF_PATH) check_call(cmd, shell=True) Popen('sleep 1; sudo systemctl restart nginx', shell=True) return 'SSL is now {0} on the manager'.format(status)
def authenticate(self, request): user = None auth = request.authorization token = user_handler.get_token_from_request(request) api_token = user_handler.get_api_token_from_request(request) if auth: # Basic authentication (User + Password) user = user_handler.get_user_from_auth(auth) user = self._authenticate_password(user, auth) elif token: # Token authentication user = self._authenticate_token(token) elif api_token: # API token authentication user, user_token_key = user_handler.extract_api_token(api_token) if not user or user.api_token_key != user_token_key: raise_unauthorized_user_error( 'API token authentication failed') elif self.okta_configured and \ current_app.okta.okta_saml_inside(request): user = user_handler.get_okta_user(request.data, logger=self.logger) if not user: raise_unauthorized_user_error('OKTA authentication failed') if not user: raise_unauthorized_user_error('No authentication info provided') self.logger.info('Authenticated user: {0}'.format(user)) user.last_login_at = datetime.now() user_datastore.commit() return user
def post(self, maintenance_action, **_): if not current_user.is_admin: raise_unauthorized_user_error( '{0} does not have privileges to set maintenance mode'.format( current_user)) maintenance_file_path = get_maintenance_file_path() if maintenance_action == 'activate': if os.path.isfile(maintenance_file_path): state = utils.read_json_file(maintenance_file_path) return state, 304 now = utils.get_formatted_timestamp() try: user = current_user.username except AttributeError: user = '' remaining_executions = get_running_executions() status = MAINTENANCE_MODE_ACTIVATING \ if remaining_executions else MAINTENANCE_MODE_ACTIVATED activated_at = '' if remaining_executions else now utils.mkdirs(config.instance.maintenance_folder) new_state = prepare_maintenance_dict( status=status, activation_requested_at=now, activated_at=activated_at, remaining_executions=remaining_executions, requested_by=user) utils.write_dict_to_json_file(maintenance_file_path, new_state) return new_state if maintenance_action == 'deactivate': if not os.path.isfile(maintenance_file_path): return prepare_maintenance_dict( MAINTENANCE_MODE_DEACTIVATED), 304 os.remove(maintenance_file_path) return prepare_maintenance_dict(MAINTENANCE_MODE_DEACTIVATED) valid_actions = ['activate', 'deactivate'] raise BadParametersError( 'Invalid action: {0}, Valid action ' 'values are: {1}'.format(maintenance_action, valid_actions))
def _http_auth(self, user, username, password): """Perform basic user authentication - Check that the password that was passed in the request can be verified against the password stored in the DB :param user: The DB user object :param username: The username from the request :param password: The password from the request :return: The DB user object """ self.logger.debug('Running basic HTTP authentication') if not user: raise_unauthorized_user_error( 'Authentication failed for ' '<User username=`{0}`>'.format(username) ) if not verify_password(password, user.password): self._increment_failed_logins_counter(user) raise_unauthorized_user_error( 'Authentication failed for {0}.' ' Bad credentials or locked account'.format(user) ) return user
def _authenticate_execution_token(self): """Make sure the token passed exists and valid (by verifying the current_execution). Valid token is connected to an active execution :return: A user object """ self.logger.debug('Authenticating execution token') error_msg = 'Authentication failed, invalid Execution Token' if not current_execution: self.logger.debug('{0}. Exactly one execution should match this ' 'token'.format(error_msg)) raise_unauthorized_user_error(error_msg) if current_execution.status not in ExecutionState.ACTIVE_STATES: # Valid if it is a scheduled execution that is just started to run if self._is_valid_scheduled_execution(): return current_execution.creator # Not an active execution self.logger.debug('{0}. The execution is not active' .format(error_msg)) raise_unauthorized_user_error(error_msg) return current_execution.creator
def authenticate(self, request): user = self._internal_auth(request) is_bootstrap_admin = user and user.is_bootstrap_admin if self.external_auth_configured \ and not is_bootstrap_admin \ and not self.token_based_auth: self.logger.debug('using external auth') user = user_handler.get_user_from_auth(request.authorization) response = self.external_auth.authenticate(request, user) if isinstance(response, Response): return response user = response if not user: raise_unauthorized_user_error('No authentication info provided') self.logger.debug('Authenticated user: {0}'.format(user)) if request.authorization: # Reset the counter only when using basic authentication # (User + Password), otherwise the counter will be reset on # every UI refresh (every 4 sec) and accounts won't be locked. user.failed_logins_counter = 0 user.last_login_at = datetime.now() user_datastore.commit() return user
def _authenticate_token(self, token): """Make sure that the token passed exists, is valid, is not expired, and that the user contained within it exists in the DB :param token: An authentication token :return: A tuple: (A user object, its hashed password) """ self.logger.debug('Authenticating token') expired, invalid, user, data, error = \ user_handler.get_token_status(token) if expired: raise_unauthorized_user_error('Token is expired') elif invalid or (not isinstance(data, list) or len(data) != 2): raise_unauthorized_user_error( 'Authentication token is invalid:\n{0}'.format(error) ) elif not user: raise_unauthorized_user_error('No authentication info provided') else: self._verify_token(token=data[1], user=user) return user