Add check_is_image_mutable() legacy helper
This adds a method to let API code replicate the legacy admin-or-owner behavior where needed. Since the authorization layer does this in some places (which is being removed) and the DB does it in others, we need a way to replicate that check when secure_rbac is not in use for certain code paths (like image delete) which need it. Change-Id: I89785ae04e7f66651a1b9673f7e5513c2eac10fc Partially-implements: blueprint policy-refactor
This commit is contained in:
parent
2841892229
commit
39198f93f8
|
@ -13,13 +13,44 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
import webob.exc
|
||||
|
||||
from glance.api import policy
|
||||
from glance.common import exception
|
||||
from glance.i18n import _
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
# TODO(danms): Remove this once secure RBAC is fully implemented and
|
||||
# used instead of legacy policy checks.
|
||||
def check_is_image_mutable(context, image):
|
||||
"""Replicate the DB-layer admin-or-owner check for the API.
|
||||
|
||||
Much of the API code depends on hard-coded admin-or-owner
|
||||
enforcement in the DB or authorization layer, as the policy layer
|
||||
is largely a no-op by default. During blueprint policy-refactor,
|
||||
we are trying to remove as much of that as possible, but in
|
||||
certain places we need to do that (if secure_rbac is not
|
||||
enabled). This transitional helper provides a way to do that
|
||||
enforcement where necessary.
|
||||
|
||||
:param context: A RequestContext
|
||||
:param image: An ImageProxy
|
||||
:raises: exception.Forbidden if the context is not the owner or an admin
|
||||
"""
|
||||
# Is admin == image mutable
|
||||
if context.is_admin:
|
||||
return
|
||||
|
||||
# No owner == image not mutable
|
||||
# Image only mutable by its owner
|
||||
if (image.owner is None or context.owner is None or
|
||||
image.owner != context.owner):
|
||||
raise exception.Forbidden(_('You do not own this image'))
|
||||
|
||||
|
||||
class APIPolicyBase(object):
|
||||
|
|
|
@ -55,6 +55,40 @@ class APIPolicyBase(utils.BaseTestCase):
|
|||
self.enforcer.enforce.side_effect = exception.Forbidden
|
||||
self.assertFalse(self.policy.check('_enforce', 'fake_rule'))
|
||||
|
||||
def test_check_is_image_mutable(self):
|
||||
context = mock.MagicMock()
|
||||
image = mock.MagicMock()
|
||||
|
||||
# Admin always wins
|
||||
context.is_admin = True
|
||||
context.owner = 'someuser'
|
||||
self.assertIsNone(policy.check_is_image_mutable(context, image))
|
||||
|
||||
# Image has no owner is never mutable by non-admins
|
||||
context.is_admin = False
|
||||
image.owner = None
|
||||
self.assertRaises(exception.Forbidden,
|
||||
policy.check_is_image_mutable,
|
||||
context, image)
|
||||
|
||||
# Not owner is not mutable
|
||||
image.owner = 'someoneelse'
|
||||
self.assertRaises(exception.Forbidden,
|
||||
policy.check_is_image_mutable,
|
||||
context, image)
|
||||
|
||||
# No project in context means not mutable
|
||||
image.owner = 'someoneelse'
|
||||
context.owner = None
|
||||
self.assertRaises(exception.Forbidden,
|
||||
policy.check_is_image_mutable,
|
||||
context, image)
|
||||
|
||||
# Context matches image owner is mutable
|
||||
image.owner = 'someuser'
|
||||
context.owner = 'someuser'
|
||||
self.assertIsNone(policy.check_is_image_mutable(context, image))
|
||||
|
||||
|
||||
class APIImagePolicy(APIPolicyBase):
|
||||
def setUp(self):
|
||||
|
|
Loading…
Reference in New Issue