<commit_before>#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

"""Policy engine for openstack_auth"""

import logging
import os.path

from django.conf import settings
from oslo_config import cfg
from oslo_policy import opts as policy_opts
from oslo_policy import policy

from openstack_auth import user as auth_user
from openstack_auth import utils as auth_utils

LOG = logging.getLogger(__name__)

_ENFORCER = None
_BASE_PATH = settings.POLICY_FILES_PATH


def _get_policy_conf(policy_file, policy_dirs=None):
    conf = cfg.ConfigOpts()
    # Passing [] is required. Otherwise oslo.config looks up sys.argv.
    conf([])
    policy_opts.set_defaults(conf)
    conf.set_default('policy_file', policy_file, 'oslo_policy')
    # Policy Enforcer has been updated to take in a policy directory
    # as a config option. However, the default value in is set to
    # ['policy.d'] which causes the code to break. Set the default
    # value to empty list for now.
    if policy_dirs is None:
        policy_dirs = []
    conf.set_default('policy_dirs', policy_dirs, 'oslo_policy')
    return conf


def _get_policy_file_with_full_path(service):
    policy_files = settings.POLICY_FILES
    policy_file = os.path.join(_BASE_PATH, policy_files[service])
    policy_dirs = settings.POLICY_DIRS.get(service, [])
    policy_dirs = [os.path.join(_BASE_PATH, policy_dir)
                   for policy_dir in policy_dirs]
    return policy_file, policy_dirs


def _get_enforcer():
    global _ENFORCER
    if not _ENFORCER:
        _ENFORCER = {}
        policy_files = settings.POLICY_FILES
        for service in policy_files.keys():
            policy_file, policy_dirs = _get_policy_file_with_full_path(service)
            conf = _get_policy_conf(policy_file, policy_dirs)
            enforcer = policy.Enforcer(conf)
            try:
                enforcer.load_rules()
            except IOError:
                # Just in case if we have permission denied error which is not
                # handled by oslo.policy now. It will handled in the code like
                # we don't have any policy file: allow action from the Horizon
                # side.
                LOG.warning("Cannot load a policy file '%s' for service '%s' "
                            "due to IOError. One possible reason is "
                            "permission denied.", policy_file, service)
            # Ensure enforcer.rules is populated.
            if enforcer.rules:
                LOG.debug("adding enforcer for service: %s", service)
                _ENFORCER[service] = enforcer
            else:
                locations = policy_file
                if policy_dirs:
                    locations += ' and files under %s' % policy_dirs
                LOG.warning("No policy rules for service '%s' in %s",
                            service, locations)
    return _ENFORCER


def reset():
    global _ENFORCER
    _ENFORCER = None


def check(actions, request, target=None):
    """Check user permission.

    Check if the user has permission to the action according
    to policy setting.

    :param actions: list of scope and action to do policy checks on,
        the composition of which is (scope, action). Multiple actions<commit_msg>Try loading all policy files even if some files are invalid<commit_after>#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

"""Policy engine for openstack_auth"""

import logging
import os.path

from django.conf import settings
from oslo_config import cfg
from oslo_policy import opts as policy_opts
from oslo_policy import policy

from openstack_auth import user as auth_user
from openstack_auth import utils as auth_utils

LOG = logging.getLogger(__name__)

_ENFORCER = None
_BASE_PATH = settings.POLICY_FILES_PATH


def _get_policy_conf(policy_file, policy_dirs=None):
    conf = cfg.ConfigOpts()
    # Passing [] is required. Otherwise oslo.config looks up sys.argv.
    conf([])
    policy_opts.set_defaults(conf)
    conf.set_default('policy_file', policy_file, 'oslo_policy')
    # Policy Enforcer has been updated to take in a policy directory
    # as a config option. However, the default value in is set to
    # ['policy.d'] which causes the code to break. Set the default
    # value to empty list for now.
    if policy_dirs is None:
        policy_dirs = []
    conf.set_default('policy_dirs', policy_dirs, 'oslo_policy')
    return conf


def _get_policy_file_with_full_path(service):
    policy_files = settings.POLICY_FILES
    policy_file = os.path.join(_BASE_PATH, policy_files[service])
    policy_dirs = settings.POLICY_DIRS.get(service, [])
    policy_dirs = [os.path.join(_BASE_PATH, policy_dir)
                   for policy_dir in policy_dirs]
    return policy_file, policy_dirs


def _get_enforcer():
    global _ENFORCER
    if not _ENFORCER:
        _ENFORCER = {}
        policy_files = settings.POLICY_FILES
        for service in policy_files.keys():
            policy_file, policy_dirs = _get_policy_file_with_full_path(service)
            conf = _get_policy_conf(policy_file, policy_dirs)
            enforcer = policy.Enforcer(conf)
            try:
                enforcer.load_rules()
            except IOError:
                # Just in case if we have permission denied error which is not
                # handled by oslo.policy now. It will handled in the code like
                # we don't have any policy file: allow action from the Horizon
                # side.
                LOG.warning("Cannot load a policy file '%s' for service '%s' "
                            "due to IOError. One possible reason is "
                            "permission denied.", policy_file, service)
            except ValueError:
                LOG.warning("Cannot load a policy file '%s' for service '%s' "
                            "due to ValueError. The file might be wrongly "
                            "formatted.", policy_file, service)

            # Ensure enforcer.rules is populated.
            if enforcer.rules:
                LOG.debug("adding enforcer for service: %s", service)
                _ENFORCER[service] = enforcer
            else:
                locations = policy_file
                if policy_dirs:
                    locations += ' and files under %s' % policy_dirs
                LOG.warning("No policy rules for service '%s' in %s",
                            service, locations)
    return _ENFORCER


def reset():
    global _ENFORCER
    _ENFORCER = None


def check(actions, request, target=None):
    """Check user permission.

    Check if the user has permission to the action according
    to policy setting.

    :param actions: list of scope and action to do policy checks on,
        the composition of which is (scope, action). Multiple actions
{'fraction_non_alphanumeric': 0.06849840255591054, 'fraction_numerical': 0.0010223642172523962, 'mean_word_length': 2.4828660436137073, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6578849', 'n_tokens_mistral': 2186, 'n_tokens_neox': 2140, 'n_words': 779}