Esempio n. 1
0
 def _handle_action(request, id, **kwargs):
     arg_list = [request.context, id]
     # Ensure policy engine is initialized
     policy.init()
     # Fetch the resource and verify if the user can access it
     try:
         parent_id = kwargs.get(self._parent_id_name)
         resource = self._item(request,
                               id,
                               do_authz=True,
                               field_list=None,
                               parent_id=parent_id)
     except oslo_policy.PolicyNotAuthorized:
         msg = _('The resource could not be found.')
         raise webob.exc.HTTPNotFound(msg)
     body = copy.deepcopy(kwargs.pop('body', None))
     # Explicit comparison with None to distinguish from {}
     if body is not None:
         arg_list.append(body)
     # It is ok to raise a 403 because accessibility to the
     # object was checked earlier in this method
     policy.enforce(request.context,
                    name,
                    resource,
                    pluralized=self._collection)
     ret_value = getattr(self._plugin, name)(*arg_list, **kwargs)
     # It is simply impossible to predict whether one of this
     # actions alters resource usage. For instance a tenant port
     # is created when a router interface is added. Therefore it is
     # important to mark as dirty resources whose counters have
     # been altered by this operation
     resource_registry.set_resources_dirty(request.context)
     return ret_value
    def index(self, request, **kwargs):
        lbaas_plugin = manager.NeutronManager.get_service_plugins().get(plugin_const.LOADBALANCER)
        if not lbaas_plugin:
            return {"pools": []}

        policy.enforce(request.context, "get_%s" % LOADBALANCER_POOLS, {}, plugin=lbaas_plugin)
        return lbaas_plugin.list_pools_on_lbaas_agent(request.context, kwargs["agent_id"])
    def index(self, request, **kwargs):
        lbaas_plugin = manager.NeutronManager.get_service_plugins().get(plugin_const.LOADBALANCER)
        if not lbaas_plugin:
            return

        policy.enforce(request.context, "get_%s" % LOADBALANCER_AGENT, {}, plugin=lbaas_plugin)
        return lbaas_plugin.get_lbaas_agent_hosting_pool(request.context, kwargs["pool_id"])
Esempio n. 4
0
    def delete(self, request, id, **kwargs):
        """Deletes the specified entity."""
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.delete.start',
                            notifier_api.CONF.default_notification_level,
                            {self._resource + '_id': id})
        action = self._plugin_handlers[self.DELETE]

        # Check authz
        parent_id = kwargs.get(self._parent_id_name)
        obj = self._item(request, id, parent_id=parent_id)
        try:
            policy.enforce(request.context,
                           action,
                           obj)
        except exceptions.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            msg = _('The resource could not be found.')
            raise webob.exc.HTTPNotFound(msg)

        obj_deleter = getattr(self._plugin, action)
        obj_deleter(request.context, id, **kwargs)
        notifier_method = self._resource + '.delete.end'
        notifier_api.notify(request.context,
                            self._publisher_id,
                            notifier_method,
                            notifier_api.CONF.default_notification_level,
                            {self._resource + '_id': id})
        result = {self._resource: self._view(request.context, obj)}
        self._send_dhcp_notification(request.context,
                                     result,
                                     notifier_method)
Esempio n. 5
0
 def before(self, state):
     if state.request.method not in self.ACTION_MAP:
         pecan.abort(405)
     neutron_context = state.request.context.get('neutron_context')
     resource = state.request.context.get('resource')
     is_update = (state.request.method == 'PUT')
     items = state.request.resources
     policy.init()
     action = '%s_%s' % (self.ACTION_MAP[state.request.method], resource)
     for item in items:
         if is_update:
             obj = copy.copy(state.request.original_object)
             obj.update(item)
             obj[const.ATTRIBUTES_TO_UPDATE] = item.keys()
             item = obj
         try:
             policy.enforce(
                 neutron_context, action, item,
                 pluralized=attribute_population._plural(resource))
         except oslo_policy.PolicyNotAuthorized:
             with excutils.save_and_reraise_exception() as ctxt:
                 # If a tenant is modifying it's own object, it's safe to
                 # return a 403. Otherwise, pretend that it doesn't exist
                 # to avoid giving away information.
                 if (is_update and
                         neutron_context.tenant_id != obj['tenant_id']):
                     ctxt.reraise = False
             msg = _('The resource could not be found.')
             raise webob.exc.HTTPNotFound(msg)
Esempio n. 6
0
 def index(self, request, **kwargs):
     plugin = self.get_plugin()
     policy.enforce(request.context,
                    "get_%s" % L3_ROUTERS,
                    {})
     return plugin.list_routers_on_l3_agent(
         request.context, kwargs['agent_id'])
Esempio n. 7
0
 def index(self, request, **kwargs):
     plugin = self.get_plugin()
     policy.enforce(request.context,
                    "get_%s" % L3_AGENTS,
                    {})
     return plugin.list_l3_agents_hosting_router(
         request.context, kwargs['router_id'])
 def index(self, request, **kwargs):
     plugin = directory.get_plugin()
     policy.enforce(request.context,
                    "get_%s" % DHCP_AGENTS,
                    {})
     return plugin.list_dhcp_agents_hosting_network(
         request.context, kwargs['network_id'])
Esempio n. 9
0
    def _delete(self, request, id, **kwargs):
        action = self._plugin_handlers[self.DELETE]

        # Check authz
        policy.init()
        parent_id = kwargs.get(self._parent_id_name)
        obj = self._item(request, id, parent_id=parent_id)
        try:
            policy.enforce(request.context,
                           action,
                           obj,
                           pluralized=self._collection)
        except oslo_policy.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            msg = _('The resource could not be found.')
            raise webob.exc.HTTPNotFound(msg)

        obj_deleter = getattr(self._plugin, action)
        obj_deleter(request.context, id, **kwargs)
        # A delete operation usually alters resource usage, so mark affected
        # usage trackers as dirty
        resource_registry.set_resources_dirty(request.context)
        notifier_method = self._resource + '.delete.end'
        self._notifier.info(request.context,
                            notifier_method,
                            {self._resource + '_id': id})
        result = {self._resource: self._view(request.context, obj)}
        self._send_nova_notification(action, {}, result)
        self._send_dhcp_notification(request.context,
                                     result,
                                     notifier_method)
Esempio n. 10
0
 def index(self, request, **kwargs):
     plugin = directory.get_plugin()
     policy.enforce(request.context,
                    "get_%s" % DHCP_NETS,
                    {})
     return plugin.list_networks_on_dhcp_agent(
         request.context, kwargs['agent_id'])
Esempio n. 11
0
    def update(self, request, id, body=None, **kwargs):
        """Updates the specified entity's attributes."""
        parent_id = kwargs.get(self._parent_id_name)
        try:
            payload = body.copy()
        except AttributeError:
            msg = _("Invalid format: %s") % request.body
            raise exceptions.BadRequest(resource='body', msg=msg)
        payload['id'] = id
        self._notifier.info(request.context,
                            self._resource + '.update.start',
                            payload)
        body = Controller.prepare_request_body(request.context, body, False,
                                               self._resource, self._attr_info,
                                               allow_bulk=self._allow_bulk)
        action = self._plugin_handlers[self.UPDATE]
        # Load object to check authz
        # but pass only attributes in the original body and required
        # by the policy engine to the policy 'brain'
        field_list = [name for (name, value) in self._attr_info.iteritems()
                      if (value.get('required_by_policy') or
                          value.get('primary_key') or
                          'default' not in value)]
        # Ensure policy engine is initialized
        policy.init()
        orig_obj = self._item(request, id, field_list=field_list,
                              parent_id=parent_id)
        orig_object_copy = copy.copy(orig_obj)
        orig_obj.update(body[self._resource])
        # Make a list of attributes to be updated to inform the policy engine
        # which attributes are set explicitly so that it can distinguish them
        # from the ones that are set to their default values.
        orig_obj[const.ATTRIBUTES_TO_UPDATE] = body[self._resource].keys()
        try:
            policy.enforce(request.context,
                           action,
                           orig_obj)
        except common_policy.PolicyNotAuthorized:
            with excutils.save_and_reraise_exception() as ctxt:
                # If a tenant is modifying it's own object, it's safe to return
                # a 403. Otherwise, pretend that it doesn't exist to avoid
                # giving away information.
                if request.context.tenant_id != orig_obj['tenant_id']:
                    ctxt.reraise = False
            msg = _('The resource could not be found.')
            raise webob.exc.HTTPNotFound(msg)

        obj_updater = getattr(self._plugin, action)
        kwargs = {self._resource: body}
        if parent_id:
            kwargs[self._parent_id_name] = parent_id
        obj = obj_updater(request.context, id, **kwargs)
        result = {self._resource: self._view(request.context, obj)}
        notifier_method = self._resource + '.update.end'
        self._notifier.info(request.context, notifier_method, result)
        self._send_dhcp_notification(request.context,
                                     result,
                                     notifier_method)
        self._send_nova_notification(action, orig_object_copy, result)
        return result
Esempio n. 12
0
 def delete(self, request, id, **kwargs):
     plugin = manager.NeutronManager.get_plugin()
     policy.enforce(request.context,
                    "delete_%s" % DHCP_NET,
                    {})
     return plugin.remove_network_from_dhcp_agent(
         request.context, kwargs['agent_id'], id)
Esempio n. 13
0
 def index(self, request, **kwargs):
     plugin = self.get_plugin()
     policy.enforce(request.context,
                    "get_%s" % FIREWALLS,
                    {})
     return plugin.list_firewalls_on_l3_agent(
         request.context, kwargs['agent_id'])
Esempio n. 14
0
 def create(self, request, body, **kwargs):
     plugin = manager.NeutronManager.get_plugin()
     policy.enforce(request.context,
                    "create_%s" % DHCP_NET,
                    {})
     return plugin.add_network_to_dhcp_agent(
         request.context, kwargs['agent_id'], body['network_id'])
Esempio n. 15
0
 def delete(self, request, id, **kwargs):
     plugin = self.get_plugin()
     policy.enforce(request.context,
                    "delete_%s" % FIREWALL,
                    {})
     return plugin.remove_firewall_from_l3_agent(
         request.context, kwargs['agent_id'], id)
Esempio n. 16
0
 def delete(self, request, id, **kwargs):
     plugin = self.get_plugin()
     policy.enforce(request.context,
                    "delete_%s" % L3_ROUTER,
                    {})
     return plugin.remove_router_from_l3_agent(
         request.context, kwargs['agent_id'], id)
Esempio n. 17
0
    def delete(self, request, id, **kwargs):
        """Deletes the specified entity."""
        self._notifier.info(request.context,
                            self._resource + '.delete.start',
                            {self._resource + '_id': id})
        action = self._plugin_handlers[self.DELETE]

        # Check authz
        policy.init()
        parent_id = kwargs.get(self._parent_id_name)
        obj = self._item(request, id, parent_id=parent_id)
        try:
            policy.enforce(request.context,
                           action,
                           obj,
                           pluralized=self._collection)
        except oslo_policy.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            msg = _('The resource could not be found.')
            raise webob.exc.HTTPNotFound(msg)

        obj_deleter = getattr(self._plugin, action)
        obj_deleter(request.context, id, **kwargs)
        notifier_method = self._resource + '.delete.end'
        self._notifier.info(request.context,
                            notifier_method,
                            {self._resource + '_id': id})
        result = {self._resource: self._view(request.context, obj)}
        self._send_nova_notification(action, {}, result)
        self._send_dhcp_notification(request.context,
                                     result,
                                     notifier_method)
Esempio n. 18
0
    def _delete(self, request, id, **kwargs):
        action = self._plugin_handlers[self.DELETE]

        # Check authz
        policy.init()
        parent_id = kwargs.get(self._parent_id_name)
        obj = self._item(request, id, parent_id=parent_id)
        try:
            policy.enforce(request.context, action, obj, pluralized=self._collection)
        except oslo_policy.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            msg = _("The resource could not be found.")
            raise webob.exc.HTTPNotFound(msg)

        obj_deleter = getattr(self._plugin, action)
        obj_deleter(request.context, id, **kwargs)
        # A delete operation usually alters resource usage, so mark affected
        # usage trackers as dirty
        resource_registry.set_resources_dirty(request.context)
        notifier_method = self._resource + ".delete.end"
        result = {self._resource: self._view(request.context, obj)}
        notifier_payload = {self._resource + "_id": id}
        notifier_payload.update(result)
        self._notifier.info(request.context, notifier_method, notifier_payload)
        registry.notify(
            self._resource,
            events.BEFORE_RESPONSE,
            self,
            context=request.context,
            data=result,
            method_name=notifier_method,
            action=action,
            original={},
        )
Esempio n. 19
0
    def _update(self, request, id, body, **kwargs):
        body = Controller.prepare_request_body(
            request.context, copy.deepcopy(body), False, self._resource, self._attr_info, allow_bulk=self._allow_bulk
        )
        action = self._plugin_handlers[self.UPDATE]
        # Load object to check authz
        # but pass only attributes in the original body and required
        # by the policy engine to the policy 'brain'
        field_list = [
            name
            for (name, value) in six.iteritems(self._attr_info)
            if (value.get("required_by_policy") or value.get("primary_key") or "default" not in value)
        ]
        # Ensure policy engine is initialized
        policy.init()
        parent_id = kwargs.get(self._parent_id_name)
        orig_obj = self._item(request, id, field_list=field_list, parent_id=parent_id)
        orig_object_copy = copy.copy(orig_obj)
        orig_obj.update(body[self._resource])
        # Make a list of attributes to be updated to inform the policy engine
        # which attributes are set explicitly so that it can distinguish them
        # from the ones that are set to their default values.
        orig_obj[n_const.ATTRIBUTES_TO_UPDATE] = body[self._resource].keys()
        try:
            policy.enforce(request.context, action, orig_obj, pluralized=self._collection)
        except oslo_policy.PolicyNotAuthorized:
            with excutils.save_and_reraise_exception() as ctxt:
                # If a tenant is modifying it's own object, it's safe to return
                # a 403. Otherwise, pretend that it doesn't exist to avoid
                # giving away information.
                if request.context.tenant_id != orig_obj["tenant_id"]:
                    ctxt.reraise = False
            msg = _("The resource could not be found.")
            raise webob.exc.HTTPNotFound(msg)

        obj_updater = getattr(self._plugin, action)
        kwargs = {self._resource: body}
        if parent_id:
            kwargs[self._parent_id_name] = parent_id
        obj = obj_updater(request.context, id, **kwargs)
        # Usually an update operation does not alter resource usage, but as
        # there might be side effects it might be worth checking for changes
        # in resource usage here as well (e.g: a tenant port is created when a
        # router interface is added)
        resource_registry.set_resources_dirty(request.context)

        result = {self._resource: self._view(request.context, obj)}
        notifier_method = self._resource + ".update.end"
        self._notifier.info(request.context, notifier_method, result)
        registry.notify(
            self._resource,
            events.BEFORE_RESPONSE,
            self,
            context=request.context,
            data=result,
            method_name=notifier_method,
            action=action,
            original=orig_object_copy,
        )
        return result
Esempio n. 20
0
 def delete(self, request, id, **kwargs):
     plugin = self.get_plugin()
     policy.enforce(request.context, "delete_%s" % L3_ROUTER, {})
     agent_id = kwargs["agent_id"]
     result = plugin.remove_router_from_l3_agent(request.context, agent_id, id)
     notify(request.context, "l3_agent.router.remove", id, agent_id)
     return result
    def delete(self, request, id, **kwargs):
        """Deletes the specified entity."""
        self._notifier.info(request.context,
                            self._resource + '.delete.start',
                            {self._resource + '_id': id}) #通知
        action = self._plugin_handlers[self.DELETE]  #获取具体资源操作行为 eg delete_port

        # Check authz
        policy.init()
        parent_id = kwargs.get(self._parent_id_name)
        obj = self._item(request, id, parent_id=parent_id)
        try:
            policy.enforce(request.context,
                           action,
                           obj)                                    #检查操作权限
        except exceptions.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            msg = _('The resource could not be found.')
            raise webob.exc.HTTPNotFound(msg)

        obj_deleter = getattr(self._plugin, action) #获取具体操作方法 eg:M2lplugin类中delete_port
        obj_deleter(request.context, id, **kwargs)  #根据参数,执行具体操作方法
        notifier_method = self._resource + '.delete.end'
        self._notifier.info(request.context,
                            notifier_method,
                            {self._resource + '_id': id}) #消息格式??
        result = {self._resource: self._view(request.context, obj)}
        self._send_nova_notification(action, {}, result)  #通知nova消息,消息内容什么样的?
        self._send_dhcp_notification(request.context,          #通知dhcp消息,消息内容什么样的?
                                     result,
                                     notifier_method)
Esempio n. 22
0
 def test_templatized_enforcement(self):
     target_mine = {'tenant_id': 'fake'}
     target_not_mine = {'tenant_id': 'another'}
     action = "example:my_file"
     policy.enforce(self.context, action, target_mine)
     self.assertRaises(exceptions.PolicyNotAuthorized, policy.enforce,
                       self.context, action, target_not_mine)
Esempio n. 23
0
    def update(self, request, id, body=None, **kwargs):
        """Updates the specified entity's attributes."""
        parent_id = kwargs.get(self._parent_id_name)
        try:
            payload = body.copy()
        except AttributeError:
            msg = _("Invalid format: %s") % request.body
            raise exceptions.BadRequest(resource='body', msg=msg)
        payload['id'] = id
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.update.start',
                            notifier_api.CONF.default_notification_level,
                            payload)
        body = Controller.prepare_request_body(request.context, body, False,
                                               self._resource, self._attr_info,
                                               allow_bulk=self._allow_bulk)
        action = self._plugin_handlers[self.UPDATE]
        # Load object to check authz
        # but pass only attributes in the original body and required
        # by the policy engine to the policy 'brain'
        field_list = [name for (name, value) in self._attr_info.iteritems()
                      if (value.get('required_by_policy') or
                          value.get('primary_key') or
                          'default' not in value)]
        # Ensure policy engine is initialized
        policy.init()
        orig_obj = self._item(request, id, field_list=field_list,
                              parent_id=parent_id)
        orig_object_copy = copy.copy(orig_obj)
        orig_obj.update(body[self._resource])
        try:
            policy.enforce(request.context,
                           action,
                           orig_obj)
        except exceptions.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            msg = _('The resource could not be found.')
            raise webob.exc.HTTPNotFound(msg)

        obj_updater = getattr(self._plugin, action)
        kwargs = {self._resource: body}
        if parent_id:
            kwargs[self._parent_id_name] = parent_id
        obj = obj_updater(request.context, id, **kwargs)
        result = {self._resource: self._view(request.context, obj)}
        notifier_method = self._resource + '.update.end'
        notifier_api.notify(request.context,
                            self._publisher_id,
                            notifier_method,
                            notifier_api.CONF.default_notification_level,
                            result)
        self._send_dhcp_notification(request.context,
                                     result,
                                     notifier_method)
        self._nova_notifier.send_network_change(
            action, orig_object_copy, result)
        return result
Esempio n. 24
0
 def create(self, request, body, **kwargs):
     plugin = self.get_plugin()
     policy.enforce(request.context, "create_%s" % L3_ROUTER, {})
     agent_id = kwargs["agent_id"]
     router_id = body["router_id"]
     result = plugin.add_router_to_l3_agent(request.context, agent_id, router_id)
     notify(request.context, "l3_agent.router.add", router_id, agent_id)
     return result
Esempio n. 25
0
 def index(self, request, **kwargs):
     plugin = manager.NeutronManager.get_service_plugins().get(
         service_constants.L3_ROUTER_NAT)
     policy.enforce(request.context,
                    "get_%s" % L3_AGENTS,
                    {})
     return plugin.list_l3_agents_hosting_router(
         request.context, kwargs['router_id'])
Esempio n. 26
0
 def index(self, request, **kwargs):
     plugin = manager.NeutronManager.get_service_plugins().get(
         service_constants.FIREWALL)
     policy.enforce(request.context,
                    "get_%s" % FIREWALLS,
                    {})
     return plugin.list_l3_agents_hosting_firewall(
         request.context, kwargs['firewall_id'])
Esempio n. 27
0
 def test_ignore_case_role_check(self):
     lowercase_action = "example:lowercase_admin"
     uppercase_action = "example:uppercase_admin"
     # NOTE(dprince) we mix case in the Admin role here to ensure
     # case is ignored
     admin_context = context.Context('admin', 'fake', roles=['AdMiN'])
     policy.enforce(admin_context, lowercase_action, self.target)
     policy.enforce(admin_context, uppercase_action, self.target)
Esempio n. 28
0
 def create(self, request, body, **kwargs):
     plugin = self.get_plugin()
     policy.enforce(request.context,
                    "create_%s" % FIREWALLS,
                    {})
     return plugin.add_firewall_to_l3_agent(
         request.context,
         kwargs['agent_id'],
         body['firewall_id'])
Esempio n. 29
0
 def create(self, request, body, **kwargs):
     plugin = self.get_plugin()
     policy.enforce(request.context,
                    "create_%s" % L3_ROUTER,
                    {})
     return plugin.add_router_to_l3_agent(
         request.context,
         kwargs['agent_id'],
         body['router_id'])
Esempio n. 30
0
 def delete(self, request, id, **kwargs):
     plugin = directory.get_plugin()
     policy.enforce(request.context,
                    "delete_%s" % DHCP_NET,
                    {})
     agent_id = kwargs['agent_id']
     result = plugin.remove_network_from_dhcp_agent(request.context,
                                                    agent_id, id)
     notify(request.context, 'dhcp_agent.network.remove', id, agent_id)
     return result
Esempio n. 31
0
 def test_enforce_regularuser_on_read(self):
     action = "get_network"
     target = {'shared': True, 'tenant_id': 'somebody_else'}
     result = policy.enforce(self.context, action, target)
     self.assertTrue(result)
Esempio n. 32
0
 def test_enforce_tenant_id_check(self):
     # Trigger a policy with rule admin_or_owner
     action = "create_network"
     target = {'tenant_id': 'fake'}
     result = policy.enforce(self.context, action, target)
     self.assertTrue(result)
Esempio n. 33
0
 def test_enforce_firewall_rule_shared(self):
     action = "get_firewall_rule"
     target = {'shared': True, 'tenant_id': 'somebody_else'}
     result = policy.enforce(self.context, action, target)
     self.assertTrue(result)
Esempio n. 34
0
    def _update(self, request, id, body, **kwargs):
        body = Controller.prepare_request_body(request.context,
                                               body,
                                               False,
                                               self._resource,
                                               self._attr_info,
                                               allow_bulk=self._allow_bulk)
        action = self._plugin_handlers[self.UPDATE]
        # Load object to check authz
        # but pass only attributes in the original body and required
        # by the policy engine to the policy 'brain'
        field_list = [
            name for (name, value) in self._attr_info.items()
            if (value.get('required_by_policy') or value.get('primary_key')
                or 'default' not in value)
        ]
        # Ensure policy engine is initialized
        policy.init()
        parent_id = kwargs.get(self._parent_id_name)
        # If the parent_id exist, we should get orig_obj with
        # self._parent_id_name field.
        if parent_id and self._parent_id_name not in field_list:
            field_list.append(self._parent_id_name)
        orig_obj = self._item(request,
                              id,
                              field_list=field_list,
                              parent_id=parent_id)
        orig_object_copy = copy.copy(orig_obj)
        orig_obj.update(body[self._resource])
        # Make a list of attributes to be updated to inform the policy engine
        # which attributes are set explicitly so that it can distinguish them
        # from the ones that are set to their default values.
        orig_obj[constants.ATTRIBUTES_TO_UPDATE] = body[self._resource].keys()
        # Then get the ext_parent_id, format to ext_parent_parent_resource_id
        if self._parent_id_name in orig_obj:
            self._set_parent_id_into_ext_resources_request(
                request, orig_obj, parent_id)
        try:
            policy.enforce(request.context,
                           action,
                           orig_obj,
                           pluralized=self._collection)
        except oslo_policy.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist if policy does not authorize SHOW
            with excutils.save_and_reraise_exception() as ctxt:
                if not policy.check(request.context,
                                    self._plugin_handlers[self.SHOW],
                                    orig_obj,
                                    pluralized=self._collection):
                    ctxt.reraise = False
            msg = _('The resource could not be found.')
            raise webob.exc.HTTPNotFound(msg)

        if self._native_bulk and hasattr(self._plugin, "%s_bulk" % action):
            obj_updater = getattr(self._plugin, "%s_bulk" % action)
        else:
            obj_updater = getattr(self._plugin, action)

        kwargs = {self._resource: body}
        if parent_id:
            kwargs[self._parent_id_name] = parent_id
        obj = obj_updater(request.context, id, **kwargs)
        # Usually an update operation does not alter resource usage, but as
        # there might be side effects it might be worth checking for changes
        # in resource usage here as well (e.g: a tenant port is created when a
        # router interface is added)
        resource_registry.set_resources_dirty(request.context)

        result = {self._resource: self._view(request.context, obj)}
        notifier_method = self._resource + '.update.end'
        self._notifier.info(request.context, notifier_method, result)
        registry.publish(self._resource,
                         events.BEFORE_RESPONSE,
                         self,
                         payload=events.APIEventPayload(
                             request.context,
                             notifier_method,
                             action,
                             request_body=body,
                             states=(
                                 orig_object_copy,
                                 result,
                             ),
                             collection_name=self._collection))
        return result
Esempio n. 35
0
    def before(self, state):
        # This hook should be run only for PUT,POST and DELETE methods and for
        # requests targeting a neutron resource
        resources = state.request.context.get('resources', [])
        if state.request.method not in ('POST', 'PUT', 'DELETE'):
            return
        # As this routine will likely alter the resources, do a shallow copy
        resources_copy = resources[:]
        neutron_context = state.request.context.get('neutron_context')
        resource = state.request.context.get('resource')
        # If there is no resource for this request, don't bother running authZ
        # policies
        if not resource:
            return
        controller = utils.get_controller(state)
        if not controller or utils.is_member_action(controller):
            return
        collection = state.request.context.get('collection')
        needs_prefetch = (state.request.method == 'PUT'
                          or state.request.method == 'DELETE')
        policy.init()

        action = controller.plugin_handlers[pecan_constants.ACTION_MAP[
            state.request.method]]

        # NOTE(salv-orlando): As bulk updates are not supported, in case of PUT
        # requests there will be only a single item to process, and its
        # identifier would have been already retrieved by the lookup process;
        # in the case of DELETE requests there won't be any item to process in
        # the request body
        original_resources = []
        if needs_prefetch:
            try:
                item = resources_copy.pop()
            except IndexError:
                # Ops... this was a delete after all!
                item = {}
            resource_id = state.request.context.get('resource_id')
            parent_id = state.request.context.get('parent_id')
            resource_obj = fetch_resource(neutron_context,
                                          controller,
                                          resource,
                                          resource_id,
                                          parent_id=parent_id)
            if resource_obj:
                original_resources.append(resource_obj)
                obj = copy.copy(resource_obj)
                obj.update(item)
                obj[const.ATTRIBUTES_TO_UPDATE] = item.keys()
                # Put back the item in the list so that policies could be
                # enforced
                resources_copy.append(obj)
        # TODO(salv-orlando): as other hooks might need to prefetch resources,
        # store them in the request context. However, this should be done in a
        # separate hook which is conventietly called before all other hooks
        state.request.context['original_resources'] = original_resources
        for item in resources_copy:
            try:
                policy.enforce(neutron_context,
                               action,
                               item,
                               pluralized=collection)
            except oslo_policy.PolicyNotAuthorized:
                with excutils.save_and_reraise_exception() as ctxt:
                    # If a tenant is modifying it's own object, it's safe to
                    # return a 403. Otherwise, pretend that it doesn't exist
                    # to avoid giving away information.
                    if (needs_prefetch and
                            neutron_context.tenant_id != item['tenant_id']):
                        ctxt.reraise = False
                msg = _('The resource could not be found.')
                raise webob.exc.HTTPNotFound(msg)
Esempio n. 36
0
 def test_early_OR_enforcement(self):
     action = "example:early_or_success"
     policy.enforce(self.context, action, self.target)
Esempio n. 37
0
 def test_enforce_http_true(self):
     self.useFixture(op_fixture.HttpCheckFixture())
     action = "example:get_http"
     target = {}
     result = policy.enforce(self.context, action, target)
     self.assertTrue(result)
Esempio n. 38
0
 def test_delete_segment(self):
     self.assertTrue(
         policy.enforce(self.context, 'delete_segment', self.target))
Esempio n. 39
0
 def test_get_service_provider(self):
     self.assertTrue(
         policy.enforce(self.context, 'get_service_provider', self.target))
Esempio n. 40
0
    def create(self, request, body=None, **kwargs):
        """Creates a new instance of the requested entity."""
        parent_id = kwargs.get(self._parent_id_name)
        notifier_api.notify(request.context, self._publisher_id,
                            self._resource + '.create.start',
                            notifier_api.CONF.default_notification_level, body)
        body = Controller.prepare_request_body(request.context,
                                               body,
                                               True,
                                               self._resource,
                                               self._attr_info,
                                               allow_bulk=self._allow_bulk)
        action = self._plugin_handlers[self.CREATE]
        # Check authz
        if self._collection in body:
            # Have to account for bulk create
            items = body[self._collection]
            deltas = {}
            bulk = True
        else:
            items = [body]
            bulk = False
        for item in items:
            self._validate_network_tenant_ownership(request,
                                                    item[self._resource])
            policy.enforce(request.context, action, item[self._resource])
            try:
                tenant_id = item[self._resource]['tenant_id']
                count = quota.QUOTAS.count(request.context, self._resource,
                                           self._plugin, self._collection,
                                           tenant_id)
                if bulk:
                    delta = deltas.get(tenant_id, 0) + 1
                    deltas[tenant_id] = delta
                else:
                    delta = 1
                kwargs = {self._resource: count + delta}
            except exceptions.QuotaResourceUnknown as e:
                # We don't want to quota this resource
                LOG.debug(e)
            else:
                quota.QUOTAS.limit_check(request.context,
                                         item[self._resource]['tenant_id'],
                                         **kwargs)

        def notify(create_result):
            notifier_method = self._resource + '.create.end'
            notifier_api.notify(request.context, self._publisher_id,
                                notifier_method,
                                notifier_api.CONF.default_notification_level,
                                create_result)
            self._send_dhcp_notification(request.context, create_result,
                                         notifier_method)
            return create_result

        kwargs = {self._parent_id_name: parent_id} if parent_id else {}
        if self._collection in body and self._native_bulk:
            # plugin does atomic bulk create operations
            obj_creator = getattr(self._plugin, "%s_bulk" % action)
            objs = obj_creator(request.context, body, **kwargs)
            return notify({
                self._collection:
                [self._view(request.context, obj) for obj in objs]
            })
        else:
            obj_creator = getattr(self._plugin, action)
            if self._collection in body:
                # Emulate atomic bulk behavior
                objs = self._emulate_bulk_create(obj_creator, request, body,
                                                 parent_id)
                return notify({self._collection: objs})
            else:
                kwargs.update({self._resource: body})
                obj = obj_creator(request.context, **kwargs)
                return notify(
                    {self._resource: self._view(request.context, obj)})
Esempio n. 41
0
def validate_policy(context, policy_name):
    policy.init()
    policy.enforce(context,
                   policy_name,
                   target={'project_id': context.project_id},
                   plugin=None)
Esempio n. 42
0
 def test_create_floatingip_with_ip_address(self):
     self.assertTrue(
         policy.enforce(self.context,
                        "create_floatingip:floating_ip_address",
                        self.target))
Esempio n. 43
0
 def test_get_floatingip(self):
     self.assertTrue(
         policy.enforce(self.context, "get_floatingip", self.target))
Esempio n. 44
0
    def _create(self, request, body, **kwargs):
        """Creates a new instance of the requested entity."""
        parent_id = kwargs.get(self._parent_id_name)
        body = Controller.prepare_request_body(request.context,
                                               body, True,
                                               self._resource, self._attr_info,
                                               allow_bulk=self._allow_bulk)
        action = self._plugin_handlers[self.CREATE]
        # Check authz
        if self._collection in body:
            # Have to account for bulk create
            items = body[self._collection]
        else:
            items = [body]
        # Ensure policy engine is initialized
        policy.init()
        # Store requested resource amounts grouping them by tenant
        # This won't work with multiple resources. However because of the
        # current structure of this controller there will hardly be more than
        # one resource for which reservations are being made
        request_deltas = collections.defaultdict(int)
        for item in items:
            self._validate_network_tenant_ownership(request,
                                                    item[self._resource])
            policy.enforce(request.context,
                           action,
                           item[self._resource],
                           pluralized=self._collection)
            if 'tenant_id' not in item[self._resource]:
                # no tenant_id - no quota check
                continue
            tenant_id = item[self._resource]['tenant_id']
            request_deltas[tenant_id] += 1
        # Quota enforcement
        reservations = []
        try:
            for (tenant, delta) in request_deltas.items():
                reservation = quota.QUOTAS.make_reservation(
                    request.context,
                    tenant,
                    {self._resource: delta},
                    self._plugin)
                reservations.append(reservation)
        except n_exc.QuotaResourceUnknown as e:
            # We don't want to quota this resource
            LOG.debug(e)

        def notify(create_result):
            # Ensure usage trackers for all resources affected by this API
            # operation are marked as dirty
            with db_api.context_manager.writer.using(request.context):
                # Commit the reservation(s)
                for reservation in reservations:
                    quota.QUOTAS.commit_reservation(
                        request.context, reservation.reservation_id)
                resource_registry.set_resources_dirty(request.context)

            notifier_method = self._resource + '.create.end'
            self._notifier.info(request.context,
                                notifier_method,
                                create_result)
            registry.notify(self._resource, events.BEFORE_RESPONSE, self,
                            context=request.context, data=create_result,
                            method_name=notifier_method,
                            collection=self._collection,
                            action=action, original={})
            return create_result

        def do_create(body, bulk=False, emulated=False):
            kwargs = {self._parent_id_name: parent_id} if parent_id else {}
            if bulk and not emulated:
                obj_creator = getattr(self._plugin, "%s_bulk" % action)
            else:
                obj_creator = getattr(self._plugin, action)
            try:
                if emulated:
                    return self._emulate_bulk_create(obj_creator, request,
                                                     body, parent_id)
                else:
                    if self._collection in body:
                        # This is weird but fixing it requires changes to the
                        # plugin interface
                        kwargs.update({self._collection: body})
                    else:
                        kwargs.update({self._resource: body})
                    return obj_creator(request.context, **kwargs)
            except Exception:
                # In case of failure the plugin will always raise an
                # exception. Cancel the reservation
                with excutils.save_and_reraise_exception():
                    for reservation in reservations:
                        quota.QUOTAS.cancel_reservation(
                            request.context, reservation.reservation_id)

        if self._collection in body and self._native_bulk:
            # plugin does atomic bulk create operations
            objs = do_create(body, bulk=True)
            # Use first element of list to discriminate attributes which
            # should be removed because of authZ policies
            fields_to_strip = self._exclude_attributes_by_policy(
                request.context, objs[0])
            return notify({self._collection: [self._filter_attributes(
                obj, fields_to_strip=fields_to_strip)
                for obj in objs]})
        else:
            if self._collection in body:
                # Emulate atomic bulk behavior
                objs = do_create(body, bulk=True, emulated=True)
                return notify({self._collection: objs})
            else:
                obj = do_create(body)
                return notify({self._resource: self._view(request.context,
                                                          obj)})
Esempio n. 45
0
 def test_enforce_subattribute(self):
     action = "create_" + FAKE_RESOURCE_NAME
     target = {'tenant_id': 'fake', 'attr': {'sub_attr_1': 'x'}}
     result = policy.enforce(self.context, action, target, None)
     self.assertTrue(result)
Esempio n. 46
0
    def update(self, request, id, body=None, **kwargs):
        """Updates the specified entity's attributes."""
        parent_id = kwargs.get(self._parent_id_name)
        try:
            payload = body.copy()
        except AttributeError:
            msg = _("Invalid format: %s") % request.body
            raise exceptions.BadRequest(resource='body', msg=msg)
        payload['id'] = id
        self._notifier.info(request.context, self._resource + '.update.start',
                            payload)
        body = Controller.prepare_request_body(request.context,
                                               body,
                                               False,
                                               self._resource,
                                               self._attr_info,
                                               allow_bulk=self._allow_bulk)
        action = self._plugin_handlers[self.UPDATE]
        # Load object to check authz
        # but pass only attributes in the original body and required
        # by the policy engine to the policy 'brain'
        field_list = [
            name for (name, value) in six.iteritems(self._attr_info)
            if (value.get('required_by_policy') or value.get('primary_key')
                or 'default' not in value)
        ]
        # Ensure policy engine is initialized
        policy.init()
        orig_obj = self._item(request,
                              id,
                              field_list=field_list,
                              parent_id=parent_id)
        orig_object_copy = copy.copy(orig_obj)
        orig_obj.update(body[self._resource])
        # Make a list of attributes to be updated to inform the policy engine
        # which attributes are set explicitly so that it can distinguish them
        # from the ones that are set to their default values.
        orig_obj[const.ATTRIBUTES_TO_UPDATE] = body[self._resource].keys()
        try:
            policy.enforce(request.context,
                           action,
                           orig_obj,
                           pluralized=self._collection)
        except oslo_policy.PolicyNotAuthorized:
            with excutils.save_and_reraise_exception() as ctxt:
                # If a tenant is modifying it's own object, it's safe to return
                # a 403. Otherwise, pretend that it doesn't exist to avoid
                # giving away information.
                if request.context.tenant_id != orig_obj['tenant_id']:
                    ctxt.reraise = False
            msg = _('The resource could not be found.')
            raise webob.exc.HTTPNotFound(msg)

        obj_updater = getattr(self._plugin, action)
        kwargs = {self._resource: body}
        if parent_id:
            kwargs[self._parent_id_name] = parent_id
        obj = obj_updater(request.context, id, **kwargs)
        result = {self._resource: self._view(request.context, obj)}
        notifier_method = self._resource + '.update.end'
        self._notifier.info(request.context, notifier_method, result)
        self._send_dhcp_notification(request.context, result, notifier_method)
        self._send_nova_notification(action, orig_object_copy, result)
        return result
Esempio n. 47
0
 def test_not_found_policy_calls_default(self):
     policy.enforce(self.context, "example:noexist", {})
Esempio n. 48
0
    def create(self, request, body=None, **kwargs):
        """Creates a new instance of the requested entity."""
        parent_id = kwargs.get(self._parent_id_name)
        self._notifier.info(request.context, self._resource + '.create.start',
                            body)
        body = Controller.prepare_request_body(request.context,
                                               copy.deepcopy(body),
                                               True,
                                               self._resource,
                                               self._attr_info,
                                               allow_bulk=self._allow_bulk)
        action = self._plugin_handlers[self.CREATE]
        # Check authz
        if self._collection in body:
            # Have to account for bulk create
            items = body[self._collection]
            deltas = {}
            bulk = True
        else:
            items = [body]
            bulk = False
        # Ensure policy engine is initialized
        policy.init()
        for item in items:
            self._validate_network_tenant_ownership(request,
                                                    item[self._resource])
            policy.enforce(request.context,
                           action,
                           item[self._resource],
                           pluralized=self._collection)
            if 'tenant_id' not in item[self._resource]:
                # no tenant_id - no quota check
                continue
            try:
                tenant_id = item[self._resource]['tenant_id']
                count = quota.QUOTAS.count(request.context, self._resource,
                                           self._plugin, self._collection,
                                           tenant_id)
                if bulk:
                    delta = deltas.get(tenant_id, 0) + 1
                    deltas[tenant_id] = delta
                else:
                    delta = 1
                kwargs = {self._resource: count + delta}
            except exceptions.QuotaResourceUnknown as e:
                # We don't want to quota this resource
                LOG.debug(e)
            else:
                quota.QUOTAS.limit_check(request.context,
                                         item[self._resource]['tenant_id'],
                                         **kwargs)

        def notify(create_result):
            notifier_method = self._resource + '.create.end'
            self._notifier.info(request.context, notifier_method,
                                create_result)
            self._send_dhcp_notification(request.context, create_result,
                                         notifier_method)
            return create_result

        kwargs = {self._parent_id_name: parent_id} if parent_id else {}
        if self._collection in body and self._native_bulk:
            # plugin does atomic bulk create operations
            obj_creator = getattr(self._plugin, "%s_bulk" % action)
            objs = obj_creator(request.context, body, **kwargs)
            # Use first element of list to discriminate attributes which
            # should be removed because of authZ policies
            fields_to_strip = self._exclude_attributes_by_policy(
                request.context, objs[0])
            return notify({
                self._collection: [
                    self._filter_attributes(request.context,
                                            obj,
                                            fields_to_strip=fields_to_strip)
                    for obj in objs
                ]
            })
        else:
            obj_creator = getattr(self._plugin, action)
            if self._collection in body:
                # Emulate atomic bulk behavior
                objs = self._emulate_bulk_create(obj_creator, request, body,
                                                 parent_id)
                return notify({self._collection: objs})
            else:
                kwargs.update({self._resource: body})
                obj = obj_creator(request.context, **kwargs)
                self._send_nova_notification(action, {}, {self._resource: obj})
                return notify(
                    {self._resource: self._view(request.context, obj)})
Esempio n. 49
0
 def index(self, request, **kwargs):
     plugin = directory.get_plugin()
     policy.enforce(request.context, "get_%s" % DHCP_AGENTS, {})
     return plugin.list_dhcp_agents_hosting_network(request.context,
                                                    kwargs['network_id'])
 def index(self, request, **kwargs):
     plugin = self.get_plugin()
     policy.enforce(request.context, "get_%s" % HOSTING_DEVICE_CFG_AGENTS,
                    {})
     return plugin.list_cfg_agents_handling_hosting_device(
         request.context, kwargs['hosting_device_id'])
Esempio n. 51
0
 def test_get_log(self):
     self.assertTrue(
         policy.enforce(self.context, 'get_log', self.target))
Esempio n. 52
0
 def test_enforce_good_action(self):
     action = "example:allowed"
     result = policy.enforce(self.context, action, self.target)
     self.assertTrue(result)
Esempio n. 53
0
 def test_enforce_subattribute(self):
     action = "create_something"
     target = {'tenant_id': 'fake', 'attr': {'sub_attr_1': 'x'}}
     result = policy.enforce(self.context, action, target, None)
     self.assertEqual(result, True)
Esempio n. 54
0
 def index(self, request, **kwargs):
     plugin = directory.get_plugin()
     policy.enforce(request.context, "get_%s" % DHCP_NETS, {})
     return plugin.list_networks_on_dhcp_agent(request.context,
                                               kwargs['agent_id'])
Esempio n. 55
0
 def test_enforce_http_true(self, mock_urlrequest):
     action = "example:get_http"
     target = {}
     result = policy.enforce(self.context, action, target)
     self.assertEqual(result, True)
Esempio n. 56
0
 def test_get_loggable_resource(self):
     self.assertTrue(
         policy.enforce(self.context, 'get_loggable_resource', self.target))
Esempio n. 57
0
 def test_create_network(self):
     self.assertTrue(
         policy.enforce(self.context, 'create_network', self.target))
     self.assertRaises(base_policy.PolicyNotAuthorized, policy.enforce,
                       self.context, 'create_network', self.alt_target)
Esempio n. 58
0
 def _test_enforce_adminonly_attribute(self, action):
     admin_context = context.get_admin_context()
     target = {'shared': True}
     result = policy.enforce(admin_context, action, target)
     self.assertEqual(result, True)
 def index(self, request, **kwargs):
     plugin = self.get_plugin()
     policy.enforce(request.context, "get_%s" % CFG_AGENT_HOSTING_DEVICES,
                    {})
     return plugin.list_hosting_devices_handled_by_cfg_agent(
         request.context, kwargs['agent_id'])
Esempio n. 60
0
 def test_enforce_subattribute_as_list(self):
     action = "create_" + FAKE_RESOURCE_NAME
     target = {'tenant_id': 'fake', 'list_attr': [{'user_element': 'x'}]}
     result = policy.enforce(self.context, action, target, None)
     self.assertTrue(result)