Example #1
0
class GuestAuthorizationPolicyTest(unittest.TestCase):
    def setUp(self):
        self.authz = AuthorizationPolicy()
        self.authz.get_bound_permissions = lambda o, p: []
        self.request = DummyRequest(method='GET')
        self.context = RouteFactory(self.request)
        self.context.on_collection = True
        self.context.check_permission = mock.Mock(return_value=False)

    def test_permits_returns_true_if_collection_and_shared_records(self):
        self.context.fetch_shared_records = mock.MagicMock(
            return_value=['record1', 'record2'])
        allowed = self.authz.permits(self.context, ['userid'], 'dynamic')
        # Note: we use the list of principals from request.prefixed_principals
        self.context.fetch_shared_records.assert_called_with(
            'read',
            ['system.Everyone', 'system.Authenticated', 'basicauth:bob'],
            self.authz.get_bound_permissions)
        self.assertTrue(allowed)

    def test_permits_does_not_return_true_if_not_collection(self):
        self.context.on_collection = False
        allowed = self.authz.permits(self.context, ['userid'], 'dynamic')
        self.assertFalse(allowed)

    def test_permits_does_not_return_true_if_not_list_operation(self):
        self.context.required_permission = 'create'
        allowed = self.authz.permits(self.context, ['userid'], 'dynamic')
        self.assertFalse(allowed)
        allowed = self.authz.permits(self.context, ['userid'], 'create')
        self.assertFalse(allowed)

    def test_permits_returns_false_if_collection_is_unknown(self):
        self.context.fetch_shared_records = mock.MagicMock(return_value=None)
        allowed = self.authz.permits(self.context, ['userid'], 'dynamic')
        # Note: we use the list of principals from request.prefixed_principals
        self.context.fetch_shared_records.assert_called_with(
            'read',
            ['system.Everyone', 'system.Authenticated', 'basicauth:bob'],
            self.authz.get_bound_permissions)
        self.assertFalse(allowed)

    def test_perm_object_id_is_naive_if_no_record_path_exists(self):
        def route_path(service_name, **kwargs):
            # Simulate a resource that has no record_path (only list).
            if service_name == 'article-record':
                raise KeyError
            return '/comments/sub/{id}'.format(**kwargs)

        self.request.route_path.side_effect = route_path

        self.request.path = '/comments'
        self.context.resource_name = 'comment'
        obj_id = self.context.get_permission_object_id(self.request, '*')
        self.assertEquals(obj_id, '/comments/sub/*')

        self.request.path = '/articles'
        self.context.resource_name = 'article'
        obj_id = self.context.get_permission_object_id(self.request, '*')
        self.assertEquals(obj_id, '/articles/*')
 def setUp(self):
     self.authz = AuthorizationPolicy()
     self.authz.get_bound_permissions = lambda o, p: []
     self.request = DummyRequest(method="GET")
     self.context = RouteFactory(self.request)
     self.context.on_plural_endpoint = True
     self.context.check_permission = mock.Mock(return_value=False)
Example #3
0
class GuestAuthorizationPolicyTest(unittest.TestCase):
    def setUp(self):
        self.authz = AuthorizationPolicy()
        self.authz.get_bound_permissions = lambda o, p: []
        self.request = DummyRequest(method='GET')
        self.context = RouteFactory(self.request)
        self.context.on_collection = True
        self.context.check_permission = mock.Mock(return_value=False)

    def test_permits_returns_true_if_collection_and_shared_records(self):
        self.context.fetch_shared_records = mock.MagicMock(return_value=[
            'record1', 'record2'])
        allowed = self.authz.permits(self.context, ['userid'], 'dynamic')
        # Note: we use the list of principals from request.prefixed_principals
        self.context.fetch_shared_records.assert_called_with(
            'read',
            ['basicauth:bob', 'system.Everyone', 'system.Authenticated'],
            self.authz.get_bound_permissions)
        self.assertTrue(allowed)

    def test_permits_does_not_return_true_if_not_collection(self):
        self.context.on_collection = False
        allowed = self.authz.permits(self.context, ['userid'], 'dynamic')
        self.assertFalse(allowed)

    def test_permits_does_not_return_true_if_not_list_operation(self):
        self.context.required_permission = 'create'
        allowed = self.authz.permits(self.context, ['userid'], 'dynamic')
        self.assertFalse(allowed)
        allowed = self.authz.permits(self.context, ['userid'], 'create')
        self.assertFalse(allowed)

    def test_permits_returns_false_if_collection_is_unknown(self):
        self.context.fetch_shared_records = mock.MagicMock(return_value=None)
        allowed = self.authz.permits(self.context, ['userid'], 'dynamic')
        # Note: we use the list of principals from request.prefixed_principals
        self.context.fetch_shared_records.assert_called_with(
            'read',
            ['basicauth:bob', 'system.Everyone', 'system.Authenticated'],
            self.authz.get_bound_permissions)
        self.assertFalse(allowed)

    def test_perm_object_id_is_naive_if_no_record_path_exists(self):
        def route_path(service_name, **kwargs):
            # Simulate a resource that has no record_path (only list).
            if service_name == 'article-record':
                raise KeyError
            return '/comments/sub/{id}'.format_map(kwargs)

        self.request.route_path.side_effect = route_path

        self.request.path = '/comments'
        self.context.resource_name = 'comment'
        obj_id = self.context.get_permission_object_id(self.request, '*')
        self.assertEquals(obj_id, '/comments/sub/*')

        self.request.path = '/articles'
        self.context.resource_name = 'article'
        obj_id = self.context.get_permission_object_id(self.request, '*')
        self.assertEquals(obj_id, '/articles/*')
Example #4
0
 def test_permits_takes_route_factory_allowed_principals_into_account_for_object_creation(self):
     request = DummyRequest()
     context = RouteFactory(request)
     context._check_permission.return_value = False
     context.resource_name = "book"
     context.required_permission = "book:create"
     context._settings = {"book_create_principals": "fxa:user"}
     self.assertTrue(context.check_permission(["fxa:user"], None))
    def test_fetch_shared_records_sets_shared_ids_to_none_if_empty(self):
        request = DummyRequest()
        context = RouteFactory(request)
        request.registry.permission.get_accessible_objects.return_value = {}

        context.fetch_shared_records('read', ['userid'], None)

        self.assertIsNone(context.shared_ids)
    def test_fetch_shared_objects_sets_shared_ids_if_empty(self):
        request = DummyRequest()
        context = RouteFactory(request)
        request.registry.permission.get_accessible_objects.return_value = {}

        context.fetch_shared_objects("read", ["userid"], None)

        self.assertEqual(context.shared_ids, [])
Example #7
0
    def test_fetch_shared_records_sets_shared_ids_to_none_if_empty(self):
        request = DummyRequest()
        context = RouteFactory(request)
        request.registry.permission.get_accessible_objects.return_value = {}

        context.fetch_shared_records('read', ['userid'], None)

        self.assertIsNone(context.shared_ids)
Example #8
0
    def test_fetch_shared_records_sets_shared_ids_if_empty(self):
        request = DummyRequest()
        context = RouteFactory(request)
        request.registry.permission.get_accessible_objects.return_value = {}

        context.fetch_shared_records("read", ["userid"], None)

        self.assertEqual(context.shared_ids, [])
 def test_fetch_shared_records_sets_shared_ids_from_results(self):
     request = DummyRequest()
     context = RouteFactory(request)
     request.registry.permission.get_accessible_objects.return_value = {
         '/obj/1': ['read', 'write'],
         '/obj/3': ['obj:create']
     }
     context.fetch_shared_records('read', ['userid'], None)
     self.assertEquals(sorted(context.shared_ids), ['1', '3'])
Example #10
0
 def test_fetch_shared_records_sets_shared_ids_from_results(self):
     request = DummyRequest()
     context = RouteFactory(request)
     request.registry.permission.get_accessible_objects.return_value = {
         '/obj/1': ['read', 'write'],
         '/obj/3': ['obj:create']
     }
     context.fetch_shared_records('read', ['userid'], None)
     self.assertEquals(sorted(context.shared_ids), ['1', '3'])
 def test_fetch_shared_objects_sets_shared_ids_from_results(self):
     request = DummyRequest()
     context = RouteFactory(request)
     request.registry.permission.get_accessible_objects.return_value = {
         "/obj/1": ["read", "write"],
         "/obj/3": ["obj:create"],
     }
     context.fetch_shared_objects("read", ["userid"], None)
     self.assertEqual(sorted(context.shared_ids), ["1", "3"])
Example #12
0
 def test_fetch_shared_records_sets_shared_ids_from_results(self):
     request = DummyRequest()
     context = RouteFactory(request)
     request.registry.permission.get_accessible_objects.return_value = {
         "/obj/1": ["read", "write"],
         "/obj/3": ["obj:create"],
     }
     context.fetch_shared_records("read", ["userid"], None)
     self.assertEqual(sorted(context.shared_ids), ["1", "3"])
Example #13
0
    def test_fetch_shared_records_uses_pattern_if_on_collection(self):
        request = DummyRequest()
        request.route_path.return_value = '/v1/buckets/%2A'
        service = mock.MagicMock()
        service.type = 'collection'
        with mock.patch('kinto.core.authorization.utils.current_service') as m:
            m.return_value = service
            context = RouteFactory(request)
        self.assertTrue(context.on_collection)

        context.fetch_shared_records('read', ['userid'], None)

        request.registry.permission.get_accessible_objects.assert_called_with(
            ['userid'], [('/buckets/*', 'read')], with_children=False)
    def test_fetch_shared_objects_uses_pattern_if_on_plural_endpoint(self):
        request = DummyRequest()
        request.route_path.return_value = "/v1/buckets/%2A"
        service = mock.MagicMock()
        service.type = "plural"
        with mock.patch("kinto.core.authorization.utils.current_service") as m:
            m.return_value = service
            context = RouteFactory(request)
        self.assertTrue(context.on_plural_endpoint)

        context.fetch_shared_objects("read", ["userid"], None)

        request.registry.permission.get_accessible_objects.assert_called_with(
            ["userid"], [("/buckets/*", "read")], with_children=False)
    def test_fetch_shared_records_uses_pattern_if_on_collection(self):
        request = DummyRequest()
        request.route_path.return_value = '/v1/buckets/%2A'
        service = mock.MagicMock()
        service.type = 'collection'
        with mock.patch('kinto.core.authorization.utils.current_service') as m:
            m.return_value = service
            context = RouteFactory(request)
        self.assertTrue(context.on_collection)

        context.fetch_shared_records('read', ['userid'], None)

        request.registry.permission.get_accessible_objects.assert_called_with(
            ['userid'],
            [('/buckets/*', 'read')])
Example #16
0
    def test_fetch_shared_records_uses_pattern_if_on_collection(self):
        request = DummyRequest()
        request.route_path.return_value = "/v1/buckets/%2A"
        service = mock.MagicMock()
        service.type = "collection"
        with mock.patch("kinto.core.authorization.utils.current_service") as m:
            m.return_value = service
            context = RouteFactory(request)
        self.assertTrue(context.on_collection)

        context.fetch_shared_records("read", ["userid"], None)

        request.registry.permission.get_accessible_objects.assert_called_with(
            ["userid"], [("/buckets/*", "read")], with_children=False
        )
Example #17
0
    def assert_request_resolves_to(self,
                                   method,
                                   permission,
                                   uri=None,
                                   record_not_found=False):
        if uri is None:
            uri = self.record_uri

        with mock.patch('kinto.core.utils.current_service') as current_service:
            # Patch current service.
            resource = mock.MagicMock()
            resource.record_id = 1
            if record_not_found:
                resource.model.get_record.side_effect = \
                    storage_exceptions.RecordNotFoundError
            else:
                resource.model.get_record.return_value = 1
            current_service().resource.return_value = resource

            # Do the actual call.
            request = DummyRequest(method=method)
            request.upath_info = uri
            context = RouteFactory(request)

            self.assertEquals(context.required_permission, permission)
Example #18
0
 def setUp(self):
     self.authz = AuthorizationPolicy()
     self.authz.get_bound_permissions = mock.sentinel.get_bound_perms
     self.request = DummyRequest(method='GET')
     self.context = RouteFactory(self.request)
     self.context.on_collection = True
     self.context.check_permission = mock.Mock(return_value=False)
Example #19
0
 def setUp(self):
     self.authz = AuthorizationPolicy()
     self.authz.get_bound_permissions = lambda o, p: []
     self.request = DummyRequest(method="GET")
     self.context = RouteFactory(self.request)
     self.context.on_collection = True
     self.context.check_permission = mock.Mock(return_value=False)
Example #20
0
    def test_fetch_shared_records_uses_get_bound_permission_callback(self):
        request = DummyRequest()
        service = mock.MagicMock()
        request.route_path.return_value = '/v1/buckets/%2A'
        service.type = 'collection'
        with mock.patch('kinto.core.authorization.utils.current_service') as m:
            m.return_value = service
            context = RouteFactory(request)
        self.assertTrue(context.on_collection)

        # Define a callback where write means read:
        def get_bound_perms(obj_id, perm):
            return [(obj_id, 'write'), (obj_id, 'read')]

        context.fetch_shared_records('read', ['userid'], get_bound_perms)

        request.registry.permission.get_accessible_objects.assert_called_with(
            ['userid'], [('/buckets/*', 'write'), ('/buckets/*', 'read')])
 def test_attributes_are_none_with_blank_requests(self):
     request = Request.blank(path="/")
     request.registry = mock.Mock(settings={})
     request.authn_type = "fxa"
     request.prefixed_userid = property(utils.prefixed_userid)
     context = RouteFactory(request)
     self.assertIsNone(context.required_permission)
     self.assertIsNone(context.current_object)
     self.assertIsNone(context.resource_name)
Example #22
0
 def test_attributes_are_none_with_blank_requests(self):
     request = Request.blank(path='/')
     request.registry = mock.Mock(settings={})
     request.authn_type = 'fxa'
     request.prefixed_userid = property(authentication.prefixed_userid)
     context = RouteFactory(request)
     self.assertIsNone(context.required_permission)
     self.assertIsNone(context.current_record)
     self.assertIsNone(context.resource_name)
Example #23
0
    def test_fetch_shared_records_uses_get_bound_permission_callback(self):
        request = DummyRequest()
        service = mock.MagicMock()
        request.route_path.return_value = "/v1/buckets/%2A"
        service.type = "collection"
        with mock.patch("kinto.core.authorization.utils.current_service") as m:
            m.return_value = service
            context = RouteFactory(request)
        self.assertTrue(context.on_collection)

        # Define a callback where write means read:
        def get_bound_perms(obj_id, perm):
            return [(obj_id, "write"), (obj_id, "read")]

        context.fetch_shared_records("read", ["userid"], get_bound_perms)

        request.registry.permission.get_accessible_objects.assert_called_with(
            ["userid"], [("/buckets/*", "write"), ("/buckets/*", "read")], with_children=False
        )
    def test_fetch_shared_records_uses_get_bound_permission_callback(self):
        request = DummyRequest()
        service = mock.MagicMock()
        request.route_path.return_value = '/v1/buckets/%2A'
        service.type = 'collection'
        with mock.patch('kinto.core.authorization.utils.current_service') as m:
            m.return_value = service
            context = RouteFactory(request)
        self.assertTrue(context.on_collection)

        # Define a callback where write means read:
        def get_bound_perms(obj_id, perm):
            return [(obj_id, 'write'), (obj_id, 'read')]

        context.fetch_shared_records('read', ['userid'], get_bound_perms)

        request.registry.permission.get_accessible_objects.assert_called_with(
            ['userid'],
            [('/buckets/*', 'write'), ('/buckets/*', 'read')])
    def test_fetch_shared_objects_uses_get_bound_permission_callback(self):
        request = DummyRequest()
        service = mock.MagicMock()
        request.route_path.return_value = "/v1/buckets/%2A"
        service.type = "plural"
        with mock.patch("kinto.core.authorization.utils.current_service") as m:
            m.return_value = service
            context = RouteFactory(request)
        self.assertTrue(context.on_plural_endpoint)

        # Define a callback where write means read:
        def get_bound_perms(obj_id, perm):
            return [(obj_id, "write"), (obj_id, "read")]

        context.fetch_shared_objects("read", ["userid"], get_bound_perms)

        request.registry.permission.get_accessible_objects.assert_called_with(
            ["userid"], [("/buckets/*", "write"), ("/buckets/*", "read")],
            with_children=False)
Example #26
0
 def test_http_put_sets_current_record_attribute(self):
     with mock.patch('kinto.core.utils.current_service') as current_service:
         # Patch current service.
         resource = mock.MagicMock()
         resource.record_id = 1
         resource.model.get_record.return_value = mock.sentinel.record
         current_service().resource.return_value = resource
         # Do the actual call.
         request = DummyRequest(method='put')
         context = RouteFactory(request)
         self.assertEquals(context.current_record, mock.sentinel.record)
 def test_http_put_sets_current_object_attribute(self):
     with mock.patch("kinto.core.utils.current_service") as current_service:
         # Patch current service.
         resource = mock.MagicMock()
         resource.object_id = 1
         resource.model.get_object.return_value = mock.sentinel.object
         current_service().resource.return_value = resource
         # Do the actual call.
         request = DummyRequest(method="put")
         context = RouteFactory(request)
         self.assertEqual(context.current_object, mock.sentinel.object)
    def test_attributes_are_none_with_non_resource_requests(self):
        basic_service = object()
        request = Request.blank(path="/")
        request.prefixed_userid = property(utils.prefixed_userid)
        request.matched_route = mock.Mock(pattern="foo")
        request.registry = mock.Mock(cornice_services={"foo": basic_service})
        request.registry.settings = {}

        context = RouteFactory(request)
        self.assertIsNone(context.current_object)
        self.assertIsNone(context.required_permission)
        self.assertIsNone(context.resource_name)
Example #29
0
    def test_attributes_are_none_with_non_resource_requests(self):
        basic_service = object()
        request = Request.blank(path='/')
        request.prefixed_userid = property(authentication.prefixed_userid)
        request.matched_route = mock.Mock(pattern='foo')
        request.registry = mock.Mock(cornice_services={'foo': basic_service})
        request.registry.settings = {}

        context = RouteFactory(request)
        self.assertIsNone(context.current_record)
        self.assertIsNone(context.required_permission)
        self.assertIsNone(context.resource_name)
        self.assertIsNone(context.get_shared_ids)
Example #30
0
 def test_permits_takes_route_factory_allowed_principals_into_account_for_object_creation(self):
     request = DummyRequest()
     context = RouteFactory(request)
     context._check_permission.return_value = False
     context.resource_name = "book"
     context.required_permission = "book:create"
     context._settings = {"book_create_principals": "fxa:user"}
     self.assertTrue(context.check_permission(["fxa:user"], None))
    def test_http_put_unexisting_object_resolves_in_a_create_permission(self):
        with mock.patch("kinto.core.utils.current_service") as current_service:
            # Patch current service.
            resource = mock.MagicMock()
            resource.object_id = 1
            resource.model.get_object.side_effect = storage_exceptions.ObjectNotFoundError
            current_service().resource.return_value = resource
            current_service().plural_path = "/school/{school_id}"
            # Do the actual call.
            request = DummyRequest(method="put")
            request.upath_info = "/school/abc/students/1"
            request.matchdict = {"school_id": "abc"}
            context = RouteFactory(request)

            self.assertEqual(context.required_permission, "create")
Example #32
0
    def test_http_put_unexisting_record_resolves_in_a_create_permission(self):
        with mock.patch('kinto.core.utils.current_service') as current_service:
            # Patch current service.
            resource = mock.MagicMock()
            resource.record_id = 1
            resource.model.get_record.side_effect = \
                storage_exceptions.RecordNotFoundError
            current_service().resource.return_value = resource
            current_service().collection_path = '/buckets/{bucket_id}'
            # Do the actual call.
            request = DummyRequest(method='put')
            request.upath_info = '/buckets/abc/collections/1'
            request.matchdict = {'bucket_id': 'abc'}
            context = RouteFactory(request)

            self.assertEquals(context.required_permission, 'create')
Example #33
0
    def test_route_factory_adds_allowed_principals_from_settings(self):
        with mock.patch('kinto.core.utils.current_service') as current_service:
            # Patch current service.
            resource = mock.MagicMock()
            current_service().resource.return_value = resource
            current_service().collection_path = '/buckets'
            # Do the actual call.
            request = DummyRequest(method='post')
            request.current_resource_name = 'bucket'
            request.upath_info = '/buckets'
            request.matchdict = {}
            request.registry = mock.Mock()
            request.registry.settings = {
                'bucket_create_principals': 'fxa:user'
            }
            context = RouteFactory(request)

            self.assertEquals(context.allowed_principals, ['fxa:user'])
Example #34
0
 def get_context(self):
     return RouteFactory(self.get_request())
Example #35
0
class GuestAuthorizationPolicyTest(unittest.TestCase):
    def setUp(self):
        self.authz = AuthorizationPolicy()
        self.authz.get_bound_permissions = lambda o, p: []
        self.request = DummyRequest(method="GET")
        self.context = RouteFactory(self.request)
        self.context.on_collection = True
        self.context.check_permission = mock.Mock(return_value=False)

    def test_permits_returns_true_if_collection_and_shared_records(self):
        self.context.fetch_shared_records = mock.MagicMock(return_value=["record1", "record2"])
        allowed = self.authz.permits(self.context, ["userid"], "dynamic")
        # Note: we use the list of principals from request.prefixed_principals
        self.context.fetch_shared_records.assert_called_with(
            "read",
            ["basicauth:bob", "system.Everyone", "system.Authenticated"],
            self.authz.get_bound_permissions,
        )
        self.assertTrue(allowed)

    def test_permits_does_not_return_true_if_not_collection(self):
        self.context.on_collection = False
        allowed = self.authz.permits(self.context, ["userid"], "dynamic")
        self.assertFalse(allowed)

    def test_permits_does_not_return_true_if_not_list_operation(self):
        self.context.required_permission = "create"
        allowed = self.authz.permits(self.context, ["userid"], "dynamic")
        self.assertFalse(allowed)
        allowed = self.authz.permits(self.context, ["userid"], "create")
        self.assertFalse(allowed)

    def test_permits_returns_false_if_collection_is_unknown(self):
        self.context.fetch_shared_records = mock.MagicMock(return_value=None)
        allowed = self.authz.permits(self.context, ["userid"], "dynamic")
        # Note: we use the list of principals from request.prefixed_principals
        self.context.fetch_shared_records.assert_called_with(
            "read",
            ["basicauth:bob", "system.Everyone", "system.Authenticated"],
            self.authz.get_bound_permissions,
        )
        self.assertFalse(allowed)

    def test_perm_object_id_is_naive_if_no_record_path_exists(self):
        def route_path(service_name, **kwargs):
            # Simulate a resource that has no record_path (only list).
            if service_name == "article-record":
                raise KeyError
            return "/comments/sub/{id}".format_map(kwargs)

        self.request.route_path.side_effect = route_path

        self.request.path = "/comments"
        self.context.resource_name = "comment"
        obj_id = self.context.get_permission_object_id(self.request, "*")
        self.assertEqual(obj_id, "/comments/sub/*")

        self.request.path = "/articles"
        self.context.resource_name = "article"
        obj_id = self.context.get_permission_object_id(self.request, "*")
        self.assertEqual(obj_id, "/articles/*")
class GuestAuthorizationPolicyTest(unittest.TestCase):
    def setUp(self):
        self.authz = AuthorizationPolicy()
        self.authz.get_bound_permissions = lambda o, p: []
        self.request = DummyRequest(method="GET")
        self.context = RouteFactory(self.request)
        self.context.on_plural_endpoint = True
        self.context.check_permission = mock.Mock(return_value=False)

    def test_permits_returns_true_if_plural_endpoint_and_shared_objects(self):
        self.context.fetch_shared_objects = mock.MagicMock(
            return_value=["object1", "object2"])
        allowed = self.authz.permits(self.context, ["userid"], "dynamic")
        # Note: we use the list of principals from request.prefixed_principals
        self.context.fetch_shared_objects.assert_called_with(
            "read",
            ["basicauth:bob", "system.Everyone", "system.Authenticated"],
            self.authz.get_bound_permissions,
        )
        self.assertTrue(allowed)

    def test_permits_does_not_return_true_if_not_plural_endpoint(self):
        self.context.on_plural_endpoint = False
        allowed = self.authz.permits(self.context, ["userid"], "dynamic")
        self.assertFalse(allowed)

    def test_permits_does_not_return_true_if_not_list_operation(self):
        self.context.required_permission = "create"
        allowed = self.authz.permits(self.context, ["userid"], "dynamic")
        self.assertFalse(allowed)
        allowed = self.authz.permits(self.context, ["userid"], "create")
        self.assertFalse(allowed)

    def test_permits_returns_false_if_resource_is_unknown(self):
        self.context.fetch_shared_objects = mock.MagicMock(return_value=None)
        allowed = self.authz.permits(self.context, ["userid"], "dynamic")
        # Note: we use the list of principals from request.prefixed_principals
        self.context.fetch_shared_objects.assert_called_with(
            "read",
            ["basicauth:bob", "system.Everyone", "system.Authenticated"],
            self.authz.get_bound_permissions,
        )
        self.assertFalse(allowed)

    def test_perm_object_id_is_naive_if_no_object_path_exists(self):
        def route_path(service_name, **kwargs):
            # Simulate a resource that has no object_path (only list).
            if service_name == "article-object":
                raise KeyError
            return "/comments/sub/{id}".format_map(kwargs)

        self.request.route_path.side_effect = route_path

        self.request.path = "/comments"
        self.context.resource_name = "comment"
        obj_id = self.context.get_permission_object_id(self.request, "*")
        self.assertEqual(obj_id, "/comments/sub/*")

        self.request.path = "/articles"
        self.context.resource_name = "article"
        obj_id = self.context.get_permission_object_id(self.request, "*")
        self.assertEqual(obj_id, "/articles/*")