)]}'
{"glance/api/policy.py":[{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"02acbf0e992dbf413fc9dbccaee52155562e4b63","unresolved":true,"context_lines":[{"line_number":113,"context_line":"            raise"},{"line_number":114,"context_line":"        else:"},{"line_number":115,"context_line":"            self.policy.enforce(self.context, \u0027get_image\u0027,"},{"line_number":116,"context_line":"                                dict(ImageTarget(image)))"},{"line_number":117,"context_line":"        return image"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"    def list(self, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":1,"id":"d29be871_ced6d01c","side":"PARENT","line":116,"range":{"start_line":116,"start_character":32,"end_line":116,"end_character":56},"updated":"2020-12-03 05:37:44.000000000","message":"We need this for property protection, IMO you should add project_id to this dict","commit_id":"e6c6a2e45021130cc8744cc95710f5b57b7a0a92"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"02acbf0e992dbf413fc9dbccaee52155562e4b63","unresolved":true,"context_lines":[{"line_number":125,"context_line":"        return super(ImageRepoProxy, self).save(image, from_state\u003dfrom_state)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"    def add(self, image):"},{"line_number":128,"context_line":"        self.policy.enforce(self.context, \u0027add_image\u0027, dict(image.target))"},{"line_number":129,"context_line":"        return super(ImageRepoProxy, self).add(image)"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"f7b919f4_0a6ee888","side":"PARENT","line":128,"range":{"start_line":128,"start_character":55,"end_line":128,"end_character":73},"updated":"2020-12-03 05:37:44.000000000","message":"ditto,\n\nimage.target is the dict representation of Image which needs for property protection, you need to add project_id to this dict","commit_id":"e6c6a2e45021130cc8744cc95710f5b57b7a0a92"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"02acbf0e992dbf413fc9dbccaee52155562e4b63","unresolved":true,"context_lines":[{"line_number":173,"context_line":"        self.image.locations \u003d new_locations"},{"line_number":174,"context_line":""},{"line_number":175,"context_line":"    def delete(self):"},{"line_number":176,"context_line":"        self.policy.enforce(self.context, \u0027delete_image\u0027, dict(self.target))"},{"line_number":177,"context_line":"        return self.image.delete()"},{"line_number":178,"context_line":""},{"line_number":179,"context_line":"    def deactivate(self):"}],"source_content_type":"text/x-python","patch_set":1,"id":"ff75f501_b1c723df","side":"PARENT","line":176,"range":{"start_line":176,"start_character":58,"end_line":176,"end_character":75},"updated":"2020-12-03 05:37:44.000000000","message":"ditto,\nwe need entire image dict to be passed to ensure that the caller have proper role/scope to delete the protected property.","commit_id":"e6c6a2e45021130cc8744cc95710f5b57b7a0a92"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"87bddb681cc8ae9c1ecdb961ae745a2c4ddeec21","unresolved":true,"context_lines":[{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    def list(self, *args, **kwargs):"},{"line_number":125,"context_line":"        if self.context.project_id:"},{"line_number":126,"context_line":"            target \u003d {\u0027project_id\u0027: self.context.project_id}"},{"line_number":127,"context_line":"        else:"},{"line_number":128,"context_line":"            target \u003d {}"},{"line_number":129,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"bb10d115_136a6259","line":126,"range":{"start_line":126,"start_character":36,"end_line":126,"end_character":59},"updated":"2021-02-03 18:30:00.000000000","message":"This is a bit tricky since we\u0027re effectively performing a policy no-op because we\u0027re making sure the project_id matches itself.\n\nIf we do this - I think we need to make sure we\u0027re doing the filtering somewhere else?","commit_id":"0f66fa68decef26e0cdf18d216916eda7c969c91"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"87bddb681cc8ae9c1ecdb961ae745a2c4ddeec21","unresolved":true,"context_lines":[{"line_number":131,"context_line":"        return super(ImageRepoProxy, self).list(*args, **kwargs)"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    def save(self, image, from_state\u003dNone):"},{"line_number":134,"context_line":"        target \u003d dict(image.target)"},{"line_number":135,"context_line":"        target_project_id \u003d target[\u0027owner\u0027]"},{"line_number":136,"context_line":"        target[\u0027project_id\u0027] \u003d target_project_id"},{"line_number":137,"context_line":"        self.policy.enforce(self.context, \u0027modify_image\u0027, target)"}],"source_content_type":"text/x-python","patch_set":2,"id":"403b842e_20f90989","line":134,"range":{"start_line":134,"start_character":8,"end_line":134,"end_character":35},"updated":"2021-02-03 18:30:00.000000000","message":"It appears the only difference between doing:\n\n  target \u003d dict(image.target)\n\nand\n\n  target \u003d dict(ImageTarget(image))\n\nIs that `ImageTarget` will validate the attributes in the dictionary?\n\nIn that case, is there preferred approach? Should I be using ImageTarget in one case and dict(image.target) in another?","commit_id":"0f66fa68decef26e0cdf18d216916eda7c969c91"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"f260b1340be1ce1d3f8f32fdec9fe65e34d8edde","unresolved":true,"context_lines":[{"line_number":131,"context_line":"        return super(ImageRepoProxy, self).list(*args, **kwargs)"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    def save(self, image, from_state\u003dNone):"},{"line_number":134,"context_line":"        target \u003d dict(image.target)"},{"line_number":135,"context_line":"        target_project_id \u003d target[\u0027owner\u0027]"},{"line_number":136,"context_line":"        target[\u0027project_id\u0027] \u003d target_project_id"},{"line_number":137,"context_line":"        self.policy.enforce(self.context, \u0027modify_image\u0027, target)"}],"source_content_type":"text/x-python","patch_set":2,"id":"1c16363f_d517593d","line":134,"range":{"start_line":134,"start_character":8,"end_line":134,"end_character":35},"in_reply_to":"403b842e_20f90989","updated":"2021-02-04 13:45:04.000000000","message":"I guess if you do image.target means image is instance of ImgaeTarget, so when image is not instance of ImageTarget you need to use target \u003d dict(ImageTarget(image))","commit_id":"0f66fa68decef26e0cdf18d216916eda7c969c91"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"5ceb32ad425bc010f615a99d2387feefb2340942","unresolved":true,"context_lines":[{"line_number":486,"context_line":"        self.target \u003d target"},{"line_number":487,"context_line":"        # We ignore the locations attribute from policy target data because the"},{"line_number":488,"context_line":"        # ImageLocationsProxy translate into a dictionary that usable in policy"},{"line_number":489,"context_line":"        # enforcement."},{"line_number":490,"context_line":"        self._target_keys \u003d [k for k in dir(ImageProxy)"},{"line_number":491,"context_line":"                             if not k.startswith(\u0027__\u0027)"},{"line_number":492,"context_line":"                             if not k \u003d\u003d \u0027locations\u0027"}],"source_content_type":"text/x-python","patch_set":3,"id":"8627b78f_dc0777f2","line":489,"updated":"2021-02-05 14:15:25.000000000","message":"I\u0027m curious what people think about this. As far as I can tell, based on the class name and my grepping, I don\u0027t think class or it\u0027s objects are used outside of policy enforcement.\n\nDo we expect deployers to write policies using the location of the image? For example:\n\n  image:do_something: \"role:foo and bar:%(image_location)s\"\n\nI can\u0027t really see a use case for that, but I\u0027m also not acutely familiar with glance.\n\nI removed the locations attribute from the ImageTarget because it\u0027s also an instance of ImageLocationsProxy. In order for us to write sensible checks, we\u0027d need a representations of this instance that people can actually write things against in addition to teaching oslo.policy how to handle target objects that aren\u0027t strings.","commit_id":"1a88452b23664a7b6b541503f5034cc56d490fc2"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"4f89512aba734fb2356af05ad48da3195a23247f","unresolved":true,"context_lines":[{"line_number":124,"context_line":"            self.policy.enforce(self.context, \u0027get_image\u0027, target)"},{"line_number":125,"context_line":"        except exception.Forbidden:"},{"line_number":126,"context_line":"            msg \u003d _(\"No image found with ID %s\") % image_id"},{"line_number":127,"context_line":"            raise exception.NotFound(msg)"},{"line_number":128,"context_line":"        return image"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def _build_image_target(self, image):"}],"source_content_type":"text/x-python","patch_set":11,"id":"654ded05_38caea43","line":127,"range":{"start_line":127,"start_character":18,"end_line":127,"end_character":36},"updated":"2021-02-19 02:57:54.000000000","message":"So, when a user is not allowed to access this resource, we tell them that it could not be found, instead of explicitely telling them they are not allowed to access it, as we used to do.\n\n\nIs this something that is done for all resources in all projects when using S-RBAC? Will it not be confusing for users?","commit_id":"a371713d3053dc37b5a0ea722f336e0820c27446"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0b32def222ee4c80b280ecb2cdf955fc907dcc14","unresolved":true,"context_lines":[{"line_number":124,"context_line":"            self.policy.enforce(self.context, \u0027get_image\u0027, target)"},{"line_number":125,"context_line":"        except exception.Forbidden:"},{"line_number":126,"context_line":"            msg \u003d _(\"No image found with ID %s\") % image_id"},{"line_number":127,"context_line":"            raise exception.NotFound(msg)"},{"line_number":128,"context_line":"        return image"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def _build_image_target(self, image):"}],"source_content_type":"text/x-python","patch_set":11,"id":"faad4bbc_a5fb1390","line":127,"range":{"start_line":127,"start_character":18,"end_line":127,"end_character":36},"in_reply_to":"654ded05_38caea43","updated":"2021-02-19 18:55:29.000000000","message":"A few of us dug into overall community guidance about this a couple of weeks ago, but we didn\u0027t find anything definitive, which prompted a related fix [1].\n\nI don\u0027t think explicitly handling 403 versus 404s is targeted or guaranteed for each service adopting the personas.\n\n[0] http://eavesdrop.openstack.org/irclogs/%23openstack-glance/%23openstack-glance.2021-02-12.log.html#t2021-02-12T15:28:21\n[1] https://review.opendev.org/c/openstack/glance/+/775435/4","commit_id":"a371713d3053dc37b5a0ea722f336e0820c27446"}],"glance/api/v2/image_data.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"87bddb681cc8ae9c1ecdb961ae745a2c4ddeec21","unresolved":true,"context_lines":[{"line_number":137,"context_line":"        refresher \u003d None"},{"line_number":138,"context_line":"        cxt \u003d req.context"},{"line_number":139,"context_line":"        try:"},{"line_number":140,"context_line":"            target \u003d {\u0027project_id\u0027: cxt.project_id}"},{"line_number":141,"context_line":"            self.policy.enforce(cxt, \u0027upload_image\u0027, target)"},{"line_number":142,"context_line":"            image \u003d image_repo.get(image_id)"},{"line_number":143,"context_line":"            image.status \u003d \u0027saving\u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"5dde80ee_4331c20d","line":140,"range":{"start_line":140,"start_character":12,"end_line":140,"end_character":51},"updated":"2021-02-03 18:30:00.000000000","message":"I think this is a policy no-op again. Is the necessary because somewhere else in glance updates the image.owner to always be the project_id of the token used to create the image?","commit_id":"0f66fa68decef26e0cdf18d216916eda7c969c91"}],"glance/api/v2/images.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"87bddb681cc8ae9c1ecdb961ae745a2c4ddeec21","unresolved":true,"context_lines":[{"line_number":420,"context_line":"                        project_images.append(image)"},{"line_number":421,"context_line":"                    elif image.visibility \u003d\u003d \u0027public\u0027:"},{"line_number":422,"context_line":"                        project_images.append(image)"},{"line_number":423,"context_line":"                images \u003d project_images\u0027\u0027\u0027"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":"            if len(images) !\u003d 0 and len(images) \u003d\u003d limit:"},{"line_number":426,"context_line":"                result[\u0027next_marker\u0027] \u003d images[-1].image_id"}],"source_content_type":"text/x-python","patch_set":2,"id":"90b7a02e_7204b692","line":423,"updated":"2021-02-03 18:30:00.000000000","message":"I wonder if we can implement this as a filter instead of iterating a list of images in python?\n\n  try:\n      \n      if req.context.project_id\n          filter[\u0027owner\u0027] \u003d req.context.project_id\n      images \u003d image_repo.list(...\n\nBut that might require changes at the database layer to implement that specific filter.","commit_id":"0f66fa68decef26e0cdf18d216916eda7c969c91"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"f260b1340be1ce1d3f8f32fdec9fe65e34d8edde","unresolved":true,"context_lines":[{"line_number":420,"context_line":"                        project_images.append(image)"},{"line_number":421,"context_line":"                    elif image.visibility \u003d\u003d \u0027public\u0027:"},{"line_number":422,"context_line":"                        project_images.append(image)"},{"line_number":423,"context_line":"                images \u003d project_images\u0027\u0027\u0027"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":"            if len(images) !\u003d 0 and len(images) \u003d\u003d limit:"},{"line_number":426,"context_line":"                result[\u0027next_marker\u0027] \u003d images[-1].image_id"}],"source_content_type":"text/x-python","patch_set":2,"id":"10b9e389_42098c55","line":423,"in_reply_to":"90b7a02e_7204b692","updated":"2021-02-04 13:45:04.000000000","message":"It would be better to implement this as a filter instead iterating a list of images here.","commit_id":"0f66fa68decef26e0cdf18d216916eda7c969c91"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"d3868cf219739af2c869c5f927ce311b799c8cba","unresolved":true,"context_lines":[{"line_number":411,"context_line":"                                     sort_dir\u003dsort_dir,"},{"line_number":412,"context_line":"                                     filters\u003dfilters,"},{"line_number":413,"context_line":"                                     member_status\u003dmember_status)"},{"line_number":414,"context_line":""},{"line_number":415,"context_line":"            if len(images) !\u003d 0 and len(images) \u003d\u003d limit:"},{"line_number":416,"context_line":"                result[\u0027next_marker\u0027] \u003d images[-1].image_id"},{"line_number":417,"context_line":"        except (exception.NotFound, exception.InvalidSortKey,"}],"source_content_type":"text/x-python","patch_set":5,"id":"a05a165a_935377f5","line":414,"updated":"2021-02-09 04:13:31.000000000","message":"Revert this.","commit_id":"cca4e5756ec5f7d542dfbb98af03a0de2e6129e1"}],"glance/db/sqlalchemy/api.py":[{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"436c19a3f100261a32cce5d58905b253a4f1633f","unresolved":true,"context_lines":[{"line_number":664,"context_line":"        owner_query \u003d _build_owner_select("},{"line_number":665,"context_line":"            session, conditional, context.project_id)"},{"line_number":666,"context_line":"        query \u003d image_query.union(member_query, owner_query)"},{"line_number":667,"context_line":"    elif context.owner_is_tenant is False:"},{"line_number":668,"context_line":"        image_query \u003d _build_image_select(session, conditional)"},{"line_number":669,"context_line":"        image_query \u003d _add_public_and_community_image_filters(image_query)"},{"line_number":670,"context_line":"        member_query \u003d _build_member_select(session, conditional)"}],"source_content_type":"text/x-python","patch_set":9,"id":"f1d55364_cf51a00b","line":667,"range":{"start_line":667,"start_character":9,"end_line":667,"end_character":32},"updated":"2021-02-16 07:19:23.000000000","message":"owner_is_tenant has been removed in https://review.opendev.org/c/openstack/glance/+/763920 and no longer be used.","commit_id":"5bbe52ab98002962c9354c34420d3b9adcdec8f7"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"8f269a07a8b8c672253524c0ce12e2c6763253bd","unresolved":true,"context_lines":[{"line_number":664,"context_line":"        owner_query \u003d _build_owner_select("},{"line_number":665,"context_line":"            session, conditional, context.project_id)"},{"line_number":666,"context_line":"        query \u003d image_query.union(member_query, owner_query)"},{"line_number":667,"context_line":"    elif context.owner_is_tenant is False:"},{"line_number":668,"context_line":"        image_query \u003d _build_image_select(session, conditional)"},{"line_number":669,"context_line":"        image_query \u003d _add_public_and_community_image_filters(image_query)"},{"line_number":670,"context_line":"        member_query \u003d _build_member_select(session, conditional)"}],"source_content_type":"text/x-python","patch_set":9,"id":"40a2031f_aec95935","line":667,"range":{"start_line":667,"start_character":9,"end_line":667,"end_character":32},"in_reply_to":"f1d55364_cf51a00b","updated":"2021-02-16 14:01:24.000000000","message":"++\n\nI\u0027ll remove this case. Thanks, Abhishek.","commit_id":"5bbe52ab98002962c9354c34420d3b9adcdec8f7"}],"glance/tests/functional/db/base.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"c921af22b3b8ec76adf5036a7e71a849babc9a44","unresolved":true,"context_lines":[{"line_number":2239,"context_line":"        images \u003d self.db_api.image_get_all(self.admin_context)"},{"line_number":2240,"context_line":"        self.assertEqual(13, len(images))"},{"line_number":2241,"context_line":""},{"line_number":2242,"context_line":"    def test_admin_as_user_true(self):"},{"line_number":2243,"context_line":"        images \u003d self.db_api.image_get_all(self.admin_context,"},{"line_number":2244,"context_line":"                                           admin_as_user\u003dTrue)"},{"line_number":2245,"context_line":"        self.assertEqual(7, len(images))"}],"source_content_type":"text/x-python","patch_set":7,"id":"2a8f7536_8acf5c4d","side":"PARENT","line":2242,"updated":"2021-02-10 13:40:38.000000000","message":"I couldn\u0027t find anything in the actual glance code path that invokes admin_as_user, so this looks like a stale test.","commit_id":"f1ba4c5bb4e5b2912760b0aed93c81d8435b6f7f"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"20e95d6461f1aade5de504ad39d6bdb20cccc405","unresolved":true,"context_lines":[{"line_number":2239,"context_line":"        images \u003d self.db_api.image_get_all(self.admin_context)"},{"line_number":2240,"context_line":"        self.assertEqual(13, len(images))"},{"line_number":2241,"context_line":""},{"line_number":2242,"context_line":"    def test_admin_as_user_true(self):"},{"line_number":2243,"context_line":"        images \u003d self.db_api.image_get_all(self.admin_context,"},{"line_number":2244,"context_line":"                                           admin_as_user\u003dTrue)"},{"line_number":2245,"context_line":"        self.assertEqual(7, len(images))"}],"source_content_type":"text/x-python","patch_set":7,"id":"7f1be2e1_7a1158b4","side":"PARENT","line":2242,"in_reply_to":"2a8f7536_8acf5c4d","updated":"2021-02-10 14:36:25.000000000","message":"admin_as_user was part of registry which we removed during victoria, so yes you are correct.","commit_id":"f1ba4c5bb4e5b2912760b0aed93c81d8435b6f7f"}],"glance/tests/unit/test_policy.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"a9ae8c314baf73c48852a5ab07274eb3c177944a","unresolved":true,"context_lines":[{"line_number":617,"context_line":"                                                    target)"},{"line_number":618,"context_line":""},{"line_number":619,"context_line":""},{"line_number":620,"context_line":"class TestMemberPolicy(test_utils.BaseTestCase):"},{"line_number":621,"context_line":""},{"line_number":622,"context_line":"    def setUp(self):"},{"line_number":623,"context_line":"        self.policy \u003d mock.Mock()"}],"source_content_type":"text/x-python","patch_set":2,"id":"38417f35_f6e5734e","line":620,"range":{"start_line":620,"start_character":6,"end_line":620,"end_character":22},"updated":"2021-02-03 19:27:01.000000000","message":"All these tests are failing because we\u0027re asserting policy enforcement it called with a specific target, but the tests we using don\u0027t mock the image.location attribute properly. The failure is because the image.location (which is an instance of glance.api.policy.ImageLocationsProxy) is different in the self.target here and the target_enforcer object of the glance API policy code.","commit_id":"0f66fa68decef26e0cdf18d216916eda7c969c91"}]}
