Example #1
0
    def test_enforcer_force_reload_without_overwrite(self):
        self.create_config_file('policy.d/a.conf', POLICY_A_CONTENTS)
        self.create_config_file('policy.d/b.conf', POLICY_B_CONTENTS)

        # Prepare in memory fake policies.
        self.enforcer.set_rules({'test': _parser.parse_rule('role:test')},
                                use_conf=True)
        self.enforcer.set_rules({'default': _parser.parse_rule('role:fakeZ')},
                                overwrite=False,  # Keeps 'test' role.
                                use_conf=True)

        self.enforcer.overwrite = False
        self.enforcer._is_directory_updated = lambda x, y: True

        # Call enforce(), it will load rules from
        # policy configuration files, to merge with
        # existing fake ones.
        self.assertTrue(self.enforcer.enforce('test', {},
                                              {'roles': ['test']}))
        # The existing rules have a same key with
        # new loaded ones will be overwrote.
        self.assertFalse(self.enforcer.enforce('default', {},
                                               {'roles': ['fakeZ']}))

        # Check against rule dict again from
        # enforcer object directly.
        self.assertIn('test', self.enforcer.rules)
        self.assertIn('default', self.enforcer.rules)
        self.assertIn('admin', self.enforcer.rules)
        loaded_rules = jsonutils.loads(str(self.enforcer.rules))
        self.assertEqual(3, len(loaded_rules))
        self.assertIn('role:test', loaded_rules['test'])
        self.assertIn('role:fakeB', loaded_rules['default'])
        self.assertIn('is_admin:True', loaded_rules['admin'])
Example #2
0
    def test_enforcer_force_reload_without_overwrite(self):
        self.create_config_file('policy.d/a.conf', POLICY_A_CONTENTS)
        self.create_config_file('policy.d/b.conf', POLICY_B_CONTENTS)

        # Prepare in memory fake policies.
        self.enforcer.set_rules({'test': _parser.parse_rule('role:test')},
                                use_conf=True)
        self.enforcer.set_rules(
            {'default': _parser.parse_rule('role:fakeZ')},
            overwrite=False,  # Keeps 'test' role.
            use_conf=True)

        self.enforcer.overwrite = False

        # Call enforce(), it will load rules from
        # policy configuration files, to merge with
        # existing fake ones.
        self.assertTrue(self.enforcer.enforce('test', {}, {'roles': ['test']}))
        # The existing rules have a same key with
        # new loaded ones will be overwrote.
        self.assertFalse(
            self.enforcer.enforce('default', {}, {'roles': ['fakeZ']}))

        # Check against rule dict again from
        # enforcer object directly.
        self.assertIn('test', self.enforcer.rules)
        self.assertIn('default', self.enforcer.rules)
        self.assertIn('admin', self.enforcer.rules)
        loaded_rules = jsonutils.loads(str(self.enforcer.rules))
        self.assertEqual(3, len(loaded_rules))
        self.assertIn('role:test', loaded_rules['test'])
        self.assertIn('role:fakeB', loaded_rules['default'])
        self.assertIn('is_admin:True', loaded_rules['admin'])
Example #3
0
    def test_enforcer_force_reload_with_overwrite(self, opts_registered=0):
        self.create_config_file(os.path.join('policy.d', 'a.conf'),
                                POLICY_A_CONTENTS)
        self.create_config_file(os.path.join('policy.d', 'b.conf'),
                                POLICY_B_CONTENTS)

        # Prepare in memory fake policies.
        self.enforcer.set_rules({'test': _parser.parse_rule('role:test')},
                                use_conf=True)
        self.enforcer.set_rules(
            {'default': _parser.parse_rule('role:fakeZ')},
            overwrite=False,  # Keeps 'test' role.
            use_conf=True)

        self.enforcer.overwrite = True

        # Call enforce(), it will load rules from
        # policy configuration files, to overwrite
        # existing fake ones.
        self.assertFalse(self.enforcer.enforce('test', {},
                                               {'roles': ['test']}))
        self.assertTrue(
            self.enforcer.enforce('default', {}, {'roles': ['fakeB']}))

        # Check against rule dict again from
        # enforcer object directly.
        self.assertNotIn('test', self.enforcer.rules)
        self.assertIn('default', self.enforcer.rules)
        self.assertIn('admin', self.enforcer.rules)
        loaded_rules = jsonutils.loads(str(self.enforcer.rules))
        self.assertEqual(2 + opts_registered, len(loaded_rules))
        self.assertIn('role:fakeB', loaded_rules['default'])
        self.assertIn('is_admin:True', loaded_rules['admin'])
Example #4
0
    def test_enforcer_force_reload_with_overwrite(self, opts_registered=0):
        self.create_config_file(
            os.path.join('policy.d', 'a.conf'), POLICY_A_CONTENTS)
        self.create_config_file(
            os.path.join('policy.d', 'b.conf'), POLICY_B_CONTENTS)

        # Prepare in memory fake policies.
        self.enforcer.set_rules({'test': _parser.parse_rule('role:test')},
                                use_conf=True)
        self.enforcer.set_rules({'default': _parser.parse_rule('role:fakeZ')},
                                overwrite=False,  # Keeps 'test' role.
                                use_conf=True)

        self.enforcer.overwrite = True

        # Call enforce(), it will load rules from
        # policy configuration files, to overwrite
        # existing fake ones.
        self.assertFalse(self.enforcer.enforce('test', {},
                                               {'roles': ['test']}))
        self.assertTrue(self.enforcer.enforce('default', {},
                                              {'roles': ['fakeB']}))

        # Check against rule dict again from
        # enforcer object directly.
        self.assertNotIn('test', self.enforcer.rules)
        self.assertIn('default', self.enforcer.rules)
        self.assertIn('admin', self.enforcer.rules)
        loaded_rules = jsonutils.loads(str(self.enforcer.rules))
        self.assertEqual(2 + opts_registered, len(loaded_rules))
        self.assertIn('role:fakeB', loaded_rules['default'])
        self.assertIn('is_admin:True', loaded_rules['admin'])
Example #5
0
    def test_parse_rule_string(self, mock_parse_list_rule,
                               mock_parse_text_rule):
        result = _parser.parse_rule('a string')

        self.assertEqual('text rule', result)
        self.assertFalse(mock_parse_list_rule.called)
        mock_parse_text_rule.assert_called_once_with('a string')
    def from_dict(cls, rules_dict, default_rule=None):
        """Allow loading of rule data from a dictionary."""

        # Parse the rules stored in the dictionary
        rules = dict((k, _parser.parse_rule(v)) for k, v in rules_dict.items())

        return cls(rules, default_rule)
Example #7
0
    def from_dict(cls, rules_dict, default_rule=None):
        """Allow loading of rule data from a dictionary."""

        # Parse the rules stored in the dictionary
        rules = dict((k, _parser.parse_rule(v)) for k, v in rules_dict.items())

        return cls(rules, default_rule)
Example #8
0
    def enforce(self, action, target, creds, **kwargs):
        LOG.debug('Evaluating against System Authz Policy')
        sys_rst = self._enforce(action, target, creds, rule_dict=
                                                self.sys_rules, **kwargs)
        if not sys_rst:
            return sys_rst

        LOG.debug('Evaluating against Domain Authz Policy')
        # We can always get scope_domain_id from creds.
        domain_id = creds['domain_id'] 
        p_ref = self.policy_api.get_enabled_policy_in_domain(domain_id)
        if p_ref:
            try:
                r_dict = self.policy_api.get_rule(p_ref['id'], action[0],
                                                                    action[1])
                rule = _parser.parse_rule(r_dict['condition'])
                return self._enforce(rule, target, creds, **kwargs)

            except exception.RuleNotFound:
                LOG.debug('Tenant domain has an enabled policy, but rule'
                          ' on target service and permission has not been'
                          ' specified. Using the corresponding rule in'
                          ' default policy.')
                return self._enforce(action, target, creds,
                                        rule_dict=self.dflt_rules, **kwargs)
        else:
            LOG.debug('Tenant domain has no enabled policy. Using'
                      ' the corresponding rule in default policy.')
            return self._enforce(action, target, creds,
                                        rule_dict=self.dflt_rules, **kwargs)
Example #9
0
    def test_parse_rule_string(self, mock_parse_list_rule,
                               mock_parse_text_rule):
        result = _parser.parse_rule('a string')

        self.assertEqual('text rule', result)
        self.assertFalse(mock_parse_list_rule.called)
        mock_parse_text_rule.assert_called_once_with('a string')
Example #10
0
    def load_json(cls, data, default_rule=None):
        """Allow loading of JSON rule data."""

        # Suck in the JSON data and parse the rules
        rules = dict((k, _parser.parse_rule(v)) for k, v in
                     jsonutils.loads(data).items())

        return cls(rules, default_rule)
    def load_json(cls, data, default_rule=None):
        """Allow loading of JSON rule data."""

        # Suck in the JSON data and parse the rules
        rules = dict((k, _parser.parse_rule(v)) for k, v in
                     jsonutils.loads(data).items())

        return cls(rules, default_rule)
Example #12
0
    def from_dict(cls, rules_dict, default_rule=None):
        """Allow loading of rule data from a dictionary."""

        # Parse the rules stored in the dictionary
        rules = dict()
        for k, v in rules_dict.items():
            LOG.debug('Processing policy: "%s": "%s"', k, v)
            rules[k] = _parser.parse_rule(v)

        return cls(rules, default_rule)
Example #13
0
    def load_json(cls, data, default_rule=None):
        """Allow loading of JSON rule data."""
        data = jsonutils.loads(data)
        
        # Parse the rules stored in  JSON data loaded
        rules = {}
        for serv in data.iterkeys():
            rules[serv] = dict((k, _parser.parse_rule(v)) 
                               for k, v in data[serv].items())

        return cls(rules, default_rule)
Example #14
0
    def load(cls, data, default_rule=None):
        """Allow loading of YAML/JSON rule data.

        .. versionadded:: 1.5.0

        """
        parsed_file = parse_file_contents(data)

        # Parse the rules
        rules = {k: _parser.parse_rule(v) for k, v in parsed_file.items()}

        return cls(rules, default_rule)
Example #15
0
    def load(cls, data, default_rule=None):
        """Allow loading of YAML/JSON rule data.

        .. versionadded:: 1.5.0

        """
        parsed_file = parse_file_contents(data)

        # Parse the rules
        rules = {k: _parser.parse_rule(v) for k, v in parsed_file.items()}

        return cls(rules, default_rule)
Example #16
0
    def load(cls, data, default_rule=None):
        """Allow loading of YAML/JSON rule data.

        .. versionadded:: 1.5.0

        """

        try:
            parsed = yaml.safe_load(data)
        except yaml.YAMLError as e:
            # For backwards-compatibility, convert yaml error to ValueError,
            # which is what JSON loader raised.
            raise ValueError(six.text_type(e))

        # Parse the rules
        rules = {k: _parser.parse_rule(v) for k, v in parsed.items()}

        return cls(rules, default_rule)
Example #17
0
    def load(cls, data, default_rule=None):
        """Allow loading of YAML/JSON rule data.

        .. versionadded:: 1.5.0

        """

        try:
            parsed = yaml.safe_load(data)
        except yaml.YAMLError as e:
            # For backwards-compatibility, convert yaml error to ValueError,
            # which is what JSON loader raised.
            raise ValueError(six.text_type(e))

        # Parse the rules
        rules = {k: _parser.parse_rule(v) for k, v in parsed.items()}

        return cls(rules, default_rule)
Example #18
0
    def __init__(self,
                 name,
                 check_str,
                 description=None,
                 deprecated_rule=None,
                 deprecated_for_removal=False,
                 deprecated_reason=None,
                 deprecated_since=None,
                 scope_types=None):
        self.name = name
        self.check_str = check_str
        self.check = _parser.parse_rule(check_str)
        self.description = description
        self.deprecated_rule = copy.deepcopy(deprecated_rule) or []
        self.deprecated_for_removal = deprecated_for_removal
        self.deprecated_reason = deprecated_reason
        self.deprecated_since = deprecated_since

        if self.deprecated_rule:
            if not isinstance(self.deprecated_rule, DeprecatedRule):
                raise ValueError(
                    'deprecated_rule must be a DeprecatedRule object.')

        if (deprecated_for_removal
                or deprecated_rule) and (deprecated_reason is None
                                         or deprecated_since is None):
            raise ValueError(
                '%(name)s deprecated without deprecated_reason or '
                'deprecated_since. Both must be supplied if deprecating a '
                'policy' % {'name': self.name})

        if scope_types:
            msg = 'scope_types must be a list of strings.'
            if not isinstance(scope_types, list):
                raise ValueError(msg)
            for scope_type in scope_types:
                if not isinstance(scope_type, six.string_types):
                    raise ValueError(msg)
                if scope_types.count(scope_type) > 1:
                    raise ValueError(
                        'scope_types must be a list of unique strings.')
        self.scope_types = scope_types
Example #19
0
 def set_rules(self, rules):
     policy = zun_policy._ENFORCER
     policy.set_rules({k: _parser.parse_rule(v) for k, v in rules.items()})
Example #20
0
 def set_rules(self, rules):
     self._add_default_rules(rules)
     policy = zun_policy._ENFORCER
     policy.set_rules({k: _parser.parse_rule(v) for k, v in rules.items()})
Example #21
0
    def load_rules(self, force_reload=False):
        """Loads policy_path's rules.

        Policy file is cached and will be reloaded if modified.

        :param force_reload: Whether to reload rules from config file.
        """

        if force_reload:
            self.use_conf = force_reload

        if self.use_conf:
            if not self.policy_path:
                try:
                    self.policy_path = self._get_policy_path(self.policy_file)
                except cfg.ConfigFilesNotFoundError:
                    if not self._informed_no_policy_file:
                        LOG.debug('The policy file %s could not be found.',
                                  self.policy_file)
                        self._informed_no_policy_file = True

            if self.policy_path:
                self._load_policy_file(self.policy_path,
                                       force_reload,
                                       overwrite=self.overwrite)
            for path in self.conf.oslo_policy.policy_dirs:
                try:
                    path = self._get_policy_path(path)
                except cfg.ConfigFilesNotFoundError:
                    continue
                if (force_reload or self._is_directory_updated(
                        self._policy_dir_mtimes, path)):
                    self._walk_through_policy_directory(
                        path, self._load_policy_file, force_reload, False)

            for default in self.registered_rules.values():
                if default.deprecated_rule:
                    deprecated_msg = (
                        'Policy "%(old_name)s":"%(old_check_str)s" was '
                        'deprecated in %(release)s in favor of "%(name)s":'
                        '"%(check_str)s". Reason: %(reason)s. Either ensure '
                        'your deployment is ready for the new default or '
                        'copy/paste the deprecated policy into your policy '
                        'file and maintain it manually.' % {
                            'old_name': default.deprecated_rule.name,
                            'old_check_str': default.deprecated_rule.check_str,
                            'release': default.deprecated_since,
                            'name': default.name,
                            'check_str': default.check_str,
                            'reason': default.deprecated_reason
                        })
                    if default.deprecated_rule.name != default.name and (
                            default.deprecated_rule.name in self.rules):
                        # Print a warning because the actual policy name is
                        # changing. If deployers are relying on an override for
                        # foo:bar and it's getting renamed to foo:create_bar
                        # then they need to be able to see that before they
                        # roll out the next release.
                        warnings.warn(deprecated_msg)
                    if (default.deprecated_rule.check_str != default.check_str
                            and default.name not in self.rules):
                        # In this case, the default check_str is changing. We
                        # need to let operators know that this is going to
                        # change. If they don't want to override it, they are
                        # going to have to make sure the right infrastructure
                        # exists before they upgrade. This overrides the new
                        # check with an OrCheck that combines the new and old
                        # check_str attributes from the new and deprecated
                        # policies. This will make it so that deployments don't
                        # break on upgrade, but they receive log messages
                        # telling them stuff is going to change if they don't
                        # maintain the policy manually or add infrastructure to
                        # their deployment to support the new policy.
                        default.check = _parser.parse_rule(
                            default.check_str + ' or ' +
                            default.deprecated_rule.check_str)
                        warnings.warn(deprecated_msg)
                if default.deprecated_for_removal and (default.name
                                                       in self.file_rules):
                    # If a policy is going to be removed altogether, then we
                    # need to make sure we let operators know so they can clean
                    # up their policy files, if they are overriding it.
                    warnings.warn(
                        'Policy "%(policy)s":"%(check_str)s" was '
                        'deprecated for removal in %(release)s. Reason: '
                        '%(reason)s. Its value may be silently ignored in '
                        'the future.' % {
                            'policy': default.name,
                            'check_str': default.check_str,
                            'release': default.deprecated_since,
                            'reason': default.deprecated_reason
                        })
                if default.name not in self.rules:
                    self.rules[default.name] = default.check

            # Detect and log obvious incorrect rule definitions
            self.check_rules()
 def set_rules(self, rules):
     policy = commissaire_openstack_policy._ENFORCER
     policy.set_rules({k: _parser.parse_rule(v) for k, v in rules.items()})
Example #23
0
 def __init__(self, name, check_str, description=None):
     self.name = name
     self.check_str = check_str
     self.check = _parser.parse_rule(check_str)
     self.description = description
Example #24
0
 def __init__(self, name, check_str, description=None):
     self.name = name
     self.check_str = check_str
     self.check = _parser.parse_rule(check_str)
     self.description = description
Example #25
0
 def __init__(self, name, check_str):
     self.name = name
     self.check = _parser.parse_rule(check_str)
Example #26
0
    def test_parse_rule_list(self, mock_parse_list_rule, mock_parse_text_rule):
        result = _parser.parse_rule([['a'], ['list']])

        self.assertEqual('list rule', result)
        self.assertFalse(mock_parse_text_rule.called)
        mock_parse_list_rule.assert_called_once_with([['a'], ['list']])
Example #27
0
 def __init__(self, name, check_str):
     self.name = name
     self.check = _parser.parse_rule(check_str)
Example #28
0
 def set_rules(self, rules):
     policy = watcher_policy._ENFORCER
     policy.set_rules({k: _parser.parse_rule(v)
                       for k, v in rules.items()})
Example #29
0
    def test_parse_rule_list(self, mock_parse_list_rule, mock_parse_text_rule):
        result = _parser.parse_rule([['a'], ['list']])

        self.assertEqual('list rule', result)
        self.assertFalse(mock_parse_text_rule.called)
        mock_parse_list_rule.assert_called_once_with([['a'], ['list']])