Merge "Fix events rbac"
This commit is contained in:
commit
1af401653c
@ -54,8 +54,8 @@ def enforce(policy_name, request):
|
|||||||
|
|
||||||
policy_dict = dict()
|
policy_dict = dict()
|
||||||
policy_dict['roles'] = headers.get('X-Roles', "").split(",")
|
policy_dict['roles'] = headers.get('X-Roles', "").split(",")
|
||||||
policy_dict['target.user_id'] = (headers.get('X-User-Id'))
|
policy_dict['user_id'] = (headers.get('X-User-Id'))
|
||||||
policy_dict['target.project_id'] = (headers.get('X-Project-Id'))
|
policy_dict['project_id'] = (headers.get('X-Project-Id'))
|
||||||
|
|
||||||
# maintain backward compat with Juno and previous by allowing the action if
|
# maintain backward compat with Juno and previous by allowing the action if
|
||||||
# there is no rule defined for it
|
# there is no rule defined for it
|
||||||
@ -82,8 +82,8 @@ def get_limited_to(headers):
|
|||||||
|
|
||||||
policy_dict = dict()
|
policy_dict = dict()
|
||||||
policy_dict['roles'] = headers.get('X-Roles', "").split(",")
|
policy_dict['roles'] = headers.get('X-Roles', "").split(",")
|
||||||
policy_dict['target.user_id'] = (headers.get('X-User-Id'))
|
policy_dict['user_id'] = (headers.get('X-User-Id'))
|
||||||
policy_dict['target.project_id'] = (headers.get('X-Project-Id'))
|
policy_dict['project_id'] = (headers.get('X-Project-Id'))
|
||||||
|
|
||||||
# maintain backward compat with Juno and previous by using context_is_admin
|
# maintain backward compat with Juno and previous by using context_is_admin
|
||||||
# rule if the segregation rule (added in Kilo) is not defined
|
# rule if the segregation rule (added in Kilo) is not defined
|
||||||
|
@ -24,6 +24,7 @@ import six
|
|||||||
import webtest
|
import webtest
|
||||||
|
|
||||||
from ceilometer.api import app
|
from ceilometer.api import app
|
||||||
|
from ceilometer.event.storage import models as ev_model
|
||||||
from ceilometer.publisher import utils
|
from ceilometer.publisher import utils
|
||||||
from ceilometer import sample
|
from ceilometer import sample
|
||||||
from ceilometer.tests.functional.api import v2
|
from ceilometer.tests.functional.api import v2
|
||||||
@ -195,51 +196,18 @@ class TestAPIEventACL(TestAPIACL):
|
|||||||
self.assertEqual(401, data.status_int)
|
self.assertEqual(401, data.status_int)
|
||||||
|
|
||||||
|
|
||||||
class TestApiEventRBAC(v2.FunctionalTest):
|
class TestBaseApiEventRBAC(v2.FunctionalTest):
|
||||||
|
|
||||||
PATH = '/events'
|
PATH = '/events'
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestApiEventRBAC, self).setUp()
|
super(TestBaseApiEventRBAC, self).setUp()
|
||||||
content = ('{"context_is_admin": "role:admin",'
|
traits = [ev_model.Trait('project_id', 1, 'project-good'),
|
||||||
'"segregation": "rule:context_is_admin",'
|
ev_model.Trait('user_id', 1, 'user-good')]
|
||||||
'"default" : "!",'
|
self.message_id = str(uuid.uuid4())
|
||||||
'"telemetry:events:index": "rule:context_is_admin",'
|
ev = ev_model.Event(self.message_id, 'event_type',
|
||||||
'"telemetry:events:show": "rule:context_is_admin"}')
|
datetime.datetime.now(), traits, {})
|
||||||
if six.PY3:
|
self.event_conn.record_events([ev])
|
||||||
content = content.encode('utf-8')
|
|
||||||
self.tempfile = fileutils.write_to_tempfile(content=content,
|
|
||||||
prefix='policy',
|
|
||||||
suffix='.json')
|
|
||||||
|
|
||||||
self.CONF.set_override("policy_file",
|
|
||||||
self.path_get(self.tempfile),
|
|
||||||
group='oslo_policy')
|
|
||||||
self.app = self._make_app()
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
os.remove(self.tempfile)
|
|
||||||
super(TestApiEventRBAC, self).tearDown()
|
|
||||||
|
|
||||||
def test_get_event_by_message_rbac(self):
|
|
||||||
headers_rbac = {"X-Roles": "non-admin"}
|
|
||||||
data = self.get_json(self.PATH + "/100",
|
|
||||||
expect_errors=True,
|
|
||||||
headers=headers_rbac,
|
|
||||||
status=403)
|
|
||||||
self.assertEqual(u'403 Forbidden\n\nAccess was denied to this '
|
|
||||||
'resource.\n\n RBAC Authorization Failed ',
|
|
||||||
data.json['error_message'])
|
|
||||||
|
|
||||||
def test_get_events_rbac(self):
|
|
||||||
headers_rbac = {"X-Roles": "non-admin"}
|
|
||||||
data = self.get_json(self.PATH,
|
|
||||||
expect_errors=True,
|
|
||||||
headers=headers_rbac,
|
|
||||||
status=403)
|
|
||||||
self.assertEqual(u'403 Forbidden\n\nAccess was denied to this '
|
|
||||||
'resource.\n\n RBAC Authorization Failed ',
|
|
||||||
data.json['error_message'])
|
|
||||||
|
|
||||||
def test_get_events_without_project(self):
|
def test_get_events_without_project(self):
|
||||||
headers_no_proj = {"X-Roles": "admin", "X-User-Id": "user-good"}
|
headers_no_proj = {"X-Roles": "admin", "X-User-Id": "user-good"}
|
||||||
@ -260,3 +228,57 @@ class TestApiEventRBAC(v2.FunctionalTest):
|
|||||||
headers=headers_no_user_proj,
|
headers=headers_no_user_proj,
|
||||||
status=403)
|
status=403)
|
||||||
self.assertEqual(403, resp.status_int)
|
self.assertEqual(403, resp.status_int)
|
||||||
|
|
||||||
|
def test_get_events(self):
|
||||||
|
headers = {"X-Roles": "Member", "X-User-Id": "user-good",
|
||||||
|
"X-Project-Id": "project-good"}
|
||||||
|
self.get_json(self.PATH, headers=headers, status=200)
|
||||||
|
|
||||||
|
def test_get_event(self):
|
||||||
|
headers = {"X-Roles": "Member", "X-User-Id": "user-good",
|
||||||
|
"X-Project-Id": "project-good"}
|
||||||
|
self.get_json(self.PATH + "/" + self.message_id, headers=headers,
|
||||||
|
status=200)
|
||||||
|
|
||||||
|
|
||||||
|
class TestApiEventAdminRBAC(TestBaseApiEventRBAC):
|
||||||
|
|
||||||
|
def _make_app(self, enable_acl=False):
|
||||||
|
content = ('{"context_is_admin": "role:admin",'
|
||||||
|
'"telemetry:events:index": "rule:context_is_admin",'
|
||||||
|
'"telemetry:events:show": "rule:context_is_admin"}')
|
||||||
|
if six.PY3:
|
||||||
|
content = content.encode('utf-8')
|
||||||
|
self.tempfile = fileutils.write_to_tempfile(content=content,
|
||||||
|
prefix='policy',
|
||||||
|
suffix='.json')
|
||||||
|
|
||||||
|
self.CONF.set_override("policy_file", self.tempfile,
|
||||||
|
group='oslo_policy')
|
||||||
|
return super(TestApiEventAdminRBAC, self)._make_app()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
os.remove(self.tempfile)
|
||||||
|
super(TestApiEventAdminRBAC, self).tearDown()
|
||||||
|
|
||||||
|
def test_get_events(self):
|
||||||
|
headers_rbac = {"X-Roles": "admin", "X-User-Id": "user-good",
|
||||||
|
"X-Project-Id": "project-good"}
|
||||||
|
self.get_json(self.PATH, headers=headers_rbac, status=200)
|
||||||
|
|
||||||
|
def test_get_events_bad(self):
|
||||||
|
headers_rbac = {"X-Roles": "Member", "X-User-Id": "user-good",
|
||||||
|
"X-Project-Id": "project-good"}
|
||||||
|
self.get_json(self.PATH, headers=headers_rbac, status=403)
|
||||||
|
|
||||||
|
def test_get_event(self):
|
||||||
|
headers = {"X-Roles": "admin", "X-User-Id": "user-good",
|
||||||
|
"X-Project-Id": "project-good"}
|
||||||
|
self.get_json(self.PATH + "/" + self.message_id, headers=headers,
|
||||||
|
status=200)
|
||||||
|
|
||||||
|
def test_get_event_bad(self):
|
||||||
|
headers = {"X-Roles": "Member", "X-User-Id": "user-good",
|
||||||
|
"X-Project-Id": "project-good"}
|
||||||
|
self.get_json(self.PATH + "/" + self.message_id, headers=headers,
|
||||||
|
status=403)
|
||||||
|
@ -12,12 +12,25 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
from oslo_utils import fileutils
|
||||||
from oslotest import mockpatch
|
from oslotest import mockpatch
|
||||||
|
import six
|
||||||
|
|
||||||
from ceilometer.tests.functional.api import v2
|
from ceilometer.tests.functional.api import v2
|
||||||
|
|
||||||
|
|
||||||
class TestAPIUpgradePath(v2.FunctionalTest):
|
class TestAPIUpgradePath(v2.FunctionalTest):
|
||||||
|
def _make_app(self):
|
||||||
|
content = ('{"default": ""}')
|
||||||
|
if six.PY3:
|
||||||
|
content = content.encode('utf-8')
|
||||||
|
self.tempfile = fileutils.write_to_tempfile(content=content,
|
||||||
|
prefix='policy',
|
||||||
|
suffix='.json')
|
||||||
|
self.CONF.set_override("policy_file", self.tempfile,
|
||||||
|
group='oslo_policy')
|
||||||
|
return super(TestAPIUpgradePath, self)._make_app()
|
||||||
|
|
||||||
def _setup_osloconfig_options(self):
|
def _setup_osloconfig_options(self):
|
||||||
self.CONF.set_override('gnocchi_is_enabled', True, group='api')
|
self.CONF.set_override('gnocchi_is_enabled', True, group='api')
|
||||||
self.CONF.set_override('aodh_is_enabled', True, group='api')
|
self.CONF.set_override('aodh_is_enabled', True, group='api')
|
||||||
|
@ -17,10 +17,13 @@
|
|||||||
|
|
||||||
import copy
|
import copy
|
||||||
import datetime
|
import datetime
|
||||||
|
import os
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
from oslo_utils import fileutils
|
||||||
from oslo_utils import timeutils
|
from oslo_utils import timeutils
|
||||||
from oslotest import mockpatch
|
from oslotest import mockpatch
|
||||||
|
import six
|
||||||
|
|
||||||
from ceilometer.tests.functional.api import v2
|
from ceilometer.tests.functional.api import v2
|
||||||
|
|
||||||
@ -32,6 +35,23 @@ class TestPostSamples(v2.FunctionalTest):
|
|||||||
del m['message_signature']
|
del m['message_signature']
|
||||||
self.published.append(samples)
|
self.published.append(samples)
|
||||||
|
|
||||||
|
def _make_app(self, enable_acl=False):
|
||||||
|
content = ('{"context_is_project": "project_id:%(project_id)s",'
|
||||||
|
'"default" : "!",'
|
||||||
|
'"telemetry:create_samples": ""}')
|
||||||
|
if six.PY3:
|
||||||
|
content = content.encode('utf-8')
|
||||||
|
self.tempfile = fileutils.write_to_tempfile(content=content,
|
||||||
|
prefix='policy',
|
||||||
|
suffix='.json')
|
||||||
|
self.CONF.set_override("policy_file", self.tempfile,
|
||||||
|
group='oslo_policy')
|
||||||
|
return super(TestPostSamples, self)._make_app()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
os.remove(self.tempfile)
|
||||||
|
super(TestPostSamples, self).tearDown()
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.published = []
|
self.published = []
|
||||||
notifier = mock.Mock()
|
notifier = mock.Mock()
|
||||||
|
@ -25,6 +25,8 @@ from gabbi import fixture
|
|||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_config import fixture as fixture_config
|
from oslo_config import fixture as fixture_config
|
||||||
from oslo_policy import opts
|
from oslo_policy import opts
|
||||||
|
from oslo_utils import fileutils
|
||||||
|
import six
|
||||||
from six.moves.urllib import parse as urlparse
|
from six.moves.urllib import parse as urlparse
|
||||||
|
|
||||||
from ceilometer.event.storage import models
|
from ceilometer.event.storage import models
|
||||||
@ -62,8 +64,15 @@ class ConfigFixture(fixture.GabbiFixture):
|
|||||||
conf.import_group('api', 'ceilometer.api.controllers.v2.root')
|
conf.import_group('api', 'ceilometer.api.controllers.v2.root')
|
||||||
conf.import_opt('store_events', 'ceilometer.notification',
|
conf.import_opt('store_events', 'ceilometer.notification',
|
||||||
group='notification')
|
group='notification')
|
||||||
conf.set_override('policy_file',
|
|
||||||
os.path.abspath('etc/ceilometer/policy.json'),
|
content = ('{"default": ""}')
|
||||||
|
if six.PY3:
|
||||||
|
content = content.encode('utf-8')
|
||||||
|
self.tempfile = fileutils.write_to_tempfile(content=content,
|
||||||
|
prefix='policy',
|
||||||
|
suffix='.json')
|
||||||
|
|
||||||
|
conf.set_override("policy_file", self.tempfile,
|
||||||
group='oslo_policy')
|
group='oslo_policy')
|
||||||
conf.set_override(
|
conf.set_override(
|
||||||
'api_paste_config',
|
'api_paste_config',
|
||||||
|
@ -1,7 +1,18 @@
|
|||||||
{
|
{
|
||||||
"context_is_admin": "role:admin",
|
"context_is_admin": "role:admin",
|
||||||
"context_is_project": "project_id:%(target.project_id)s",
|
|
||||||
"context_is_owner": "user_id:%(target.user_id)s",
|
|
||||||
"segregation": "rule:context_is_admin",
|
"segregation": "rule:context_is_admin",
|
||||||
"default": ""
|
|
||||||
|
"telemetry:get_samples": "",
|
||||||
|
"telemetry:get_sample": "",
|
||||||
|
"telemetry:query_sample": "",
|
||||||
|
"telemetry:create_samples": "rule:context_is_admin",
|
||||||
|
|
||||||
|
"telemetry:compute_statistics": "",
|
||||||
|
"telemetry:get_meters": "",
|
||||||
|
|
||||||
|
"telemetry:get_resource": "",
|
||||||
|
"telemetry:get_resources": "",
|
||||||
|
|
||||||
|
"telemetry:events:index": "",
|
||||||
|
"telemetry:events:show": ""
|
||||||
}
|
}
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"context_is_admin": "role:admin",
|
|
||||||
"context_is_project": "project_id:%(target.project_id)s",
|
|
||||||
"context_is_owner": "user_id:%(target.user_id)s",
|
|
||||||
"segregation": "rule:context_is_admin",
|
|
||||||
"service_role": "role:service",
|
|
||||||
"iaas_role": "role:iaas",
|
|
||||||
|
|
||||||
"telemetry:get_samples": "rule:service_role or rule:iaas_role",
|
|
||||||
"telemetry:get_sample": "rule:context_is_project",
|
|
||||||
"telemetry:query_sample": "rule:context_is_admin",
|
|
||||||
"telemetry:create_samples": "rule:context_is_admin",
|
|
||||||
|
|
||||||
"telemetry:compute_statistics": "rule:context_is_admin",
|
|
||||||
"telemetry:get_meters": "rule:context_is_admin",
|
|
||||||
|
|
||||||
"telemetry:get_resource": "rule:context_is_admin",
|
|
||||||
"telemetry:get_resources": "rule:context_is_admin",
|
|
Loading…
Reference in New Issue
Block a user