from cmdb.framework.utils import Model from cmdb.interface.api_parameters import CollectionParameters from cmdb.interface.response import GetMultiResponse, GetListResponse, UpdateMultiResponse from cmdb.interface.route_utils import make_response, insert_request_user, login_required, right_required from cmdb.interface.blueprint import RootBlueprint, APIBlueprint from cmdb.manager import ManagerIterationError, ManagerGetError, ManagerUpdateError from cmdb.security.acl.errors import AccessDeniedError from cmdb.security.acl.permission import AccessControlPermission from cmdb.user_management import UserModel, UserManager from cmdb.utils.error import CMDBError with current_app.app_context(): object_manager = CmdbObjectManager(current_app.database_manager, current_app.event_queue) log_manager = CmdbLogManager(current_app.database_manager) user_manager = UserManager(current_app.database_manager) LOGGER = logging.getLogger(__name__) objects_blueprint = APIBlueprint('objects', __name__) object_blueprint = RootBlueprint('object_blueprint', __name__, url_prefix='/object') @objects_blueprint.route('/', methods=['GET', 'HEAD']) @objects_blueprint.protect(auth=True, right='base.framework.object.view') @objects_blueprint.parse_collection_parameters(view='native') @insert_request_user def get_objects(params: CollectionParameters, request_user: UserModel): from cmdb.framework.managers.object_manager import ObjectManager
def authenticate(self, user_name: str, password: str, **kwargs) -> User: __dbm = DatabaseManagerMongo( **SystemConfigReader().get_all_values_from_section('Database')) __user_manager = UserManager(__dbm) try: ldap_connection_status = self.connect() LOGGER.debug( f'[LdapAuthenticationProvider] Connection status: {ldap_connection_status}' ) except Exception as e: LOGGER.error( f'[LdapAuthenticationProvider] Failed to connect to LDAP server - error: {e}' ) raise AuthenticationError(LdapAuthenticationProvider.get_name(), e) ldap_search_filter = self.config.search['searchfilter'].replace( "%username%", user_name) LOGGER.debug( f'[LdapAuthenticationProvider] Search Filter: {ldap_search_filter}' ) search_result = self.__ldap_connection.search( self.config.search['basedn'], ldap_search_filter) LOGGER.debug( f'[LdapAuthenticationProvider] Search result: {search_result}') if not search_result: raise AuthenticationError(LdapAuthenticationProvider.get_name(), 'No matching entry') for entry in self.__ldap_connection.entries: LOGGER.debug(f'[LdapAuthenticationProvider] Entry: {entry}') entry_dn = entry.entry_dn try: entry_connection_result = LdapAuthenticationProvider.Connection( self.__ldap_server, entry_dn, password, auto_bind=True) LOGGER.debug( f'[LdapAuthenticationProvider] User connection result: {entry_connection_result}' ) except Exception as e: LOGGER.error( f'[LdapAuthenticationProvider] User auth result: {e}') raise AuthenticationError( LdapAuthenticationProvider.get_name(), e) # Check if user exists try: user_instance: User = __user_manager.get_user_by_name( user_name=user_name) except UserManagerGetError as umge: LOGGER.warning( f'[LdapAuthenticationProvider] User exists on LDAP but not in database: {umge}' ) LOGGER.info( f'[LdapAuthenticationProvider] Try creating user: {user_name}') try: new_user_data = dict() new_user_data['public_id'] = __user_manager.get_new_id( User.COLLECTION) new_user_data['user_name'] = user_name new_user_data['group_id'] = self.config.default_group new_user_data['registration_time'] = datetime.utcnow() new_user_data[ 'authenticator'] = LdapAuthenticationProvider.get_name() new_user = User(**new_user_data) except Exception as e: LOGGER.debug(f'[LdapAuthenticationProvider] {e}') raise AuthenticationError( LdapAuthenticationProvider.get_name(), e) LOGGER.debug(f'[LdapAuthenticationProvider] New user was init') try: user_id = __user_manager.insert_user(new_user) except UserManagerInsertError as umie: LOGGER.debug(f'[LdapAuthenticationProvider] {umie}') raise AuthenticationError( LdapAuthenticationProvider.get_name(), umie) try: user_instance: User = __user_manager.get_user( public_id=user_id) except UserManagerGetError as umge: LOGGER.debug(f'[LdapAuthenticationProvider] {umge}') raise AuthenticationError( LdapAuthenticationProvider.get_name(), umge) return user_instance
def create_rest_api(event_queue): from cmdb.interface.config import app_config from cmdb.utils.system_config import SystemConfigReader system_config_reader = SystemConfigReader() # Create managers from cmdb.data_storage.database_manager import DatabaseManagerMongo app_database = DatabaseManagerMongo( **system_config_reader.get_all_values_from_section('Database')) object_manager = CmdbObjectManager(database_manager=app_database, event_queue=event_queue) log_manager = CmdbLogManager(database_manager=app_database) security_manager = SecurityManager(database_manager=app_database) user_manager = UserManager(database_manager=app_database) exportd_job_manager = ExportdJobManagement(database_manager=app_database, event_queue=event_queue) exportd_log_manager = ExportdLogManager(database_manager=app_database) media_file_manager = MediaFileManagement(database_manager=app_database) docapi_tpl_manager = DocapiTemplateManager(database_manager=app_database) # Create APP from cmdb.interface.cmdb_app import BaseCmdbApp app = BaseCmdbApp(__name__, database_manager=app_database, docapi_tpl_manager=docapi_tpl_manager, media_file_manager=media_file_manager, exportd_manager=exportd_job_manager, exportd_log_manager=exportd_log_manager, object_manager=object_manager, log_manager=log_manager, user_manager=user_manager, security_manager=security_manager) app.url_map.strict_slashes = True # Import App Extensions from flask_cors import CORS CORS(app, expose_headers=['X-API-Version', 'X-Total-Count']) import cmdb if cmdb.__MODE__ == 'DEBUG': config = app_config['development'] config.APPLICATION_ROOT = '/rest/' app.config.from_object(config) else: config = app_config['production'] config.APPLICATION_ROOT = '/rest/' app.config.from_object(config) with app.app_context(): register_converters(app) register_error_pages(app) register_blueprints(app) return app
def login(self, user_manager: UserManager, user_name: str, password: str) -> Union[User, None]: """ Performs a login try with given username and password If the user is not found, iterate over all installed and activated providers Args: user_manager: Usermanager instance user_name: Name of the user password: Password Returns: User: instance if user was found and password was correct None: if something went wrong """ user_name = user_name.lower() user_instance = None try: founded_user = user_manager.get_user_by_name(user_name=user_name) provider_class_name = founded_user.get_authenticator() LOGGER.debug( f'[AUTH] Founded user: {founded_user} with provider: {provider_class_name}' ) if not self.provider_exists(provider_class_name): raise AuthenticationProviderNotExistsError(provider_class_name) provider: ClassVar[ AuthenticationProvider] = self.get_provider_class( provider_class_name) provider_config_class: ClassVar[ str] = provider.PROVIDER_CONFIG_CLASS provider_config_settings = self.settings.get_provider_settings( provider.get_name()) provider_config_instance = provider_config_class( **provider_config_settings) provider_instance = provider(config=provider_config_instance) if not provider_config_instance.is_active(): raise AuthenticationProviderNotActivated( f'Provider {provider_class_name} is deactivated') if provider_instance.EXTERNAL_PROVIDER and not self.settings.enable_external: raise AuthenticationProviderNotActivated( f'External providers are deactivated') try: user_instance = provider_instance.authenticate( user_name, password) except AuthenticationError as ae: LOGGER.error(f'[LOGIN] User could not login: {ae}') except UserManagerGetError as umge: LOGGER.error(f'[AUTH] {user_name} not in database: {umge}') LOGGER.info( f'[AUTH] Check for other providers - request_user: {user_name}' ) # get installed providers provider_list = self.providers LOGGER.debug(f'[AUTH] Provider list: {provider_list}') external_enabled = self.settings.enable_external for provider in provider_list: LOGGER.debug(f'[AUTH] using provider: {provider}') provider_config_class = provider.PROVIDER_CONFIG_CLASS provider_settings = self.settings.get_provider_settings( provider.get_name()) provider_config_instance = provider_config_class( **provider_settings) if not provider_config_instance.is_active(): continue if provider.EXTERNAL_PROVIDER and not self.settings.enable_external: continue provider_instance = provider(config=provider_config_instance) try: user_instance = provider_instance.authenticate( user_name, password) if user_instance: break except AuthenticationError as ae: LOGGER.error( f'[AUTH] User {user_name} could not validate with provider {provider}: {ae}' ) LOGGER.info(f'[AUTH] Provider instance: {provider_instance}') except Exception as e: import traceback traceback.print_exc() LOGGER.error(f'[AUTH] Error while login: {e}') return None finally: return user_instance
def create_rest_api(event_queue): from cmdb.interface.config import app_config from cmdb.utils.system_config import SystemConfigReader system_config_reader = SystemConfigReader() try: cache_config = { 'DEBUG': True, 'CACHE_TYPE': system_config_reader.get_value('name', 'Cache'), 'CACHE_REDIS_HOST': system_config_reader.get_value('host', 'Cache'), 'CACHE_REDIS_PORT': system_config_reader.get_value('port', 'Cache'), 'CACHE_REDIS_PASSWORD': system_config_reader.get_value('password', 'Cache'), } except (ImportError, CMDBError) as e: LOGGER.debug(e.message) cache_config = {'CACHE_TYPE': 'simple'} from flask_caching import Cache cache = Cache(config=cache_config) # Create manager from cmdb.data_storage.database_manager import DatabaseManagerMongo app_database = DatabaseManagerMongo( **system_config_reader.get_all_values_from_section('Database')) object_manager = CmdbObjectManager(database_manager=app_database, event_queue=event_queue) log_manager = CmdbLogManager(database_manager=app_database) security_manager = SecurityManager(database_manager=app_database) user_manager = UserManager(database_manager=app_database) exportd_job_manager = ExportdJobManagement(database_manager=app_database, event_queue=event_queue) exportd_log_manager = ExportdLogManager(database_manager=app_database) media_file_manager = MediaFileManagement(database_manager=app_database) docapi_tpl_manager = DocapiTemplateManager(database_manager=app_database) # Create APP from cmdb.interface.cmdb_app import BaseCmdbApp app = BaseCmdbApp(__name__, database_manager=app_database, docapi_tpl_manager=docapi_tpl_manager, media_file_manager=media_file_manager, exportd_manager=exportd_job_manager, exportd_log_manager=exportd_log_manager, object_manager=object_manager, log_manager=log_manager, user_manager=user_manager, security_manager=security_manager) # Import App Extensions from flask_cors import CORS CORS(app) import cmdb cache.init_app(app) cache.clear() app.cache = cache if cmdb.__MODE__ == 'DEBUG': app.config.from_object(app_config['rest_development']) LOGGER.info('RestAPI starting with config mode {}'.format( app.config.get("ENV"))) elif cmdb.__MODE__ == 'TESTING': app.config.from_object(app_config['testing']) else: app.config.from_object(app_config['rest']) LOGGER.info('RestAPI starting with config mode {}'.format( app.config.get("ENV"))) with app.app_context(): register_converters(app) register_error_pages(app) register_blueprints(app) return app