)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"1a1a6ede5c3c8d9375bf9497801d590ad3ab7726","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Unimplemented get roles by group for project list"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The list_projects_for_user() function on LDAP assignment backend only"},{"line_number":10,"context_line":"search projects with associations across user_id, not across group_ids."},{"line_number":11,"context_line":"This function admits the group_ids parameter, but never is used on the"},{"line_number":12,"context_line":"body of the function."},{"line_number":13,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":9,"id":"AAAAXH%2F%2FaZA%3D","line":10,"updated":"2014-04-23 22:33:16.000000000","message":"change \"search projects\" to \"listed projects\"","commit_id":"1bacf53f6a946026777bfcb6c1deb646791825ed"}],"keystone/assignment/backends/ldap.py":[{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"18d78e956c9ec0b2d24b644ffad712cd97e5dfde","unresolved":false,"context_lines":[{"line_number":133,"context_line":"    def list_projects_for_user(self, user_id, group_ids, hints):"},{"line_number":134,"context_line":"        # NOTE(henry-nash): The LDAP backend is being deprecated, so no"},{"line_number":135,"context_line":"        # support is provided for projects that the user has a role on solely"},{"line_number":136,"context_line":"        # by virtue of group membership."},{"line_number":137,"context_line":"        user_dn \u003d self.user._id_to_dn(user_id)"},{"line_number":138,"context_line":"        associations \u003d (self.role.list_project_roles_for_user"},{"line_number":139,"context_line":"                        (user_dn, self.project.tree_dn))"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAU3%2F%2FcuY%3D","line":136,"updated":"2014-02-26 15:33:03.000000000","message":"now that you are implemented the code, you can remove my comment!","commit_id":"81391e510bbdfbf3846816ad1c25902ef3b7a4a2"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"6f4b4dbd4ab8eed3495177743e55531150efcefc","unresolved":false,"context_lines":[{"line_number":138,"context_line":"        for group_id in group_ids:"},{"line_number":139,"context_line":"            group_dn \u003d self.group._id_to_dn(group_id)"},{"line_number":140,"context_line":"            for a in (self.role.list_project_roles_for_group"},{"line_number":141,"context_line":"                      (group_dn, self.project.tree_dn)):"},{"line_number":142,"context_line":"                associations.append(a)"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":"        # Since the LDAP backend doesn\u0027t store the domain_id in the LDAP"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAVn%2F%2FiKI%3D","line":141,"updated":"2014-03-05 15:08:55.000000000","message":"the use of parens here makes it difficult to see what\u0027s going on; instead:\n\n  for a in self.role.list-project_roles_for_group(\n          group_dn, self.project_tree_dn)\n      associations.append(a)","commit_id":"1ef1c38f3d042cca613989c961839553da1062c9"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"485526525bcc14f0abe56fb93b33a21b06b98c01","unresolved":false,"context_lines":[{"line_number":138,"context_line":"        for group_id in group_ids:"},{"line_number":139,"context_line":"            group_dn \u003d self.group._id_to_dn(group_id)"},{"line_number":140,"context_line":"            for a in (self.role.list_project_roles_for_group"},{"line_number":141,"context_line":"                      (group_dn, self.project.tree_dn)):"},{"line_number":142,"context_line":"                associations.append(a)"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":"        # Since the LDAP backend doesn\u0027t store the domain_id in the LDAP"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAVn%2F%2FZ3o%3D","line":141,"in_reply_to":"AAAAVn%2F%2FiKI%3D","updated":"2014-03-06 09:54:27.000000000","message":"Done","commit_id":"1ef1c38f3d042cca613989c961839553da1062c9"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"6f4b4dbd4ab8eed3495177743e55531150efcefc","unresolved":false,"context_lines":[{"line_number":659,"context_line":"            #ldap.dn.dn2str returns an array, where the first"},{"line_number":660,"context_line":"            #element is the first segment."},{"line_number":661,"context_line":"            #For a role assignment, this contains the role ID,"},{"line_number":662,"context_line":"            #The remainder is the DN of the tenant."},{"line_number":663,"context_line":"            tenant \u003d ldap.dn.str2dn(role_dn)"},{"line_number":664,"context_line":"            tenant.pop(0)"},{"line_number":665,"context_line":"            tenant_dn \u003d ldap.dn.dn2str(tenant)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAVn%2F%2FiJM%3D","line":662,"updated":"2014-03-05 15:08:55.000000000","message":"(pep8) add a single space after each #","commit_id":"1ef1c38f3d042cca613989c961839553da1062c9"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"485526525bcc14f0abe56fb93b33a21b06b98c01","unresolved":false,"context_lines":[{"line_number":659,"context_line":"            #ldap.dn.dn2str returns an array, where the first"},{"line_number":660,"context_line":"            #element is the first segment."},{"line_number":661,"context_line":"            #For a role assignment, this contains the role ID,"},{"line_number":662,"context_line":"            #The remainder is the DN of the tenant."},{"line_number":663,"context_line":"            tenant \u003d ldap.dn.str2dn(role_dn)"},{"line_number":664,"context_line":"            tenant.pop(0)"},{"line_number":665,"context_line":"            tenant_dn \u003d ldap.dn.dn2str(tenant)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAVn%2F%2FZ3g%3D","line":662,"in_reply_to":"AAAAVn%2F%2FiJM%3D","updated":"2014-03-06 09:54:27.000000000","message":"Done","commit_id":"1ef1c38f3d042cca613989c961839553da1062c9"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"ec7f0b303e10709aab34709ffc1766fe4567e555","unresolved":false,"context_lines":[{"line_number":138,"context_line":""},{"line_number":139,"context_line":"        for group_id in group_ids:"},{"line_number":140,"context_line":"            group_dn \u003d self.group._id_to_dn(group_id)"},{"line_number":141,"context_line":"            for a in self.role.list_project_roles_for_group("},{"line_number":142,"context_line":"                    group_dn, self.project.tree_dn):"},{"line_number":143,"context_line":"                associations.append(a)"},{"line_number":144,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2F59w%3D","line":141,"updated":"2014-04-16 17:00:35.000000000","message":"(nit) Suggest renaming a to role or role_id to show what it is. Looking at this code I can\u0027t tell.","commit_id":"3f525074184241e8a06d198bb443c7b2a4475e3b"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"be6c2b0303a45c1095cf8dcb848337c1ec81b56e","unresolved":false,"context_lines":[{"line_number":138,"context_line":""},{"line_number":139,"context_line":"        for group_id in group_ids:"},{"line_number":140,"context_line":"            group_dn \u003d self.group._id_to_dn(group_id)"},{"line_number":141,"context_line":"            for a in self.role.list_project_roles_for_group("},{"line_number":142,"context_line":"                    group_dn, self.project.tree_dn):"},{"line_number":143,"context_line":"                associations.append(a)"},{"line_number":144,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2F0oQ%3D","line":141,"in_reply_to":"AAAAXH%2F%2F59w%3D","updated":"2014-04-17 07:02:38.000000000","message":"I\u0027ve changed it by group_role, because self.role.list_project_roles_for_group() function returns a GroupRoleAssociation object list","commit_id":"3f525074184241e8a06d198bb443c7b2a4475e3b"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"1a1a6ede5c3c8d9375bf9497801d590ad3ab7726","unresolved":false,"context_lines":[{"line_number":616,"context_line":"        conn \u003d self.get_connection()"},{"line_number":617,"context_line":"        query \u003d \u0027(\u0026(objectClass\u003d%s)(%s\u003d%s))\u0027 % (self.object_class,"},{"line_number":618,"context_line":"                                                self.member_attribute,"},{"line_number":619,"context_line":"                                                group_dn)"},{"line_number":620,"context_line":"        try:"},{"line_number":621,"context_line":"            roles \u003d conn.search_s(project_subtree,"},{"line_number":622,"context_line":"                                  ldap.SCOPE_SUBTREE,"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAXH%2F%2FHYw%3D","line":619,"updated":"2014-04-23 22:33:16.000000000","message":"escape values in filters so that it\u0027s valid -- http://www.python-ldap.org/doc/html/ldap-filter.html#ldap.filter.escape_filter_chars","commit_id":"1bacf53f6a946026777bfcb6c1deb646791825ed"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"8eeeb8a4347f92ce875129cd9c3f301898deed5b","unresolved":false,"context_lines":[{"line_number":616,"context_line":"        conn \u003d self.get_connection()"},{"line_number":617,"context_line":"        query \u003d \u0027(\u0026(objectClass\u003d%s)(%s\u003d%s))\u0027 % (self.object_class,"},{"line_number":618,"context_line":"                                                self.member_attribute,"},{"line_number":619,"context_line":"                                                group_dn)"},{"line_number":620,"context_line":"        try:"},{"line_number":621,"context_line":"            roles \u003d conn.search_s(project_subtree,"},{"line_number":622,"context_line":"                                  ldap.SCOPE_SUBTREE,"}],"source_content_type":"text/x-python","patch_set":9,"id":"9ad9bd40_a07db3e9","line":619,"in_reply_to":"AAAAXH%2F%2FHYw%3D","updated":"2014-05-02 14:48:07.000000000","message":"Done","commit_id":"1bacf53f6a946026777bfcb6c1deb646791825ed"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"1a1a6ede5c3c8d9375bf9497801d590ad3ab7726","unresolved":false,"context_lines":[{"line_number":620,"context_line":"        try:"},{"line_number":621,"context_line":"            roles \u003d conn.search_s(project_subtree,"},{"line_number":622,"context_line":"                                  ldap.SCOPE_SUBTREE,"},{"line_number":623,"context_line":"                                  query)"},{"line_number":624,"context_line":"        except ldap.NO_SUCH_OBJECT:"},{"line_number":625,"context_line":"            return []"},{"line_number":626,"context_line":"        finally:"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAXH%2F%2FHW0%3D","line":623,"updated":"2014-04-23 22:33:16.000000000","message":"this query should have attrlist\u003d[\u00271.1\u0027] since we don\u0027t care about the attributes here, just the DNs.","commit_id":"1bacf53f6a946026777bfcb6c1deb646791825ed"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"8eeeb8a4347f92ce875129cd9c3f301898deed5b","unresolved":false,"context_lines":[{"line_number":620,"context_line":"        try:"},{"line_number":621,"context_line":"            roles \u003d conn.search_s(project_subtree,"},{"line_number":622,"context_line":"                                  ldap.SCOPE_SUBTREE,"},{"line_number":623,"context_line":"                                  query)"},{"line_number":624,"context_line":"        except ldap.NO_SUCH_OBJECT:"},{"line_number":625,"context_line":"            return []"},{"line_number":626,"context_line":"        finally:"}],"source_content_type":"text/x-python","patch_set":9,"id":"9ad9bd40_604acbad","line":623,"in_reply_to":"AAAAXH%2F%2FHW0%3D","updated":"2014-05-02 14:48:07.000000000","message":"Done","commit_id":"1bacf53f6a946026777bfcb6c1deb646791825ed"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"1a1a6ede5c3c8d9375bf9497801d590ad3ab7726","unresolved":false,"context_lines":[{"line_number":628,"context_line":""},{"line_number":629,"context_line":"        res \u003d []"},{"line_number":630,"context_line":"        for role_dn, _ in roles:"},{"line_number":631,"context_line":"            # ldap.dn.dn2str returns an array, where the first"},{"line_number":632,"context_line":"            # element is the first segment."},{"line_number":633,"context_line":"            # For a role assignment, this contains the role ID,"},{"line_number":634,"context_line":"            # The remainder is the DN of the tenant."}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAXH%2F%2FHXw%3D","line":631,"updated":"2014-04-23 22:33:16.000000000","message":"should be str2dn not dn2str\n\nalso, change array to list.","commit_id":"1bacf53f6a946026777bfcb6c1deb646791825ed"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"8eeeb8a4347f92ce875129cd9c3f301898deed5b","unresolved":false,"context_lines":[{"line_number":628,"context_line":""},{"line_number":629,"context_line":"        res \u003d []"},{"line_number":630,"context_line":"        for role_dn, _ in roles:"},{"line_number":631,"context_line":"            # ldap.dn.dn2str returns an array, where the first"},{"line_number":632,"context_line":"            # element is the first segment."},{"line_number":633,"context_line":"            # For a role assignment, this contains the role ID,"},{"line_number":634,"context_line":"            # The remainder is the DN of the tenant."}],"source_content_type":"text/x-python","patch_set":9,"id":"9ad9bd40_a0cbf31c","line":631,"in_reply_to":"AAAAXH%2F%2FHXw%3D","updated":"2014-05-02 14:48:07.000000000","message":"Done","commit_id":"1bacf53f6a946026777bfcb6c1deb646791825ed"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"1a1a6ede5c3c8d9375bf9497801d590ad3ab7726","unresolved":false,"context_lines":[{"line_number":629,"context_line":"        res \u003d []"},{"line_number":630,"context_line":"        for role_dn, _ in roles:"},{"line_number":631,"context_line":"            # ldap.dn.dn2str returns an array, where the first"},{"line_number":632,"context_line":"            # element is the first segment."},{"line_number":633,"context_line":"            # For a role assignment, this contains the role ID,"},{"line_number":634,"context_line":"            # The remainder is the DN of the tenant."},{"line_number":635,"context_line":"            tenant \u003d ldap.dn.str2dn(role_dn)"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAXH%2F%2FHUw%3D","line":632,"updated":"2014-04-23 22:33:16.000000000","message":"not sure what a segment is... change \"segment\" to \"RDN\".","commit_id":"1bacf53f6a946026777bfcb6c1deb646791825ed"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"8eeeb8a4347f92ce875129cd9c3f301898deed5b","unresolved":false,"context_lines":[{"line_number":629,"context_line":"        res \u003d []"},{"line_number":630,"context_line":"        for role_dn, _ in roles:"},{"line_number":631,"context_line":"            # ldap.dn.dn2str returns an array, where the first"},{"line_number":632,"context_line":"            # element is the first segment."},{"line_number":633,"context_line":"            # For a role assignment, this contains the role ID,"},{"line_number":634,"context_line":"            # The remainder is the DN of the tenant."},{"line_number":635,"context_line":"            tenant \u003d ldap.dn.str2dn(role_dn)"}],"source_content_type":"text/x-python","patch_set":9,"id":"9ad9bd40_c0d2b7d1","line":632,"in_reply_to":"AAAAXH%2F%2FHUw%3D","updated":"2014-05-02 14:48:07.000000000","message":"Done","commit_id":"1bacf53f6a946026777bfcb6c1deb646791825ed"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"1a1a6ede5c3c8d9375bf9497801d590ad3ab7726","unresolved":false,"context_lines":[{"line_number":631,"context_line":"            # ldap.dn.dn2str returns an array, where the first"},{"line_number":632,"context_line":"            # element is the first segment."},{"line_number":633,"context_line":"            # For a role assignment, this contains the role ID,"},{"line_number":634,"context_line":"            # The remainder is the DN of the tenant."},{"line_number":635,"context_line":"            tenant \u003d ldap.dn.str2dn(role_dn)"},{"line_number":636,"context_line":"            tenant.pop(0)"},{"line_number":637,"context_line":"            tenant_dn \u003d ldap.dn.dn2str(tenant)"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAXH%2F%2FHT8%3D","line":634,"updated":"2014-04-23 22:33:16.000000000","message":"the parent of the role entry would only be the project if the role entry was found directly under the tenant entry, but since a SUBTREE search was done that\u0027s not necessarily the case.","commit_id":"1bacf53f6a946026777bfcb6c1deb646791825ed"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"1a1a6ede5c3c8d9375bf9497801d590ad3ab7726","unresolved":false,"context_lines":[{"line_number":632,"context_line":"            # element is the first segment."},{"line_number":633,"context_line":"            # For a role assignment, this contains the role ID,"},{"line_number":634,"context_line":"            # The remainder is the DN of the tenant."},{"line_number":635,"context_line":"            tenant \u003d ldap.dn.str2dn(role_dn)"},{"line_number":636,"context_line":"            tenant.pop(0)"},{"line_number":637,"context_line":"            tenant_dn \u003d ldap.dn.dn2str(tenant)"},{"line_number":638,"context_line":"            res.append(GroupRoleAssociation("}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAXH%2F%2FHXE%3D","line":635,"updated":"2014-04-23 22:33:16.000000000","message":"change tenant to project","commit_id":"1bacf53f6a946026777bfcb6c1deb646791825ed"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"8eeeb8a4347f92ce875129cd9c3f301898deed5b","unresolved":false,"context_lines":[{"line_number":632,"context_line":"            # element is the first segment."},{"line_number":633,"context_line":"            # For a role assignment, this contains the role ID,"},{"line_number":634,"context_line":"            # The remainder is the DN of the tenant."},{"line_number":635,"context_line":"            tenant \u003d ldap.dn.str2dn(role_dn)"},{"line_number":636,"context_line":"            tenant.pop(0)"},{"line_number":637,"context_line":"            tenant_dn \u003d ldap.dn.dn2str(tenant)"},{"line_number":638,"context_line":"            res.append(GroupRoleAssociation("}],"source_content_type":"text/x-python","patch_set":9,"id":"9ad9bd40_e0a33b4d","line":635,"in_reply_to":"AAAAXH%2F%2FHXE%3D","updated":"2014-05-02 14:48:07.000000000","message":"Done","commit_id":"1bacf53f6a946026777bfcb6c1deb646791825ed"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"6bfde1ab45d67dae51631000083d8df5ffd824fa","unresolved":false,"context_lines":[{"line_number":597,"context_line":"                                  ldap.SCOPE_SUBTREE,"},{"line_number":598,"context_line":"                                  query,"},{"line_number":599,"context_line":"                                  attrlist\u003d[\u00271.1\u0027])"},{"line_number":600,"context_line":"        except ldap.NO_SUCH_OBJECT:"},{"line_number":601,"context_line":"            return []"},{"line_number":602,"context_line":"        finally:"},{"line_number":603,"context_line":"            conn.unbind_s()"}],"source_content_type":"text/x-python","patch_set":11,"id":"7adec928_2f892a75","line":600,"updated":"2014-05-18 17:20:34.000000000","message":"add a comment why it\u0027s correct to return no roles rather than raise an exception if the project subtree entry doesn\u0027t exist.\n\nAlso, add a debug log.","commit_id":"57f90569a47bfceb5d76c4d0954c3603bc235632"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"01c521b34ba0b414df9444ba7a48215069cddfd2","unresolved":false,"context_lines":[{"line_number":597,"context_line":"                                  ldap.SCOPE_SUBTREE,"},{"line_number":598,"context_line":"                                  query,"},{"line_number":599,"context_line":"                                  attrlist\u003d[\u00271.1\u0027])"},{"line_number":600,"context_line":"        except ldap.NO_SUCH_OBJECT:"},{"line_number":601,"context_line":"            return []"},{"line_number":602,"context_line":"        finally:"},{"line_number":603,"context_line":"            conn.unbind_s()"}],"source_content_type":"text/x-python","patch_set":11,"id":"7adec928_9c525a65","line":600,"in_reply_to":"7adec928_2f892a75","updated":"2014-05-19 07:07:56.000000000","message":"Done","commit_id":"57f90569a47bfceb5d76c4d0954c3603bc235632"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"6bfde1ab45d67dae51631000083d8df5ffd824fa","unresolved":false,"context_lines":[{"line_number":604,"context_line":""},{"line_number":605,"context_line":"        res \u003d []"},{"line_number":606,"context_line":"        for role_dn, _ in roles:"},{"line_number":607,"context_line":"            # ldap.dn.str2dn returns an list, where the first"},{"line_number":608,"context_line":"            # element is the first RDN."},{"line_number":609,"context_line":"            # For a role assignment, this contains the role ID,"},{"line_number":610,"context_line":"            # The remainder is the DN of the tenant."}],"source_content_type":"text/x-python","patch_set":11,"id":"7adec928_8fb07e44","line":607,"updated":"2014-05-18 17:20:34.000000000","message":"(nit) change \"an\" to \"a\"","commit_id":"57f90569a47bfceb5d76c4d0954c3603bc235632"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"01c521b34ba0b414df9444ba7a48215069cddfd2","unresolved":false,"context_lines":[{"line_number":604,"context_line":""},{"line_number":605,"context_line":"        res \u003d []"},{"line_number":606,"context_line":"        for role_dn, _ in roles:"},{"line_number":607,"context_line":"            # ldap.dn.str2dn returns an list, where the first"},{"line_number":608,"context_line":"            # element is the first RDN."},{"line_number":609,"context_line":"            # For a role assignment, this contains the role ID,"},{"line_number":610,"context_line":"            # The remainder is the DN of the tenant."}],"source_content_type":"text/x-python","patch_set":11,"id":"7adec928_5c5d3278","line":607,"in_reply_to":"7adec928_8fb07e44","updated":"2014-05-19 07:07:56.000000000","message":"Done","commit_id":"57f90569a47bfceb5d76c4d0954c3603bc235632"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"6bfde1ab45d67dae51631000083d8df5ffd824fa","unresolved":false,"context_lines":[{"line_number":607,"context_line":"            # ldap.dn.str2dn returns an list, where the first"},{"line_number":608,"context_line":"            # element is the first RDN."},{"line_number":609,"context_line":"            # For a role assignment, this contains the role ID,"},{"line_number":610,"context_line":"            # The remainder is the DN of the tenant."},{"line_number":611,"context_line":"            project \u003d ldap.dn.str2dn(role_dn)"},{"line_number":612,"context_line":"            project.pop(0)"},{"line_number":613,"context_line":"            project_dn \u003d ldap.dn.dn2str(project)"}],"source_content_type":"text/x-python","patch_set":11,"id":"7adec928_afad3aeb","line":610,"updated":"2014-05-18 17:20:34.000000000","message":"(nit) change \"The\" to \"the\" (lowercase), also change \"tenant\" to \"project\"","commit_id":"57f90569a47bfceb5d76c4d0954c3603bc235632"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"01c521b34ba0b414df9444ba7a48215069cddfd2","unresolved":false,"context_lines":[{"line_number":607,"context_line":"            # ldap.dn.str2dn returns an list, where the first"},{"line_number":608,"context_line":"            # element is the first RDN."},{"line_number":609,"context_line":"            # For a role assignment, this contains the role ID,"},{"line_number":610,"context_line":"            # The remainder is the DN of the tenant."},{"line_number":611,"context_line":"            project \u003d ldap.dn.str2dn(role_dn)"},{"line_number":612,"context_line":"            project.pop(0)"},{"line_number":613,"context_line":"            project_dn \u003d ldap.dn.dn2str(project)"}],"source_content_type":"text/x-python","patch_set":11,"id":"7adec928_3c5a2683","line":610,"in_reply_to":"7adec928_afad3aeb","updated":"2014-05-19 07:07:56.000000000","message":"Done","commit_id":"57f90569a47bfceb5d76c4d0954c3603bc235632"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"d77f123b234cbc88e1cf73febe33c9a2158c1970","unresolved":false,"context_lines":[{"line_number":614,"context_line":"            conn.unbind_s()"},{"line_number":615,"context_line":""},{"line_number":616,"context_line":"        res \u003d []"},{"line_number":617,"context_line":"        for role_dn, _ in roles:"},{"line_number":618,"context_line":"            # ldap.dn.str2dn returns a list, where the first"},{"line_number":619,"context_line":"            # element is the first RDN."},{"line_number":620,"context_line":"            # For a role assignment, this contains the role ID,"}],"source_content_type":"text/x-python","patch_set":13,"id":"1ae5cdf2_7187dc0f","line":617,"updated":"2014-06-02 19:31:40.000000000","message":"Suggest using something other than _ as we use that for translation(s) (see line 29) - not that it\u0027s breaking anything in this method at this time.","commit_id":"33a3822ecd3095f36983d88439644dc90446e896"}],"keystone/tests/test_backend_ldap.py":[{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"c1813cf08e936dc433f269bf99784655ec3cc0f9","unresolved":false,"context_lines":[{"line_number":267,"context_line":"                                         project_id\u003dself.tenant_bar[\u0027id\u0027],"},{"line_number":268,"context_line":"                                         role_id\u003dself.role_member[\u0027id\u0027])"},{"line_number":269,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user2[\u0027id\u0027])"},{"line_number":270,"context_line":"        self.assertEqual(len(user_projects), 1)"},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"    def test_list_projects_for_user_with_grants(self):"},{"line_number":273,"context_line":"        domain \u003d self._get_domain_fixture()"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAU3%2F%2FcJY%3D","line":270,"updated":"2014-02-26 16:20:48.000000000","message":"Perhaps a sightly better test would be to add the membership to the same user as in the first part of this test, (with the group role on a different project) and hence shows that we return the sum of all such projects","commit_id":"1ef1c38f3d042cca613989c961839553da1062c9"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"485526525bcc14f0abe56fb93b33a21b06b98c01","unresolved":false,"context_lines":[{"line_number":267,"context_line":"                                         project_id\u003dself.tenant_bar[\u0027id\u0027],"},{"line_number":268,"context_line":"                                         role_id\u003dself.role_member[\u0027id\u0027])"},{"line_number":269,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user2[\u0027id\u0027])"},{"line_number":270,"context_line":"        self.assertEqual(len(user_projects), 1)"},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"    def test_list_projects_for_user_with_grants(self):"},{"line_number":273,"context_line":"        domain \u003d self._get_domain_fixture()"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAVn%2F%2FZ04%3D","line":270,"in_reply_to":"AAAAU3%2F%2FcJY%3D","updated":"2014-03-06 09:54:27.000000000","message":"Done","commit_id":"1ef1c38f3d042cca613989c961839553da1062c9"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"70d976155caf13eea05516a0c930b203926318ec","unresolved":false,"context_lines":[{"line_number":271,"context_line":"                                         role_id\u003dself.role_member[\u0027id\u0027])"},{"line_number":272,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user2[\u0027id\u0027])"},{"line_number":273,"context_line":"        self.assertEqual(len(user_projects), 2)"},{"line_number":274,"context_line":""},{"line_number":275,"context_line":"    def test_list_projects_for_user_with_grants(self):"},{"line_number":276,"context_line":"        domain \u003d self._get_domain_fixture()"},{"line_number":277,"context_line":"        new_user \u003d {\u0027id\u0027: uuid.uuid4().hex, \u0027name\u0027: \u0027new_user\u0027,"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAVn%2F%2FZhg%3D","line":274,"updated":"2014-03-06 10:49:47.000000000","message":"So I would suggest you do the following:\n- Keep the test above, but:\n\na) use a different role for one of the tenants (e.g. for tenant_bar). and\n\nb) change tenant_baz to one that is user 1 does not have a role on.\n\nThis won\u0027t change the results of this part of the test, but then…\n\n- Add another section of the test that adds user1 to the group1.\n- Then list projects for user1 and you should get back 3 projects for user1 (testing that the list is the sum of tenants with both direct and group membership roles AND that we don\u0027t count a project twice if it has both direct and group roles)","commit_id":"377976fa796b5f0afc406ea686d4f3c157376d95"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"7f928d3bf53dfc8bc5fc1b9e4bfa172d05e03609","unresolved":false,"context_lines":[{"line_number":271,"context_line":"                                         role_id\u003dself.role_member[\u0027id\u0027])"},{"line_number":272,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user2[\u0027id\u0027])"},{"line_number":273,"context_line":"        self.assertEqual(len(user_projects), 2)"},{"line_number":274,"context_line":""},{"line_number":275,"context_line":"    def test_list_projects_for_user_with_grants(self):"},{"line_number":276,"context_line":"        domain \u003d self._get_domain_fixture()"},{"line_number":277,"context_line":"        new_user \u003d {\u0027id\u0027: uuid.uuid4().hex, \u0027name\u0027: \u0027new_user\u0027,"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F%2F%2FrA%3D","line":274,"in_reply_to":"AAAAVn%2F%2FZhg%3D","updated":"2014-03-12 13:35:05.000000000","message":"I\u0027m sorry Henry, I don\u0027t understand enough the b) part, could you explain it a bit more, please?","commit_id":"377976fa796b5f0afc406ea686d4f3c157376d95"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"3b8559bfeceee7e52c735dc7c0e9cef7da9d77ee","unresolved":false,"context_lines":[{"line_number":287,"context_line":"                                         project_id\u003dself.tenant_bar[\u0027id\u0027],"},{"line_number":288,"context_line":"                                         role_id\u003dself.role_other[\u0027id\u0027])"},{"line_number":289,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user2[\u0027id\u0027])"},{"line_number":290,"context_line":"        self.assertEqual(len(user_projects), 2)"},{"line_number":291,"context_line":""},{"line_number":292,"context_line":"    def test_list_projects_for_user_with_grants(self):"},{"line_number":293,"context_line":"        domain \u003d self._get_domain_fixture()"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWH%2F%2By8s%3D","line":290,"updated":"2014-03-24 09:42:50.000000000","message":"So as per my previous comment, I\u0027d like us to improve this test.  I think it would be beneficial to have an additional test (or adapt this test) that:\n\na) returned a list of projects which was the combination of projects that a user has a direct role on as well as by group membership. For example, if your new code to check for group membership in backends/ldap.py overwrote the projects the user had direct roles on, then your tests would still pass\n\nb) Ensued the new test above included a project that the user has both a direct role and a group role on...to make sure that project only appears in the list once.","commit_id":"1c6b4edf3dfa9643f426cca9c19374b25f67a893"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"ec7f0b303e10709aab34709ffc1766fe4567e555","unresolved":false,"context_lines":[{"line_number":364,"context_line":""},{"line_number":365,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user("},{"line_number":366,"context_line":"            new_user[\u0027id\u0027])"},{"line_number":367,"context_line":"        self.assertEqual(len(user_projects), 3)"},{"line_number":368,"context_line":""},{"line_number":369,"context_line":"    def test_create_duplicate_user_name_in_different_domains(self):"},{"line_number":370,"context_line":"        self.skipTest(\u0027Blocked by bug 1101276\u0027)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2F548%3D","line":367,"updated":"2014-04-16 17:00:35.000000000","message":"Why switch the order here? I thought the call order was (expected, actual).","commit_id":"3f525074184241e8a06d198bb443c7b2a4475e3b"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"be6c2b0303a45c1095cf8dcb848337c1ec81b56e","unresolved":false,"context_lines":[{"line_number":364,"context_line":""},{"line_number":365,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user("},{"line_number":366,"context_line":"            new_user[\u0027id\u0027])"},{"line_number":367,"context_line":"        self.assertEqual(len(user_projects), 3)"},{"line_number":368,"context_line":""},{"line_number":369,"context_line":"    def test_create_duplicate_user_name_in_different_domains(self):"},{"line_number":370,"context_line":"        self.skipTest(\u0027Blocked by bug 1101276\u0027)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2F0ng%3D","line":367,"in_reply_to":"AAAAXH%2F%2F548%3D","updated":"2014-04-17 07:02:38.000000000","message":"Done","commit_id":"3f525074184241e8a06d198bb443c7b2a4475e3b"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"6bfde1ab45d67dae51631000083d8df5ffd824fa","unresolved":false,"context_lines":[{"line_number":301,"context_line":"                                         project_id\u003dself.tenant_bar[\u0027id\u0027],"},{"line_number":302,"context_line":"                                         role_id\u003dself.role_other[\u0027id\u0027])"},{"line_number":303,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user2[\u0027id\u0027])"},{"line_number":304,"context_line":"        self.assertEqual(len(user_projects), 2)"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"    def test_list_projects_for_user_and_groups(self):"},{"line_number":307,"context_line":"        domain \u003d self._get_domain_fixture()"}],"source_content_type":"text/x-python","patch_set":11,"id":"7adec928_0feb8e13","line":304,"updated":"2014-05-18 17:20:34.000000000","message":"suggest use HasLength matcher","commit_id":"57f90569a47bfceb5d76c4d0954c3603bc235632"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"01c521b34ba0b414df9444ba7a48215069cddfd2","unresolved":false,"context_lines":[{"line_number":301,"context_line":"                                         project_id\u003dself.tenant_bar[\u0027id\u0027],"},{"line_number":302,"context_line":"                                         role_id\u003dself.role_other[\u0027id\u0027])"},{"line_number":303,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user2[\u0027id\u0027])"},{"line_number":304,"context_line":"        self.assertEqual(len(user_projects), 2)"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"    def test_list_projects_for_user_and_groups(self):"},{"line_number":307,"context_line":"        domain \u003d self._get_domain_fixture()"}],"source_content_type":"text/x-python","patch_set":11,"id":"7adec928_dcdf82d4","line":304,"in_reply_to":"7adec928_0feb8e13","updated":"2014-05-19 07:07:56.000000000","message":"Done","commit_id":"57f90569a47bfceb5d76c4d0954c3603bc235632"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"6bfde1ab45d67dae51631000083d8df5ffd824fa","unresolved":false,"context_lines":[{"line_number":329,"context_line":""},{"line_number":330,"context_line":"        # The result is user1 has only one project granted"},{"line_number":331,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user1[\u0027id\u0027])"},{"line_number":332,"context_line":"        self.assertEqual(1, len(user_projects))"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"        # Now, delete user1 grant into tenant_bar and check"},{"line_number":335,"context_line":"        self.assignment_api.delete_grant(user_id\u003duser1[\u0027id\u0027],"}],"source_content_type":"text/x-python","patch_set":11,"id":"7adec928_cf8d267e","line":332,"updated":"2014-05-18 17:20:34.000000000","message":"suggest use HasLength matcher","commit_id":"57f90569a47bfceb5d76c4d0954c3603bc235632"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"01c521b34ba0b414df9444ba7a48215069cddfd2","unresolved":false,"context_lines":[{"line_number":329,"context_line":""},{"line_number":330,"context_line":"        # The result is user1 has only one project granted"},{"line_number":331,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user1[\u0027id\u0027])"},{"line_number":332,"context_line":"        self.assertEqual(1, len(user_projects))"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"        # Now, delete user1 grant into tenant_bar and check"},{"line_number":335,"context_line":"        self.assignment_api.delete_grant(user_id\u003duser1[\u0027id\u0027],"}],"source_content_type":"text/x-python","patch_set":11,"id":"7adec928_1cf56a56","line":332,"in_reply_to":"7adec928_cf8d267e","updated":"2014-05-19 07:07:56.000000000","message":"Done","commit_id":"57f90569a47bfceb5d76c4d0954c3603bc235632"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"6bfde1ab45d67dae51631000083d8df5ffd824fa","unresolved":false,"context_lines":[{"line_number":339,"context_line":"        # The result is user1 has only one project granted."},{"line_number":340,"context_line":"        # Granted through group1."},{"line_number":341,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user1[\u0027id\u0027])"},{"line_number":342,"context_line":"        self.assertEqual(1, len(user_projects))"},{"line_number":343,"context_line":""},{"line_number":344,"context_line":"    def test_list_projects_for_user_with_grants(self):"},{"line_number":345,"context_line":"        domain \u003d self._get_domain_fixture()"}],"source_content_type":"text/x-python","patch_set":11,"id":"7adec928_af945a8b","line":342,"updated":"2014-05-18 17:20:34.000000000","message":"suggest use HasLength matcher","commit_id":"57f90569a47bfceb5d76c4d0954c3603bc235632"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"01c521b34ba0b414df9444ba7a48215069cddfd2","unresolved":false,"context_lines":[{"line_number":339,"context_line":"        # The result is user1 has only one project granted."},{"line_number":340,"context_line":"        # Granted through group1."},{"line_number":341,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user1[\u0027id\u0027])"},{"line_number":342,"context_line":"        self.assertEqual(1, len(user_projects))"},{"line_number":343,"context_line":""},{"line_number":344,"context_line":"    def test_list_projects_for_user_with_grants(self):"},{"line_number":345,"context_line":"        domain \u003d self._get_domain_fixture()"}],"source_content_type":"text/x-python","patch_set":11,"id":"7adec928_5ceb7277","line":342,"in_reply_to":"7adec928_af945a8b","updated":"2014-05-19 07:07:56.000000000","message":"Done","commit_id":"57f90569a47bfceb5d76c4d0954c3603bc235632"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a66d090e6c915f77e9e7d25d6000e542f8d9395e","unresolved":false,"context_lines":[{"line_number":301,"context_line":"                                         project_id\u003dself.tenant_bar[\u0027id\u0027],"},{"line_number":302,"context_line":"                                         role_id\u003dself.role_other[\u0027id\u0027])"},{"line_number":303,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user2[\u0027id\u0027])"},{"line_number":304,"context_line":"        self.assertEqual(len(user_projects), 2)"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"    def test_list_projects_for_user_and_groups(self):"},{"line_number":307,"context_line":"        domain \u003d self._get_domain_fixture()"}],"source_content_type":"text/x-python","patch_set":12,"id":"7adec928_60d69f29","line":304,"updated":"2014-05-19 23:27:18.000000000","message":"suggest use HasLength matcher","commit_id":"4ec72adbccb28fc3300df2c317e487e5a0aa81f9"},{"author":{"_account_id":8533,"name":"Marcos Fermín Lobo","email":"lobo@lukos.org","username":"mlobo"},"change_message_id":"9e5c114ad916f34c3d8977753e5adf1c96629710","unresolved":false,"context_lines":[{"line_number":301,"context_line":"                                         project_id\u003dself.tenant_bar[\u0027id\u0027],"},{"line_number":302,"context_line":"                                         role_id\u003dself.role_other[\u0027id\u0027])"},{"line_number":303,"context_line":"        user_projects \u003d self.assignment_api.list_projects_for_user(user2[\u0027id\u0027])"},{"line_number":304,"context_line":"        self.assertEqual(len(user_projects), 2)"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"    def test_list_projects_for_user_and_groups(self):"},{"line_number":307,"context_line":"        domain \u003d self._get_domain_fixture()"}],"source_content_type":"text/x-python","patch_set":12,"id":"7adec928_3e34b7fa","line":304,"in_reply_to":"7adec928_60d69f29","updated":"2014-05-20 07:45:47.000000000","message":"Ups! Done.","commit_id":"4ec72adbccb28fc3300df2c317e487e5a0aa81f9"}]}
