def get_repo(self, context): image_repo = glance.db.ImageRepo(context, self.db_api) store_image_repo = glance.location.ImageRepoProxy( image_repo, context, self.store_api, self.store_utils) quota_image_repo = glance.quota.ImageRepoProxy(store_image_repo, context, self.db_api, self.store_utils) policy_image_repo = policy.ImageRepoProxy(quota_image_repo, context, self.policy) notifier_image_repo = glance.notifier.ImageRepoProxy( policy_image_repo, context, self.notifier) if property_utils.is_property_protection_enabled(): property_rules = property_utils.PropertyRules(self.policy) protected_image_repo = property_protections.\ ProtectedImageRepoProxy(notifier_image_repo, context, property_rules) authorized_image_repo = authorization.ImageRepoProxy( protected_image_repo, context) else: authorized_image_repo = authorization.ImageRepoProxy( notifier_image_repo, context) if CONF.sync_enabled: sync_image_repo = glance.sync.ImageRepoProxy( authorized_image_repo, context, self.sync_api) return sync_image_repo return authorized_image_repo
def get_repo(self, context, authorization_layer=True): """Get the layered ImageRepo model. This is where we construct the "the onion" by layering ImageRepo models on top of each other, starting with the DB at the bottom. NB: Code that has implemented policy checks fully above this layer should pass authorization_layer=False to ensure that no conflicts with old checks happen. Legacy code should continue passing True until legacy checks are no longer needed. :param context: The RequestContext :param authorization_layer: Controls whether or not we add the legacy glance.authorization and glance.policy layers. :returns: An ImageRepo-like object """ repo = glance.db.ImageRepo(context, self.db_api) repo = glance.location.ImageRepoProxy(repo, context, self.store_api, self.store_utils) repo = glance.quota.ImageRepoProxy(repo, context, self.db_api, self.store_utils) if authorization_layer: repo = policy.ImageRepoProxy(repo, context, self.policy) repo = glance.notifier.ImageRepoProxy(repo, context, self.notifier) if property_utils.is_property_protection_enabled(): property_rules = property_utils.PropertyRules(self.policy) repo = property_protections.ProtectedImageRepoProxy( repo, context, property_rules) if authorization_layer: repo = authorization.ImageRepoProxy(repo, context) return repo
def _enforce_delete_protected_props(self, delete_props, image_meta, orig_meta, req): """ Check request is permitted to delete certain properties. Read permission is required to delete a property. Note, the absence of a property in a request does not necessarily indicate a delete. The requester may not have read access, and so can not know the property exists. Hence, read access is a requirement for delete, otherwise the delete is ignored transparently. :param delete_props: List of properties to check :param image_meta: Mapping of proposed new metadata about image :param orig_meta: Mapping of existing metadata about image :param req: The WSGI/Webob Request object :raises HTTPForbidden if request forbidden to create a property """ if property_utils.is_property_protection_enabled(): for key in delete_props: if (self.prop_enforcer.check_property_rules( key, 'read', req.context) is False): # NOTE(bourke): if read protected, re-add to image_meta to # prevent deletion image_meta['properties'][key] = \ orig_meta['properties'][key] elif (self.prop_enforcer.check_property_rules( key, 'delete', req.context) is False): msg = _("Property '%s' is protected") % key LOG.debug(msg) raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain")
def get_image_factory(self, context): image_factory = glance.domain.ImageFactory() store_image_factory = glance.store.ImageFactoryProxy( image_factory, context, self.store_api) quota_image_factory = glance.quota.ImageFactoryProxy( store_image_factory, context, self.db_api) policy_image_factory = policy.ImageFactoryProxy( quota_image_factory, context, self.policy) notifier_image_factory = glance.notifier.ImageFactoryProxy( policy_image_factory, context, self.notifier) if property_utils.is_property_protection_enabled(): property_rules = property_utils.PropertyRules(self.policy) protected_image_factory = property_protections.\ ProtectedImageFactoryProxy(notifier_image_factory, context, property_rules) authorized_image_factory = authorization.ImageFactoryProxy( protected_image_factory, context) else: authorized_image_factory = authorization.ImageFactoryProxy( notifier_image_factory, context) if CONF.sync_enabled: sync_image_factory = glance.sync.ImageFactoryProxy( authorized_image_factory, context, self.sync_api) return sync_image_factory return authorized_image_factory
def __init__(self, db_api=None, policy_enforcer=None): super(ImageIndex, self).__init__() self.db_api = db_api or glance.db.get_api() self.policy = policy_enforcer or policy.Enforcer() if property_utils.is_property_protection_enabled(): self.property_rules = property_utils.PropertyRules(self.policy) self._image_base_properties = [ "checksum", "created_at", "container_format", "disk_format", "id", "min_disk", "min_ram", "name", "size", "virtual_size", "status", "tags", "updated_at", "visibility", "protected", "owner", "members", ]
def _enforce_update_protected_props(self, update_props, image_meta, orig_meta, req): """ Check request is permitted to update certain properties. Read permission is required to delete a property. If the property value is unchanged, i.e. a noop, it is permitted, however, it is important to ensure read access first. Otherwise the value could be discovered using brute force. :param update_props: List of properties to check :param image_meta: Mapping of proposed new metadata about image :param orig_meta: Mapping of existing metadata about image :param req: The WSGI/Webob Request object :raises HTTPForbidden if request forbidden to create a property """ if property_utils.is_property_protection_enabled(): for key in update_props: has_read = self.prop_enforcer.check_property_rules( key, 'read', req.context) if ((self.prop_enforcer.check_property_rules( key, 'update', req.context) is False and image_meta['properties'][key] != orig_meta['properties'][key]) or not has_read): msg = _("Property '%s' is protected") % key LOG.debug(msg) raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain")
def get_repo(self, context): image_repo = glance.db.ImageRepo(context, self.db_api) store_image_repo = glance.location.ImageRepoProxy( image_repo, context, self.store_api, self.store_utils) quota_image_repo = glance.quota.ImageRepoProxy( store_image_repo, context, self.db_api, self.store_utils) policy_image_repo = policy.ImageRepoProxy( quota_image_repo, context, self.policy) notifier_image_repo = glance.notifier.ImageRepoProxy( policy_image_repo, context, self.notifier) if property_utils.is_property_protection_enabled(): property_rules = property_utils.PropertyRules(self.policy) protected_image_repo = property_protections.\ ProtectedImageRepoProxy(notifier_image_repo, context, property_rules) authorized_image_repo = authorization.ImageRepoProxy( protected_image_repo, context) else: authorized_image_repo = authorization.ImageRepoProxy( notifier_image_repo, context) if CONF.sync_enabled: sync_image_repo = glance.sync.ImageRepoProxy( authorized_image_repo, context, self.sync_api) return sync_image_repo return authorized_image_repo
def get_repo(self, context): #生成数据库操作对象 image_repo = glance.db.ImageRepo(context, self.db_api) #??? store_image_repo = glance.location.ImageRepoProxy( image_repo, context, self.store_api, self.store_utils) #包装上配额检查 quota_image_repo = glance.quota.ImageRepoProxy( store_image_repo, context, self.db_api, self.store_utils) #包装上策略检查 policy_image_repo = policy.ImageRepoProxy( quota_image_repo, context, self.policy) #包装上消息通知 notifier_image_repo = glance.notifier.ImageRepoProxy( policy_image_repo, context, self.notifier) if property_utils.is_property_protection_enabled(): property_rules = property_utils.PropertyRules(self.policy) pir = property_protections.ProtectedImageRepoProxy( notifier_image_repo, context, property_rules) authorized_image_repo = authorization.ImageRepoProxy( pir, context) else: #简单起点,我们认为没有开启,再封装一层 authorized_image_repo = authorization.ImageRepoProxy( notifier_image_repo, context) return authorized_image_repo
def __init__(self): self.notifier = notifier.Notifier() registry.configure_registry_client() self.policy = policy.Enforcer() self.pool = eventlet.GreenPool(size=1024) if property_utils.is_property_protection_enabled(): self.prop_enforcer = property_utils.PropertyRules(self.policy) else: self.prop_enforcer = None
def _enforce_read_protected_props(self, image_meta, req): """ Remove entries from metadata properties if they are read protected :param image_meta: Mapping of metadata about image :param req: The WSGI/Webob Request object """ if property_utils.is_property_protection_enabled(): for key in image_meta["properties"].keys(): if self.prop_enforcer.check_property_rules(key, "read", req.context) is False: image_meta["properties"].pop(key)
def filter_result(self, result, request_context): if property_utils.is_property_protection_enabled(): hits = result["hits"]["hits"] for hit in hits: if hit["_type"] == self.get_document_type(): source = hit["_source"] for key in source.keys(): if key not in self._image_base_properties: if not self.property_rules.check_property_rules(key, "read", request_context): del hit["_source"][key] return result
def __init__(self, db_api=None, policy_enforcer=None): super(ImageIndex, self).__init__() self.db_api = db_api or glance.db.get_api() self.policy = policy_enforcer or policy.Enforcer() if property_utils.is_property_protection_enabled(): self.property_rules = property_utils.PropertyRules(self.policy) self._image_base_properties = [ 'checksum', 'created_at', 'container_format', 'disk_format', 'id', 'min_disk', 'min_ram', 'name', 'size', 'virtual_size', 'status', 'tags', 'updated_at', 'visibility', 'protected', 'owner', 'members' ]
def _enforce_read_protected_props(self, image_meta, req): """ Remove entries from metadata properties if they are read protected :param image_meta: Mapping of metadata about image :param req: The WSGI/Webob Request object """ if property_utils.is_property_protection_enabled(): for key in image_meta['properties'].keys(): if (self.prop_enforcer.check_property_rules( key, 'read', req.context) is False): image_meta['properties'].pop(key)
def filter_result(self, result, request_context): if property_utils.is_property_protection_enabled(): hits = result['hits']['hits'] for hit in hits: if hit['_type'] == self.get_document_type(): source = hit['_source'] for key in source.keys(): if key not in self._image_base_properties: if not self.property_rules.check_property_rules( key, 'read', request_context): del hit['_source'][key] return result
def _enforce_create_protected_props(self, create_props, req): """ Check request is permitted to create certain properties :param create_props: List of properties to check :param req: The WSGI/Webob Request object :raises HTTPForbidden if request forbidden to create a property """ if property_utils.is_property_protection_enabled(): for key in create_props: if self.prop_enforcer.check_property_rules(key, "create", req.context) is False: msg = "Property '%s' is protected" % key LOG.debug(msg) raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain")
def _enforce_create_protected_props(self, create_props, req): """ Check request is permitted to create certain properties :param create_props: List of properties to check :param req: The WSGI/Webob Request object :raises HTTPForbidden if request forbidden to create a property """ if property_utils.is_property_protection_enabled(): for key in create_props: if (self.prop_enforcer.check_property_rules( key, 'create', req.context) is False): msg = _("Property '%s' is protected") % key LOG.debug(msg) raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain")
def get_image_factory(self, context, authorization_layer=True): factory = glance.domain.ImageFactory() factory = glance.location.ImageFactoryProxy(factory, context, self.store_api, self.store_utils) factory = glance.quota.ImageFactoryProxy(factory, context, self.db_api, self.store_utils) if authorization_layer: factory = policy.ImageFactoryProxy(factory, context, self.policy) factory = glance.notifier.ImageFactoryProxy(factory, context, self.notifier) if property_utils.is_property_protection_enabled(): property_rules = property_utils.PropertyRules(self.policy) factory = property_protections.ProtectedImageFactoryProxy( factory, context, property_rules) if authorization_layer: factory = authorization.ImageFactoryProxy(factory, context) return factory
def get_image_factory(self, context): image_factory = glance.domain.ImageFactory() store_image_factory = glance.location.ImageFactoryProxy( image_factory, context, self.store_api, self.store_utils) quota_image_factory = glance.quota.ImageFactoryProxy( store_image_factory, context, self.db_api, self.store_utils) policy_image_factory = policy.ImageFactoryProxy( quota_image_factory, context, self.policy) notifier_image_factory = glance.notifier.ImageFactoryProxy( policy_image_factory, context, self.notifier) if property_utils.is_property_protection_enabled(): property_rules = property_utils.PropertyRules(self.policy) pif = property_protections.ProtectedImageFactoryProxy( notifier_image_factory, context, property_rules) authorized_image_factory = authorization.ImageFactoryProxy( pif, context) else: authorized_image_factory = authorization.ImageFactoryProxy( notifier_image_factory, context) return authorized_image_factory
def test_is_property_protections_enabled_false(self): self.config(property_protection_file=None) self.assertFalse(property_utils.is_property_protection_enabled())
def test_is_property_protections_enabled_true(self): self.config(property_protection_file="property-protections.conf") self.assertTrue(property_utils.is_property_protection_enabled())