Enabled new defaults and scope checks by default

Enabling the enforce scope and new defaults by default in glance

Related blueprint secure-rbac

Change-Id: I0808dc0b1b34b527e38aa137c1dd25e1fc06409f
This commit is contained in:
Pranali Deore 2023-02-02 10:24:00 +00:00
parent 81da9ccbde
commit 8c04d19e88
12 changed files with 177 additions and 44 deletions

View File

@ -289,6 +289,20 @@
glance_store:
rbd_thin_provisioning: True
# TODO(pdeore): Remove this jobs once all the glance jobs will be tested
# with new RBAC in integrated way and we do not need this separate job.
- job:
name: tempest-integrated-storage-enforce-scope-new-defaults
parent: tempest-integrated-storage
description: |
This job runs the Tempest tests with scope and new defaults enabled
Glance services.
vars:
devstack_localrc:
NOVA_ENFORCE_SCOPE: true
CINDER_ENFORCE_SCOPE: true
GLANCE_ENFORCE_SCOPE: true
- project:
templates:
- check-requirements
@ -319,6 +333,8 @@
- ^\.zuul\.yaml$
- tempest-integrated-storage:
irrelevant-files: *tempest-irrelevant-files
- tempest-integrated-storage-enforce-scope-new-defaults:
irrelevant-files: *tempest-irrelevant-files
- tempest-integrated-storage-import:
irrelevant-files: *tempest-irrelevant-files
- tempest-integrated-storage-import-standalone:
@ -339,6 +355,8 @@
- openstack-tox-functional-py39
- tempest-integrated-storage:
irrelevant-files: *tempest-irrelevant-files
- tempest-integrated-storage-enforce-scope-new-defaults:
irrelevant-files: *tempest-irrelevant-files
- tempest-integrated-storage-import:
irrelevant-files: *tempest-irrelevant-files
- tempest-integrated-storage-import-standalone:

View File

@ -34,11 +34,15 @@ CONF = cfg.CONF
_ENFORCER = None
# TODO(gmann): Remove setting the default value of config policy_file
# once oslo_policy change the default value to 'policy.yaml'.
# https://github.com/openstack/oslo.policy/blob/a626ad12fe5a3abd49d70e3e5b95589d279ab578/oslo_policy/opts.py#L49
# TODO(gmann): Remove overriding the default value of config options
# 'policy_file', 'enforce_scope', and 'enforce_new_defaults' once
# oslo_policy change their default value to what is overridden here.
DEFAULT_POLICY_FILE = 'policy.yaml'
opts.set_defaults(cfg.CONF, DEFAULT_POLICY_FILE)
opts.set_defaults(
cfg.CONF,
DEFAULT_POLICY_FILE,
enforce_scope=True,
enforce_new_defaults=True)
class Enforcer(policy.Enforcer):

View File

@ -593,7 +593,7 @@ Related options:
Related options:
* [DEFAULT]/node_staging_uri""")),
cfg.BoolOpt('enforce_secure_rbac', default=False,
cfg.BoolOpt('enforce_secure_rbac', default=True,
deprecated_for_removal=True,
deprecated_reason=_("""
This option has been introduced to require operators to opt into enforcing

View File

@ -585,6 +585,9 @@ class ApiServerForMultipleBackend(Server):
self.image_location_quota = 2
self.disable_path = None
self.enforce_secure_rbac = True
self.enforce_new_defaults = True
self.needs_database = True
default_sql_connection = SQLITE_CONN_TEMPLATE % self.test_dir
self.sql_connection = os.environ.get('GLANCE_TEST_SQL_CONNECTION',
@ -626,9 +629,11 @@ image_location_quota=%(image_location_quota)s
location_strategy=%(location_strategy)s
allow_additional_image_properties = True
enabled_backends=file1:file,file2:file,file3:file
enforce_secure_rbac=%(enforce_secure_rbac)s
[oslo_policy]
policy_file = %(policy_file)s
policy_default_rule = %(policy_default_rule)s
enforce_new_defaults=%(enforce_new_defaults)s
[paste_deploy]
flavor = %(deployment_flavor)s
[store_type_location_strategy]

View File

@ -409,7 +409,8 @@ class TestCacheMiddlewareProcessResponse(base.IsolatedUnitTest):
rules = {
"restricted":
"not ('test_1234':%(x_test_key)s and role:_member_)",
"download_image": "role:admin or rule:restricted"
"download_image": "role:admin or rule:restricted",
"get_image": ""
}
self.set_policy_rules(rules)
cache_filter.policy = glance.api.policy.Enforcer(

View File

@ -320,7 +320,8 @@ class TestPolicyEnforcer(base.IsolatedUnitTest):
self.assertEqual(False, enforcer.check(context, 'get_image', {}))
def test_policy_file_get_image_default_everybody(self):
rules = {"default": ''}
rules = {"default": '',
"get_image": ''}
self.set_policy_rules(rules)
enforcer = glance.api.policy.Enforcer(

View File

@ -20,6 +20,7 @@ from unittest import mock
import urllib
from oslo_config import cfg
from oslo_policy import policy
from glance.async_.flows._internal_plugins import base_download
from glance.common import exception
@ -87,6 +88,14 @@ def get_fake_request(path='', method='POST', is_admin=False, user=USER1,
return req
def enforcer_from_rules(unparsed_rules):
rules = policy.Rules.from_dict(unparsed_rules)
enforcer = glance.api.policy.Enforcer(
suppress_deprecation_warnings=True)
enforcer.set_rules(rules, overwrite=True)
return enforcer
def fake_get_size_from_backend(uri, context=None):
return 1

View File

@ -135,7 +135,7 @@ class TestImagesController(base.StoreClearingUnitTest):
self.addCleanup(patcher.stop)
def test_download(self):
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage('abcd',
locations=[{'url': 'http://example.com/image',
'metadata': {}, 'status': 'active'}])
@ -156,7 +156,7 @@ class TestImagesController(base.StoreClearingUnitTest):
def test_download_no_location(self):
# NOTE(mclaren): NoContent will be raised by the ResponseSerializer
# That's tested below.
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
self.image_repo.result = FakeImage('abcd')
image = self.controller.download(request, unit_test_utils.UUID2)
self.assertEqual('abcd', image.image_id)
@ -179,7 +179,7 @@ class TestImagesController(base.StoreClearingUnitTest):
def __len__(self):
raise exception.Forbidden()
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage('abcd')
self.image_repo.result = image
image.locations = ImageLocations()
@ -187,7 +187,7 @@ class TestImagesController(base.StoreClearingUnitTest):
self.assertEqual('abcd', image.image_id)
def test_upload(self):
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage('abcd', owner='tenant1')
self.image_repo.result = image
self.controller.upload(request, unit_test_utils.UUID2, 'YYYY', 4)
@ -217,7 +217,7 @@ class TestImagesController(base.StoreClearingUnitTest):
self.assertTrue(mock_enf.called)
def test_upload_status(self):
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage('abcd')
self.image_repo.result = image
insurance = {'called': False}
@ -234,7 +234,7 @@ class TestImagesController(base.StoreClearingUnitTest):
self.image_repo.saved_image.status)
def test_upload_no_size(self):
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage('abcd')
self.image_repo.result = image
self.controller.upload(request, unit_test_utils.UUID2, 'YYYY', None)
@ -256,7 +256,7 @@ class TestImagesController(base.StoreClearingUnitTest):
mock_enforce.assert_has_calls(expected_call)
def test_upload_invalid(self):
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage('abcd')
image.status = ValueError()
self.image_repo.result = image
@ -270,7 +270,7 @@ class TestImagesController(base.StoreClearingUnitTest):
mocked_save = mock.Mock(side_effect=side_effect)
mocked_delete = mock.Mock()
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage('abcd')
image.delete = mocked_delete
self.image_repo.result = image
@ -287,7 +287,7 @@ class TestImagesController(base.StoreClearingUnitTest):
mocked_save.side_effect = [lambda *a: None,
exception.NotAuthenticated(),
lambda *a: None]
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
request.environ['keystone.token_info'] = {
'token': {
'roles': [{'name': 'member'}]
@ -309,7 +309,8 @@ class TestImagesController(base.StoreClearingUnitTest):
raise exception.Conflict()
for fun in [fake_save_not_found, fake_save_conflict]:
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(
roles=['admin', 'member'])
image = FakeImage('abcd', locations=['http://example.com/image'])
self.image_repo.result = image
self.image_repo.save = fun
@ -325,7 +326,7 @@ class TestImagesController(base.StoreClearingUnitTest):
def fake_delete():
raise exception.ImageNotFound()
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage('abcd', locations=['http://example.com/image'])
self.image_repo.result = image
self.image_repo.save = fake_save
@ -340,7 +341,7 @@ class TestImagesController(base.StoreClearingUnitTest):
def fake_delete():
raise exception.ImageNotFound()
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage('abcd', locations=['http://example.com/image'])
self.image_repo.result = image
self.image_repo.save = fake_save
@ -355,7 +356,7 @@ class TestImagesController(base.StoreClearingUnitTest):
request, str(uuid.uuid4()), 'ABC', 3)
def test_upload_data_exists(self):
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage()
exc = exception.InvalidImageStatusTransition(cur_status='active',
new_status='queued')
@ -365,7 +366,7 @@ class TestImagesController(base.StoreClearingUnitTest):
request, unit_test_utils.UUID1, 'YYYY', 4)
def test_upload_storage_full(self):
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage()
image.set_data = Raise(glance_store.StorageFull)
self.image_repo.result = image
@ -374,7 +375,7 @@ class TestImagesController(base.StoreClearingUnitTest):
request, unit_test_utils.UUID2, 'YYYYYYY', 7)
def test_upload_signature_verification_fails(self):
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage()
image.set_data = Raise(cursive_exception.SignatureVerificationError)
self.image_repo.result = image
@ -383,7 +384,7 @@ class TestImagesController(base.StoreClearingUnitTest):
self.assertEqual('queued', self.image_repo.saved_image.status)
def test_image_size_limit_exceeded(self):
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage()
image.set_data = Raise(exception.ImageSizeLimitExceeded)
self.image_repo.result = image
@ -399,7 +400,8 @@ class TestImagesController(base.StoreClearingUnitTest):
request, unit_test_utils.UUID1, 'YYYYYYY', 7)
def test_upload_storage_forbidden(self):
request = unit_test_utils.get_fake_request(user=unit_test_utils.USER2)
request = unit_test_utils.get_fake_request(
user=unit_test_utils.USER2, roles=['admin', 'member'])
image = FakeImage()
image.set_data = Raise(exception.Forbidden)
self.image_repo.result = image
@ -414,7 +416,8 @@ class TestImagesController(base.StoreClearingUnitTest):
request, unit_test_utils.UUID1, 'ABC', 3)
def test_upload_storage_write_denied(self):
request = unit_test_utils.get_fake_request(user=unit_test_utils.USER3)
request = unit_test_utils.get_fake_request(
user=unit_test_utils.USER3, roles=['admin', 'member'])
image = FakeImage()
image.set_data = Raise(glance_store.StorageWriteDenied)
self.image_repo.result = image
@ -424,7 +427,8 @@ class TestImagesController(base.StoreClearingUnitTest):
def test_upload_storage_store_disabled(self):
"""Test that uploading an image file raises StoreDisabled exception"""
request = unit_test_utils.get_fake_request(user=unit_test_utils.USER3)
request = unit_test_utils.get_fake_request(
user=unit_test_utils.USER3, roles=['admin', 'member'])
image = FakeImage()
image.set_data = Raise(glance_store.StoreAddDisabled)
self.image_repo.result = image
@ -484,7 +488,7 @@ class TestImagesController(base.StoreClearingUnitTest):
self.assertEqual(activate_log, output_log[2])
def test_restore_image_when_upload_failed(self):
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage('fake')
image.set_data = Raise(glance_store.StorageWriteDenied)
self.image_repo.result = image
@ -496,7 +500,7 @@ class TestImagesController(base.StoreClearingUnitTest):
@mock.patch.object(filesystem.Store, 'add')
def test_restore_image_when_staging_failed(self, mock_store_add):
mock_store_add.side_effect = glance_store.StorageWriteDenied()
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image_id = str(uuid.uuid4())
image = FakeImage('fake')
self.image_repo.result = image
@ -507,7 +511,7 @@ class TestImagesController(base.StoreClearingUnitTest):
def test_stage(self):
image_id = str(uuid.uuid4())
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage(image_id=image_id)
self.image_repo.result = image
with mock.patch.object(filesystem.Store, 'add') as mock_add:
@ -518,7 +522,7 @@ class TestImagesController(base.StoreClearingUnitTest):
def test_image_already_on_staging(self):
image_id = str(uuid.uuid4())
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage(image_id=image_id)
self.image_repo.result = image
with mock.patch.object(filesystem.Store, 'add') as mock_store_add:
@ -534,7 +538,7 @@ class TestImagesController(base.StoreClearingUnitTest):
def test_image_stage_raises_bad_store_uri(self, mock_store_configure):
mock_store_configure.side_effect = AttributeError()
image_id = str(uuid.uuid4())
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
self.assertRaises(exception.BadStoreUri, self.controller.stage,
request, image_id, 'YYYY', 4)
@ -542,7 +546,7 @@ class TestImagesController(base.StoreClearingUnitTest):
def test_image_stage_raises_storage_full(self, mock_store_add):
mock_store_add.side_effect = glance_store.StorageFull()
image_id = str(uuid.uuid4())
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage(image_id=image_id)
self.image_repo.result = image
with mock.patch.object(self.controller, "_unstage"):
@ -554,7 +558,7 @@ class TestImagesController(base.StoreClearingUnitTest):
def test_image_stage_raises_storage_quota_full(self, mock_store_add):
mock_store_add.side_effect = exception.StorageQuotaFull("message")
image_id = str(uuid.uuid4())
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage(image_id=image_id)
self.image_repo.result = image
with mock.patch.object(self.controller, "_unstage"):
@ -566,7 +570,7 @@ class TestImagesController(base.StoreClearingUnitTest):
def test_image_stage_raises_storage_write_denied(self, mock_store_add):
mock_store_add.side_effect = glance_store.StorageWriteDenied()
image_id = str(uuid.uuid4())
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage(image_id=image_id)
self.image_repo.result = image
with mock.patch.object(self.controller, "_unstage"):
@ -592,7 +596,7 @@ class TestImagesController(base.StoreClearingUnitTest):
def test_image_stage_raises_image_size_exceeded(self, mock_store_add):
mock_store_add.side_effect = exception.ImageSizeLimitExceeded()
image_id = str(uuid.uuid4())
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage(image_id=image_id)
self.image_repo.result = image
with mock.patch.object(self.controller, "_unstage"):
@ -603,7 +607,7 @@ class TestImagesController(base.StoreClearingUnitTest):
@mock.patch.object(filesystem.Store, 'add')
def test_image_stage_invalid_image_transition(self, mock_store_add):
image_id = str(uuid.uuid4())
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage(image_id=image_id)
self.image_repo.result = image
with mock.patch.object(filesystem.Store, 'add') as mock_add:
@ -619,7 +623,7 @@ class TestImagesController(base.StoreClearingUnitTest):
def _test_image_stage_records_host(self, expected_url):
image_id = str(uuid.uuid4())
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage(image_id=image_id)
self.image_repo.result = image
with mock.patch.object(filesystem.Store, 'add') as mock_add:
@ -651,7 +655,7 @@ class TestImagesController(base.StoreClearingUnitTest):
# image staged.
self.config(public_endpoint='http://worker1.example.com')
image_id = str(uuid.uuid4())
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage(image_id=image_id)
self.image_repo.result = image
exc_cls = glance_store.exceptions.StorageFull
@ -732,7 +736,7 @@ class TestImageDataDeserializer(test_utils.BaseTestCase):
self.deserializer.upload, request)
def test_stage(self):
req = unit_test_utils.get_fake_request()
req = unit_test_utils.get_fake_request(roles=['admin', 'member'])
req.headers['Content-Type'] = 'application/octet-stream'
req.headers['Content-Length'] = 4
req.body_file = io.BytesIO(b'YYYY')
@ -1078,7 +1082,7 @@ class TestMultiBackendImagesController(base.MultiStoreClearingUnitTest):
self.addCleanup(patcher.stop)
def test_upload(self):
request = unit_test_utils.get_fake_request()
request = unit_test_utils.get_fake_request(roles=['admin', 'member'])
image = FakeImage('abcd')
self.image_repo.result = image
self.controller.upload(request, unit_test_utils.UUID2, 'YYYY', 4)

View File

@ -316,6 +316,11 @@ class TestImageMembersController(test_utils.BaseTestCase):
self.assertEqual('accepted', output.status)
def test_update_done_by_owner(self):
enforcer = unit_test_utils.enforcer_from_rules({
"get_image": "",
"modify_image": "'{0}':%(owner)s".format(TENANT1)
})
self.controller.policy = enforcer
request = unit_test_utils.get_fake_request(tenant=TENANT1)
self.assertRaises(webob.exc.HTTPForbidden, self.controller.update,
request, UUID2, TENANT4, status='accepted')
@ -331,6 +336,10 @@ class TestImageMembersController(test_utils.BaseTestCase):
request, UUID2, TENANT4, status='accept')
def test_create_private_image(self):
enforcer = unit_test_utils.enforcer_from_rules({
"get_image": "",
})
self.controller.policy = enforcer
request = unit_test_utils.get_fake_request()
self.assertRaises(webob.exc.HTTPForbidden, self.controller.create,
request, UUID4, TENANT2)
@ -359,7 +368,14 @@ class TestImageMembersController(test_utils.BaseTestCase):
self.assertEqual([], found_member)
def test_delete_by_member(self):
enforcer = unit_test_utils.enforcer_from_rules({
"get_image": "",
"delete_member": "'{0}':%(owner)s".format(TENANT4),
"get_members": "",
"get_member": ""
})
request = unit_test_utils.get_fake_request(tenant=TENANT4)
self.controller.policy = enforcer
self.assertRaises(webob.exc.HTTPForbidden, self.controller.delete,
request, UUID2, TENANT4)
request = unit_test_utils.get_fake_request()
@ -395,6 +411,12 @@ class TestImageMembersController(test_utils.BaseTestCase):
request, UUID2, TENANT4)
def test_delete_private_image(self):
enforcer = unit_test_utils.enforcer_from_rules({
"get_image": "",
"delete_member": "'{0}':%(owner)s".format(TENANT1),
"get_member": ""
})
self.controller.policy = enforcer
request = unit_test_utils.get_fake_request()
self.assertRaises(webob.exc.HTTPForbidden, self.controller.delete,
request, UUID4, TENANT1)

View File

@ -1253,17 +1253,25 @@ class TestImagesController(base.IsolatedUnitTest):
tags=tags)
def test_create_with_owner_non_admin(self):
enforcer = unit_test_utils.enforcer_from_rules({
"add_image": "role:member,reader",
})
request = unit_test_utils.get_fake_request()
request.context.is_admin = False
image = {'owner': '12345'}
self.controller.policy = enforcer
self.assertRaises(webob.exc.HTTPForbidden,
self.controller.create,
request, image=image, extra_properties={},
tags=[])
enforcer = unit_test_utils.enforcer_from_rules({
"add_image": "'{0}':%(owner)s".format(TENANT1),
})
request = unit_test_utils.get_fake_request()
request.context.is_admin = False
image = {'owner': TENANT1}
self.controller.policy = enforcer
output = self.controller.create(request, image=image,
extra_properties={}, tags=[])
self.assertEqual(TENANT1, output.owner)
@ -1616,7 +1624,7 @@ class TestImagesController(base.IsolatedUnitTest):
enforcer,
self.notifier,
self.store)
request = unit_test_utils.get_fake_request(roles=['spl_role'])
request = unit_test_utils.get_fake_request(roles=['spl_role', 'admin'])
image = {'name': 'image-1'}
extra_props = {'spl_creator_policy': 'bar'}
created_image = self.controller.create(request, image=image,
@ -1629,8 +1637,19 @@ class TestImagesController(base.IsolatedUnitTest):
changes = [
{'op': 'replace', 'path': ['spl_creator_policy'], 'value': 'par'},
]
enforcer = unit_test_utils.enforcer_from_rules({
"get_image": "",
"modify_image": "role:spl_role"
})
self.controller.policy = enforcer
self.assertRaises(webob.exc.HTTPForbidden, self.controller.update,
another_request, created_image.image_id, changes)
enforcer = unit_test_utils.enforcer_from_rules({
"get_image": "",
"modify_image": "role:admin"
})
self.controller.policy = enforcer
another_request = unit_test_utils.get_fake_request(roles=['admin'])
output = self.controller.update(another_request,
created_image.image_id, changes)
@ -1655,9 +1674,19 @@ class TestImagesController(base.IsolatedUnitTest):
changes = [
{'op': 'add', 'path': ['spl_creator_policy'], 'value': 'bar'},
]
enforcer = unit_test_utils.enforcer_from_rules({
"get_image": "",
"modify_image": "role:fake_role"
})
self.controller.policy = enforcer
self.assertRaises(webob.exc.HTTPForbidden, self.controller.update,
another_request, created_image.image_id, changes)
enforcer = unit_test_utils.enforcer_from_rules({
"get_image": "",
"modify_image": "role:member"
})
self.controller.policy = enforcer
another_request = unit_test_utils.get_fake_request(roles=['member',
'spl_role'])
output = self.controller.update(another_request,
@ -1679,6 +1708,11 @@ class TestImagesController(base.IsolatedUnitTest):
extra_properties={},
tags=[])
roles = ['fake_member']
enforcer = unit_test_utils.enforcer_from_rules({
"get_image": "",
"modify_image": "role:fake_member"
})
self.controller.policy = enforcer
another_request = unit_test_utils.get_fake_request(roles=roles)
changes = [
{'op': 'add', 'path': ['x_owner_foo'], 'value': 'bar'},
@ -1762,6 +1796,11 @@ class TestImagesController(base.IsolatedUnitTest):
created_image = self.controller.create(request, image=image,
extra_properties=extra_props,
tags=[])
enforcer = unit_test_utils.enforcer_from_rules({
"get_image": "",
"modify_image": "role:fake_role"
})
self.controller.policy = enforcer
another_request = unit_test_utils.get_fake_request(roles=['fake_role'])
changes = [
{'op': 'replace', 'path': ['x_owner_foo'], 'value': 'baz'},
@ -1806,6 +1845,11 @@ class TestImagesController(base.IsolatedUnitTest):
created_image = self.controller.create(request, image=image,
extra_properties=extra_props,
tags=[])
enforcer = unit_test_utils.enforcer_from_rules({
"get_image": "",
"modify_image": "role:fake_role"
})
self.controller.policy = enforcer
another_request = unit_test_utils.get_fake_request(roles=['fake_role'])
changes = [
{'op': 'remove', 'path': ['x_owner_foo']}
@ -3420,7 +3464,12 @@ class TestImagesController(base.IsolatedUnitTest):
def test_image_import_not_allowed(self, mock_get, mock_new_task):
# NOTE(danms): FakeImage is owned by utils.TENANT1. Try to do the
# import as TENANT2 and we should get an HTTPForbidden
request = unit_test_utils.get_fake_request(tenant=TENANT2)
enforcer = unit_test_utils.enforcer_from_rules({
"get_image": "",
"modify_image": "'{0}':%(owner)s".format(TENANT2)
})
request = unit_test_utils.get_fake_request()
self.controller.policy = enforcer
mock_get.return_value = FakeImage(status='uploading')
self.assertRaises(webob.exc.HTTPForbidden,
self.controller.import_image,
@ -6008,7 +6057,13 @@ class TestMultiImagesController(base.MultiIsolatedUnitTest):
{'method': {'name': 'glance-direct'}})
def test_delete_from_store_as_non_owner(self):
enforcer = unit_test_utils.enforcer_from_rules({
"get_image": "",
"delete_image_location": "'TENANT4':%(owner)s",
"get_image_location": ""
})
request = unit_test_utils.get_fake_request()
self.controller.policy = enforcer
self.assertRaises(webob.exc.HTTPForbidden,
self.controller.delete_from_store,
request,

View File

@ -0,0 +1,14 @@
---
upgrade:
- |
The Glance service enables the API policies (RBAC) new defaults and scope by
default. The Default value of config options ``[oslo_policy] enforce_scope``
and ``[oslo_policy] oslo_policy.enforce_new_defaults`` have been changed
to ``True``.
If you want to disable them then modify the below config options value in
``glance-api.conf`` file::
[oslo_policy]
enforce_new_defaults=False
enforce_scope=False

View File

@ -41,7 +41,7 @@ oslo.log>=4.5.0 # Apache-2.0
oslo.messaging>=5.29.0,!=9.0.0 # Apache-2.0
oslo.middleware>=3.31.0 # Apache-2.0
oslo.reports>=1.18.0 # Apache-2.0
oslo.policy>=3.8.1 # Apache-2.0
oslo.policy>=3.11.0 # Apache-2.0
retrying!=1.3.0,>=1.2.3 # Apache-2.0
osprofiler>=1.4.0 # Apache-2.0