Exemple #1
0
    def __init__(self, params_dict, temp_folder):
        super().__init__()

        self.url = model_helper.read_obligatory(params_dict, 'url', ' for LDAP auth')

        username_pattern = strip(params_dict.get('username_pattern'))
        if username_pattern:
            self.username_template = Template(username_pattern)
        else:
            self.username_template = None

        base_dn = params_dict.get('base_dn')
        if base_dn:
            self._base_dn = base_dn.strip()
        else:
            resolved_base_dn = _resolve_base_dn(username_pattern)

            if resolved_base_dn:
                LOGGER.info('Resolved base dn: ' + resolved_base_dn)
                self._base_dn = resolved_base_dn
            else:
                LOGGER.warning(
                    'Cannot resolve LDAP base dn, so using empty. Please specify it using "base_dn" attribute')
                self._base_dn = ''

        self.version = params_dict.get("version")
        if not self.version:
            self.version = 3

        self._groups_file = os.path.join(temp_folder, 'ldap_groups.json')
        self._user_groups = self._load_groups(self._groups_file)
Exemple #2
0
    def __init__(self, params_dict, temp_folder):
        super().__init__()

        self.url = model_helper.read_obligatory(params_dict, 'url',
                                                ' for LDAP auth')

        username_pattern = strip(params_dict.get('username_pattern'))
        if username_pattern:
            self.username_template = Template(username_pattern)
        else:
            self.username_template = None

        base_dn = params_dict.get('base_dn')
        if base_dn:
            self._base_dn = base_dn.strip()
        else:
            resolved_base_dn = _resolve_base_dn(username_pattern)

            if resolved_base_dn:
                LOGGER.info('Resolved base dn: ' + resolved_base_dn)
                self._base_dn = resolved_base_dn
            else:
                LOGGER.warning(
                    'Cannot resolve LDAP base dn, so using empty. Please specify it using "base_dn" attribute'
                )
                self._base_dn = ''

        self.version = params_dict.get("version")
        if not self.version:
            self.version = 3

        self._groups_file = os.path.join(temp_folder, 'ldap_groups.json')
        self._user_groups = self._load_groups(self._groups_file)
Exemple #3
0
def _parse_admin_users(json_object, default_admins=None):
    admins = strip(read_list(json_object, 'admin_users', default=default_admins))
    if '*' in admins:
        LOGGER.warning('Any user is allowed to access admin page, be careful!')
        return [ANY_USER]

    return admins
Exemple #4
0
def _resolve_excluded_files(config, key, file_dir):
    raw_patterns = model_helper.read_list(config, key)
    if raw_patterns is None:
        patterns = []
    else:
        patterns = [resolve_env_vars(e) for e in strip(raw_patterns)]
    return FileMatcher(patterns, file_dir)
Exemple #5
0
    def _reload(self):
        config = self._original_config

        self.param = config.get('param')
        self.no_value = read_boolean('no_value', config, False)
        self.description = config.get('description')
        self.required = read_boolean('required', config, False)
        self.min = config.get('min')
        self.max = config.get('max')
        self.secure = read_boolean('secure', config, False)
        self.separator = config.get('separator', ',')
        self.multiple_arguments = read_boolean('multiple_arguments', config, default=False)
        self.default = _resolve_default(config.get('default'), self._username, self._audit_name)
        self.file_dir = config.get('file_dir')
        self.file_type = config.get('file_type', '').strip().lower()
        self.file_extensions = strip(model_helper.read_list(config, 'file_extensions'))

        self.type = self._read_type(config)

        self.constant = read_boolean('constant', config, False)

        self._validate_config()

        values_provider = self._create_values_provider(
            config.get('values'),
            self.type,
            self.constant)
        self._values_provider = values_provider
        self._reload_values()
Exemple #6
0
def from_json(conf_path):
    if os.path.exists(conf_path):
        file_content = file_utils.read_file(conf_path)
    else:
        file_content = "{}"

    config = ServerConfig()

    json_object = json.loads(file_content)

    address = "0.0.0.0"
    port = 5000

    ssl = json_object.get("ssl")
    if ssl is not None:
        key_path = model_helper.read_obligatory(ssl, 'key_path', ' for ssl')
        cert_path = model_helper.read_obligatory(ssl, 'cert_path', ' for ssl')

        config.ssl = True
        config.ssl_key_path = key_path
        config.ssl_cert_path = cert_path
        port = 5443

    if json_object.get("address"):
        address = json_object.get("address")
    config.address = address

    if json_object.get("port"):
        port = json_object.get("port")
    config.port = port

    if json_object.get('title'):
        config.title = json_object.get('title')

    auth_config = json_object.get('auth')
    if auth_config:
        config.authenticator = create_authenticator(auth_config)

        allowed_users = auth_config.get('allowed_users')

        auth_type = config.authenticator.auth_type
        if auth_type == 'google_oauth' and allowed_users is None:
            raise Exception('auth.allowed_users field is mandatory for ' + auth_type)

        def_trusted_ips = []
        def_admins = []
    else:
        allowed_users = '*'
        def_trusted_ips = ['127.0.0.1', '::1']
        def_admins = def_trusted_ips

    config.trusted_ips = strip(read_list(json_object, 'trusted_ips', default=def_trusted_ips))

    admin_users = _parse_admin_users(json_object, default_admins=def_admins)
    config.authorizer = _create_authorizer(allowed_users, admin_users)

    config.alerts_config = parse_alerts_config(json_object)
    config.logging_config = parse_logging_config(json_object)

    return config
Exemple #7
0
def _parse_admin_users(json_object, default_admins=None):
    admins = strip(
        read_list(json_object, 'admin_users', default=default_admins))
    if '*' in admins:
        LOGGER.warning('Any user is allowed to access admin page, be careful!')
        return [ANY_USER]

    return admins
Exemple #8
0
def _parse_code_editor_users(json_object, admin_users):
    full_code_editor_users = strip(
        read_list(json_object, 'code_editors', default=admin_users))
    if (isinstance(full_code_editor_users, list) and '*' in full_code_editor_users) \
            or full_code_editor_users == '*':
        return [ANY_USER]

    return full_code_editor_users
Exemple #9
0
def _parse_history_users(json_object):
    full_history_users = strip(
        read_list(json_object, 'full_history', default=[]))
    if (isinstance(full_history_users, list) and '*' in full_history_users) \
            or full_history_users == '*':
        return [ANY_USER]

    return full_history_users
Exemple #10
0
def _create_authorizer(allowed_users, admin_users):
    if (allowed_users is None) or (allowed_users == '*'):
        coerced_users = [ANY_USER]

    elif not isinstance(allowed_users, list):
        raise Exception('allowed_users should be list')

    else:
        coerced_users = strip(allowed_users)
        coerced_users = [user for user in coerced_users if len(user) > 0]

        if '*' in coerced_users:
            coerced_users = [ANY_USER]

    return Authorizer(coerced_users, admin_users)
Exemple #11
0
def _prepare_allowed_users(allowed_users, admin_users, user_groups):
    if (allowed_users is None) or (allowed_users == '*'):
        return [ANY_USER]

    elif not isinstance(allowed_users, list):
        raise Exception('allowed_users should be list')

    coerced_users = strip(allowed_users)
    coerced_users = {user for user in coerced_users if len(user) > 0}

    if '*' in coerced_users:
        return [ANY_USER]

    if admin_users and (ANY_USER != admin_users) and (ANY_USER not in admin_users):
        coerced_users.update(admin_users)

    if user_groups:
        for group, users in user_groups.items():
            if (ANY_USER != users) and (ANY_USER not in users):
                coerced_users.update(users)

    return list(coerced_users)
Exemple #12
0
def _prepare_allowed_users(allowed_users, admin_users, user_groups):
    if (allowed_users is None) or (allowed_users == '*'):
        return [ANY_USER]

    elif not isinstance(allowed_users, list):
        raise Exception('allowed_users should be list')

    coerced_users = strip(allowed_users)
    coerced_users = {user for user in coerced_users if len(user) > 0}

    if '*' in coerced_users:
        return [ANY_USER]

    if admin_users and (ANY_USER != admin_users) and (ANY_USER
                                                      not in admin_users):
        coerced_users.update(admin_users)

    if user_groups:
        for group, users in user_groups.items():
            if (ANY_USER != users) and (ANY_USER not in users):
                coerced_users.update(users)

    return list(coerced_users)
Exemple #13
0
def _parse_admin_users(json_object):
    default_admins = ['127.0.0.1']
    admin_users = read_list(json_object, 'admin_users', default_admins)

    return strip(admin_users)
def _resolve_file_extensions(config, key):
    result = model_helper.read_list(config, key)
    if result is None:
        return []

    return [normalize_extension(e) for e in strip(result)]
Exemple #15
0
def from_json(conf_path, temp_folder):
    if os.path.exists(conf_path):
        file_content = file_utils.read_file(conf_path)
    else:
        file_content = "{}"

    config = ServerConfig()

    json_object = json.loads(file_content)

    address = "0.0.0.0"
    port = 5000

    ssl = json_object.get("ssl")
    if ssl is not None:
        key_path = model_helper.read_obligatory(ssl, 'key_path', ' for ssl')
        cert_path = model_helper.read_obligatory(ssl, 'cert_path', ' for ssl')

        config.ssl = True
        config.ssl_key_path = key_path
        config.ssl_cert_path = cert_path
        port = 5443

    if json_object.get("address"):
        address = json_object.get("address")
    config.address = address

    if json_object.get("port"):
        port = json_object.get("port")
    config.port = port

    if json_object.get('title'):
        config.title = json_object.get('title')

    access_config = json_object.get('access')
    if access_config:
        allowed_users = access_config.get('allowed_users')
        user_groups = model_helper.read_dict(access_config, 'groups')
    else:
        allowed_users = None
        user_groups = {}

    auth_config = json_object.get('auth')
    if auth_config:
        config.authenticator = create_authenticator(auth_config, temp_folder)

        auth_type = config.authenticator.auth_type
        if auth_type == 'google_oauth' and allowed_users is None:
            raise Exception('auth.allowed_users field is mandatory for ' +
                            auth_type)

        def_trusted_ips = []
        def_admins = []
    else:
        def_trusted_ips = ['127.0.0.1', '::1']
        def_admins = def_trusted_ips

    if access_config:
        config.trusted_ips = strip(
            read_list(access_config, 'trusted_ips', default=def_trusted_ips))
        admin_users = _parse_admin_users(access_config,
                                         default_admins=def_admins)
    else:
        config.trusted_ips = def_trusted_ips
        admin_users = def_admins

    config.allowed_users = _prepare_allowed_users(allowed_users, admin_users,
                                                  user_groups)
    config.alerts_config = parse_alerts_config(json_object)
    config.logging_config = parse_logging_config(json_object)
    config.user_groups = user_groups
    config.admin_users = admin_users

    config.max_request_size_mb = read_int_from_config('max_request_size',
                                                      json_object,
                                                      default=10)

    return config
Exemple #16
0
def _parse_admin_users(json_object, default_admins=None):
    return strip(read_list(json_object, 'admin_users', default=default_admins))
def _resolve_file_extensions(config, key):
    result = model_helper.read_list(config, key)
    if result is None:
        return []

    return [normalize_extension(e) for e in strip(result)]
Exemple #18
0
def from_json(conf_path, temp_folder):
    if os.path.exists(conf_path):
        file_content = file_utils.read_file(conf_path)
    else:
        file_content = "{}"

    config = ServerConfig()

    json_object = json.loads(file_content)

    address = "0.0.0.0"
    port = 5000

    ssl = json_object.get("ssl")
    if ssl is not None:
        key_path = model_helper.read_obligatory(ssl, 'key_path', ' for ssl')
        cert_path = model_helper.read_obligatory(ssl, 'cert_path', ' for ssl')

        config.ssl = True
        config.ssl_key_path = key_path
        config.ssl_cert_path = cert_path
        port = 5443

    if json_object.get("address"):
        address = json_object.get("address")
    config.address = address

    if json_object.get("port"):
        port = json_object.get("port")
    config.port = port

    if json_object.get('title'):
        config.title = json_object.get('title')
    config.enable_script_titles = read_bool_from_config('enable_script_titles',
                                                        json_object,
                                                        default=True)

    access_config = json_object.get('access')
    if access_config:
        allowed_users = access_config.get('allowed_users')
        user_groups = model_helper.read_dict(access_config, 'groups')
        user_header_name = access_config.get('user_header_name')
    else:
        allowed_users = None
        user_groups = {}
        user_header_name = None

    auth_config = json_object.get('auth')
    if auth_config:
        config.authenticator = create_authenticator(auth_config, temp_folder)

        auth_type = config.authenticator.auth_type
        if auth_type == 'google_oauth' and allowed_users is None:
            raise Exception('access.allowed_users field is mandatory for ' +
                            auth_type)

        def_trusted_ips = []
        def_admins = []
    else:
        def_trusted_ips = ['127.0.0.1', '::1']
        def_admins = def_trusted_ips

    if access_config:
        trusted_ips = strip(
            read_list(access_config, 'trusted_ips', default=def_trusted_ips))
        admin_users = _parse_admin_users(access_config,
                                         default_admins=def_admins)
        full_history_users = _parse_history_users(access_config)
        code_editor_users = _parse_code_editor_users(access_config,
                                                     admin_users)
    else:
        trusted_ips = def_trusted_ips
        admin_users = def_admins
        full_history_users = []
        code_editor_users = def_admins

    security = model_helper.read_dict(json_object, 'security')

    config.allowed_users = _prepare_allowed_users(allowed_users, admin_users,
                                                  user_groups)
    config.alerts_config = json_object.get('alerts')
    config.callbacks_config = json_object.get('callbacks')
    config.logging_config = parse_logging_config(json_object)
    config.user_groups = user_groups
    config.admin_users = admin_users
    config.full_history_users = full_history_users
    config.code_editor_users = code_editor_users
    config.user_header_name = user_header_name
    config.ip_validator = TrustedIpValidator(trusted_ips)

    config.max_request_size_mb = read_int_from_config('max_request_size',
                                                      json_object,
                                                      default=10)

    config.secret_storage_file = json_object.get(
        'secret_storage_file', os.path.join(temp_folder, 'secret.dat'))
    config.xsrf_protection = _parse_xsrf_protection(security)

    return config
Exemple #19
0
    def _preprocess_script_fields(self, config, original_config_json,
                                  uploaded_script, user):
        script_config = config.get('script')
        if not script_config:
            raise InvalidConfigException('script option is required')

        if SCRIPT_PATH_FIELD in config:
            del config[SCRIPT_PATH_FIELD]
        del config['script']

        new_path = strip(script_config.get('path'))
        if is_blank(new_path):
            raise InvalidConfigException('script.path option is required')

        config[SCRIPT_PATH_FIELD] = new_path

        mode = script_config.get('mode')
        if is_blank(mode) or mode == SCRIPT_EDIT_PATH_MODE:
            pass

        elif mode in (SCRIPT_EDIT_UPLOAD_MODE, SCRIPT_EDIT_CODE_MODE):
            if not self._authorizer.can_edit_code(user.user_id):
                raise InvalidAccessException('User ' + str(user) +
                                             ' is not allowed to edit code')

            if mode == SCRIPT_EDIT_UPLOAD_MODE:
                if uploaded_script is None:
                    raise InvalidConfigException(
                        'Uploaded script should be specified')

            if original_config_json is None:  # new config
                if mode == SCRIPT_EDIT_UPLOAD_MODE:
                    # escaped name is needed, when uploaded file and server has different OSes,
                    # thus different special characters
                    escaped_name = to_filename(uploaded_script.filename)
                    target_path = os.path.join(self._scripts_folder,
                                               escaped_name)
                else:
                    filename = os.path.basename(new_path)
                    target_path = os.path.join(
                        self._scripts_folder,
                        _escape_characters_in_filename(filename))

                script_path = file_utils.create_unique_filename(
                    target_path, 100)
                config[SCRIPT_PATH_FIELD] = script_path

            else:
                existing_code = self._load_script_code_by_config(
                    original_config_json)
                script_path = existing_code['file_path']

                if (mode == SCRIPT_EDIT_CODE_MODE
                    ) and existing_code.get('code_edit_error') is not None:
                    raise InvalidConfigException(
                        'Failed to edit code: ' +
                        existing_code.get('code_edit_error'))

                if new_path != original_config_json.get(SCRIPT_PATH_FIELD):
                    raise InvalidConfigException(
                        'script.path override is not allowed for ' + mode +
                        ' mode')

            if mode == SCRIPT_EDIT_UPLOAD_MODE:
                file_utils.write_file(script_path,
                                      uploaded_script.body,
                                      byte_content=True)
            else:
                code = script_config.get('code')
                if code is None:
                    raise InvalidConfigException(
                        'script.code should be specified')
                file_utils.write_file(script_path, code)

            file_utils.make_executable(script_path)

        else:
            raise InvalidConfigException('Unsupported mode: ' + mode)
Exemple #20
0
def from_json(conf_path, temp_folder):
    if os.path.exists(conf_path):
        file_content = file_utils.read_file(conf_path)
    else:
        file_content = "{}"

    config = ServerConfig()

    json_object = json.loads(file_content)

    address = "0.0.0.0"
    port = 5000

    ssl = json_object.get("ssl")
    if ssl is not None:
        key_path = model_helper.read_obligatory(ssl, 'key_path', ' for ssl')
        cert_path = model_helper.read_obligatory(ssl, 'cert_path', ' for ssl')

        config.ssl = True
        config.ssl_key_path = key_path
        config.ssl_cert_path = cert_path
        port = 5443

    if json_object.get("address"):
        address = json_object.get("address")
    config.address = address

    if json_object.get("port"):
        port = json_object.get("port")
    config.port = port

    if json_object.get('title'):
        config.title = json_object.get('title')

    access_config = json_object.get('access')
    if access_config:
        allowed_users = access_config.get('allowed_users')
        user_groups = model_helper.read_dict(access_config, 'groups')
    else:
        allowed_users = None
        user_groups = {}

    auth_config = json_object.get('auth')
    if auth_config:
        config.authenticator = create_authenticator(auth_config, temp_folder)

        auth_type = config.authenticator.auth_type
        if auth_type == 'google_oauth' and allowed_users is None:
            raise Exception('auth.allowed_users field is mandatory for ' + auth_type)

        def_trusted_ips = []
        def_admins = []
    else:
        def_trusted_ips = ['127.0.0.1', '::1']
        def_admins = def_trusted_ips

    if access_config:
        config.trusted_ips = strip(read_list(access_config, 'trusted_ips', default=def_trusted_ips))
        admin_users = _parse_admin_users(access_config, default_admins=def_admins)
    else:
        config.trusted_ips = def_trusted_ips
        admin_users = def_admins

    config.allowed_users = _prepare_allowed_users(allowed_users, admin_users, user_groups)
    config.alerts_config = json_object.get('alerts')
    config.callbacks_config = json_object.get('callbacks')
    config.logging_config = parse_logging_config(json_object)
    config.user_groups = user_groups
    config.admin_users = admin_users

    config.max_request_size_mb = read_int_from_config('max_request_size', json_object, default=10)

    return config