Exemple #1
0
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
Exemple #3
0
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
Exemple #4
0
    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
Exemple #5
0
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