)]}'
{"doc/source/policy_mapping.rst":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"631df4871acef0cc85a96c8ab3a4c6982610843a","unresolved":false,"context_lines":[{"line_number":36,"context_line":"identity:list_user_projects                                GET /v3/users/{user_id}/projects"},{"line_number":37,"context_line":"identity:create_project                                    POST /v3/projects"},{"line_number":38,"context_line":"identity:update_project                                    PATCH /v3/projects/{project_id}"},{"line_number":39,"context_line":"identity:update_project_cascade                            PATCH /v3/projects/{project_id}/cascade"},{"line_number":40,"context_line":"identity:delete_project                                    DELETE /v3/projects/{project_id}"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"identity:get_user                                          GET /v3/users/{user_id}"}],"source_content_type":"text/x-rst","patch_set":5,"id":"9a68dd71_ece788aa","line":39,"range":{"start_line":39,"start_character":90,"end_line":39,"end_character":98},"updated":"2016-01-20 20:13:07.000000000","message":"should this be a query string?","commit_id":"c41298e1666191ebb44794516acef081f1da0a43"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"be89769ba2cfa52a8baac73946ff16acfa1d7c0d","unresolved":false,"context_lines":[{"line_number":36,"context_line":"identity:list_user_projects                                GET /v3/users/{user_id}/projects"},{"line_number":37,"context_line":"identity:create_project                                    POST /v3/projects"},{"line_number":38,"context_line":"identity:update_project                                    PATCH /v3/projects/{project_id}"},{"line_number":39,"context_line":"identity:update_project_cascade                            PATCH /v3/projects/{project_id}/cascade"},{"line_number":40,"context_line":"identity:delete_project                                    DELETE /v3/projects/{project_id}"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"identity:get_user                                          GET /v3/users/{user_id}"}],"source_content_type":"text/x-rst","patch_set":5,"id":"7a5de9d1_30fffaab","line":39,"range":{"start_line":39,"start_character":90,"end_line":39,"end_character":98},"in_reply_to":"9a68dd71_ece788aa","updated":"2016-01-28 16:35:03.000000000","message":"Isn\u0027t this the pattern we\u0027ve been using so far ? FOr example L47 identity:change_password and","commit_id":"c41298e1666191ebb44794516acef081f1da0a43"}],"keystone/common/controller.py":[{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"9e8a1a7c5ce62a5b46212fec131e4eb7571a1ad6","unresolved":false,"context_lines":[{"line_number":304,"context_line":"                    assignments \u003d self.assignment_api.list_role_assignments("},{"line_number":305,"context_line":"                        user_id\u003duser_id, project_id\u003dsubproject[\u0027id\u0027],"},{"line_number":306,"context_line":"                        effective\u003dTrue, include_names\u003dTrue)"},{"line_number":307,"context_line":"                    if not assignments:"},{"line_number":308,"context_line":"                        msg \u003d _(\u0027Cannot perform cascade operation, because the\u0027"},{"line_number":309,"context_line":"                                \u0027 user %(user_id)s does not have access to the\u0027"},{"line_number":310,"context_line":"                                \u0027 whole subtree of project %(root_id)s.\u0027) % ("},{"line_number":311,"context_line":"                            {\u0027user_id\u0027: user_id, \u0027root_id\u0027: root_id})"},{"line_number":312,"context_line":"                        raise exception.Forbidden(message\u003dmsg)"},{"line_number":313,"context_line":""},{"line_number":314,"context_line":"                    role_names \u003d [a[\u0027role_name\u0027] for a in assignments]"},{"line_number":315,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_a0048114","line":312,"range":{"start_line":307,"start_character":0,"end_line":312,"end_character":62},"updated":"2016-02-24 16:03:07.000000000","message":"I\u0027d like to not do this if we are using a domain scoped token","commit_id":"4502c76d193765bc274c5e28eb70ccba6214b966"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"a2d8970f061d48610c909e4919cd240854796176","unresolved":false,"context_lines":[{"line_number":304,"context_line":"                    assignments \u003d self.assignment_api.list_role_assignments("},{"line_number":305,"context_line":"                        user_id\u003duser_id, project_id\u003dsubproject[\u0027id\u0027],"},{"line_number":306,"context_line":"                        effective\u003dTrue, include_names\u003dTrue)"},{"line_number":307,"context_line":"                    if not assignments:"},{"line_number":308,"context_line":"                        msg \u003d _(\u0027Cannot perform cascade operation, because the\u0027"},{"line_number":309,"context_line":"                                \u0027 user %(user_id)s does not have access to the\u0027"},{"line_number":310,"context_line":"                                \u0027 whole subtree of project %(root_id)s.\u0027) % ("},{"line_number":311,"context_line":"                            {\u0027user_id\u0027: user_id, \u0027root_id\u0027: root_id})"},{"line_number":312,"context_line":"                        raise exception.Forbidden(message\u003dmsg)"},{"line_number":313,"context_line":""},{"line_number":314,"context_line":"                    role_names \u003d [a[\u0027role_name\u0027] for a in assignments]"},{"line_number":315,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_a03121a4","line":312,"range":{"start_line":307,"start_character":0,"end_line":312,"end_character":62},"in_reply_to":"bae84128_a0048114","updated":"2016-02-24 16:07:12.000000000","message":"sure, agreed! not for domain scoped tokens, but for project ones we need, so we only call oslo.policy if it\u0027s like a real project scoped token (WITH roles)","commit_id":"4502c76d193765bc274c5e28eb70ccba6214b966"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"9e8a1a7c5ce62a5b46212fec131e4eb7571a1ad6","unresolved":false,"context_lines":[{"line_number":313,"context_line":""},{"line_number":314,"context_line":"                    role_names \u003d [a[\u0027role_name\u0027] for a in assignments]"},{"line_number":315,"context_line":""},{"line_number":316,"context_line":"                    creds \u003d {\u0027user_id\u0027: user_id,"},{"line_number":317,"context_line":"                             \u0027user_domain_id\u0027: user_domain_id,"},{"line_number":318,"context_line":"                             \u0027project_id\u0027: subproject[\u0027id\u0027],"},{"line_number":319,"context_line":"                             \u0027project_domain_id\u0027: subproject[\u0027domain_id\u0027],"},{"line_number":320,"context_line":"                             \u0027roles\u0027: role_names}"},{"line_number":321,"context_line":""},{"line_number":322,"context_line":"                    subproject.update(updated_root)"},{"line_number":323,"context_line":"                    prep_info[\u0027input_attr\u0027] \u003d {\u0027project_id\u0027: subproject[\u0027id\u0027],"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_bd978aea","line":320,"range":{"start_line":316,"start_character":0,"end_line":320,"end_character":49},"updated":"2016-02-24 16:03:07.000000000","message":"so we need to take into account this could be a domain scoped token or a project scoped token. If it is a domain scoped token I would suggest you DON\u0027T modify the creds each time.","commit_id":"4502c76d193765bc274c5e28eb70ccba6214b966"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"a2d8970f061d48610c909e4919cd240854796176","unresolved":false,"context_lines":[{"line_number":313,"context_line":""},{"line_number":314,"context_line":"                    role_names \u003d [a[\u0027role_name\u0027] for a in assignments]"},{"line_number":315,"context_line":""},{"line_number":316,"context_line":"                    creds \u003d {\u0027user_id\u0027: user_id,"},{"line_number":317,"context_line":"                             \u0027user_domain_id\u0027: user_domain_id,"},{"line_number":318,"context_line":"                             \u0027project_id\u0027: subproject[\u0027id\u0027],"},{"line_number":319,"context_line":"                             \u0027project_domain_id\u0027: subproject[\u0027domain_id\u0027],"},{"line_number":320,"context_line":"                             \u0027roles\u0027: role_names}"},{"line_number":321,"context_line":""},{"line_number":322,"context_line":"                    subproject.update(updated_root)"},{"line_number":323,"context_line":"                    prep_info[\u0027input_attr\u0027] \u003d {\u0027project_id\u0027: subproject[\u0027id\u0027],"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_601439e8","line":320,"range":{"start_line":316,"start_character":0,"end_line":320,"end_character":49},"in_reply_to":"bae84128_bd978aea","updated":"2016-02-24 16:07:12.000000000","message":"exactly! ++","commit_id":"4502c76d193765bc274c5e28eb70ccba6214b966"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"9e8a1a7c5ce62a5b46212fec131e4eb7571a1ad6","unresolved":false,"context_lines":[{"line_number":318,"context_line":"                             \u0027project_id\u0027: subproject[\u0027id\u0027],"},{"line_number":319,"context_line":"                             \u0027project_domain_id\u0027: subproject[\u0027domain_id\u0027],"},{"line_number":320,"context_line":"                             \u0027roles\u0027: role_names}"},{"line_number":321,"context_line":""},{"line_number":322,"context_line":"                    subproject.update(updated_root)"},{"line_number":323,"context_line":"                    prep_info[\u0027input_attr\u0027] \u003d {\u0027project_id\u0027: subproject[\u0027id\u0027],"},{"line_number":324,"context_line":"                                               \u0027project\u0027: subproject}"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_1dae762d","line":321,"updated":"2016-02-24 16:03:07.000000000","message":"Suggest we also build a target_attr containing the (sub)project in question.\n\nI\u0027d also like to pass in the fact that we are in a cascade operation (not sure if this is best in the creds or the target)","commit_id":"4502c76d193765bc274c5e28eb70ccba6214b966"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"a2d8970f061d48610c909e4919cd240854796176","unresolved":false,"context_lines":[{"line_number":318,"context_line":"                             \u0027project_id\u0027: subproject[\u0027id\u0027],"},{"line_number":319,"context_line":"                             \u0027project_domain_id\u0027: subproject[\u0027domain_id\u0027],"},{"line_number":320,"context_line":"                             \u0027roles\u0027: role_names}"},{"line_number":321,"context_line":""},{"line_number":322,"context_line":"                    subproject.update(updated_root)"},{"line_number":323,"context_line":"                    prep_info[\u0027input_attr\u0027] \u003d {\u0027project_id\u0027: subproject[\u0027id\u0027],"},{"line_number":324,"context_line":"                                               \u0027project\u0027: subproject}"}],"source_content_type":"text/x-python","patch_set":23,"id":"bae84128_c0bc25de","line":321,"in_reply_to":"bae84128_1dae762d","updated":"2016-02-24 16:07:12.000000000","message":"yes we can do that too","commit_id":"4502c76d193765bc274c5e28eb70ccba6214b966"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"0504e3791e11474a413ae891d901e08bb94fd61b","unresolved":false,"context_lines":[{"line_number":256,"context_line":"    `cascade` may be specified. In that case, the operation will be executed"},{"line_number":257,"context_line":"    for both the specified project and its subtree."},{"line_number":258,"context_line":""},{"line_number":259,"context_line":"    The of a cascade operation is the same of executing the same API for each"},{"line_number":260,"context_line":"    node in the tree separately."},{"line_number":261,"context_line":""},{"line_number":262,"context_line":"    That said, the policy check needs to be performed for every project in the"}],"source_content_type":"text/x-python","patch_set":24,"id":"bae84128_dd840ed4","line":259,"range":{"start_line":259,"start_character":8,"end_line":259,"end_character":12},"updated":"2016-02-24 15:59:16.000000000","message":"henry-nash: remove this (comments in a previous version of another patch)","commit_id":"516c0bb33450b8e8ce21e87d820bf8939e3171ca"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"527482714989333731e0aa3162548195f509bd56","unresolved":false,"context_lines":[{"line_number":251,"context_line":""},{"line_number":252,"context_line":"def cascadeprotected():"},{"line_number":253,"context_line":"    \"\"\"Wraps project tree API calls with role based access controls (RBAC)."},{"line_number":254,"context_line":""},{"line_number":255,"context_line":"    When performing write or delete operations on a project, the option"},{"line_number":256,"context_line":"    `cascade` may be specified. In that case, the operation will be executed"},{"line_number":257,"context_line":"    for both the specified project and its subtree."}],"source_content_type":"text/x-python","patch_set":25,"id":"9aed3d3a_ef6f5690","line":254,"updated":"2016-02-26 13:22:49.000000000","message":"Loving the long doc string!!!!!","commit_id":"c21399c742a221ae095106ff24037bbbfd00679c"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"527482714989333731e0aa3162548195f509bd56","unresolved":false,"context_lines":[{"line_number":274,"context_line":"    2) For project scoped tokens, the idea is to check to see if the same token"},{"line_number":275,"context_line":"    workflow can be applied to the current subproject:"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        2.1) If the token was obtained via federation workflow, check to see if"},{"line_number":278,"context_line":"        the groups have roles assigned in the current subproject."},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"        2.2) If the token was obtained via trust workflow, check to see if"},{"line_number":281,"context_line":"        there is a trust for the user in the current subproject."},{"line_number":282,"context_line":""},{"line_number":283,"context_line":"        2.3) If the token was obtained via normal workflow, check to see if the"},{"line_number":284,"context_line":"        user has role assignments in the current subproject."},{"line_number":285,"context_line":""},{"line_number":286,"context_line":"        If that\u0027s the case, build credentials based on that and pass it along"},{"line_number":287,"context_line":"        with the current target to the policy enforcement library; otherwise"},{"line_number":288,"context_line":"        raise unauthorized."},{"line_number":289,"context_line":""},{"line_number":290,"context_line":"        2.4) If unauthorized was raised in any of the cases above, try to do as"},{"line_number":291,"context_line":"        for domain scoped tokens, i.e try with existing token and vary only the"}],"source_content_type":"text/x-python","patch_set":25,"id":"9aed3d3a_4f63e2dc","line":288,"range":{"start_line":277,"start_character":0,"end_line":288,"end_character":27},"updated":"2016-02-26 13:22:49.000000000","message":"So my one bit of unease about this, is that it feels odd that if I have a token for Project A, with roles X, Y in it, that as I run down the hierarchy, I might call policy on a subproject with MORE roles that I had in the original token (i.e. if I also had role Z on subproject B, then I\u0027d call policy with roles X, Y and Z). This feels wrong.\n\nHow about saying that the roles you pass to policy will always be a subset of the ones in the initial token (where subset \u003d the same or less roles)?","commit_id":"c21399c742a221ae095106ff24037bbbfd00679c"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"18b6d6079cb695a640fdc0f46216a7ac72522310","unresolved":false,"context_lines":[{"line_number":274,"context_line":"    2) For project scoped tokens, the idea is to check to see if the same token"},{"line_number":275,"context_line":"    workflow can be applied to the current subproject:"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        2.1) If the token was obtained via federation workflow, check to see if"},{"line_number":278,"context_line":"        the groups have roles assigned in the current subproject."},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"        2.2) If the token was obtained via trust workflow, check to see if"},{"line_number":281,"context_line":"        there is a trust for the user in the current subproject."},{"line_number":282,"context_line":""},{"line_number":283,"context_line":"        2.3) If the token was obtained via normal workflow, check to see if the"},{"line_number":284,"context_line":"        user has role assignments in the current subproject."},{"line_number":285,"context_line":""},{"line_number":286,"context_line":"        If that\u0027s the case, build credentials based on that and pass it along"},{"line_number":287,"context_line":"        with the current target to the policy enforcement library; otherwise"},{"line_number":288,"context_line":"        raise unauthorized."},{"line_number":289,"context_line":""},{"line_number":290,"context_line":"        2.4) If unauthorized was raised in any of the cases above, try to do as"},{"line_number":291,"context_line":"        for domain scoped tokens, i.e try with existing token and vary only the"}],"source_content_type":"text/x-python","patch_set":25,"id":"9aed3d3a_af038e72","line":288,"range":{"start_line":277,"start_character":0,"end_line":288,"end_character":27},"in_reply_to":"9aed3d3a_4f63e2dc","updated":"2016-02-26 13:26:35.000000000","message":"I wouldn\u0027t care about subset of roles, the only thing we need to ensure is that the user would be able to do the same operation in the subprojects by getting a token on them. It doesn\u0027t matter if the policy rule will pass thanks to other roles he has there.\n\nWe only ensure he has powers to do the same there.","commit_id":"c21399c742a221ae095106ff24037bbbfd00679c"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"a6eabbf60b2baf54488fb684d9d5706f45cbe508","unresolved":false,"context_lines":[{"line_number":274,"context_line":"    2) For project scoped tokens, the idea is to check to see if the same token"},{"line_number":275,"context_line":"    workflow can be applied to the current subproject:"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        2.1) If the token was obtained via federation workflow, check to see if"},{"line_number":278,"context_line":"        the groups have roles assigned in the current subproject."},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"        2.2) If the token was obtained via trust workflow, check to see if"},{"line_number":281,"context_line":"        there is a trust for the user in the current subproject."},{"line_number":282,"context_line":""},{"line_number":283,"context_line":"        2.3) If the token was obtained via normal workflow, check to see if the"},{"line_number":284,"context_line":"        user has role assignments in the current subproject."},{"line_number":285,"context_line":""},{"line_number":286,"context_line":"        If that\u0027s the case, build credentials based on that and pass it along"},{"line_number":287,"context_line":"        with the current target to the policy enforcement library; otherwise"},{"line_number":288,"context_line":"        raise unauthorized."},{"line_number":289,"context_line":""},{"line_number":290,"context_line":"        2.4) If unauthorized was raised in any of the cases above, try to do as"},{"line_number":291,"context_line":"        for domain scoped tokens, i.e try with existing token and vary only the"}],"source_content_type":"text/x-python","patch_set":25,"id":"9aed3d3a_ef511664","line":288,"range":{"start_line":277,"start_character":0,"end_line":288,"end_character":27},"in_reply_to":"9aed3d3a_af038e72","updated":"2016-02-26 13:28:22.000000000","message":"I think the idea here is use current context, change the project_id( keep same roles, users and so on) and request a new token.","commit_id":"c21399c742a221ae095106ff24037bbbfd00679c"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"d140baf6840c6c05cb5484275510383d6e62f657","unresolved":false,"context_lines":[{"line_number":274,"context_line":"    2) For project scoped tokens, the idea is to check to see if the same token"},{"line_number":275,"context_line":"    workflow can be applied to the current subproject:"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        2.1) If the token was obtained via federation workflow, check to see if"},{"line_number":278,"context_line":"        the groups have roles assigned in the current subproject."},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"        2.2) If the token was obtained via trust workflow, check to see if"},{"line_number":281,"context_line":"        there is a trust for the user in the current subproject."},{"line_number":282,"context_line":""},{"line_number":283,"context_line":"        2.3) If the token was obtained via normal workflow, check to see if the"},{"line_number":284,"context_line":"        user has role assignments in the current subproject."},{"line_number":285,"context_line":""},{"line_number":286,"context_line":"        If that\u0027s the case, build credentials based on that and pass it along"},{"line_number":287,"context_line":"        with the current target to the policy enforcement library; otherwise"},{"line_number":288,"context_line":"        raise unauthorized."},{"line_number":289,"context_line":""},{"line_number":290,"context_line":"        2.4) If unauthorized was raised in any of the cases above, try to do as"},{"line_number":291,"context_line":"        for domain scoped tokens, i.e try with existing token and vary only the"}],"source_content_type":"text/x-python","patch_set":25,"id":"9aed3d3a_fc708ede","line":288,"range":{"start_line":277,"start_character":0,"end_line":288,"end_character":27},"in_reply_to":"9aed3d3a_ef511664","updated":"2016-02-27 00:18:38.000000000","message":"i agree with henry, the subset is the safer way to do things. but i\u0027m willing to fix that behaviour as a bug and not hold up the rest of this code.","commit_id":"c21399c742a221ae095106ff24037bbbfd00679c"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"e7d61315cb89895e3f5077cd380f01c9bae6a184","unresolved":false,"context_lines":[{"line_number":297,"context_line":"    specified project."},{"line_number":298,"context_line":""},{"line_number":299,"context_line":"    \"\"\""},{"line_number":300,"context_line":"    def _cascadeprotected(f):"},{"line_number":301,"context_line":"        @functools.wraps(f)"},{"line_number":302,"context_line":"        def wrapper(self, context, **kwargs):"},{"line_number":303,"context_line":"            if \u0027is_admin\u0027 in context and context[\u0027is_admin\u0027]:"},{"line_number":304,"context_line":"                LOG.warning(_LW(\u0027RBAC: Bypassing authorization\u0027))"},{"line_number":305,"context_line":"            else:"},{"line_number":306,"context_line":"                # First check permission on the tree\u0027s root"},{"line_number":307,"context_line":"                root_id \u003d kwargs.get(\u0027project_id\u0027)"},{"line_number":308,"context_line":"                prep_info \u003d {\u0027f_name\u0027: f.__name__, \u0027input_attr\u0027: kwargs}"},{"line_number":309,"context_line":"                self.check_protection(context, prep_info)"},{"line_number":310,"context_line":""},{"line_number":311,"context_line":"                params \u003d context[\u0027query_string\u0027]"},{"line_number":312,"context_line":"                cascade \u003d (\u0027cascade\u0027 in params and"},{"line_number":313,"context_line":"                           self.query_filter_is_true(params[\u0027cascade\u0027]))"},{"line_number":314,"context_line":""},{"line_number":315,"context_line":"                if not cascade:"},{"line_number":316,"context_line":"                    return f(self, context, **kwargs)"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"                # NOTE(samueldmq): In update calls, the controller receives the"},{"line_number":319,"context_line":"                # project dict to update. In that case, update each subproject"},{"line_number":320,"context_line":"                # accordingly to make sure the same info is available at policy"},{"line_number":321,"context_line":"                # enforcement, as it was being done with multiple API calls."},{"line_number":322,"context_line":"                updated_root \u003d kwargs.get(\u0027project\u0027, {})"},{"line_number":323,"context_line":"                updated_root.pop(\u0027id\u0027, None)"},{"line_number":324,"context_line":""},{"line_number":325,"context_line":"                # Now check permission on every project in its subtree"},{"line_number":326,"context_line":"                subtree \u003d self.resource_api.list_projects_in_subtree(root_id)"},{"line_number":327,"context_line":"                user_id \u003d self.get_auth_context(context).get(\u0027user_id\u0027)"},{"line_number":328,"context_line":"                user_domain_id \u003d self.get_auth_context(context).get("},{"line_number":329,"context_line":"                    \u0027user_domain_id\u0027)"},{"line_number":330,"context_line":"                for subproject in subtree:"},{"line_number":331,"context_line":"                    # TODO(samueldmq): Need to think about trusted and"},{"line_number":332,"context_line":"                    # federated authorization"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"                    assignments \u003d self.assignment_api.list_role_assignments("},{"line_number":335,"context_line":"                        user_id\u003duser_id, project_id\u003dsubproject[\u0027id\u0027],"},{"line_number":336,"context_line":"                        effective\u003dTrue, include_names\u003dTrue)"},{"line_number":337,"context_line":"                    if not assignments:"},{"line_number":338,"context_line":"                        msg \u003d _(\u0027Cannot perform cascade operation, because the\u0027"},{"line_number":339,"context_line":"                                \u0027 user %(user_id)s does not have access to the\u0027"},{"line_number":340,"context_line":"                                \u0027 whole subtree of project %(root_id)s.\u0027) % ("},{"line_number":341,"context_line":"                            {\u0027user_id\u0027: user_id, \u0027root_id\u0027: root_id})"},{"line_number":342,"context_line":"                        raise exception.Forbidden(message\u003dmsg)"},{"line_number":343,"context_line":""},{"line_number":344,"context_line":"                    role_names \u003d [a[\u0027role_name\u0027] for a in assignments]"},{"line_number":345,"context_line":""},{"line_number":346,"context_line":"                    creds \u003d {\u0027user_id\u0027: user_id,"},{"line_number":347,"context_line":"                             \u0027user_domain_id\u0027: user_domain_id,"},{"line_number":348,"context_line":"                             \u0027project_id\u0027: subproject[\u0027id\u0027],"},{"line_number":349,"context_line":"                             \u0027project_domain_id\u0027: subproject[\u0027domain_id\u0027],"},{"line_number":350,"context_line":"                             \u0027roles\u0027: role_names}"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"                    subproject.update(updated_root)"},{"line_number":353,"context_line":"                    prep_info[\u0027input_attr\u0027] \u003d {\u0027project_id\u0027: subproject[\u0027id\u0027],"},{"line_number":354,"context_line":"                                               \u0027project\u0027: subproject}"},{"line_number":355,"context_line":"                    self.check_protection(context, prep_info, creds\u003dcreds)"},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"            return f(self, context, **kwargs)"},{"line_number":358,"context_line":"        return wrapper"},{"line_number":359,"context_line":"    return _cascadeprotected"},{"line_number":360,"context_line":""},{"line_number":361,"context_line":""},{"line_number":362,"context_line":"class V2Controller(wsgi.Application):"}],"source_content_type":"text/x-python","patch_set":25,"id":"9aed3d3a_f6ac53ef","line":359,"range":{"start_line":300,"start_character":4,"end_line":359,"end_character":28},"updated":"2016-02-26 12:35:07.000000000","message":"This code needs to be updated to be in accordance with the docstring above. For now, it doesn\u0027t address domain scoped tokens, neither federation or trust workflows.","commit_id":"c21399c742a221ae095106ff24037bbbfd00679c"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"a81e5f1144efbc5e0319376a0db95988e44731af","unresolved":false,"context_lines":[{"line_number":273,"context_line":""},{"line_number":274,"context_line":"    2) For project scoped tokens, as this is designed to work with *inherited"},{"line_number":275,"context_line":"    role assignments*, check to see if the same token workflow can be applied"},{"line_number":276,"context_line":"    to the current subproject and consider the roles which are a *subset* of"},{"line_number":277,"context_line":"    the actual roles on the original project."},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"        2.1) If the token was obtained via federation workflow, check to see if"},{"line_number":280,"context_line":"        the groups have roles assigned in the current subproject."}],"source_content_type":"text/x-python","patch_set":26,"id":"9aed3d3a_02ff9faa","line":277,"range":{"start_line":276,"start_character":53,"end_line":277,"end_character":45},"updated":"2016-02-29 09:58:55.000000000","message":"There are a couple of options even with this:\n\na) We call policy with those roles in the token, but only if you have at least the roles from the token\nb) we call policy with those roles in the token which are ALSO assigned for that user on the subproject\nc) We call policy with the roles the user has on the subproject\n\nI think we rejected c) for now - and the proposal was for b). I think this makes sense for the normal token case. For trust tokens, however, I can imagine doing either a) above (this is how trusts with implies roles works - i.e. you MUST have at least the roles in trust, no partial set of roles), or as the docstring states, we check if you have a specific trust for each subproject. I haven\u0027t quiet worked out what we should do with federation.","commit_id":"7e41428a57e3df41ed7ca76c5e553232be1411fc"}],"keystone/resource/controllers.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"631df4871acef0cc85a96c8ab3a4c6982610843a","unresolved":false,"context_lines":[{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    @controller.protected()"},{"line_number":309,"context_line":"    @validation.validated(schema.project_update, \u0027project\u0027)"},{"line_number":310,"context_line":"    def update_project_cascade(self, context, project_id, project):"},{"line_number":311,"context_line":"        self._require_matching_id(project_id, project)"},{"line_number":312,"context_line":"        self._require_matching_domain_id("},{"line_number":313,"context_line":"            project_id, project, self.resource_api.get_project)"},{"line_number":314,"context_line":"        initiator \u003d notifications._get_request_audit_info(context)"},{"line_number":315,"context_line":"        ref \u003d self.resource_api.update_project(project_id, project,"},{"line_number":316,"context_line":"                                               cascade\u003dTrue,"},{"line_number":317,"context_line":"                                               initiator\u003dinitiator)"},{"line_number":318,"context_line":"        return ProjectV3.wrap_member(context, ref)"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"    @controller.protected()"},{"line_number":321,"context_line":"    def delete_project(self, context, project_id):"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a68dd71_ec43086b","line":318,"range":{"start_line":310,"start_character":4,"end_line":318,"end_character":50},"updated":"2016-01-20 20:13:07.000000000","message":"This seems like a lot of duplicate code with the above update_project method. We should try and consolidate this.","commit_id":"c41298e1666191ebb44794516acef081f1da0a43"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"be89769ba2cfa52a8baac73946ff16acfa1d7c0d","unresolved":false,"context_lines":[{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    @controller.protected()"},{"line_number":309,"context_line":"    @validation.validated(schema.project_update, \u0027project\u0027)"},{"line_number":310,"context_line":"    def update_project_cascade(self, context, project_id, project):"},{"line_number":311,"context_line":"        self._require_matching_id(project_id, project)"},{"line_number":312,"context_line":"        self._require_matching_domain_id("},{"line_number":313,"context_line":"            project_id, project, self.resource_api.get_project)"},{"line_number":314,"context_line":"        initiator \u003d notifications._get_request_audit_info(context)"},{"line_number":315,"context_line":"        ref \u003d self.resource_api.update_project(project_id, project,"},{"line_number":316,"context_line":"                                               cascade\u003dTrue,"},{"line_number":317,"context_line":"                                               initiator\u003dinitiator)"},{"line_number":318,"context_line":"        return ProjectV3.wrap_member(context, ref)"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"    @controller.protected()"},{"line_number":321,"context_line":"    def delete_project(self, context, project_id):"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a5de9d1_a5b40af2","line":318,"range":{"start_line":310,"start_character":4,"end_line":318,"end_character":50},"in_reply_to":"9a68dd71_ec43086b","updated":"2016-01-28 16:35:03.000000000","message":"++\n\nIt\u0027s actually the same code but the cascade\u003dTrue parameter to update_project call","commit_id":"c41298e1666191ebb44794516acef081f1da0a43"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"8ab59ab6f64d8a0cc4e56b0220601327c26a21f0","unresolved":false,"context_lines":[{"line_number":311,"context_line":"                               if proj[\u0027id\u0027] in user_projects_ids]"},{"line_number":312,"context_line":"        if subtree !\u003d user_project_access:"},{"line_number":313,"context_line":"            msg \u003d _(\u0027Cannot perform cascade operation, because the user \u0027"},{"line_number":314,"context_line":"                    \u0027(u_id)%s does not have access in the whole subtree.\u0027)"},{"line_number":315,"context_line":"            raise exception.Forbidden(message\u003dmsg)"},{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    def _get_cascade(self, hints):"}],"source_content_type":"text/x-python","patch_set":9,"id":"7a5de9d1_5de69145","line":314,"range":{"start_line":314,"start_character":27,"end_line":314,"end_character":28},"updated":"2016-02-02 14:30:47.000000000","message":"shouldn\u0027t the \u0027%\u0027 be leading.   %(u_id)s","commit_id":"bc275d872a1c49c7121e19d69418e9c00a788293"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"8ab59ab6f64d8a0cc4e56b0220601327c26a21f0","unresolved":false,"context_lines":[{"line_number":312,"context_line":"        if subtree !\u003d user_project_access:"},{"line_number":313,"context_line":"            msg \u003d _(\u0027Cannot perform cascade operation, because the user \u0027"},{"line_number":314,"context_line":"                    \u0027(u_id)%s does not have access in the whole subtree.\u0027)"},{"line_number":315,"context_line":"            raise exception.Forbidden(message\u003dmsg)"},{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    def _get_cascade(self, hints):"},{"line_number":318,"context_line":"        for hint in hints:"}],"source_content_type":"text/x-python","patch_set":9,"id":"7a5de9d1_dd5601ce","line":315,"range":{"start_line":315,"start_character":49,"end_line":315,"end_character":50},"updated":"2016-02-02 14:30:47.000000000","message":"shouldn\u0027t there u_id here to be placed inside the msg?","commit_id":"bc275d872a1c49c7121e19d69418e9c00a788293"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"f679f7e2e8e987fac46e0810d37f892351426374","unresolved":false,"context_lines":[{"line_number":312,"context_line":"        if subtree !\u003d user_project_access:"},{"line_number":313,"context_line":"            msg \u003d _(\u0027Cannot perform cascade operation, because the user \u0027"},{"line_number":314,"context_line":"                    \u0027(u_id)%s does not have access in the whole subtree.\u0027)"},{"line_number":315,"context_line":"            raise exception.Forbidden(message\u003dmsg)"},{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    def _get_cascade(self, hints):"},{"line_number":318,"context_line":"        for hint in hints:"}],"source_content_type":"text/x-python","patch_set":9,"id":"7a5de9d1_1da019a5","line":315,"range":{"start_line":315,"start_character":49,"end_line":315,"end_character":50},"in_reply_to":"7a5de9d1_dd5601ce","updated":"2016-02-02 14:32:41.000000000","message":"Ops, I forgot it. I\u0027ll send a new patch set.","commit_id":"bc275d872a1c49c7121e19d69418e9c00a788293"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"278527af740d5508c0d9144529264e998fd05c94","unresolved":false,"context_lines":[{"line_number":314,"context_line":"                    \u0027%s does not have access in the whole subtree.\u0027) % user_id"},{"line_number":315,"context_line":"            raise exception.Forbidden(message\u003dmsg)"},{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    def _get_cascade(self, hints):"},{"line_number":318,"context_line":"        for hint in hints:"},{"line_number":319,"context_line":"            if \u0027cascade\u0027 in hint[\u0027name\u0027]:"},{"line_number":320,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":10,"id":"7a5de9d1_e8b9b97a","line":317,"range":{"start_line":317,"start_character":27,"end_line":317,"end_character":32},"updated":"2016-02-02 15:29:09.000000000","message":"shouldn\u0027t this be named \u0027filters\u0027?","commit_id":"205e8ab25d014749c1412ba1c2359b0c8ebb60da"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"a0a41cf08017215d4780e0035bf07b6af19768d4","unresolved":false,"context_lines":[{"line_number":314,"context_line":"                    \u0027%s does not have access in the whole subtree.\u0027) % user_id"},{"line_number":315,"context_line":"            raise exception.Forbidden(message\u003dmsg)"},{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    def _get_cascade(self, hints):"},{"line_number":318,"context_line":"        for hint in hints:"},{"line_number":319,"context_line":"            if \u0027cascade\u0027 in hint[\u0027name\u0027]:"},{"line_number":320,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":10,"id":"7a5de9d1_1186bd13","line":317,"range":{"start_line":317,"start_character":27,"end_line":317,"end_character":32},"in_reply_to":"7a5de9d1_e8b9b97a","updated":"2016-02-02 16:29:54.000000000","message":"Done","commit_id":"205e8ab25d014749c1412ba1c2359b0c8ebb60da"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"278527af740d5508c0d9144529264e998fd05c94","unresolved":false,"context_lines":[{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    def _get_cascade(self, hints):"},{"line_number":318,"context_line":"        for hint in hints:"},{"line_number":319,"context_line":"            if \u0027cascade\u0027 in hint[\u0027name\u0027]:"},{"line_number":320,"context_line":"                return True"},{"line_number":321,"context_line":"        return False"},{"line_number":322,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"7a5de9d1_8994c744","line":319,"range":{"start_line":319,"start_character":25,"end_line":319,"end_character":27},"updated":"2016-02-02 15:29:09.000000000","message":"this should be the equality operator. what if the name was cool_cascade... Also you are filter protecting just \u0027cascade\u0027 not any string that contains \u0027cascade\u0027","commit_id":"205e8ab25d014749c1412ba1c2359b0c8ebb60da"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"a0a41cf08017215d4780e0035bf07b6af19768d4","unresolved":false,"context_lines":[{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    def _get_cascade(self, hints):"},{"line_number":318,"context_line":"        for hint in hints:"},{"line_number":319,"context_line":"            if \u0027cascade\u0027 in hint[\u0027name\u0027]:"},{"line_number":320,"context_line":"                return True"},{"line_number":321,"context_line":"        return False"},{"line_number":322,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"7a5de9d1_f180c1f9","line":319,"range":{"start_line":319,"start_character":25,"end_line":319,"end_character":27},"in_reply_to":"7a5de9d1_8994c744","updated":"2016-02-02 16:29:54.000000000","message":"Done","commit_id":"205e8ab25d014749c1412ba1c2359b0c8ebb60da"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"278527af740d5508c0d9144529264e998fd05c94","unresolved":false,"context_lines":[{"line_number":344,"context_line":"        self._require_matching_domain_id("},{"line_number":345,"context_line":"            project_id, project, self.resource_api.get_project)"},{"line_number":346,"context_line":"        initiator \u003d notifications._get_request_audit_info(context)"},{"line_number":347,"context_line":"        hints \u003d ProjectV3.build_driver_hints(context, filters)"},{"line_number":348,"context_line":"        cascade \u003d self._get_cascade(hints.filters)"},{"line_number":349,"context_line":"        ref \u003d self.resource_api.update_project(project_id, project,"},{"line_number":350,"context_line":"                                               cascade\u003dcascade,"}],"source_content_type":"text/x-python","patch_set":10,"id":"7a5de9d1_23937251","line":347,"range":{"start_line":347,"start_character":61,"end_line":347,"end_character":62},"updated":"2016-02-02 15:29:09.000000000","message":").filters","commit_id":"205e8ab25d014749c1412ba1c2359b0c8ebb60da"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"a0a41cf08017215d4780e0035bf07b6af19768d4","unresolved":false,"context_lines":[{"line_number":344,"context_line":"        self._require_matching_domain_id("},{"line_number":345,"context_line":"            project_id, project, self.resource_api.get_project)"},{"line_number":346,"context_line":"        initiator \u003d notifications._get_request_audit_info(context)"},{"line_number":347,"context_line":"        hints \u003d ProjectV3.build_driver_hints(context, filters)"},{"line_number":348,"context_line":"        cascade \u003d self._get_cascade(hints.filters)"},{"line_number":349,"context_line":"        ref \u003d self.resource_api.update_project(project_id, project,"},{"line_number":350,"context_line":"                                               cascade\u003dcascade,"}],"source_content_type":"text/x-python","patch_set":10,"id":"7a5de9d1_51e195cf","line":347,"range":{"start_line":347,"start_character":61,"end_line":347,"end_character":62},"in_reply_to":"7a5de9d1_23937251","updated":"2016-02-02 16:29:54.000000000","message":"Done","commit_id":"205e8ab25d014749c1412ba1c2359b0c8ebb60da"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"278527af740d5508c0d9144529264e998fd05c94","unresolved":false,"context_lines":[{"line_number":345,"context_line":"            project_id, project, self.resource_api.get_project)"},{"line_number":346,"context_line":"        initiator \u003d notifications._get_request_audit_info(context)"},{"line_number":347,"context_line":"        hints \u003d ProjectV3.build_driver_hints(context, filters)"},{"line_number":348,"context_line":"        cascade \u003d self._get_cascade(hints.filters)"},{"line_number":349,"context_line":"        ref \u003d self.resource_api.update_project(project_id, project,"},{"line_number":350,"context_line":"                                               cascade\u003dcascade,"},{"line_number":351,"context_line":"                                               initiator\u003dinitiator)"}],"source_content_type":"text/x-python","patch_set":10,"id":"7a5de9d1_8394a644","line":348,"updated":"2016-02-02 15:29:09.000000000","message":"maybe some list comprehension could be used instead of _get_cascade()  \n\ncascade \u003d bool([True for hint in hints if hint[\u0027name\u0027] \u003d\u003d \u0027cascade\u0027]) # Also add a comment explaining what its doing","commit_id":"205e8ab25d014749c1412ba1c2359b0c8ebb60da"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"a0a41cf08017215d4780e0035bf07b6af19768d4","unresolved":false,"context_lines":[{"line_number":345,"context_line":"            project_id, project, self.resource_api.get_project)"},{"line_number":346,"context_line":"        initiator \u003d notifications._get_request_audit_info(context)"},{"line_number":347,"context_line":"        hints \u003d ProjectV3.build_driver_hints(context, filters)"},{"line_number":348,"context_line":"        cascade \u003d self._get_cascade(hints.filters)"},{"line_number":349,"context_line":"        ref \u003d self.resource_api.update_project(project_id, project,"},{"line_number":350,"context_line":"                                               cascade\u003dcascade,"},{"line_number":351,"context_line":"                                               initiator\u003dinitiator)"}],"source_content_type":"text/x-python","patch_set":10,"id":"7a5de9d1_91c06d2c","line":348,"in_reply_to":"7a5de9d1_8394a644","updated":"2016-02-02 16:29:54.000000000","message":"Done","commit_id":"205e8ab25d014749c1412ba1c2359b0c8ebb60da"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"11745298f52a5ff47378e233a6da7865adb88cc8","unresolved":false,"context_lines":[{"line_number":341,"context_line":"        hints \u003d ProjectV3.build_driver_hints(context, filters).filters"},{"line_number":342,"context_line":"        # If cascade was passed as a filter in the API request, keystone will"},{"line_number":343,"context_line":"        # recursively enable/disable a project tree"},{"line_number":344,"context_line":"        cascade \u003d  bool([True for hint in hints if hint[\u0027name\u0027] \u003d\u003d \u0027cascade\u0027])"},{"line_number":345,"context_line":"        ref \u003d self.resource_api.update_project(project_id, project,"},{"line_number":346,"context_line":"                                               cascade\u003dcascade,"},{"line_number":347,"context_line":"                                               initiator\u003dinitiator)"}],"source_content_type":"text/x-python","patch_set":11,"id":"5a5ae5dd_56096b2b","line":344,"range":{"start_line":344,"start_character":17,"end_line":344,"end_character":18},"updated":"2016-02-03 21:55:16.000000000","message":"2 spaces","commit_id":"e06142fa6d7cce48f88d32c0720d48182cec5323"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"1d5161f13f3181ee95ae52d7ca7727eac8894c4b","unresolved":false,"context_lines":[{"line_number":341,"context_line":"        hints \u003d ProjectV3.build_driver_hints(context, filters).filters"},{"line_number":342,"context_line":"        # If cascade was passed as a filter in the API request, keystone will"},{"line_number":343,"context_line":"        # recursively enable/disable a project tree"},{"line_number":344,"context_line":"        cascade \u003d  bool([True for hint in hints if hint[\u0027name\u0027] \u003d\u003d \u0027cascade\u0027])"},{"line_number":345,"context_line":"        ref \u003d self.resource_api.update_project(project_id, project,"},{"line_number":346,"context_line":"                                               cascade\u003dcascade,"},{"line_number":347,"context_line":"                                               initiator\u003dinitiator)"}],"source_content_type":"text/x-python","patch_set":11,"id":"5a5ae5dd_979d785b","line":344,"range":{"start_line":344,"start_character":17,"end_line":344,"end_character":18},"in_reply_to":"5a5ae5dd_56096b2b","updated":"2016-02-04 14:16:00.000000000","message":"Done","commit_id":"e06142fa6d7cce48f88d32c0720d48182cec5323"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"c264fbc386314a6b9175625420db8a237dcf3bf8","unresolved":false,"context_lines":[{"line_number":304,"context_line":"        self._expand_project_ref(context, ref)"},{"line_number":305,"context_line":"        return ProjectV3.wrap_member(context, ref)"},{"line_number":306,"context_line":""},{"line_number":307,"context_line":"    def _check_projects_list(self, subtree, user_id):"},{"line_number":308,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user_id)"},{"line_number":309,"context_line":"        user_projects_ids \u003d set([proj[\u0027id\u0027] for proj in user_projects])"},{"line_number":310,"context_line":"        user_project_access \u003d [proj for proj in subtree"}],"source_content_type":"text/x-python","patch_set":12,"id":"3a57f1b5_833e788a","line":307,"updated":"2016-02-11 17:47:39.000000000","message":"I thought this was a little over complicated than it had to be.  I made it a little more efficent here ( http://paste.openstack.org/show/486739 )  in \"example 1\" it is more efficient but harder to read and \"example 2\" is a little easier to read than example 1, but a little less efficient. \n\nbtw you don\u0027t need to choose either i just thought i was over complicating it","commit_id":"c90f1525fc6abce38dff505c1a934d5597443820"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"bae07b6ce122e467075d8c71b8d4d0f63a2211a7","unresolved":false,"context_lines":[{"line_number":304,"context_line":"        self._expand_project_ref(context, ref)"},{"line_number":305,"context_line":"        return ProjectV3.wrap_member(context, ref)"},{"line_number":306,"context_line":""},{"line_number":307,"context_line":"    def _check_projects_list(self, subtree, user_id):"},{"line_number":308,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user_id)"},{"line_number":309,"context_line":"        user_projects_ids \u003d set([proj[\u0027id\u0027] for proj in user_projects])"},{"line_number":310,"context_line":"        user_project_access \u003d [proj for proj in subtree"}],"source_content_type":"text/x-python","patch_set":12,"id":"3a57f1b5_40a38b00","line":307,"in_reply_to":"3a57f1b5_71069f87","updated":"2016-02-11 22:03:25.000000000","message":"yeah i had to pull the code down and manually go though it the list comprehensions are really cool but when there are a couple in a row it starts to get confusing.","commit_id":"c90f1525fc6abce38dff505c1a934d5597443820"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"55b8ae10c945ec1bd3ac3fa34d822e4d1163661a","unresolved":false,"context_lines":[{"line_number":304,"context_line":"        self._expand_project_ref(context, ref)"},{"line_number":305,"context_line":"        return ProjectV3.wrap_member(context, ref)"},{"line_number":306,"context_line":""},{"line_number":307,"context_line":"    def _check_projects_list(self, subtree, user_id):"},{"line_number":308,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user_id)"},{"line_number":309,"context_line":"        user_projects_ids \u003d set([proj[\u0027id\u0027] for proj in user_projects])"},{"line_number":310,"context_line":"        user_project_access \u003d [proj for proj in subtree"}],"source_content_type":"text/x-python","patch_set":12,"id":"3a57f1b5_71069f87","line":307,"in_reply_to":"3a57f1b5_833e788a","updated":"2016-02-11 20:08:00.000000000","message":"Thanks for the suggestions, I\u0027d rather the second option, a code more readable would be better, since we can\u0027t have a huge subtree, so the code will not be so inefficient.","commit_id":"c90f1525fc6abce38dff505c1a934d5597443820"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"c264fbc386314a6b9175625420db8a237dcf3bf8","unresolved":false,"context_lines":[{"line_number":321,"context_line":"        any project on the subtree."},{"line_number":322,"context_line":"        \"\"\""},{"line_number":323,"context_line":"        subtree \u003d []"},{"line_number":324,"context_line":"        if \u0027cascade\u0027 in protection_info[\u0027filter_attr\u0027] and project_id:"},{"line_number":325,"context_line":"            subtree \u003d self.resource_api.list_projects_in_subtree(project_id)"},{"line_number":326,"context_line":"            user_id \u003d self.get_auth_context(context).get(\u0027user_id\u0027)"},{"line_number":327,"context_line":"            self._check_projects_list(subtree, user_id)"}],"source_content_type":"text/x-python","patch_set":12,"id":"3a57f1b5_7cef6b87","line":324,"range":{"start_line":324,"start_character":59,"end_line":324,"end_character":69},"updated":"2016-02-11 17:47:39.000000000","message":"is this here to check if they passed in a null project_id?","commit_id":"c90f1525fc6abce38dff505c1a934d5597443820"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"55b8ae10c945ec1bd3ac3fa34d822e4d1163661a","unresolved":false,"context_lines":[{"line_number":321,"context_line":"        any project on the subtree."},{"line_number":322,"context_line":"        \"\"\""},{"line_number":323,"context_line":"        subtree \u003d []"},{"line_number":324,"context_line":"        if \u0027cascade\u0027 in protection_info[\u0027filter_attr\u0027] and project_id:"},{"line_number":325,"context_line":"            subtree \u003d self.resource_api.list_projects_in_subtree(project_id)"},{"line_number":326,"context_line":"            user_id \u003d self.get_auth_context(context).get(\u0027user_id\u0027)"},{"line_number":327,"context_line":"            self._check_projects_list(subtree, user_id)"}],"source_content_type":"text/x-python","patch_set":12,"id":"3a57f1b5_b14737bb","line":324,"range":{"start_line":324,"start_character":59,"end_line":324,"end_character":69},"in_reply_to":"3a57f1b5_7cef6b87","updated":"2016-02-11 20:08:00.000000000","message":"yes. Thinking a little more about it, maybe we don\u0027t need this check...","commit_id":"c90f1525fc6abce38dff505c1a934d5597443820"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"c264fbc386314a6b9175625420db8a237dcf3bf8","unresolved":false,"context_lines":[{"line_number":326,"context_line":"            user_id \u003d self.get_auth_context(context).get(\u0027user_id\u0027)"},{"line_number":327,"context_line":"            self._check_projects_list(subtree, user_id)"},{"line_number":328,"context_line":""},{"line_number":329,"context_line":"        for project in subtree:"},{"line_number":330,"context_line":"            self.check_protection(context, protection_info, project)"},{"line_number":331,"context_line":""},{"line_number":332,"context_line":"    @controller.filterprotected(\u0027cascade\u0027,"},{"line_number":333,"context_line":"                                callback\u003d_check_tree_protection)"}],"source_content_type":"text/x-python","patch_set":12,"id":"3a57f1b5_bce88311","line":330,"range":{"start_line":329,"start_character":7,"end_line":330,"end_character":68},"updated":"2016-02-11 17:47:39.000000000","message":"can this be in the above \u0027if\u0027 block? If so you can removed the declaration of \u0027subtree\u0027","commit_id":"c90f1525fc6abce38dff505c1a934d5597443820"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"3cad09a596760ae7d066ae9374b827427b932350","unresolved":false,"context_lines":[{"line_number":304,"context_line":"        self._expand_project_ref(context, ref)"},{"line_number":305,"context_line":"        return ProjectV3.wrap_member(context, ref)"},{"line_number":306,"context_line":""},{"line_number":307,"context_line":"    def _check_projects_list(self, subtree, user_id):"},{"line_number":308,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user_id)"},{"line_number":309,"context_line":"        for project in subtree:"},{"line_number":310,"context_line":"            if project not in user_projects:"}],"source_content_type":"text/x-python","patch_set":17,"id":"dae33548_6d00b302","line":307,"range":{"start_line":307,"start_character":8,"end_line":307,"end_character":28},"updated":"2016-02-18 19:08:10.000000000","message":"This method name doesn\u0027t look suggestive to me\n\nWhat about: _check_user_has_access_to_subtree","commit_id":"3aa54b2e582f2b414d6cc683b17ed695e7126f5b"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"f68cf79b3dafe5c3b1e1580c19787d3b6fb50aef","unresolved":false,"context_lines":[{"line_number":304,"context_line":"        self._expand_project_ref(context, ref)"},{"line_number":305,"context_line":"        return ProjectV3.wrap_member(context, ref)"},{"line_number":306,"context_line":""},{"line_number":307,"context_line":"    def _check_projects_list(self, subtree, user_id):"},{"line_number":308,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user_id)"},{"line_number":309,"context_line":"        for project in subtree:"},{"line_number":310,"context_line":"            if project not in user_projects:"}],"source_content_type":"text/x-python","patch_set":17,"id":"dae33548_0882b5c7","line":307,"range":{"start_line":307,"start_character":8,"end_line":307,"end_character":28},"in_reply_to":"dae33548_6d00b302","updated":"2016-02-18 20:05:00.000000000","message":"Done","commit_id":"3aa54b2e582f2b414d6cc683b17ed695e7126f5b"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"3cad09a596760ae7d066ae9374b827427b932350","unresolved":false,"context_lines":[{"line_number":310,"context_line":"            if project not in user_projects:"},{"line_number":311,"context_line":"                msg \u003d _(\u0027Cannot perform cascade operation, because the user \u0027"},{"line_number":312,"context_line":"                        \u0027%s does not have access in the whole \u0027"},{"line_number":313,"context_line":"                        \u0027subtree.\u0027) % user_id"},{"line_number":314,"context_line":"                raise exception.Forbidden(message\u003dmsg)"},{"line_number":315,"context_line":""},{"line_number":316,"context_line":"    def _check_tree_protection(self, context, protection_info,"}],"source_content_type":"text/x-python","patch_set":17,"id":"dae33548_2d234bbe","line":313,"updated":"2016-02-18 19:08:10.000000000","message":"\" of project %s\" could be a good addition of valuable info","commit_id":"3aa54b2e582f2b414d6cc683b17ed695e7126f5b"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"f68cf79b3dafe5c3b1e1580c19787d3b6fb50aef","unresolved":false,"context_lines":[{"line_number":310,"context_line":"            if project not in user_projects:"},{"line_number":311,"context_line":"                msg \u003d _(\u0027Cannot perform cascade operation, because the user \u0027"},{"line_number":312,"context_line":"                        \u0027%s does not have access in the whole \u0027"},{"line_number":313,"context_line":"                        \u0027subtree.\u0027) % user_id"},{"line_number":314,"context_line":"                raise exception.Forbidden(message\u003dmsg)"},{"line_number":315,"context_line":""},{"line_number":316,"context_line":"    def _check_tree_protection(self, context, protection_info,"}],"source_content_type":"text/x-python","patch_set":17,"id":"dae33548_48703d0b","line":313,"in_reply_to":"dae33548_2d234bbe","updated":"2016-02-18 20:05:00.000000000","message":"Done","commit_id":"3aa54b2e582f2b414d6cc683b17ed695e7126f5b"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"3cad09a596760ae7d066ae9374b827427b932350","unresolved":false,"context_lines":[{"line_number":317,"context_line":"                               project_id, project):"},{"line_number":318,"context_line":"        \"\"\"Check protection for update project for tree API."},{"line_number":319,"context_line":"        The policy rule might want to inspect if the user have access for"},{"line_number":320,"context_line":"        any project on the subtree."},{"line_number":321,"context_line":"        \"\"\""},{"line_number":322,"context_line":"        if \u0027cascade\u0027 in protection_info[\u0027filter_attr\u0027] and project_id:"},{"line_number":323,"context_line":"            subtree \u003d self.resource_api.list_projects_in_subtree(project_id)"}],"source_content_type":"text/x-python","patch_set":17,"id":"dae33548_a82bc980","line":320,"range":{"start_line":320,"start_character":8,"end_line":320,"end_character":11},"updated":"2016-02-18 19:08:10.000000000","message":"every ?","commit_id":"3aa54b2e582f2b414d6cc683b17ed695e7126f5b"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"3cad09a596760ae7d066ae9374b827427b932350","unresolved":false,"context_lines":[{"line_number":317,"context_line":"                               project_id, project):"},{"line_number":318,"context_line":"        \"\"\"Check protection for update project for tree API."},{"line_number":319,"context_line":"        The policy rule might want to inspect if the user have access for"},{"line_number":320,"context_line":"        any project on the subtree."},{"line_number":321,"context_line":"        \"\"\""},{"line_number":322,"context_line":"        if \u0027cascade\u0027 in protection_info[\u0027filter_attr\u0027] and project_id:"},{"line_number":323,"context_line":"            subtree \u003d self.resource_api.list_projects_in_subtree(project_id)"}],"source_content_type":"text/x-python","patch_set":17,"id":"dae33548_e821519f","line":320,"range":{"start_line":320,"start_character":20,"end_line":320,"end_character":22},"updated":"2016-02-18 19:08:10.000000000","message":"in","commit_id":"3aa54b2e582f2b414d6cc683b17ed695e7126f5b"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"f68cf79b3dafe5c3b1e1580c19787d3b6fb50aef","unresolved":false,"context_lines":[{"line_number":317,"context_line":"                               project_id, project):"},{"line_number":318,"context_line":"        \"\"\"Check protection for update project for tree API."},{"line_number":319,"context_line":"        The policy rule might want to inspect if the user have access for"},{"line_number":320,"context_line":"        any project on the subtree."},{"line_number":321,"context_line":"        \"\"\""},{"line_number":322,"context_line":"        if \u0027cascade\u0027 in protection_info[\u0027filter_attr\u0027] and project_id:"},{"line_number":323,"context_line":"            subtree \u003d self.resource_api.list_projects_in_subtree(project_id)"}],"source_content_type":"text/x-python","patch_set":17,"id":"dae33548_286b391f","line":320,"range":{"start_line":320,"start_character":20,"end_line":320,"end_character":22},"in_reply_to":"dae33548_e821519f","updated":"2016-02-18 20:05:00.000000000","message":"Done","commit_id":"3aa54b2e582f2b414d6cc683b17ed695e7126f5b"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"3cad09a596760ae7d066ae9374b827427b932350","unresolved":false,"context_lines":[{"line_number":335,"context_line":"        self._require_matching_domain_id("},{"line_number":336,"context_line":"            project_id, project, self.resource_api.get_project)"},{"line_number":337,"context_line":"        initiator \u003d notifications._get_request_audit_info(context)"},{"line_number":338,"context_line":"        hints \u003d ProjectV3.build_driver_hints(context, filters).filters"},{"line_number":339,"context_line":"        # If cascade was passed as a filter in the API request, keystone will"},{"line_number":340,"context_line":"        # recursively enable/disable a project tree"},{"line_number":341,"context_line":"        cascade \u003d bool([True for hint in hints if hint[\u0027name\u0027] \u003d\u003d \u0027cascade\u0027])"}],"source_content_type":"text/x-python","patch_set":17,"id":"dae33548_a852a910","line":338,"range":{"start_line":338,"start_character":62,"end_line":338,"end_character":70},"updated":"2016-02-18 19:08:10.000000000","message":"so the var should be called filters, not hints","commit_id":"3aa54b2e582f2b414d6cc683b17ed695e7126f5b"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"f68cf79b3dafe5c3b1e1580c19787d3b6fb50aef","unresolved":false,"context_lines":[{"line_number":335,"context_line":"        self._require_matching_domain_id("},{"line_number":336,"context_line":"            project_id, project, self.resource_api.get_project)"},{"line_number":337,"context_line":"        initiator \u003d notifications._get_request_audit_info(context)"},{"line_number":338,"context_line":"        hints \u003d ProjectV3.build_driver_hints(context, filters).filters"},{"line_number":339,"context_line":"        # If cascade was passed as a filter in the API request, keystone will"},{"line_number":340,"context_line":"        # recursively enable/disable a project tree"},{"line_number":341,"context_line":"        cascade \u003d bool([True for hint in hints if hint[\u0027name\u0027] \u003d\u003d \u0027cascade\u0027])"}],"source_content_type":"text/x-python","patch_set":17,"id":"dae33548_a89aa911","line":338,"range":{"start_line":338,"start_character":62,"end_line":338,"end_character":70},"in_reply_to":"dae33548_a852a910","updated":"2016-02-18 20:05:00.000000000","message":"Done","commit_id":"3aa54b2e582f2b414d6cc683b17ed695e7126f5b"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"3cad09a596760ae7d066ae9374b827427b932350","unresolved":false,"context_lines":[{"line_number":338,"context_line":"        hints \u003d ProjectV3.build_driver_hints(context, filters).filters"},{"line_number":339,"context_line":"        # If cascade was passed as a filter in the API request, keystone will"},{"line_number":340,"context_line":"        # recursively enable/disable a project tree"},{"line_number":341,"context_line":"        cascade \u003d bool([True for hint in hints if hint[\u0027name\u0027] \u003d\u003d \u0027cascade\u0027])"},{"line_number":342,"context_line":"        ref \u003d self.resource_api.update_project(project_id, project,"},{"line_number":343,"context_line":"                                               cascade\u003dcascade,"},{"line_number":344,"context_line":"                                               initiator\u003dinitiator)"}],"source_content_type":"text/x-python","patch_set":17,"id":"dae33548_e8a6710d","line":341,"range":{"start_line":341,"start_character":18,"end_line":341,"end_character":77},"updated":"2016-02-18 19:08:10.000000000","message":"any([hint[\u0027name\u0027] \u003d\u003d \u0027cascade\u0027] for hint in hints]\n\nlooks cleaner ?","commit_id":"3aa54b2e582f2b414d6cc683b17ed695e7126f5b"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"f68cf79b3dafe5c3b1e1580c19787d3b6fb50aef","unresolved":false,"context_lines":[{"line_number":338,"context_line":"        hints \u003d ProjectV3.build_driver_hints(context, filters).filters"},{"line_number":339,"context_line":"        # If cascade was passed as a filter in the API request, keystone will"},{"line_number":340,"context_line":"        # recursively enable/disable a project tree"},{"line_number":341,"context_line":"        cascade \u003d bool([True for hint in hints if hint[\u0027name\u0027] \u003d\u003d \u0027cascade\u0027])"},{"line_number":342,"context_line":"        ref \u003d self.resource_api.update_project(project_id, project,"},{"line_number":343,"context_line":"                                               cascade\u003dcascade,"},{"line_number":344,"context_line":"                                               initiator\u003dinitiator)"}],"source_content_type":"text/x-python","patch_set":17,"id":"dae33548_e8a03144","line":341,"range":{"start_line":341,"start_character":18,"end_line":341,"end_character":77},"in_reply_to":"dae33548_e8a6710d","updated":"2016-02-18 20:05:00.000000000","message":"Done","commit_id":"3aa54b2e582f2b414d6cc683b17ed695e7126f5b"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"bfff21b2a1c60c14e437aaf804415244e4b4079f","unresolved":false,"context_lines":[{"line_number":317,"context_line":"    def _check_tree_protection(self, context, protection_info,"},{"line_number":318,"context_line":"                               project_id, project):"},{"line_number":319,"context_line":"        \"\"\"Check protection for update project for tree API."},{"line_number":320,"context_line":"        The policy rule might want to inspect if the user have access for"},{"line_number":321,"context_line":"        every project in the subtree."},{"line_number":322,"context_line":"        \"\"\""},{"line_number":323,"context_line":"        if \u0027cascade\u0027 in protection_info[\u0027filter_attr\u0027] and project_id:"}],"source_content_type":"text/x-python","patch_set":18,"id":"bae84128_4a094431","line":320,"updated":"2016-02-19 11:36:29.000000000","message":"(nit) add a new blank line here","commit_id":"3f7a01b9e13e3ed49d61d15d7a998cf662413092"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"bfff21b2a1c60c14e437aaf804415244e4b4079f","unresolved":false,"context_lines":[{"line_number":341,"context_line":"        filters \u003d ProjectV3.build_driver_hints(context, filters).filters"},{"line_number":342,"context_line":"        # If cascade was passed as a filter in the API request, keystone will"},{"line_number":343,"context_line":"        # recursively enable/disable a project tree"},{"line_number":344,"context_line":"        cascade \u003d any(fil[\u0027name\u0027] \u003d\u003d \u0027cascade\u0027 for fil in filters)"},{"line_number":345,"context_line":"        ref \u003d self.resource_api.update_project(project_id, project,"},{"line_number":346,"context_line":"                                               cascade\u003dcascade,"},{"line_number":347,"context_line":"                                               initiator\u003dinitiator)"}],"source_content_type":"text/x-python","patch_set":18,"id":"bae84128_2ae7a0e5","line":344,"range":{"start_line":344,"start_character":51,"end_line":344,"end_character":54},"updated":"2016-02-19 11:36:29.000000000","message":"fil looks very weird, what about just \u0027f\u0027 ?","commit_id":"3f7a01b9e13e3ed49d61d15d7a998cf662413092"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"0fc2e72a25337ba8b567f0fb66ac44c6fecd1bff","unresolved":false,"context_lines":[{"line_number":255,"context_line":"        return ProjectV3.wrap_collection(context, refs, hints\u003dhints)"},{"line_number":256,"context_line":""},{"line_number":257,"context_line":"    def _expand_project_ref(self, context, ref):"},{"line_number":258,"context_line":"        params \u003d context[\u0027query_string\u0027]"},{"line_number":259,"context_line":""},{"line_number":260,"context_line":"        parents_as_list \u003d \u0027parents_as_list\u0027 in params and ("},{"line_number":261,"context_line":"            self.query_filter_is_true(params[\u0027parents_as_list\u0027]))"},{"line_number":262,"context_line":"        parents_as_ids \u003d \u0027parents_as_ids\u0027 in params and ("},{"line_number":263,"context_line":"            self.query_filter_is_true(params[\u0027parents_as_ids\u0027]))"},{"line_number":264,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"bae84128_bda5b8b6","line":261,"range":{"start_line":258,"start_character":0,"end_line":261,"end_character":65},"updated":"2016-02-19 12:06:26.000000000","message":"I\u0027d prefer it to be done like this, rather than build driver_hints that IS NOT used as driver hints","commit_id":"4d215f7f7541938b8b84f749382544f9ce1cdf1a"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"0fc2e72a25337ba8b567f0fb66ac44c6fecd1bff","unresolved":false,"context_lines":[{"line_number":339,"context_line":"        self._require_matching_domain_id("},{"line_number":340,"context_line":"            project_id, project, self.resource_api.get_project)"},{"line_number":341,"context_line":"        initiator \u003d notifications._get_request_audit_info(context)"},{"line_number":342,"context_line":"        filters \u003d ProjectV3.build_driver_hints(context, filters).filters"},{"line_number":343,"context_line":"        # If cascade was passed as a filter in the API request, keystone will"},{"line_number":344,"context_line":"        # recursively enable/disable a project tree"},{"line_number":345,"context_line":"        cascade \u003d any(f[\u0027name\u0027] \u003d\u003d \u0027cascade\u0027 for f in filters)"}],"source_content_type":"text/x-python","patch_set":19,"id":"bae84128_7d73304e","line":342,"range":{"start_line":342,"start_character":0,"end_line":342,"end_character":72},"updated":"2016-02-19 12:06:26.000000000","message":"See comment in L258","commit_id":"4d215f7f7541938b8b84f749382544f9ce1cdf1a"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"1e8b739a15d67911aa7a9088f2a475d46ffb9314","unresolved":false,"context_lines":[{"line_number":309,"context_line":"        for project in subtree:"},{"line_number":310,"context_line":"            if project not in user_projects:"},{"line_number":311,"context_line":"                msg \u003d _(\u0027Cannot perform cascade operation, because the user \u0027"},{"line_number":312,"context_line":"                        \u0027%(u_id)s does not have access in the whole \u0027"},{"line_number":313,"context_line":"                        \u0027subtree of project %(p_id)s.\u0027) % {\u0027u_id\u0027: user_id,"},{"line_number":314,"context_line":"                                                           \u0027p_id\u0027: project_id}"},{"line_number":315,"context_line":"                raise exception.Forbidden(message\u003dmsg)"},{"line_number":316,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_0811d952","line":313,"range":{"start_line":312,"start_character":55,"end_line":313,"end_character":35},"updated":"2016-02-20 06:24:20.000000000","message":"you can replace all this with \"to\" since, the user not have access to a leaf project","commit_id":"6ce0c554fc11e64c35d0c60c894cbd527e82a164"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"1e8b739a15d67911aa7a9088f2a475d46ffb9314","unresolved":false,"context_lines":[{"line_number":314,"context_line":"                                                           \u0027p_id\u0027: project_id}"},{"line_number":315,"context_line":"                raise exception.Forbidden(message\u003dmsg)"},{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    def _check_tree_protection(self, context, protection_info,"},{"line_number":318,"context_line":"                               project_id, project):"},{"line_number":319,"context_line":"        \"\"\"Check protection for update project for tree API."},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"        The policy rule might want to inspect if the user have access for"},{"line_number":322,"context_line":"        every project in the subtree."},{"line_number":323,"context_line":"        \"\"\""},{"line_number":324,"context_line":"        if \u0027cascade\u0027 in protection_info[\u0027filter_attr\u0027] and project_id:"},{"line_number":325,"context_line":"            subtree \u003d self.resource_api.list_projects_in_subtree(project_id)"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_0838b9d2","line":322,"range":{"start_line":317,"start_character":0,"end_line":322,"end_character":37},"updated":"2016-02-20 06:24:20.000000000","message":"I had to keep looking back at https://github.com/openstack/keystone/blob/master/keystone/common/controller.py to figure this out. it may be beneficial for other reviewers and authors if you added argument descriptions into the docstring. specifically for what \"protection_info\" is supposed to look like.","commit_id":"6ce0c554fc11e64c35d0c60c894cbd527e82a164"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"b9f146bf330708bfa2ba3d38fedd52623ca835bc","unresolved":false,"context_lines":[{"line_number":314,"context_line":"                                                           \u0027p_id\u0027: project_id}"},{"line_number":315,"context_line":"                raise exception.Forbidden(message\u003dmsg)"},{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    def _check_tree_protection(self, context, protection_info,"},{"line_number":318,"context_line":"                               project_id, project):"},{"line_number":319,"context_line":"        \"\"\"Check protection for update project for tree API."},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"        The policy rule might want to inspect if the user have access for"},{"line_number":322,"context_line":"        every project in the subtree."},{"line_number":323,"context_line":"        \"\"\""},{"line_number":324,"context_line":"        if \u0027cascade\u0027 in protection_info[\u0027filter_attr\u0027] and project_id:"},{"line_number":325,"context_line":"            subtree \u003d self.resource_api.list_projects_in_subtree(project_id)"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_3f1b2a1d","line":322,"range":{"start_line":317,"start_character":0,"end_line":322,"end_character":37},"in_reply_to":"bae84128_0838b9d2","updated":"2016-02-20 14:35:16.000000000","message":"Agreed, I\u0027ll fix this in a follow patch (or a patch set here if it\u0027s necessary)","commit_id":"6ce0c554fc11e64c35d0c60c894cbd527e82a164"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"83c3cad53c0407bd0fe1a593699f465a03afc085","unresolved":false,"context_lines":[{"line_number":330,"context_line":"            for project in subtree:"},{"line_number":331,"context_line":"                self.check_protection(context, protection_info, project)"},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"    @controller.filterprotected(\u0027cascade\u0027,"},{"line_number":334,"context_line":"                                callback\u003d_check_tree_protection)"},{"line_number":335,"context_line":"    @controller.protected()"},{"line_number":336,"context_line":"    @validation.validated(schema.project_update, \u0027project\u0027)"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_4e63e6dc","line":333,"range":{"start_line":333,"start_character":16,"end_line":333,"end_character":31},"updated":"2016-02-20 11:33:11.000000000","message":"I\u0027m not sure I understand why we are using filterprotected here.....","commit_id":"6ce0c554fc11e64c35d0c60c894cbd527e82a164"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"7b52b3d6c29a20154a87b2103a157a35ce27e697","unresolved":false,"context_lines":[{"line_number":330,"context_line":"            for project in subtree:"},{"line_number":331,"context_line":"                self.check_protection(context, protection_info, project)"},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"    @controller.filterprotected(\u0027cascade\u0027,"},{"line_number":334,"context_line":"                                callback\u003d_check_tree_protection)"},{"line_number":335,"context_line":"    @controller.protected()"},{"line_number":336,"context_line":"    @validation.validated(schema.project_update, \u0027project\u0027)"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_ae46f220","line":333,"range":{"start_line":333,"start_character":16,"end_line":333,"end_character":31},"in_reply_to":"bae84128_4e63e6dc","updated":"2016-02-20 11:41:26.000000000","message":"Because the call is PATCH /projects/{id}?cascade\n\nIs there a better way to do it in our current code ?","commit_id":"6ce0c554fc11e64c35d0c60c894cbd527e82a164"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"b9f146bf330708bfa2ba3d38fedd52623ca835bc","unresolved":false,"context_lines":[{"line_number":330,"context_line":"            for project in subtree:"},{"line_number":331,"context_line":"                self.check_protection(context, protection_info, project)"},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"    @controller.filterprotected(\u0027cascade\u0027,"},{"line_number":334,"context_line":"                                callback\u003d_check_tree_protection)"},{"line_number":335,"context_line":"    @controller.protected()"},{"line_number":336,"context_line":"    @validation.validated(schema.project_update, \u0027project\u0027)"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_dff67ed6","line":333,"range":{"start_line":333,"start_character":16,"end_line":333,"end_character":31},"in_reply_to":"bae84128_ae46f220","updated":"2016-02-20 14:35:16.000000000","message":"Samuel is right, I don\u0027t know a better way to dealing with query string without use filterprotected.","commit_id":"6ce0c554fc11e64c35d0c60c894cbd527e82a164"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"86c895bdac1aa43719208fff89cbd2b8752012bf","unresolved":false,"context_lines":[{"line_number":330,"context_line":"            for project in subtree:"},{"line_number":331,"context_line":"                self.check_protection(context, protection_info, project)"},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"    @controller.filterprotected(\u0027cascade\u0027,"},{"line_number":334,"context_line":"                                callback\u003d_check_tree_protection)"},{"line_number":335,"context_line":"    @controller.protected()"},{"line_number":336,"context_line":"    @validation.validated(schema.project_update, \u0027project\u0027)"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_4eebd4b0","line":333,"range":{"start_line":333,"start_character":16,"end_line":333,"end_character":31},"in_reply_to":"bae84128_dff67ed6","updated":"2016-02-21 11:33:15.000000000","message":"So I\u0027m not quite clear exactly what we are trying to achieve. \n\n1) First, I am surprised (not saying it\u0027s wrong, just surprised) that we are going for the \"must have a role on every project in the tree\" in additional to whatever policy rule might be on the update api itself. In the past, we have always given tree operations a separate policy endpoint, so that they could be separately controlled.\n\n2) If what we want to do is just have different endpoint for update and update/cascade, then there are other examples of doing that using a wrapper method that then calls two separate methods (e.g. update and update_cascade), each of which are @controller.protected()\n\nMaybe you\u0027ve already thought through all of this....","commit_id":"6ce0c554fc11e64c35d0c60c894cbd527e82a164"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"1e8b739a15d67911aa7a9088f2a475d46ffb9314","unresolved":false,"context_lines":[{"line_number":334,"context_line":"                                callback\u003d_check_tree_protection)"},{"line_number":335,"context_line":"    @controller.protected()"},{"line_number":336,"context_line":"    @validation.validated(schema.project_update, \u0027project\u0027)"},{"line_number":337,"context_line":"    def update_project(self, context, filters, project_id, project):"},{"line_number":338,"context_line":"        self._require_matching_id(project_id, project)"},{"line_number":339,"context_line":"        self._require_matching_domain_id("},{"line_number":340,"context_line":"            project_id, project, self.resource_api.get_project)"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_3d2dfda7","line":337,"range":{"start_line":337,"start_character":38,"end_line":337,"end_character":45},"updated":"2016-02-20 06:24:20.000000000","message":"it always confuses me that this is only needed for the filterprotected call","commit_id":"6ce0c554fc11e64c35d0c60c894cbd527e82a164"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"b9f146bf330708bfa2ba3d38fedd52623ca835bc","unresolved":false,"context_lines":[{"line_number":334,"context_line":"                                callback\u003d_check_tree_protection)"},{"line_number":335,"context_line":"    @controller.protected()"},{"line_number":336,"context_line":"    @validation.validated(schema.project_update, \u0027project\u0027)"},{"line_number":337,"context_line":"    def update_project(self, context, filters, project_id, project):"},{"line_number":338,"context_line":"        self._require_matching_id(project_id, project)"},{"line_number":339,"context_line":"        self._require_matching_domain_id("},{"line_number":340,"context_line":"            project_id, project, self.resource_api.get_project)"}],"source_content_type":"text/x-python","patch_set":21,"id":"bae84128_1f6aa680","line":337,"range":{"start_line":337,"start_character":38,"end_line":337,"end_character":45},"in_reply_to":"bae84128_3d2dfda7","updated":"2016-02-20 14:35:16.000000000","message":"you\u0027re right... Do you know a better way to handle with this case without using filteprotected?","commit_id":"6ce0c554fc11e64c35d0c60c894cbd527e82a164"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"2d6e185efb6c6362dda4f50053219559215525f3","unresolved":false,"context_lines":[{"line_number":308,"context_line":"        self._expand_project_ref(context, ref)"},{"line_number":309,"context_line":"        return ProjectV3.wrap_member(context, ref)"},{"line_number":310,"context_line":""},{"line_number":311,"context_line":"    def _check_user_has_access_to_subtree(self, project_id, subtree, user_id):"},{"line_number":312,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user_id)"},{"line_number":313,"context_line":"        for project in subtree:"},{"line_number":314,"context_line":"            if project not in user_projects:"},{"line_number":315,"context_line":"                msg \u003d _(\u0027Cannot perform cascade operation, because the user \u0027"},{"line_number":316,"context_line":"                        \u0027%(u_id)s does not have access in the whole \u0027"},{"line_number":317,"context_line":"                        \u0027subtree of project %(p_id)s.\u0027) % {\u0027u_id\u0027: user_id,"},{"line_number":318,"context_line":"                                                           \u0027p_id\u0027: project_id}"},{"line_number":319,"context_line":"                raise exception.Forbidden(message\u003dmsg)"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def _check_tree_protection(self, context, protection_info,"},{"line_number":322,"context_line":"                               project_id, project):"}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_b3ef0b86","line":319,"range":{"start_line":311,"start_character":0,"end_line":319,"end_character":54},"updated":"2016-02-23 13:37:37.000000000","message":"I remain skeptical of this additional step - other than failing faster, I think it doesn\u0027t add anything and restricts the types of policy that might be written","commit_id":"ba38a71f6e860d84f4102f39a489e64a21d0b5b6"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"5814d962cbefba24f6c382f89fd247b5dc000499","unresolved":false,"context_lines":[{"line_number":308,"context_line":"        self._expand_project_ref(context, ref)"},{"line_number":309,"context_line":"        return ProjectV3.wrap_member(context, ref)"},{"line_number":310,"context_line":""},{"line_number":311,"context_line":"    def _check_user_has_access_to_subtree(self, project_id, subtree, user_id):"},{"line_number":312,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user_id)"},{"line_number":313,"context_line":"        for project in subtree:"},{"line_number":314,"context_line":"            if project not in user_projects:"},{"line_number":315,"context_line":"                msg \u003d _(\u0027Cannot perform cascade operation, because the user \u0027"},{"line_number":316,"context_line":"                        \u0027%(u_id)s does not have access in the whole \u0027"},{"line_number":317,"context_line":"                        \u0027subtree of project %(p_id)s.\u0027) % {\u0027u_id\u0027: user_id,"},{"line_number":318,"context_line":"                                                           \u0027p_id\u0027: project_id}"},{"line_number":319,"context_line":"                raise exception.Forbidden(message\u003dmsg)"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def _check_tree_protection(self, context, protection_info,"},{"line_number":322,"context_line":"                               project_id, project):"}],"source_content_type":"text/x-python","patch_set":22,"id":"bae84128_f39cf30f","line":319,"range":{"start_line":311,"start_character":0,"end_line":319,"end_character":54},"in_reply_to":"bae84128_b3ef0b86","updated":"2016-02-23 13:38:43.000000000","message":"We can remove this step.","commit_id":"ba38a71f6e860d84f4102f39a489e64a21d0b5b6"}],"keystone/resource/routers.py":[{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"d870916f5ea3f2124da09456a58882205985180c","unresolved":false,"context_lines":[{"line_number":93,"context_line":"            router.Router(controllers.ProjectV3(),"},{"line_number":94,"context_line":"                          \u0027projects\u0027, \u0027project\u0027,"},{"line_number":95,"context_line":"                          resource_descriptions\u003dself.v3_resources))"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        self._add_resource("},{"line_number":98,"context_line":"            mapper, project_controller,"},{"line_number":99,"context_line":"            path\u003d\u0027/projects/{project_id}/cascade\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"7a740942_ffb980ed","line":96,"updated":"2015-12-03 18:19:16.000000000","message":"Is that the right way to handle with new API calls? I think that are out of the pattern. I don\u0027t know if this is wrong, but it\u0027s odd don\u0027t see other project API routers here.\n\nI suggest ask for some core opinion on it.","commit_id":"12c2deae957987483793c2991f5976b3fc2447bc"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"197ff8efdd6d25e402579060ebc1cb5145346c7f","unresolved":false,"context_lines":[{"line_number":93,"context_line":"            router.Router(controllers.ProjectV3(),"},{"line_number":94,"context_line":"                          \u0027projects\u0027, \u0027project\u0027,"},{"line_number":95,"context_line":"                          resource_descriptions\u003dself.v3_resources))"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        self._add_resource("},{"line_number":98,"context_line":"            mapper, project_controller,"},{"line_number":99,"context_line":"            path\u003d\u0027/projects/{project_id}/cascade\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"7a740942_1a09fa95","line":96,"in_reply_to":"7a740942_7add9e6f","updated":"2015-12-03 18:44:47.000000000","message":"got it. Thanks!","commit_id":"12c2deae957987483793c2991f5976b3fc2447bc"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"270a8bed49ffb9595079eee20c29f394655d778b","unresolved":false,"context_lines":[{"line_number":93,"context_line":"            router.Router(controllers.ProjectV3(),"},{"line_number":94,"context_line":"                          \u0027projects\u0027, \u0027project\u0027,"},{"line_number":95,"context_line":"                          resource_descriptions\u003dself.v3_resources))"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        self._add_resource("},{"line_number":98,"context_line":"            mapper, project_controller,"},{"line_number":99,"context_line":"            path\u003d\u0027/projects/{project_id}/cascade\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"7a740942_7add9e6f","line":96,"in_reply_to":"7a740942_ffb980ed","updated":"2015-12-03 18:37:45.000000000","message":"this is the right way to add one single route. The call above (92-95) adds the CRUD basic routes for the project object. And when we need extra ones, we add them separately. Example: https://review.openstack.org/#/c/158752/","commit_id":"12c2deae957987483793c2991f5976b3fc2447bc"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"be89769ba2cfa52a8baac73946ff16acfa1d7c0d","unresolved":false,"context_lines":[{"line_number":44,"context_line":"                          resource_descriptions\u003dself.v3_resources))"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"        config_controller \u003d controllers.DomainConfigV3()"},{"line_number":47,"context_line":"        project_controller \u003d controllers.ProjectV3()"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"        self._add_resource("},{"line_number":50,"context_line":"            mapper, config_controller,"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a5de9d1_a5440a74","line":47,"updated":"2016-01-28 16:35:03.000000000","message":"There is a project controller being created at L93, we shouldn\u0027t need another controller instance just to register this operation.","commit_id":"c41298e1666191ebb44794516acef081f1da0a43"}],"keystone/tests/unit/test_v3_resource.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"631df4871acef0cc85a96c8ab3a4c6982610843a","unresolved":false,"context_lines":[{"line_number":1089,"context_line":"            \u0027/projects/%(project_id)s/cascade\u0027 % {"},{"line_number":1090,"context_line":"                \u0027project_id\u0027: project[\u0027id\u0027]},"},{"line_number":1091,"context_line":"            body\u003d{\u0027project\u0027: project})"},{"line_number":1092,"context_line":"        self.assertValidProjectResponse(r, project)"},{"line_number":1093,"context_line":""},{"line_number":1094,"context_line":"    def test_update_project_domain_id(self):"},{"line_number":1095,"context_line":"        \"\"\"Call ``PATCH /projects/{project_id}`` with domain_id.\"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"9a68dd71_c73e1fb8","line":1092,"range":{"start_line":1092,"start_character":7,"end_line":1092,"end_character":51},"updated":"2016-01-20 20:13:07.000000000","message":"We should also make sure the projects in the hierarchy were actually updated.","commit_id":"c41298e1666191ebb44794516acef081f1da0a43"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"be89769ba2cfa52a8baac73946ff16acfa1d7c0d","unresolved":false,"context_lines":[{"line_number":1089,"context_line":"            \u0027/projects/%(project_id)s/cascade\u0027 % {"},{"line_number":1090,"context_line":"                \u0027project_id\u0027: project[\u0027id\u0027]},"},{"line_number":1091,"context_line":"            body\u003d{\u0027project\u0027: project})"},{"line_number":1092,"context_line":"        self.assertValidProjectResponse(r, project)"},{"line_number":1093,"context_line":""},{"line_number":1094,"context_line":"    def test_update_project_domain_id(self):"},{"line_number":1095,"context_line":"        \"\"\"Call ``PATCH /projects/{project_id}`` with domain_id.\"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"7a5de9d1_104c3e6f","line":1092,"range":{"start_line":1092,"start_character":7,"end_line":1092,"end_character":51},"in_reply_to":"9a68dd71_c73e1fb8","updated":"2016-01-28 16:35:03.000000000","message":"We aren\u0027t creating a project hierarchy, which we should. Also add tests for the exceptional cases.","commit_id":"c41298e1666191ebb44794516acef081f1da0a43"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"11745298f52a5ff47378e233a6da7865adb88cc8","unresolved":false,"context_lines":[{"line_number":1032,"context_line":"                \u0027project_id\u0027: self.project_id},"},{"line_number":1033,"context_line":"            body\u003d{\u0027project\u0027: ref})"},{"line_number":1034,"context_line":""},{"line_number":1035,"context_line":"    def test_update_project_cascade(self):"},{"line_number":1036,"context_line":"        \"\"\"Call ``PATCH /projects/{project_id}?cascade``.\"\"\""},{"line_number":1037,"context_line":"        # Create the project hierarchy"},{"line_number":1038,"context_line":"        parent, subproject \u003d self._create_projects_hierarchy()"}],"source_content_type":"text/x-python","patch_set":11,"id":"5a5ae5dd_36494f32","line":1035,"range":{"start_line":1035,"start_character":8,"end_line":1035,"end_character":35},"updated":"2016-02-03 21:55:16.000000000","message":"I feel like we are missing a test case by not testing a more complex tree.  Could you update this to represent a more complex tree structure?","commit_id":"e06142fa6d7cce48f88d32c0720d48182cec5323"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"1d5161f13f3181ee95ae52d7ca7727eac8894c4b","unresolved":false,"context_lines":[{"line_number":1032,"context_line":"                \u0027project_id\u0027: self.project_id},"},{"line_number":1033,"context_line":"            body\u003d{\u0027project\u0027: ref})"},{"line_number":1034,"context_line":""},{"line_number":1035,"context_line":"    def test_update_project_cascade(self):"},{"line_number":1036,"context_line":"        \"\"\"Call ``PATCH /projects/{project_id}?cascade``.\"\"\""},{"line_number":1037,"context_line":"        # Create the project hierarchy"},{"line_number":1038,"context_line":"        parent, subproject \u003d self._create_projects_hierarchy()"}],"source_content_type":"text/x-python","patch_set":11,"id":"5a5ae5dd_b790b444","line":1035,"range":{"start_line":1035,"start_character":8,"end_line":1035,"end_character":35},"in_reply_to":"5a5ae5dd_36494f32","updated":"2016-02-04 14:16:00.000000000","message":"We have tests for mode complex tree on the backend level, as you can see here: https://review.openstack.org/#/c/243584/10/keystone/tests/unit/test_backend.py\n\nOn the API level, we are just testing if the possible values for the request are working. But if you think that we need more tests here or on backend, let me know :)","commit_id":"e06142fa6d7cce48f88d32c0720d48182cec5323"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"98efa041732450ce5fe0a4a2fd6815c7c95e9920","unresolved":false,"context_lines":[{"line_number":1032,"context_line":"                \u0027project_id\u0027: self.project_id},"},{"line_number":1033,"context_line":"            body\u003d{\u0027project\u0027: ref})"},{"line_number":1034,"context_line":""},{"line_number":1035,"context_line":"    def test_update_project_cascade(self):"},{"line_number":1036,"context_line":"        \"\"\"Call ``PATCH /projects/{project_id}?cascade``.\"\"\""},{"line_number":1037,"context_line":"        # Create the project hierarchy"},{"line_number":1038,"context_line":"        parent, subproject \u003d self._create_projects_hierarchy()"}],"source_content_type":"text/x-python","patch_set":11,"id":"5a5ae5dd_31687eba","line":1035,"range":{"start_line":1035,"start_character":8,"end_line":1035,"end_character":35},"in_reply_to":"5a5ae5dd_7acb01a6","updated":"2016-02-09 17:16:00.000000000","message":"Ok, I\u0027ll send a new patch set with a more complex tree.","commit_id":"e06142fa6d7cce48f88d32c0720d48182cec5323"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"3fb6335b2520b1cec39a18fe01f3feb6db9c22af","unresolved":false,"context_lines":[{"line_number":1032,"context_line":"                \u0027project_id\u0027: self.project_id},"},{"line_number":1033,"context_line":"            body\u003d{\u0027project\u0027: ref})"},{"line_number":1034,"context_line":""},{"line_number":1035,"context_line":"    def test_update_project_cascade(self):"},{"line_number":1036,"context_line":"        \"\"\"Call ``PATCH /projects/{project_id}?cascade``.\"\"\""},{"line_number":1037,"context_line":"        # Create the project hierarchy"},{"line_number":1038,"context_line":"        parent, subproject \u003d self._create_projects_hierarchy()"}],"source_content_type":"text/x-python","patch_set":11,"id":"5a5ae5dd_7acb01a6","line":1035,"range":{"start_line":1035,"start_character":8,"end_line":1035,"end_character":35},"in_reply_to":"5a5ae5dd_b790b444","updated":"2016-02-04 14:24:52.000000000","message":"Okay i would think you would want a larger test here too since it will be testing the api and backend levels are working correctly. i really feel like a strait tree isn\u0027t that complex.  I think you should go off of something like this: https://review.openstack.org/#/c/244149/20/keystone/tests/unit/test_backend.py","commit_id":"e06142fa6d7cce48f88d32c0720d48182cec5323"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"11745298f52a5ff47378e233a6da7865adb88cc8","unresolved":false,"context_lines":[{"line_number":1034,"context_line":""},{"line_number":1035,"context_line":"    def test_update_project_cascade(self):"},{"line_number":1036,"context_line":"        \"\"\"Call ``PATCH /projects/{project_id}?cascade``.\"\"\""},{"line_number":1037,"context_line":"        # Create the project hierarchy"},{"line_number":1038,"context_line":"        parent, subproject \u003d self._create_projects_hierarchy()"},{"line_number":1039,"context_line":"        # Assign a role for the user on parent and subproject"},{"line_number":1040,"context_line":"        for proj in (parent, subproject):"}],"source_content_type":"text/x-python","patch_set":11,"id":"5a5ae5dd_9637e3af","line":1037,"range":{"start_line":1037,"start_character":10,"end_line":1037,"end_character":38},"updated":"2016-02-03 21:55:16.000000000","message":"Create the project hierarchy of 2 projects","commit_id":"e06142fa6d7cce48f88d32c0720d48182cec5323"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"1d5161f13f3181ee95ae52d7ca7727eac8894c4b","unresolved":false,"context_lines":[{"line_number":1034,"context_line":""},{"line_number":1035,"context_line":"    def test_update_project_cascade(self):"},{"line_number":1036,"context_line":"        \"\"\"Call ``PATCH /projects/{project_id}?cascade``.\"\"\""},{"line_number":1037,"context_line":"        # Create the project hierarchy"},{"line_number":1038,"context_line":"        parent, subproject \u003d self._create_projects_hierarchy()"},{"line_number":1039,"context_line":"        # Assign a role for the user on parent and subproject"},{"line_number":1040,"context_line":"        for proj in (parent, subproject):"}],"source_content_type":"text/x-python","patch_set":11,"id":"5a5ae5dd_d793f04d","line":1037,"range":{"start_line":1037,"start_character":10,"end_line":1037,"end_character":38},"in_reply_to":"5a5ae5dd_9637e3af","updated":"2016-02-04 14:16:00.000000000","message":"Done","commit_id":"e06142fa6d7cce48f88d32c0720d48182cec5323"},{"author":{"_account_id":18796,"name":"Alex Petrov","email":"apetrov@mirantis.com","username":"apetrov"},"change_message_id":"14035c4991d9ec5daafc4443abb23b93289bd6e8","unresolved":false,"context_lines":[{"line_number":1066,"context_line":"        # try to update cascade to enable \u003d false"},{"line_number":1067,"context_line":"        # for the entiry subtree"},{"line_number":1068,"context_line":"        self.patch("},{"line_number":1069,"context_line":"            \u0027/projects/%(project_id)s?cascade\u0027 % {"},{"line_number":1070,"context_line":"                \u0027project_id\u0027: parent[\u0027id\u0027]},"},{"line_number":1071,"context_line":"            body\u003d{\u0027project\u0027: {\u0027enabled\u0027: False}},"},{"line_number":1072,"context_line":"            expected_status\u003dexception.Forbidden.code)"}],"source_content_type":"text/x-python","patch_set":11,"id":"5a5ae5dd_ad3c2f30","line":1069,"range":{"start_line":1069,"start_character":37,"end_line":1069,"end_character":38},"updated":"2016-02-03 10:17:57.000000000","message":"is it ok that you put \u0027?\u0027 instead of \u0027/\u0027 ?\n\nhttps://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3.html#enable-or-disable-subtree","commit_id":"e06142fa6d7cce48f88d32c0720d48182cec5323"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"fd2145ba99332d3914907010bf1f5471b60544b1","unresolved":false,"context_lines":[{"line_number":1066,"context_line":"        # try to update cascade to enable \u003d false"},{"line_number":1067,"context_line":"        # for the entiry subtree"},{"line_number":1068,"context_line":"        self.patch("},{"line_number":1069,"context_line":"            \u0027/projects/%(project_id)s?cascade\u0027 % {"},{"line_number":1070,"context_line":"                \u0027project_id\u0027: parent[\u0027id\u0027]},"},{"line_number":1071,"context_line":"            body\u003d{\u0027project\u0027: {\u0027enabled\u0027: False}},"},{"line_number":1072,"context_line":"            expected_status\u003dexception.Forbidden.code)"}],"source_content_type":"text/x-python","patch_set":11,"id":"5a5ae5dd_d079ff30","line":1069,"range":{"start_line":1069,"start_character":37,"end_line":1069,"end_character":38},"in_reply_to":"5a5ae5dd_ad3c2f30","updated":"2016-02-03 12:21:13.000000000","message":"We had discussed on the IRC in the last days, and we decided to change to use a query string instead of a new API call.\nWe sent a patch to fix the documentation: https://review.openstack.org/#/c/274836/","commit_id":"e06142fa6d7cce48f88d32c0720d48182cec5323"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"c264fbc386314a6b9175625420db8a237dcf3bf8","unresolved":false,"context_lines":[{"line_number":605,"context_line":"                               a project with one child."},{"line_number":606,"context_line":""},{"line_number":607,"context_line":"        :param parent_id (optional): if the intention is to create a"},{"line_number":608,"context_line":"                    sub-hierarchy, sets the sub-hierarchy root."},{"line_number":609,"context_line":""},{"line_number":610,"context_line":"        :returns projects: a list of the projects in the created hierarchy."},{"line_number":611,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3a57f1b5_042beb83","line":608,"updated":"2016-02-11 17:47:39.000000000","message":"thanks for adding this!","commit_id":"c90f1525fc6abce38dff505c1a934d5597443820"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"c264fbc386314a6b9175625420db8a237dcf3bf8","unresolved":false,"context_lines":[{"line_number":1039,"context_line":"                \u0027project_id\u0027: self.project_id},"},{"line_number":1040,"context_line":"            body\u003d{\u0027project\u0027: ref})"},{"line_number":1041,"context_line":""},{"line_number":1042,"context_line":"    def test_update_project_cascade(self):"},{"line_number":1043,"context_line":"        \"\"\"Call ``PATCH /projects/{project_id}?cascade``.\"\"\""},{"line_number":1044,"context_line":"        # Create the project hierarchy of 2 projects"},{"line_number":1045,"context_line":"        parent, subproject \u003d self._create_projects_hierarchy()"}],"source_content_type":"text/x-python","patch_set":12,"id":"3a57f1b5_41d8f51d","line":1042,"range":{"start_line":1042,"start_character":8,"end_line":1042,"end_character":35},"updated":"2016-02-11 17:47:39.000000000","message":"does this cover anything different from \"test_update_large_project_cascade\" ? Is there anyway we can combine the two?","commit_id":"c90f1525fc6abce38dff505c1a934d5597443820"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"55b8ae10c945ec1bd3ac3fa34d822e4d1163661a","unresolved":false,"context_lines":[{"line_number":1039,"context_line":"                \u0027project_id\u0027: self.project_id},"},{"line_number":1040,"context_line":"            body\u003d{\u0027project\u0027: ref})"},{"line_number":1041,"context_line":""},{"line_number":1042,"context_line":"    def test_update_project_cascade(self):"},{"line_number":1043,"context_line":"        \"\"\"Call ``PATCH /projects/{project_id}?cascade``.\"\"\""},{"line_number":1044,"context_line":"        # Create the project hierarchy of 2 projects"},{"line_number":1045,"context_line":"        parent, subproject \u003d self._create_projects_hierarchy()"}],"source_content_type":"text/x-python","patch_set":12,"id":"3a57f1b5_d153d337","line":1042,"range":{"start_line":1042,"start_character":8,"end_line":1042,"end_character":35},"in_reply_to":"3a57f1b5_41d8f51d","updated":"2016-02-11 20:08:00.000000000","message":"In fact, it is just a simple case and here its grant a \u0027normal\u0027 role assignment, in test_update_large_project_cascade, its grant a inherited role assignment.","commit_id":"c90f1525fc6abce38dff505c1a934d5597443820"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"c264fbc386314a6b9175625420db8a237dcf3bf8","unresolved":false,"context_lines":[{"line_number":1065,"context_line":"        self.assertFalse(subtree[0][\u0027project\u0027][\u0027enabled\u0027])"},{"line_number":1066,"context_line":""},{"line_number":1067,"context_line":"    def test_update_large_project_cascade(self):"},{"line_number":1068,"context_line":"        \"\"\"Try update a large project with cascade true"},{"line_number":1069,"context_line":"        Tree we will create::"},{"line_number":1070,"context_line":"               +-p1-+"},{"line_number":1071,"context_line":"               |    |"}],"source_content_type":"text/x-python","patch_set":12,"id":"3a57f1b5_615e5147","line":1068,"updated":"2016-02-11 17:47:39.000000000","message":"maybe add \"Call ``PATCH /projects/{project_id}?cascade``\" to docstring","commit_id":"c90f1525fc6abce38dff505c1a934d5597443820"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"55b8ae10c945ec1bd3ac3fa34d822e4d1163661a","unresolved":false,"context_lines":[{"line_number":1065,"context_line":"        self.assertFalse(subtree[0][\u0027project\u0027][\u0027enabled\u0027])"},{"line_number":1066,"context_line":""},{"line_number":1067,"context_line":"    def test_update_large_project_cascade(self):"},{"line_number":1068,"context_line":"        \"\"\"Try update a large project with cascade true"},{"line_number":1069,"context_line":"        Tree we will create::"},{"line_number":1070,"context_line":"               +-p1-+"},{"line_number":1071,"context_line":"               |    |"}],"source_content_type":"text/x-python","patch_set":12,"id":"3a57f1b5_71653f1c","line":1068,"in_reply_to":"3a57f1b5_615e5147","updated":"2016-02-11 20:08:00.000000000","message":"Done","commit_id":"c90f1525fc6abce38dff505c1a934d5597443820"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"0f6bb8009443ac7b3bae287fb9ef05dcb35a2d66","unresolved":false,"context_lines":[{"line_number":1040,"context_line":"            body\u003d{\u0027project\u0027: ref})"},{"line_number":1041,"context_line":""},{"line_number":1042,"context_line":"    def test_update_large_project_cascade(self):"},{"line_number":1043,"context_line":"        \"\"\"Call ``PATCH /projects/{project_id}?cascade``.\"\"\""},{"line_number":1044,"context_line":"        \"\"\"Try update a large project with cascade true"},{"line_number":1045,"context_line":"        Tree we will create::"},{"line_number":1046,"context_line":"               +-p1-+"},{"line_number":1047,"context_line":"               |    |"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_de560f29","line":1044,"range":{"start_line":1043,"start_character":8,"end_line":1044,"end_character":55},"updated":"2016-02-17 18:40:05.000000000","message":"Why 2 docstrings ?","commit_id":"e61939f6a6cf536934925173b466a1dc01b8e39a"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"f6e59ab677f2ab09fbbeb7a4b19a7d63de8aa51e","unresolved":false,"context_lines":[{"line_number":1040,"context_line":"            body\u003d{\u0027project\u0027: ref})"},{"line_number":1041,"context_line":""},{"line_number":1042,"context_line":"    def test_update_large_project_cascade(self):"},{"line_number":1043,"context_line":"        \"\"\"Call ``PATCH /projects/{project_id}?cascade``.\"\"\""},{"line_number":1044,"context_line":"        \"\"\"Try update a large project with cascade true"},{"line_number":1045,"context_line":"        Tree we will create::"},{"line_number":1046,"context_line":"               +-p1-+"},{"line_number":1047,"context_line":"               |    |"}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_eaa189f9","line":1044,"range":{"start_line":1043,"start_character":8,"end_line":1044,"end_character":55},"in_reply_to":"dae33548_de560f29","updated":"2016-02-17 20:12:29.000000000","message":"Done","commit_id":"e61939f6a6cf536934925173b466a1dc01b8e39a"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"0f6bb8009443ac7b3bae287fb9ef05dcb35a2d66","unresolved":false,"context_lines":[{"line_number":1074,"context_line":"            body\u003d{\u0027project\u0027: {\u0027enabled\u0027: False}})"},{"line_number":1075,"context_line":""},{"line_number":1076,"context_line":"        # Assert root project was disabled"},{"line_number":1077,"context_line":"        self.assertFalse(r.result[\u0027project\u0027][\u0027enabled\u0027])"},{"line_number":1078,"context_line":""},{"line_number":1079,"context_line":"    def test_fail_update_project_cascade_without_assignment_on_subtree(self):"},{"line_number":1080,"context_line":"        \"\"\"Call ``PATCH /projects/{project_id}?cascade``.\"\"\""}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_410ce03a","line":1077,"updated":"2016-02-17 18:40:05.000000000","message":"please update projects_hierarchy for every         projects_hierarchy \u003d _create_projects_hierarchy call and make sure ALL projects are disabled here","commit_id":"e61939f6a6cf536934925173b466a1dc01b8e39a"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"f6e59ab677f2ab09fbbeb7a4b19a7d63de8aa51e","unresolved":false,"context_lines":[{"line_number":1074,"context_line":"            body\u003d{\u0027project\u0027: {\u0027enabled\u0027: False}})"},{"line_number":1075,"context_line":""},{"line_number":1076,"context_line":"        # Assert root project was disabled"},{"line_number":1077,"context_line":"        self.assertFalse(r.result[\u0027project\u0027][\u0027enabled\u0027])"},{"line_number":1078,"context_line":""},{"line_number":1079,"context_line":"    def test_fail_update_project_cascade_without_assignment_on_subtree(self):"},{"line_number":1080,"context_line":"        \"\"\"Call ``PATCH /projects/{project_id}?cascade``.\"\"\""}],"source_content_type":"text/x-python","patch_set":16,"id":"dae33548_35b756f6","line":1077,"in_reply_to":"dae33548_410ce03a","updated":"2016-02-17 20:12:29.000000000","message":"Done","commit_id":"e61939f6a6cf536934925173b466a1dc01b8e39a"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"3cad09a596760ae7d066ae9374b827427b932350","unresolved":false,"context_lines":[{"line_number":1080,"context_line":"        # Make the API call to get the subtree"},{"line_number":1081,"context_line":"        r \u003d self.get(\u0027/projects/%(project_id)s?subtree_as_list\u0027 %"},{"line_number":1082,"context_line":"                     {\u0027project_id\u0027: p1[\u0027project\u0027][\u0027id\u0027]})"},{"line_number":1083,"context_line":"        # Assert subprojects was disabled due the cascade option"},{"line_number":1084,"context_line":"        subtree \u003d r.result[\u0027project\u0027][\u0027subtree\u0027]"},{"line_number":1085,"context_line":"        for subproject in subtree:"},{"line_number":1086,"context_line":"            self.assertFalse(subproject[\u0027project\u0027][\u0027enabled\u0027])"}],"source_content_type":"text/x-python","patch_set":17,"id":"dae33548_0840f505","line":1083,"range":{"start_line":1083,"start_character":29,"end_line":1083,"end_character":32},"updated":"2016-02-18 19:08:10.000000000","message":"were","commit_id":"3aa54b2e582f2b414d6cc683b17ed695e7126f5b"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"f68cf79b3dafe5c3b1e1580c19787d3b6fb50aef","unresolved":false,"context_lines":[{"line_number":1080,"context_line":"        # Make the API call to get the subtree"},{"line_number":1081,"context_line":"        r \u003d self.get(\u0027/projects/%(project_id)s?subtree_as_list\u0027 %"},{"line_number":1082,"context_line":"                     {\u0027project_id\u0027: p1[\u0027project\u0027][\u0027id\u0027]})"},{"line_number":1083,"context_line":"        # Assert subprojects was disabled due the cascade option"},{"line_number":1084,"context_line":"        subtree \u003d r.result[\u0027project\u0027][\u0027subtree\u0027]"},{"line_number":1085,"context_line":"        for subproject in subtree:"},{"line_number":1086,"context_line":"            self.assertFalse(subproject[\u0027project\u0027][\u0027enabled\u0027])"}],"source_content_type":"text/x-python","patch_set":17,"id":"dae33548_c8656d1e","line":1083,"range":{"start_line":1083,"start_character":29,"end_line":1083,"end_character":32},"in_reply_to":"dae33548_0840f505","updated":"2016-02-18 20:05:00.000000000","message":"Done","commit_id":"3aa54b2e582f2b414d6cc683b17ed695e7126f5b"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"3cad09a596760ae7d066ae9374b827427b932350","unresolved":false,"context_lines":[{"line_number":1092,"context_line":"        parent \u003d projects[0][\u0027project\u0027]"},{"line_number":1093,"context_line":"        # We don\u0027t give any assignment on the subprojects"},{"line_number":1094,"context_line":"        # try to update cascade to enable \u003d false"},{"line_number":1095,"context_line":"        # for the entiry subtree"},{"line_number":1096,"context_line":"        self.patch("},{"line_number":1097,"context_line":"            \u0027/projects/%(project_id)s?cascade\u0027 % {"},{"line_number":1098,"context_line":"                \u0027project_id\u0027: parent[\u0027id\u0027]},"}],"source_content_type":"text/x-python","patch_set":17,"id":"dae33548_a863c9af","line":1095,"range":{"start_line":1095,"start_character":18,"end_line":1095,"end_character":24},"updated":"2016-02-18 19:08:10.000000000","message":"entire","commit_id":"3aa54b2e582f2b414d6cc683b17ed695e7126f5b"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"f68cf79b3dafe5c3b1e1580c19787d3b6fb50aef","unresolved":false,"context_lines":[{"line_number":1092,"context_line":"        parent \u003d projects[0][\u0027project\u0027]"},{"line_number":1093,"context_line":"        # We don\u0027t give any assignment on the subprojects"},{"line_number":1094,"context_line":"        # try to update cascade to enable \u003d false"},{"line_number":1095,"context_line":"        # for the entiry subtree"},{"line_number":1096,"context_line":"        self.patch("},{"line_number":1097,"context_line":"            \u0027/projects/%(project_id)s?cascade\u0027 % {"},{"line_number":1098,"context_line":"                \u0027project_id\u0027: parent[\u0027id\u0027]},"}],"source_content_type":"text/x-python","patch_set":17,"id":"dae33548_a868e9f5","line":1095,"range":{"start_line":1095,"start_character":18,"end_line":1095,"end_character":24},"in_reply_to":"dae33548_a863c9af","updated":"2016-02-18 20:05:00.000000000","message":"Done","commit_id":"3aa54b2e582f2b414d6cc683b17ed695e7126f5b"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"0fc2e72a25337ba8b567f0fb66ac44c6fecd1bff","unresolved":false,"context_lines":[{"line_number":1098,"context_line":"                \u0027project_id\u0027: parent[\u0027id\u0027]},"},{"line_number":1099,"context_line":"            body\u003d{\u0027project\u0027: {\u0027enabled\u0027: False}},"},{"line_number":1100,"context_line":"            expected_status\u003dexception.Forbidden.code)"},{"line_number":1101,"context_line":""},{"line_number":1102,"context_line":"    def test_update_project_domain_id(self):"},{"line_number":1103,"context_line":"        \"\"\"Call ``PATCH /projects/{project_id}`` with domain_id.\"\"\""},{"line_number":1104,"context_line":"        project \u003d unit.new_project_ref(domain_id\u003dself.domain[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":19,"id":"bae84128_a09f4f5e","line":1101,"updated":"2016-02-19 12:06:26.000000000","message":"Needs another tes with ?cascade\u003dFalse","commit_id":"4d215f7f7541938b8b84f749382544f9ce1cdf1a"}]}
