)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"c29230fb6ccd36986ba445fad35d2d47b2486ec2","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Project domain must match role domain for assignment"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When assigning a Domain specific role to a user it is OK if the user"},{"line_number":10,"context_line":"is from a different domain but the project\u0027s domain must match the"},{"line_number":11,"context_line":"role\u0027s domain."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Closes-Bug: 1590587"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"9a89bdaa_517f6e65","line":10,"updated":"2016-09-07 16:06:41.000000000","message":"(nit) s/ but/, but/","commit_id":"77d31fe9030fbdab92ee4d196e9dd849967dcb5c"}],"keystone/assignment/core.py":[{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"673934c5b64448fd2dcc022cb4e0c8964539f763","unresolved":false,"context_lines":[{"line_number":348,"context_line":"            # For domain specific roles, the domain of the project must match"},{"line_number":349,"context_line":"            # the roles\u0027s"},{"line_number":350,"context_line":"            if role[\u0027domain_id\u0027] and project[\u0027domain_id\u0027] !\u003d role[\u0027domain_id\u0027]:"},{"line_number":351,"context_line":"                raise exception.ForbiddenAction(action\u003d\u0027create_grant\u0027)"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"        self.driver.create_grant(role_id, user_id, group_id, domain_id,"},{"line_number":354,"context_line":"                                 project_id, inherited_to_projects)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a89bdaa_897c0622","line":351,"range":{"start_line":351,"start_character":16,"end_line":351,"end_character":70},"updated":"2016-09-05 02:56:31.000000000","message":"i think we need to make this error message more meaningful, it\u0027ll just come back as:\n\n  You are not authorized to perform the requested action: create_grant\n\nDoesn\u0027t really explain what went wrong in a pretty specific scenario such as this one. I think this may mean creating a new exception, normally I\u0027d be OK with just a LOG.error, but this is a domain admin operation, who may not have access tot he logs.","commit_id":"77d31fe9030fbdab92ee4d196e9dd849967dcb5c"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"7cf7c105314fcc8e62ae8b8dfeef6a2602951ff7","unresolved":false,"context_lines":[{"line_number":348,"context_line":"            # For domain specific roles, the domain of the project must match"},{"line_number":349,"context_line":"            # the roles\u0027s"},{"line_number":350,"context_line":"            if role[\u0027domain_id\u0027] and project[\u0027domain_id\u0027] !\u003d role[\u0027domain_id\u0027]:"},{"line_number":351,"context_line":"                raise exception.ForbiddenAction(action\u003d\u0027create_grant\u0027)"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"        self.driver.create_grant(role_id, user_id, group_id, domain_id,"},{"line_number":354,"context_line":"                                 project_id, inherited_to_projects)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a89bdaa_57867edb","line":351,"range":{"start_line":351,"start_character":16,"end_line":351,"end_character":70},"in_reply_to":"9a89bdaa_04032110","updated":"2016-09-07 16:50:12.000000000","message":"It\u0027s usually hard to troubleshoot \"Forbidden\" responses thanks to this very approach. It would be really good to see the exact reason of the \"Forbidden\" response without browsing logs (that are usually disabled in production).\n\nAlthough, this patch follows current paradigm so I agree with it.","commit_id":"77d31fe9030fbdab92ee4d196e9dd849967dcb5c"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"2dae38537b266180b7c8e7b3cb03be13b3b95eaa","unresolved":false,"context_lines":[{"line_number":348,"context_line":"            # For domain specific roles, the domain of the project must match"},{"line_number":349,"context_line":"            # the roles\u0027s"},{"line_number":350,"context_line":"            if role[\u0027domain_id\u0027] and project[\u0027domain_id\u0027] !\u003d role[\u0027domain_id\u0027]:"},{"line_number":351,"context_line":"                raise exception.ForbiddenAction(action\u003d\u0027create_grant\u0027)"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"        self.driver.create_grant(role_id, user_id, group_id, domain_id,"},{"line_number":354,"context_line":"                                 project_id, inherited_to_projects)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a89bdaa_10e804e2","line":351,"range":{"start_line":351,"start_character":16,"end_line":351,"end_character":70},"in_reply_to":"9a89bdaa_897c0622","updated":"2016-09-05 11:41:14.000000000","message":"++","commit_id":"77d31fe9030fbdab92ee4d196e9dd849967dcb5c"},{"author":{"_account_id":17026,"name":"Sean Perry","email":"sean.perry@hpe.com","username":"sean_perry"},"change_message_id":"1469ed8e0f076b00b62f102d46212a1709638b42","unresolved":false,"context_lines":[{"line_number":348,"context_line":"            # For domain specific roles, the domain of the project must match"},{"line_number":349,"context_line":"            # the roles\u0027s"},{"line_number":350,"context_line":"            if role[\u0027domain_id\u0027] and project[\u0027domain_id\u0027] !\u003d role[\u0027domain_id\u0027]:"},{"line_number":351,"context_line":"                raise exception.ForbiddenAction(action\u003d\u0027create_grant\u0027)"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"        self.driver.create_grant(role_id, user_id, group_id, domain_id,"},{"line_number":354,"context_line":"                                 project_id, inherited_to_projects)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a89bdaa_04032110","line":351,"range":{"start_line":351,"start_character":16,"end_line":351,"end_character":70},"in_reply_to":"9a89bdaa_897c0622","updated":"2016-09-06 19:00:31.000000000","message":"From the REST API perspective this will end in a Forbidden error regardless. I can emit a log message but if the caller cannot see the logs all they will see is \"Forbidden\".","commit_id":"77d31fe9030fbdab92ee4d196e9dd849967dcb5c"}],"keystone/exception.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"343cae7ef7a564d30bca5aaea4be93caeaf089b8","unresolved":false,"context_lines":[{"line_number":352,"context_line":""},{"line_number":353,"context_line":"class DomainSpecificRoleMismatch(Forbidden):"},{"line_number":354,"context_line":"    message_format \u003d _(\"project: %(project_id)s must be in the same domain \""},{"line_number":355,"context_line":"                       \" as the role: %(role_id)s being assigned.\")"},{"line_number":356,"context_line":""},{"line_number":357,"context_line":""},{"line_number":358,"context_line":"class RoleAssignmentNotFound(NotFound):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a89bdaa_cbc82225","line":355,"updated":"2016-09-07 20:20:52.000000000","message":"(nit) maybe no period to match the other exceptions?","commit_id":"73bdbe1f87ac3571bb5a348158ad1e4ece73fbcc"}],"keystone/tests/unit/test_v3_assignment.py":[{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"2dae38537b266180b7c8e7b3cb03be13b3b95eaa","unresolved":false,"context_lines":[{"line_number":2821,"context_line":"        self.assertValidRoleListResponse(r, expected_length\u003d1)"},{"line_number":2822,"context_line":"        self.assertRoleInListResponse(r, self.domainA_role2)"},{"line_number":2823,"context_line":""},{"line_number":2824,"context_line":"    def test_cross_domain_assignment(self):"},{"line_number":2825,"context_line":"        user \u003d unit.create_user(self.identity_api,"},{"line_number":2826,"context_line":"                                domain_id\u003dself.domainB[\u0027id\u0027])"},{"line_number":2827,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9a89bdaa_b0a678bf","line":2824,"range":{"start_line":2824,"start_character":8,"end_line":2824,"end_character":36},"updated":"2016-09-05 11:41:14.000000000","message":"can you split in two tests? \"test_cross_domain_user_assignment\" and \"test_cross_domain_project_assignment\". This helps if one of them fails in the future.","commit_id":"77d31fe9030fbdab92ee4d196e9dd849967dcb5c"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"da9f6549c0c7047b4559ac1074a6dab35e8b3b64","unresolved":false,"context_lines":[{"line_number":2821,"context_line":"        self.assertValidRoleListResponse(r, expected_length\u003d1)"},{"line_number":2822,"context_line":"        self.assertRoleInListResponse(r, self.domainA_role2)"},{"line_number":2823,"context_line":""},{"line_number":2824,"context_line":"    def test_cross_domain_assignment(self):"},{"line_number":2825,"context_line":"        user \u003d unit.create_user(self.identity_api,"},{"line_number":2826,"context_line":"                                domain_id\u003dself.domainB[\u0027id\u0027])"},{"line_number":2827,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9a89bdaa_974ac624","line":2824,"range":{"start_line":2824,"start_character":8,"end_line":2824,"end_character":36},"in_reply_to":"9a89bdaa_443529f5","updated":"2016-09-07 16:41:06.000000000","message":"to proper test this, you need to cover all the cases. The suggestion I gave earlier was to try to separate them by type, but to summarize:\n\n - DomainA: userA, roleA, projectA\n - DomainB: userB, projectB\n\nYou need to cover the following cases:\n\n - userA / roleA / projectA -\u003e OK\n - userB/ roleA/ projectA -\u003e OK\n - userA / roleA / projectB -\u003e X\n\nUsually, splitting all of the cases in smaller testing units can improve maintainability.","commit_id":"77d31fe9030fbdab92ee4d196e9dd849967dcb5c"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"7cf7c105314fcc8e62ae8b8dfeef6a2602951ff7","unresolved":false,"context_lines":[{"line_number":2821,"context_line":"        self.assertValidRoleListResponse(r, expected_length\u003d1)"},{"line_number":2822,"context_line":"        self.assertRoleInListResponse(r, self.domainA_role2)"},{"line_number":2823,"context_line":""},{"line_number":2824,"context_line":"    def test_cross_domain_assignment(self):"},{"line_number":2825,"context_line":"        user \u003d unit.create_user(self.identity_api,"},{"line_number":2826,"context_line":"                                domain_id\u003dself.domainB[\u0027id\u0027])"},{"line_number":2827,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9a89bdaa_9753a66a","line":2824,"range":{"start_line":2824,"start_character":8,"end_line":2824,"end_character":36},"in_reply_to":"9a89bdaa_974ac624","updated":"2016-09-07 16:50:12.000000000","message":"++","commit_id":"77d31fe9030fbdab92ee4d196e9dd849967dcb5c"},{"author":{"_account_id":17026,"name":"Sean Perry","email":"sean.perry@hpe.com","username":"sean_perry"},"change_message_id":"1469ed8e0f076b00b62f102d46212a1709638b42","unresolved":false,"context_lines":[{"line_number":2821,"context_line":"        self.assertValidRoleListResponse(r, expected_length\u003d1)"},{"line_number":2822,"context_line":"        self.assertRoleInListResponse(r, self.domainA_role2)"},{"line_number":2823,"context_line":""},{"line_number":2824,"context_line":"    def test_cross_domain_assignment(self):"},{"line_number":2825,"context_line":"        user \u003d unit.create_user(self.identity_api,"},{"line_number":2826,"context_line":"                                domain_id\u003dself.domainB[\u0027id\u0027])"},{"line_number":2827,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9a89bdaa_443529f5","line":2824,"range":{"start_line":2824,"start_character":8,"end_line":2824,"end_character":36},"in_reply_to":"9a89bdaa_b0a678bf","updated":"2016-09-06 19:00:31.000000000","message":"These are BOTH project assignment. The only difference is which domain the project is part of. That is why I made it one test.  projectA is part of domainA and projectB is part of domainB.","commit_id":"77d31fe9030fbdab92ee4d196e9dd849967dcb5c"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"dfe3166cf89cc2cf8610cd0d17d9c86b936bd666","unresolved":false,"context_lines":[{"line_number":20,"context_line":"from testtools import matchers"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"import keystone.conf"},{"line_number":23,"context_line":"import keystone.exception"},{"line_number":24,"context_line":"from keystone.tests import unit"},{"line_number":25,"context_line":"from keystone.tests.unit import test_v3"},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9a89bdaa_7c88c2c5","line":23,"range":{"start_line":23,"start_character":0,"end_line":23,"end_character":25},"updated":"2016-09-07 18:20:11.000000000","message":"i think we usually follow the form:\n\n  from keystone import exception\n\nwe made an exception for keystone.conf","commit_id":"c89ba35abb714cbe2e4becf2e63fc0055b661b1a"},{"author":{"_account_id":17026,"name":"Sean Perry","email":"sean.perry@hpe.com","username":"sean_perry"},"change_message_id":"2c9378b4824e5018ffca0c925b453c8107d90a90","unresolved":false,"context_lines":[{"line_number":20,"context_line":"from testtools import matchers"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"import keystone.conf"},{"line_number":23,"context_line":"import keystone.exception"},{"line_number":24,"context_line":"from keystone.tests import unit"},{"line_number":25,"context_line":"from keystone.tests.unit import test_v3"},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9a89bdaa_fc505234","line":23,"range":{"start_line":23,"start_character":0,"end_line":23,"end_character":25},"in_reply_to":"9a89bdaa_7c88c2c5","updated":"2016-09-07 18:24:37.000000000","message":"Ah. I thought so but I was trying to follow convention in file.","commit_id":"c89ba35abb714cbe2e4becf2e63fc0055b661b1a"}]}
