)]}'
{"keystone/common/models.py":[{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"cc18e058d01ba887686266aedc88281d01fbed89","unresolved":false,"context_lines":[{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    required_keys \u003d (\u0027id\u0027, \u0027name\u0027)"},{"line_number":116,"context_line":"    optional_keys \u003d (\u0027description\u0027)"},{"line_number":117,"context_line":"#   optional_keys \u003d (\u0027domain_id\u0027, \u0027description\u0027)"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"class Tenant(Model):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAMX%2F%2Fz2A%3D","line":117,"updated":"2012-12-14 18:15:14.000000000","message":"Might want to remove the commented out lines in the final version.","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    required_keys \u003d (\u0027id\u0027, \u0027name\u0027)"},{"line_number":116,"context_line":"    optional_keys \u003d (\u0027description\u0027)"},{"line_number":117,"context_line":"#   optional_keys \u003d (\u0027domain_id\u0027, \u0027description\u0027)"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"class Tenant(Model):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2BCI%3D","line":117,"in_reply_to":"AAAAM3%2F%2F%2FKU%3D","updated":"2012-12-19 17:11:10.000000000","message":"Done","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    required_keys \u003d (\u0027id\u0027, \u0027name\u0027)"},{"line_number":116,"context_line":"    optional_keys \u003d (\u0027description\u0027)"},{"line_number":117,"context_line":"#   optional_keys \u003d (\u0027domain_id\u0027, \u0027description\u0027)"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"class Tenant(Model):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2FKU%3D","line":117,"in_reply_to":"AAAAMX%2F%2Fz2A%3D","updated":"2012-12-17 22:12:42.000000000","message":"+1","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"}],"keystone/common/sql/migrate_repo/versions/010_add_group_tables.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"# Copyright 2012 OpenStack LLC"},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2FJ4%3D","line":1,"updated":"2012-12-17 22:12:42.000000000","message":"i think version 12 is the latest version claimed, so this will need to be renamed after rebasing","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":27,"context_line":"        \u0027group\u0027,"},{"line_number":28,"context_line":"        meta,"},{"line_number":29,"context_line":"        sql.Column(\u0027id\u0027, sql.String(64), primary_key\u003dTrue),"},{"line_number":30,"context_line":"#       sql.Column(\u0027domain_id\u0027, sql.String(64), sql.ForeignKey(\u0027domain.id\u0027)),"},{"line_number":31,"context_line":"        sql.Column(\u0027name\u0027, sql.String(64), unique\u003dTrue, nullable\u003dFalse),"},{"line_number":32,"context_line":"        sql.Column(\u0027description\u0027, sql.Text()),"},{"line_number":33,"context_line":"        sql.Column(\u0027extra\u0027, sql.Text()))"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2FJ0%3D","line":30,"updated":"2012-12-17 22:12:42.000000000","message":"why is this commented out?","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"}],"keystone/common/sql/migrate_repo/versions/013_add_group_tables.py":[{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"ff7f5a9f78d9e005c92e0503029f224e25896064","unresolved":false,"context_lines":[{"line_number":87,"context_line":"    meta.bind \u003d migrate_engine"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    tables \u003d [\u0027group\u0027, \u0027user_group_membership\u0027, \u0027group_project_metadata\u0027,"},{"line_number":90,"context_line":"              \u0027group_domain_metadata\u0027]"},{"line_number":91,"context_line":"    for t in tables:"},{"line_number":92,"context_line":"        table \u003d sql.Table(t, meta, autoload\u003dTrue)"},{"line_number":93,"context_line":"        table.drop(migrate_engine, checkfirst\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2F1SY%3D","line":90,"updated":"2013-01-03 21:51:00.000000000","message":"Don\u0027t you need to drop the join tables first?","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":87,"context_line":"    meta.bind \u003d migrate_engine"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    tables \u003d [\u0027group\u0027, \u0027user_group_membership\u0027, \u0027group_project_metadata\u0027,"},{"line_number":90,"context_line":"              \u0027group_domain_metadata\u0027]"},{"line_number":91,"context_line":"    for t in tables:"},{"line_number":92,"context_line":"        table \u003d sql.Table(t, meta, autoload\u003dTrue)"},{"line_number":93,"context_line":"        table.drop(migrate_engine, checkfirst\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2Fz4s%3D","line":90,"in_reply_to":"AAAAM3%2F%2F1SY%3D","updated":"2013-01-05 01:36:18.000000000","message":"yes, good catch - I just saw ayoung\u0027s fix to the domain tables downgrade, so had this on this list","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"14cd9ac7867ba23ac9c081ed7858e72d3a1e4d4c","unresolved":false,"context_lines":[{"line_number":91,"context_line":"    for t in tables:"},{"line_number":92,"context_line":"        table \u003d sql.Table(t, meta, autoload\u003dTrue)"},{"line_number":93,"context_line":"        table.drop(migrate_engine, checkfirst\u003dTrue)"},{"line_number":94,"context_line":"    pass"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2FwQM%3D","line":94,"updated":"2013-01-07 21:21:31.000000000","message":"remove line 94","commit_id":"01af38686a726d8c27d371c5771b1413f3825475"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"0352b4e98ea42569c7669954865ee39e666eb03c","unresolved":false,"context_lines":[{"line_number":91,"context_line":"    for t in tables:"},{"line_number":92,"context_line":"        table \u003d sql.Table(t, meta, autoload\u003dTrue)"},{"line_number":93,"context_line":"        table.drop(migrate_engine, checkfirst\u003dTrue)"},{"line_number":94,"context_line":"    pass"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2Fvng%3D","line":94,"in_reply_to":"AAAAM3%2F%2FwQM%3D","updated":"2013-01-08 01:34:27.000000000","message":"Done","commit_id":"01af38686a726d8c27d371c5771b1413f3825475"}],"keystone/identity/backends/kvs.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        return identity.filter_user(self._get_user_by_name(user_name))"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"    def get_metadata(self, user_id\u003dNone, tenant_id\u003dNone,"},{"line_number":101,"context_line":"                     domain_id\u003dNone, group_id\u003dNone):"},{"line_number":102,"context_line":"        try:"},{"line_number":103,"context_line":"            if user_id:"},{"line_number":104,"context_line":"                return self.db.get(\u0027metadata-%s-%s\u0027 % (tenant_id, user_id))"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2FJw%3D","line":101,"updated":"2012-12-17 22:12:42.000000000","message":"you added domain_id here but didn\u0027t use it?","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        return identity.filter_user(self._get_user_by_name(user_name))"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"    def get_metadata(self, user_id\u003dNone, tenant_id\u003dNone,"},{"line_number":101,"context_line":"                     domain_id\u003dNone, group_id\u003dNone):"},{"line_number":102,"context_line":"        try:"},{"line_number":103,"context_line":"            if user_id:"},{"line_number":104,"context_line":"                return self.db.get(\u0027metadata-%s-%s\u0027 % (tenant_id, user_id))"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2BAw%3D","line":101,"in_reply_to":"AAAAM3%2F%2F%2FJw%3D","updated":"2012-12-19 17:11:10.000000000","message":"The overall domain implementation seems incomplete in general (i.e. there is no support v3 role grants on domains) -hence I don\u0027t yet use the domain parameter.  Once we get this in, I\u0027d be happy to go back and add general support for domain grants (both user and domain)","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"ed3e3f1cec99af6abd77374a84317879519d0b01","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        return identity.filter_user(self._get_user_by_name(user_name))"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"    def get_metadata(self, user_id\u003dNone, tenant_id\u003dNone,"},{"line_number":101,"context_line":"                     domain_id\u003dNone, group_id\u003dNone):"},{"line_number":102,"context_line":"        try:"},{"line_number":103,"context_line":"            if user_id:"},{"line_number":104,"context_line":"                return self.db.get(\u0027metadata-%s-%s\u0027 % (tenant_id, user_id))"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2F0Qg%3D","line":101,"updated":"2013-01-04 00:21:34.000000000","message":"The domain_id argument isn\u0027t used. Is this intentional?","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        return identity.filter_user(self._get_user_by_name(user_name))"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"    def get_metadata(self, user_id\u003dNone, tenant_id\u003dNone,"},{"line_number":101,"context_line":"                     domain_id\u003dNone, group_id\u003dNone):"},{"line_number":102,"context_line":"        try:"},{"line_number":103,"context_line":"            if user_id:"},{"line_number":104,"context_line":"                return self.db.get(\u0027metadata-%s-%s\u0027 % (tenant_id, user_id))"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2Fzm4%3D","line":101,"in_reply_to":"AAAAM3%2F%2F0Qg%3D","updated":"2013-01-05 01:36:18.000000000","message":"Domain grants are not yet supported (for users or groups) in the kvs backend - this will be added when we fix bug #1093248","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"ff7f5a9f78d9e005c92e0503029f224e25896064","unresolved":false,"context_lines":[{"line_number":243,"context_line":"        self.get_group(group_id)"},{"line_number":244,"context_line":"        user_ref \u003d self._get_user(user_id)"},{"line_number":245,"context_line":"        if not group_id in set(user_ref.get(\u0027groups\u0027, [])):"},{"line_number":246,"context_line":"            raise exception.NotFound(\u0027User not found in group\u0027)"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"    def remove_user_from_group(self, user_id, group_id):"},{"line_number":249,"context_line":"        self.get_group(group_id)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2F0bQ%3D","line":246,"updated":"2013-01-03 21:51:00.000000000","message":"i18n?\n\nraise exception.NotFound(_(\u0027User not found in group\u0027))","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":243,"context_line":"        self.get_group(group_id)"},{"line_number":244,"context_line":"        user_ref \u003d self._get_user(user_id)"},{"line_number":245,"context_line":"        if not group_id in set(user_ref.get(\u0027groups\u0027, [])):"},{"line_number":246,"context_line":"            raise exception.NotFound(\u0027User not found in group\u0027)"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"    def remove_user_from_group(self, user_id, group_id):"},{"line_number":249,"context_line":"        self.get_group(group_id)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2Fzms%3D","line":246,"in_reply_to":"AAAAM3%2F%2F0bQ%3D","updated":"2013-01-05 01:36:18.000000000","message":"Done","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"ff7f5a9f78d9e005c92e0503029f224e25896064","unresolved":false,"context_lines":[{"line_number":252,"context_line":"        try:"},{"line_number":253,"context_line":"            groups.remove(group_id)"},{"line_number":254,"context_line":"        except KeyError:"},{"line_number":255,"context_line":"            raise exception.NotFound(\u0027User not found in group\u0027)"},{"line_number":256,"context_line":"        self.update_user(user_id, {\u0027groups\u0027: list(groups)})"},{"line_number":257,"context_line":""},{"line_number":258,"context_line":"    def list_users_in_group(self, group_id):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2F0bI%3D","line":255,"updated":"2013-01-03 21:51:00.000000000","message":"i18n?","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":252,"context_line":"        try:"},{"line_number":253,"context_line":"            groups.remove(group_id)"},{"line_number":254,"context_line":"        except KeyError:"},{"line_number":255,"context_line":"            raise exception.NotFound(\u0027User not found in group\u0027)"},{"line_number":256,"context_line":"        self.update_user(user_id, {\u0027groups\u0027: list(groups)})"},{"line_number":257,"context_line":""},{"line_number":258,"context_line":"    def list_users_in_group(self, group_id):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2Fzmo%3D","line":255,"in_reply_to":"AAAAM3%2F%2F0bI%3D","updated":"2013-01-05 01:36:18.000000000","message":"Done","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"ed3e3f1cec99af6abd77374a84317879519d0b01","unresolved":false,"context_lines":[{"line_number":332,"context_line":"        self.db.delete(\u0027tenant-%s\u0027 % tenant_id)"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"    def create_metadata(self, user_id, tenant_id, metadata,"},{"line_number":335,"context_line":"                        domain_id\u003dNone, group_id\u003dNone):"},{"line_number":336,"context_line":"        if user_id:"},{"line_number":337,"context_line":"            self.db.set(\u0027metadata-%s-%s\u0027 % (tenant_id, user_id), metadata)"},{"line_number":338,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2F0N4%3D","line":335,"updated":"2013-01-04 00:21:34.000000000","message":"here\u0027s another case where domain_id isn\u0027t used. Is this intentional?","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":332,"context_line":"        self.db.delete(\u0027tenant-%s\u0027 % tenant_id)"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"    def create_metadata(self, user_id, tenant_id, metadata,"},{"line_number":335,"context_line":"                        domain_id\u003dNone, group_id\u003dNone):"},{"line_number":336,"context_line":"        if user_id:"},{"line_number":337,"context_line":"            self.db.set(\u0027metadata-%s-%s\u0027 % (tenant_id, user_id), metadata)"},{"line_number":338,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2Fzmw%3D","line":335,"in_reply_to":"AAAAM3%2F%2F0N4%3D","updated":"2013-01-05 01:36:18.000000000","message":"as above","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"ed3e3f1cec99af6abd77374a84317879519d0b01","unresolved":false,"context_lines":[{"line_number":348,"context_line":"        return metadata"},{"line_number":349,"context_line":""},{"line_number":350,"context_line":"    def delete_metadata(self, user_id, tenant_id):"},{"line_number":351,"context_line":"        self.db.delete(\u0027metadata-%s-%s\u0027 % (tenant_id, user_id))"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"    def create_role(self, role_id, role):"},{"line_number":354,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2F0N0%3D","line":351,"updated":"2013-01-04 00:21:34.000000000","message":"This function wasn\u0027t updated with group_id like the other metadata functions. Is this intentional?","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":348,"context_line":"        return metadata"},{"line_number":349,"context_line":""},{"line_number":350,"context_line":"    def delete_metadata(self, user_id, tenant_id):"},{"line_number":351,"context_line":"        self.db.delete(\u0027metadata-%s-%s\u0027 % (tenant_id, user_id))"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"    def create_role(self, role_id, role):"},{"line_number":354,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2Fzl8%3D","line":351,"in_reply_to":"AAAAM3%2F%2F0N0%3D","updated":"2013-01-05 01:36:18.000000000","message":"True...since it doesn\u0027t appear to be called from anywhere...a candidate for removal if, once we have added all the v3 functionality to here, that it is still not needed.","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"14cd9ac7867ba23ac9c081ed7858e72d3a1e4d4c","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        return identity.filter_user(self._get_user_by_name(user_name))"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"    def get_metadata(self, user_id\u003dNone, tenant_id\u003dNone,"},{"line_number":101,"context_line":"                     domain_id\u003dNone, group_id\u003dNone):"},{"line_number":102,"context_line":"        try:"},{"line_number":103,"context_line":"            if user_id:"},{"line_number":104,"context_line":"                return self.db.get(\u0027metadata-%s-%s\u0027 % (tenant_id, user_id))"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2FwQI%3D","line":101,"updated":"2013-01-07 21:21:31.000000000","message":"domain_id is not used?","commit_id":"01af38686a726d8c27d371c5771b1413f3825475"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"0352b4e98ea42569c7669954865ee39e666eb03c","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        return identity.filter_user(self._get_user_by_name(user_name))"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"    def get_metadata(self, user_id\u003dNone, tenant_id\u003dNone,"},{"line_number":101,"context_line":"                     domain_id\u003dNone, group_id\u003dNone):"},{"line_number":102,"context_line":"        try:"},{"line_number":103,"context_line":"            if user_id:"},{"line_number":104,"context_line":"                return self.db.get(\u0027metadata-%s-%s\u0027 % (tenant_id, user_id))"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2Fvjs%3D","line":101,"in_reply_to":"AAAAM3%2F%2FwQI%3D","updated":"2013-01-08 01:34:27.000000000","message":"So this was raised in a previous round of this review - domain grants (even for users) were missing entirely from the kvs backend.  There is already a bug listed that we need to come back and fix this (I\u0027ll be doing that once this initial code is in)","commit_id":"01af38686a726d8c27d371c5771b1413f3825475"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"14cd9ac7867ba23ac9c081ed7858e72d3a1e4d4c","unresolved":false,"context_lines":[{"line_number":205,"context_line":"        user \u003d utils.hash_user_password(user)"},{"line_number":206,"context_line":"        new_user \u003d user.copy()"},{"line_number":207,"context_line":"        if not \u0027groups\u0027 in new_user:"},{"line_number":208,"context_line":"            new_user[\u0027groups\u0027] \u003d []"},{"line_number":209,"context_line":""},{"line_number":210,"context_line":"        self.db.set(\u0027user-%s\u0027 % user_id, new_user)"},{"line_number":211,"context_line":"        self.db.set(\u0027user_name-%s\u0027 % new_user[\u0027name\u0027], new_user)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2FwCo%3D","line":208,"updated":"2013-01-07 21:21:31.000000000","message":"Same thing:\n\n  new_user.setdefault(\u0027groups\u0027, [])","commit_id":"01af38686a726d8c27d371c5771b1413f3825475"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"0352b4e98ea42569c7669954865ee39e666eb03c","unresolved":false,"context_lines":[{"line_number":205,"context_line":"        user \u003d utils.hash_user_password(user)"},{"line_number":206,"context_line":"        new_user \u003d user.copy()"},{"line_number":207,"context_line":"        if not \u0027groups\u0027 in new_user:"},{"line_number":208,"context_line":"            new_user[\u0027groups\u0027] \u003d []"},{"line_number":209,"context_line":""},{"line_number":210,"context_line":"        self.db.set(\u0027user-%s\u0027 % user_id, new_user)"},{"line_number":211,"context_line":"        self.db.set(\u0027user_name-%s\u0027 % new_user[\u0027name\u0027], new_user)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2Fvjk%3D","line":208,"in_reply_to":"AAAAM3%2F%2FwCo%3D","updated":"2013-01-08 01:34:27.000000000","message":"Done","commit_id":"01af38686a726d8c27d371c5771b1413f3825475"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"14cd9ac7867ba23ac9c081ed7858e72d3a1e4d4c","unresolved":false,"context_lines":[{"line_number":337,"context_line":"        self.db.delete(\u0027tenant-%s\u0027 % tenant_id)"},{"line_number":338,"context_line":""},{"line_number":339,"context_line":"    def create_metadata(self, user_id, tenant_id, metadata,"},{"line_number":340,"context_line":"                        domain_id\u003dNone, group_id\u003dNone):"},{"line_number":341,"context_line":"        if user_id:"},{"line_number":342,"context_line":"            self.db.set(\u0027metadata-%s-%s\u0027 % (tenant_id, user_id), metadata)"},{"line_number":343,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2FwCk%3D","line":340,"updated":"2013-01-07 21:21:31.000000000","message":"same question about domain_id","commit_id":"01af38686a726d8c27d371c5771b1413f3825475"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"0352b4e98ea42569c7669954865ee39e666eb03c","unresolved":false,"context_lines":[{"line_number":337,"context_line":"        self.db.delete(\u0027tenant-%s\u0027 % tenant_id)"},{"line_number":338,"context_line":""},{"line_number":339,"context_line":"    def create_metadata(self, user_id, tenant_id, metadata,"},{"line_number":340,"context_line":"                        domain_id\u003dNone, group_id\u003dNone):"},{"line_number":341,"context_line":"        if user_id:"},{"line_number":342,"context_line":"            self.db.set(\u0027metadata-%s-%s\u0027 % (tenant_id, user_id), metadata)"},{"line_number":343,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2Fvjo%3D","line":340,"in_reply_to":"AAAAM3%2F%2FwCk%3D","updated":"2013-01-08 01:34:27.000000000","message":"se earlier reply","commit_id":"01af38686a726d8c27d371c5771b1413f3825475"}],"keystone/identity/backends/ldap/core.py":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"1067128e5af79aaba8e53cb8e307f4de66ce03a1","unresolved":false,"context_lines":[{"line_number":1051,"context_line":""},{"line_number":1052,"context_line":""},{"line_number":1053,"context_line":"# TODO (henry-nash) This is a placeholder for the full LDPA implementation"},{"line_number":1054,"context_line":"# This needs to be completed (see Bug #1092187)"},{"line_number":1055,"context_line":"class GroupApi(common_ldap.BaseLdap, ApiShimMixin):"},{"line_number":1056,"context_line":"    DEFAULT_OU \u003d \u0027ou\u003dUserGroups\u0027"},{"line_number":1057,"context_line":"    DEFAULT_STRUCTURAL_CLASSES \u003d []"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2Fzh8%3D","line":1054,"updated":"2013-01-04 16:38:18.000000000","message":"I assume this TODO is still TODO?","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":1051,"context_line":""},{"line_number":1052,"context_line":""},{"line_number":1053,"context_line":"# TODO (henry-nash) This is a placeholder for the full LDPA implementation"},{"line_number":1054,"context_line":"# This needs to be completed (see Bug #1092187)"},{"line_number":1055,"context_line":"class GroupApi(common_ldap.BaseLdap, ApiShimMixin):"},{"line_number":1056,"context_line":"    DEFAULT_OU \u003d \u0027ou\u003dUserGroups\u0027"},{"line_number":1057,"context_line":"    DEFAULT_STRUCTURAL_CLASSES \u003d []"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2FyP0%3D","line":1054,"in_reply_to":"AAAAM3%2F%2Fzh8%3D","updated":"2013-01-05 01:36:18.000000000","message":"Yes, bug raised to track it","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"1067128e5af79aaba8e53cb8e307f4de66ce03a1","unresolved":false,"context_lines":[{"line_number":1071,"context_line":"        self.attribute_mapping[\u0027name\u0027] \u003d conf.ldap.group_name_attribute"},{"line_number":1072,"context_line":"        self.attribute_mapping[\u0027description\u0027] \u003d conf.ldap.group_desc_attribute"},{"line_number":1073,"context_line":"        self.member_attribute \u003d (getattr(conf.ldap, \u0027group_member_attribute\u0027)"},{"line_number":1074,"context_line":"                                 or self.DEFAULT_MEMBER_ATTRIBUTE)"},{"line_number":1075,"context_line":"        self.attribute_ignore \u003d (getattr(conf.ldap, \u0027group_attribute_ignore\u0027)"},{"line_number":1076,"context_line":"                                 or self.DEFAULT_ATTRIBUTE_IGNORE)"},{"line_number":1077,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2FzjQ%3D","line":1074,"updated":"2013-01-04 16:38:18.000000000","message":"There\u0027s a default for the conf setting so should not have \u0027or self.DEFAULT_MEMBER_ATTRIBUTE\u0027. This same comment applies to other conf settings that have a default.","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":1071,"context_line":"        self.attribute_mapping[\u0027name\u0027] \u003d conf.ldap.group_name_attribute"},{"line_number":1072,"context_line":"        self.attribute_mapping[\u0027description\u0027] \u003d conf.ldap.group_desc_attribute"},{"line_number":1073,"context_line":"        self.member_attribute \u003d (getattr(conf.ldap, \u0027group_member_attribute\u0027)"},{"line_number":1074,"context_line":"                                 or self.DEFAULT_MEMBER_ATTRIBUTE)"},{"line_number":1075,"context_line":"        self.attribute_ignore \u003d (getattr(conf.ldap, \u0027group_attribute_ignore\u0027)"},{"line_number":1076,"context_line":"                                 or self.DEFAULT_ATTRIBUTE_IGNORE)"},{"line_number":1077,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2FyO0%3D","line":1074,"in_reply_to":"AAAAM3%2F%2FzjQ%3D","updated":"2013-01-05 01:36:18.000000000","message":"Was just trying to be consistent for how the other API entities are handled in this file.  When we come back an implement this fully, will take a look at them.","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"ff7f5a9f78d9e005c92e0503029f224e25896064","unresolved":false,"context_lines":[{"line_number":1111,"context_line":"        except exception.NotFound:"},{"line_number":1112,"context_line":"            raise exception.GroupNotFound(group_id\u003did)"},{"line_number":1113,"context_line":"        if old_obj[\u0027name\u0027] !\u003d values[\u0027name\u0027]:"},{"line_number":1114,"context_line":"            msg \u003d \u0027Changing Name not supported by LDAP\u0027"},{"line_number":1115,"context_line":"            raise exception.NotImplemented(message\u003dmsg)"},{"line_number":1116,"context_line":"        super(GroupApi, self).update(id, values, old_obj)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2F0bE%3D","line":1114,"updated":"2013-01-03 21:51:00.000000000","message":"i18n?","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":1111,"context_line":"        except exception.NotFound:"},{"line_number":1112,"context_line":"            raise exception.GroupNotFound(group_id\u003did)"},{"line_number":1113,"context_line":"        if old_obj[\u0027name\u0027] !\u003d values[\u0027name\u0027]:"},{"line_number":1114,"context_line":"            msg \u003d \u0027Changing Name not supported by LDAP\u0027"},{"line_number":1115,"context_line":"            raise exception.NotImplemented(message\u003dmsg)"},{"line_number":1116,"context_line":"        super(GroupApi, self).update(id, values, old_obj)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2Fzl4%3D","line":1114,"in_reply_to":"AAAAM3%2F%2F0bE%3D","updated":"2013-01-05 01:36:18.000000000","message":"Done","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"}],"keystone/identity/backends/sql.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":49,"context_line":""},{"line_number":50,"context_line":"class Group(sql.ModelBase, sql.DictBase):"},{"line_number":51,"context_line":"    __tablename__ \u003d \u0027group\u0027"},{"line_number":52,"context_line":"    attributes \u003d [\u0027id\u0027, \u0027name\u0027]"},{"line_number":53,"context_line":"    id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":54,"context_line":"    # TODO(henry-nash): Add the domain_id when we do this for users as well"},{"line_number":55,"context_line":"    # domain_id \u003d sql.Column(sql.String(64), sql.ForeignKey(\u0027domain.id\u0027))"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2FJg%3D","line":52,"updated":"2012-12-17 22:12:42.000000000","message":"add description; domain_id will go here as well","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":49,"context_line":""},{"line_number":50,"context_line":"class Group(sql.ModelBase, sql.DictBase):"},{"line_number":51,"context_line":"    __tablename__ \u003d \u0027group\u0027"},{"line_number":52,"context_line":"    attributes \u003d [\u0027id\u0027, \u0027name\u0027]"},{"line_number":53,"context_line":"    id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":54,"context_line":"    # TODO(henry-nash): Add the domain_id when we do this for users as well"},{"line_number":55,"context_line":"    # domain_id \u003d sql.Column(sql.String(64), sql.ForeignKey(\u0027domain.id\u0027))"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F9wY%3D","line":52,"in_reply_to":"AAAAM3%2F%2F%2FJg%3D","updated":"2012-12-19 17:11:10.000000000","message":"Done","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":55,"context_line":"    # domain_id \u003d sql.Column(sql.String(64), sql.ForeignKey(\u0027domain.id\u0027))"},{"line_number":56,"context_line":"    name \u003d sql.Column(sql.String(64), unique\u003dTrue, nullable\u003dFalse)"},{"line_number":57,"context_line":"    description \u003d sql.Column(sql.Text())"},{"line_number":58,"context_line":"    # TODO(henry-nash): I\u0027m not sure we need the extra column"},{"line_number":59,"context_line":"    extra \u003d sql.Column(sql.JsonBlob())"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2FJk%3D","line":58,"updated":"2012-12-17 22:12:42.000000000","message":"you can remove this, it\u0027s necessary for consistency if nothing else","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":55,"context_line":"    # domain_id \u003d sql.Column(sql.String(64), sql.ForeignKey(\u0027domain.id\u0027))"},{"line_number":56,"context_line":"    name \u003d sql.Column(sql.String(64), unique\u003dTrue, nullable\u003dFalse)"},{"line_number":57,"context_line":"    description \u003d sql.Column(sql.Text())"},{"line_number":58,"context_line":"    # TODO(henry-nash): I\u0027m not sure we need the extra column"},{"line_number":59,"context_line":"    extra \u003d sql.Column(sql.JsonBlob())"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F9wU%3D","line":58,"in_reply_to":"AAAAM3%2F%2F%2FJk%3D","updated":"2012-12-19 17:11:10.000000000","message":"Done","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":100,"context_line":"    extra \u003d sql.Column(sql.JsonBlob())"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"class UserProjectMetadata(sql.ModelBase, sql.DictBase):"},{"line_number":104,"context_line":"    # TODO(dolph): rename to user_project_metadata (needs a migration)"},{"line_number":105,"context_line":"    __tablename__ \u003d \u0027metadata\u0027"},{"line_number":106,"context_line":"    user_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2FIo%3D","line":103,"updated":"2012-12-17 22:12:42.000000000","message":"UserProjectGrant","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":100,"context_line":"    extra \u003d sql.Column(sql.JsonBlob())"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"class UserProjectMetadata(sql.ModelBase, sql.DictBase):"},{"line_number":104,"context_line":"    # TODO(dolph): rename to user_project_metadata (needs a migration)"},{"line_number":105,"context_line":"    __tablename__ \u003d \u0027metadata\u0027"},{"line_number":106,"context_line":"    user_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F8g4%3D","line":103,"in_reply_to":"AAAAM3%2F%2F%2FIo%3D","updated":"2012-12-19 17:11:10.000000000","message":"Done","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":108,"context_line":"    tenant_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":109,"context_line":"    data \u003d sql.Column(sql.JsonBlob())"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    def to_dict(self):"},{"line_number":112,"context_line":"        \"\"\"Override parent to_dict() method with a simpler implementation."},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"        Metadata doesn\u0027t have non-indexed \u0027extra\u0027 attributes, so the parent"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2FIg%3D","line":111,"updated":"2012-12-17 22:12:42.000000000","message":"You can abstract this to a BaseGrant class or something, that simply defines role_id and overrides to_dict","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":108,"context_line":"    tenant_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":109,"context_line":"    data \u003d sql.Column(sql.JsonBlob())"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    def to_dict(self):"},{"line_number":112,"context_line":"        \"\"\"Override parent to_dict() method with a simpler implementation."},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"        Metadata doesn\u0027t have non-indexed \u0027extra\u0027 attributes, so the parent"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F8fg%3D","line":111,"in_reply_to":"AAAAM3%2F%2F%2FIg%3D","updated":"2012-12-19 17:11:10.000000000","message":"Done","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":117,"context_line":"        return dict(self.iteritems())"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"class UserDomainMetadata(sql.ModelBase, sql.DictBase):"},{"line_number":121,"context_line":"    __tablename__ \u003d \u0027user_domain_metadata\u0027"},{"line_number":122,"context_line":"    user_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":123,"context_line":"    domain_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2FIs%3D","line":120,"updated":"2012-12-17 22:12:42.000000000","message":"feel free to rename this object to UserDomainGrant","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":117,"context_line":"        return dict(self.iteritems())"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"class UserDomainMetadata(sql.ModelBase, sql.DictBase):"},{"line_number":121,"context_line":"    __tablename__ \u003d \u0027user_domain_metadata\u0027"},{"line_number":122,"context_line":"    user_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":123,"context_line":"    domain_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F8gs%3D","line":120,"in_reply_to":"AAAAM3%2F%2F%2FIs%3D","updated":"2012-12-19 17:11:10.000000000","message":"Done","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    data \u003d sql.Column(sql.JsonBlob())"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"class GroupProjectMetadata(sql.ModelBase, sql.DictBase):"},{"line_number":128,"context_line":"    __tablename__ \u003d \u0027group_project_metadata\u0027"},{"line_number":129,"context_line":"    group_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":130,"context_line":"    project_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2FJE%3D","line":127,"updated":"2012-12-17 22:12:42.000000000","message":"GroupProjectGrant","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    data \u003d sql.Column(sql.JsonBlob())"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"class GroupProjectMetadata(sql.ModelBase, sql.DictBase):"},{"line_number":128,"context_line":"    __tablename__ \u003d \u0027group_project_metadata\u0027"},{"line_number":129,"context_line":"    group_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":130,"context_line":"    project_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F8go%3D","line":127,"in_reply_to":"AAAAM3%2F%2F%2FJE%3D","updated":"2012-12-19 17:11:10.000000000","message":"Done","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":128,"context_line":"    __tablename__ \u003d \u0027group_project_metadata\u0027"},{"line_number":129,"context_line":"    group_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":130,"context_line":"    project_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":131,"context_line":"    data \u003d sql.Column(sql.JsonBlob())"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"class GroupDomainMetadata(sql.ModelBase, sql.DictBase):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2FI4%3D","line":131,"updated":"2012-12-17 22:12:42.000000000","message":"replace \u0027data\u0027 with role_id; see below","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":128,"context_line":"    __tablename__ \u003d \u0027group_project_metadata\u0027"},{"line_number":129,"context_line":"    group_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":130,"context_line":"    project_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":131,"context_line":"    data \u003d sql.Column(sql.JsonBlob())"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"class GroupDomainMetadata(sql.ModelBase, sql.DictBase):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F8gY%3D","line":131,"in_reply_to":"AAAAM3%2F%2F%2FI4%3D","updated":"2012-12-19 17:11:10.000000000","message":"See my comment below","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":131,"context_line":"    data \u003d sql.Column(sql.JsonBlob())"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"class GroupDomainMetadata(sql.ModelBase, sql.DictBase):"},{"line_number":135,"context_line":"    __tablename__ \u003d \u0027group_domain_metadata\u0027"},{"line_number":136,"context_line":"    group_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":137,"context_line":"    domain_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2FJA%3D","line":134,"updated":"2012-12-17 22:12:42.000000000","message":"GroupDomainGrant","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":131,"context_line":"    data \u003d sql.Column(sql.JsonBlob())"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"class GroupDomainMetadata(sql.ModelBase, sql.DictBase):"},{"line_number":135,"context_line":"    __tablename__ \u003d \u0027group_domain_metadata\u0027"},{"line_number":136,"context_line":"    group_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":137,"context_line":"    domain_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F8gk%3D","line":134,"in_reply_to":"AAAAM3%2F%2F%2FJA%3D","updated":"2012-12-19 17:11:10.000000000","message":"Done","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":135,"context_line":"    __tablename__ \u003d \u0027group_domain_metadata\u0027"},{"line_number":136,"context_line":"    group_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":137,"context_line":"    domain_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":138,"context_line":"    data \u003d sql.Column(sql.JsonBlob())"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"# TODO(dolph): ... do we need this table?"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2FJI%3D","line":138,"updated":"2012-12-17 22:12:42.000000000","message":"Instead of following the \"metadata\" pattern, I\u0027d prefer this to be normalized as: group_id, domain_id, role_id\n\nThe existing metadata table needs to be migrated to this pattern as well.","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":135,"context_line":"    __tablename__ \u003d \u0027group_domain_metadata\u0027"},{"line_number":136,"context_line":"    group_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":137,"context_line":"    domain_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":138,"context_line":"    data \u003d sql.Column(sql.JsonBlob())"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"# TODO(dolph): ... do we need this table?"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F8gg%3D","line":138,"in_reply_to":"AAAAM3%2F%2F%2FJI%3D","updated":"2012-12-19 17:11:10.000000000","message":"Perhaps we could merge these changes in first, then I will go back in and do a common refactor?","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":265,"context_line":"            # TODO (henry-nash) If there are no grants at all for anyone in the"},{"line_number":266,"context_line":"            # particular metadata table, then this currently incorrectly"},{"line_number":267,"context_line":"            # reports an error (this is an existing issue, unrelated to the"},{"line_number":268,"context_line":"            # changes for groups)"},{"line_number":269,"context_line":"            raise exception.MetadataNotFound()"},{"line_number":270,"context_line":""},{"line_number":271,"context_line":"    def create_grant(self, role_id, user_id, group_id, domain_id, project_id):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2FIc%3D","line":268,"updated":"2012-12-17 22:12:42.000000000","message":"I don\u0027t think the bug is here; the bug is that this exception is being exposed to the API, rather than being caught at the controller/manager and transformed to a default value.\n\nAlso, is there a bug for this?","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":265,"context_line":"            # TODO (henry-nash) If there are no grants at all for anyone in the"},{"line_number":266,"context_line":"            # particular metadata table, then this currently incorrectly"},{"line_number":267,"context_line":"            # reports an error (this is an existing issue, unrelated to the"},{"line_number":268,"context_line":"            # changes for groups)"},{"line_number":269,"context_line":"            raise exception.MetadataNotFound()"},{"line_number":270,"context_line":""},{"line_number":271,"context_line":"    def create_grant(self, role_id, user_id, group_id, domain_id, project_id):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F8d8%3D","line":268,"in_reply_to":"AAAAM3%2F%2F%2FIc%3D","updated":"2012-12-19 17:11:10.000000000","message":"Agreed. Bug #1092200 raised and assigned to me :-)","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":284,"context_line":"            metadata_ref \u003d self.get_metadata(user_id, project_id,"},{"line_number":285,"context_line":"                                             domain_id, group_id)"},{"line_number":286,"context_line":"            is_new \u003d False"},{"line_number":287,"context_line":"        except exception.MetadataNotFound:"},{"line_number":288,"context_line":"            metadata_ref \u003d {}"},{"line_number":289,"context_line":"            is_new \u003d True"},{"line_number":290,"context_line":"        roles \u003d set(metadata_ref.get(\u0027roles\u0027, []))"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2FIA%3D","line":287,"updated":"2012-12-17 22:12:42.000000000","message":"on the above comment, this is how calls to get_metadata  should be handled","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":284,"context_line":"            metadata_ref \u003d self.get_metadata(user_id, project_id,"},{"line_number":285,"context_line":"                                             domain_id, group_id)"},{"line_number":286,"context_line":"            is_new \u003d False"},{"line_number":287,"context_line":"        except exception.MetadataNotFound:"},{"line_number":288,"context_line":"            metadata_ref \u003d {}"},{"line_number":289,"context_line":"            is_new \u003d True"},{"line_number":290,"context_line":"        roles \u003d set(metadata_ref.get(\u0027roles\u0027, []))"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F8dw%3D","line":287,"in_reply_to":"AAAAM3%2F%2F%2FIA%3D","updated":"2012-12-19 17:11:10.000000000","message":"Yep - agreed","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"cc18e058d01ba887686266aedc88281d01fbed89","unresolved":false,"context_lines":[{"line_number":500,"context_line":"                        domain_id\u003dNone, group_id\u003dNone):"},{"line_number":501,"context_line":"        session \u003d self.get_session()"},{"line_number":502,"context_line":"        with session.begin():"},{"line_number":503,"context_line":"            if user_id:"},{"line_number":504,"context_line":"                if tenant_id:"},{"line_number":505,"context_line":"                    session.add(UserProjectMetadata(user_id\u003duser_id,"},{"line_number":506,"context_line":"                                                    tenant_id\u003dtenant_id,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAMX%2F%2Fzys%3D","line":503,"updated":"2012-12-14 18:15:14.000000000","message":"To many if .. elif ..\n\nTime to refactor?","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":500,"context_line":"                        domain_id\u003dNone, group_id\u003dNone):"},{"line_number":501,"context_line":"        session \u003d self.get_session()"},{"line_number":502,"context_line":"        with session.begin():"},{"line_number":503,"context_line":"            if user_id:"},{"line_number":504,"context_line":"                if tenant_id:"},{"line_number":505,"context_line":"                    session.add(UserProjectMetadata(user_id\u003duser_id,"},{"line_number":506,"context_line":"                                                    tenant_id\u003dtenant_id,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F8bQ%3D","line":503,"in_reply_to":"AAAAMX%2F%2Fzys%3D","updated":"2012-12-19 17:11:10.000000000","message":"Probably.  Dolph has requested we move away form the whole metadata idea...and have more normalized tables....so I\u0027m going to come back and look at this as a refactor.  I\u0027ll keep this in mind too.","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":528,"context_line":"        with session.begin():"},{"line_number":529,"context_line":"            if user_id:"},{"line_number":530,"context_line":"                if tenant_id:"},{"line_number":531,"context_line":"                    metadata_ref \u003d session.query(UserProjectMetadata)\\"},{"line_number":532,"context_line":"                                          .filter_by(user_id\u003duser_id)\\"},{"line_number":533,"context_line":"                                          .filter_by(tenant_id\u003dtenant_id)\\"},{"line_number":534,"context_line":"                                          .first()"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2FAU%3D","line":531,"updated":"2012-12-17 22:12:42.000000000","message":"can you rewrite these as seen in delete_tenant?\n\n  q \u003d session.query()\n  q \u003d q.whatever()\n\nand then you can extract stuff like:\n\n  metadata_ref \u003d q.first()","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":528,"context_line":"        with session.begin():"},{"line_number":529,"context_line":"            if user_id:"},{"line_number":530,"context_line":"                if tenant_id:"},{"line_number":531,"context_line":"                    metadata_ref \u003d session.query(UserProjectMetadata)\\"},{"line_number":532,"context_line":"                                          .filter_by(user_id\u003duser_id)\\"},{"line_number":533,"context_line":"                                          .filter_by(tenant_id\u003dtenant_id)\\"},{"line_number":534,"context_line":"                                          .first()"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F8cI%3D","line":531,"in_reply_to":"AAAAM3%2F%2F%2FAU%3D","updated":"2012-12-19 17:11:10.000000000","message":"Done","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":220,"name":"Haneef Ali","email":"haneef.ali@hp.com","username":"haneef"},"change_message_id":"ed62d51c67041184472fdc01d6fd4404c0fe8045","unresolved":false,"context_lines":[{"line_number":51,"context_line":"    __tablename__ \u003d \u0027group\u0027"},{"line_number":52,"context_line":"    attributes \u003d [\u0027id\u0027, \u0027name\u0027, \u0027domain_id\u0027]"},{"line_number":53,"context_line":"    id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":54,"context_line":"    name \u003d sql.Column(sql.String(64), unique\u003dTrue, nullable\u003dFalse)"},{"line_number":55,"context_line":"    domain_id \u003d sql.Column(sql.String(64), sql.ForeignKey(\u0027domain.id\u0027))"},{"line_number":56,"context_line":"    description \u003d sql.Column(sql.Text())"},{"line_number":57,"context_line":"    extra \u003d sql.Column(sql.JsonBlob())"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2FwL8%3D","line":54,"updated":"2013-01-07 16:56:39.000000000","message":"In the blueprint, group name is supposed to be unique within a domain. How it it enforced?","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"1067128e5af79aaba8e53cb8e307f4de66ce03a1","unresolved":false,"context_lines":[{"line_number":54,"context_line":"    name \u003d sql.Column(sql.String(64), unique\u003dTrue, nullable\u003dFalse)"},{"line_number":55,"context_line":"    domain_id \u003d sql.Column(sql.String(64), sql.ForeignKey(\u0027domain.id\u0027))"},{"line_number":56,"context_line":"    description \u003d sql.Column(sql.Text())"},{"line_number":57,"context_line":"    extra \u003d sql.Column(sql.JsonBlob())"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"class Credential(sql.ModelBase, sql.DictBase):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2Fzhk%3D","line":57,"updated":"2013-01-04 16:38:18.000000000","message":"In 013_add_group_tables.py, the extra column is sql.Text(), whereas here it\u0027s sql.JsonBlob(). Must the types be the same? This same comment applies to the group_project_metadata and group_domain_metadata data columns in the classes below.","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":54,"context_line":"    name \u003d sql.Column(sql.String(64), unique\u003dTrue, nullable\u003dFalse)"},{"line_number":55,"context_line":"    domain_id \u003d sql.Column(sql.String(64), sql.ForeignKey(\u0027domain.id\u0027))"},{"line_number":56,"context_line":"    description \u003d sql.Column(sql.Text())"},{"line_number":57,"context_line":"    extra \u003d sql.Column(sql.JsonBlob())"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"class Credential(sql.ModelBase, sql.DictBase):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2FyOM%3D","line":57,"in_reply_to":"AAAAM3%2F%2Fzhk%3D","updated":"2013-01-05 01:36:18.000000000","message":"JsonBlob() is a decorated sql.Text()....and the standard way all the other tables are defined is to use Text() in the table creation/migration files.","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"1067128e5af79aaba8e53cb8e307f4de66ce03a1","unresolved":false,"context_lines":[{"line_number":102,"context_line":"    def to_dict(self):"},{"line_number":103,"context_line":"        \"\"\"Override parent to_dict() method with a simpler implementation."},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"        Grant tables doesn\u0027t have non-indexed \u0027extra\u0027 attributes, so the"},{"line_number":106,"context_line":"        parent implementation is not applicable."},{"line_number":107,"context_line":"        \"\"\""},{"line_number":108,"context_line":"        return dict(self.iteritems())"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2FzhY%3D","line":105,"updated":"2013-01-04 16:38:18.000000000","message":"doesn\u0027t -\u003e don\u0027t","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":102,"context_line":"    def to_dict(self):"},{"line_number":103,"context_line":"        \"\"\"Override parent to_dict() method with a simpler implementation."},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"        Grant tables doesn\u0027t have non-indexed \u0027extra\u0027 attributes, so the"},{"line_number":106,"context_line":"        parent implementation is not applicable."},{"line_number":107,"context_line":"        \"\"\""},{"line_number":108,"context_line":"        return dict(self.iteritems())"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2FyOI%3D","line":105,"in_reply_to":"AAAAM3%2F%2FzhY%3D","updated":"2013-01-05 01:36:18.000000000","message":"Done","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"1067128e5af79aaba8e53cb8e307f4de66ce03a1","unresolved":false,"context_lines":[{"line_number":109,"context_line":""},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"class UserProjectGrant(sql.ModelBase, BaseGrant):"},{"line_number":112,"context_line":"    # TODO(dolph): rename to user_project_metadata (needs a migration)"},{"line_number":113,"context_line":"    __tablename__ \u003d \u0027metadata\u0027"},{"line_number":114,"context_line":"    user_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":115,"context_line":"    # TODO(dolph): rename to project_id (needs a migration)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2Fzg0%3D","line":112,"updated":"2013-01-04 16:38:18.000000000","message":"Is it worth it to \"rename to user_project_metadata\" with this change? (or rename it to user_project_grant instead of user_project_metadata)","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":109,"context_line":""},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"class UserProjectGrant(sql.ModelBase, BaseGrant):"},{"line_number":112,"context_line":"    # TODO(dolph): rename to user_project_metadata (needs a migration)"},{"line_number":113,"context_line":"    __tablename__ \u003d \u0027metadata\u0027"},{"line_number":114,"context_line":"    user_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":115,"context_line":"    # TODO(dolph): rename to project_id (needs a migration)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2FyNw%3D","line":112,"in_reply_to":"AAAAM3%2F%2Fzg0%3D","updated":"2013-01-05 01:36:18.000000000","message":"So good idea - however, Dolph has asked that we refactor all these metadata tables to normalize them (e.g. user_id/group_id/role_id attributes).  So one this change is in I will come back and do that refractor...and do the migrations as well - hence don\u0027t think it was worth changing this name until we do that","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"1067128e5af79aaba8e53cb8e307f4de66ce03a1","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    data \u003d sql.Column(sql.JsonBlob())"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"class GroupProjectGrant(sql.ModelBase, sql.DictBase):"},{"line_number":128,"context_line":"    __tablename__ \u003d \u0027group_project_metadata\u0027"},{"line_number":129,"context_line":"    group_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":130,"context_line":"    project_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2Fzgs%3D","line":127,"updated":"2013-01-04 16:38:18.000000000","message":"why is this one sql.DictBase and not BaseGrant? (same applies to GroupDomainGrant class below)","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    data \u003d sql.Column(sql.JsonBlob())"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"class GroupProjectGrant(sql.ModelBase, sql.DictBase):"},{"line_number":128,"context_line":"    __tablename__ \u003d \u0027group_project_metadata\u0027"},{"line_number":129,"context_line":"    group_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":130,"context_line":"    project_id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2FyNE%3D","line":127,"in_reply_to":"AAAAM3%2F%2Fzgs%3D","updated":"2013-01-05 01:36:18.000000000","message":"Good catch, missed that update.","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"ff7f5a9f78d9e005c92e0503029f224e25896064","unresolved":false,"context_lines":[{"line_number":746,"context_line":"        query \u003d session.query(UserGroupMembership)"},{"line_number":747,"context_line":"        query \u003d query.filter_by(user_id\u003duser_id)"},{"line_number":748,"context_line":"        query \u003d query.filter_by(group_id\u003dgroup_id)"},{"line_number":749,"context_line":"        rv \u003d query.first()"},{"line_number":750,"context_line":"        if rv:"},{"line_number":751,"context_line":"            return"},{"line_number":752,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2F0aw%3D","line":749,"updated":"2013-01-03 21:51:00.000000000","message":"Looks like you are duplicating code here. Can you do this instead?\n\ntry:\n    self.check_user_in_group(user_id, group_id)\nexcept exception.NotFound:\n   ... add user to group","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":746,"context_line":"        query \u003d session.query(UserGroupMembership)"},{"line_number":747,"context_line":"        query \u003d query.filter_by(user_id\u003duser_id)"},{"line_number":748,"context_line":"        query \u003d query.filter_by(group_id\u003dgroup_id)"},{"line_number":749,"context_line":"        rv \u003d query.first()"},{"line_number":750,"context_line":"        if rv:"},{"line_number":751,"context_line":"            return"},{"line_number":752,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2FzkA%3D","line":749,"in_reply_to":"AAAAM3%2F%2F0aw%3D","updated":"2013-01-05 01:36:18.000000000","message":"Good idea...although it\u0027s a little more complicated than that, since as well as NotFound, you might get UserNotFound or GroupNotFound (from the get_user and get_group calls) - both of which are derived from the NotFound class....making the exception filtering tricky....so I considered the code saving to be not worth it.","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"ff7f5a9f78d9e005c92e0503029f224e25896064","unresolved":false,"context_lines":[{"line_number":774,"context_line":"        query \u003d query.filter_by(group_id\u003dgroup_id)"},{"line_number":775,"context_line":"        membership_ref \u003d query.first()"},{"line_number":776,"context_line":"        if membership_ref is None:"},{"line_number":777,"context_line":"            raise exception.NotFound(\u0027User not found in group\u0027)"},{"line_number":778,"context_line":"        with session.begin():"},{"line_number":779,"context_line":"            session.delete(membership_ref)"},{"line_number":780,"context_line":"            session.flush()"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2F0ao%3D","line":777,"updated":"2013-01-03 21:51:00.000000000","message":"Same as above. May want to consider self.check_user_in_group() instead of duplicating code.","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":774,"context_line":"        query \u003d query.filter_by(group_id\u003dgroup_id)"},{"line_number":775,"context_line":"        membership_ref \u003d query.first()"},{"line_number":776,"context_line":"        if membership_ref is None:"},{"line_number":777,"context_line":"            raise exception.NotFound(\u0027User not found in group\u0027)"},{"line_number":778,"context_line":"        with session.begin():"},{"line_number":779,"context_line":"            session.delete(membership_ref)"},{"line_number":780,"context_line":"            session.flush()"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2Fzj8%3D","line":777,"in_reply_to":"AAAAM3%2F%2F0ao%3D","updated":"2013-01-05 01:36:18.000000000","message":"see above","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":220,"name":"Haneef Ali","email":"haneef.ali@hp.com","username":"haneef"},"change_message_id":"ed62d51c67041184472fdc01d6fd4404c0fe8045","unresolved":false,"context_lines":[{"line_number":822,"context_line":""},{"line_number":823,"context_line":"    @handle_conflicts(type\u003d\u0027group\u0027)"},{"line_number":824,"context_line":"    def create_group(self, group_id, group):"},{"line_number":825,"context_line":"        session \u003d self.get_session()"},{"line_number":826,"context_line":"        with session.begin():"},{"line_number":827,"context_line":"            ref \u003d Group.from_dict(group)"},{"line_number":828,"context_line":"            session.add(ref)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2FwLI%3D","line":825,"updated":"2013-01-07 16:56:39.000000000","message":"As per blueprint, domain id is optional and if not specified it should be part of some common domain? Where is that implemented?","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"ff7f5a9f78d9e005c92e0503029f224e25896064","unresolved":false,"context_lines":[{"line_number":877,"context_line":""},{"line_number":878,"context_line":"            q \u003d session.query(GroupDomainGrant)"},{"line_number":879,"context_line":"            q \u003d q.filter_by(group_id\u003dgroup_id)"},{"line_number":880,"context_line":"            q.delete(False)"},{"line_number":881,"context_line":""},{"line_number":882,"context_line":"            if not session.query(Group).filter_by(id\u003dgroup_id).delete(False):"},{"line_number":883,"context_line":"                raise exception.GroupNotFound(group_id\u003dgroup_id)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2F0ag%3D","line":880,"updated":"2013-01-03 21:51:00.000000000","message":"Don\u0027t we have to cleanup UserGroupMembership as well or is that being done higher up?","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":877,"context_line":""},{"line_number":878,"context_line":"            q \u003d session.query(GroupDomainGrant)"},{"line_number":879,"context_line":"            q \u003d q.filter_by(group_id\u003dgroup_id)"},{"line_number":880,"context_line":"            q.delete(False)"},{"line_number":881,"context_line":""},{"line_number":882,"context_line":"            if not session.query(Group).filter_by(id\u003dgroup_id).delete(False):"},{"line_number":883,"context_line":"                raise exception.GroupNotFound(group_id\u003dgroup_id)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2Fziw%3D","line":880,"in_reply_to":"AAAAM3%2F%2F0ag%3D","updated":"2013-01-05 01:36:18.000000000","message":"Nice catch....also required for delete user","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"}],"keystone/identity/core.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"14cd9ac7867ba23ac9c081ed7858e72d3a1e4d4c","unresolved":false,"context_lines":[{"line_number":213,"context_line":"        raise exception.NotImplemented()"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"    def delete_metadata(self, user_id, tenant_id):"},{"line_number":216,"context_line":"        raise exception.NotImplemented()"},{"line_number":217,"context_line":""},{"line_number":218,"context_line":"    # domain crud"},{"line_number":219,"context_line":"    def create_domain(self, domain_id, domain):"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2FwCY%3D","line":216,"updated":"2013-01-07 21:21:31.000000000","message":"new metadata signatures need to be documented here","commit_id":"01af38686a726d8c27d371c5771b1413f3825475"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"0352b4e98ea42569c7669954865ee39e666eb03c","unresolved":false,"context_lines":[{"line_number":213,"context_line":"        raise exception.NotImplemented()"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"    def delete_metadata(self, user_id, tenant_id):"},{"line_number":216,"context_line":"        raise exception.NotImplemented()"},{"line_number":217,"context_line":""},{"line_number":218,"context_line":"    # domain crud"},{"line_number":219,"context_line":"    def create_domain(self, domain_id, domain):"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2Fvi0%3D","line":216,"in_reply_to":"AAAAM3%2F%2FwCY%3D","updated":"2013-01-08 01:34:27.000000000","message":"Done","commit_id":"01af38686a726d8c27d371c5771b1413f3825475"}],"keystone/test.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":231,"context_line":"                    self.identity_api.add_user_to_tenant(tenant_id, user[\u0027id\u0027])"},{"line_number":232,"context_line":"                setattr(self, \u0027user_%s\u0027 % user[\u0027id\u0027], user_copy)"},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"            for group in fixtures.GROUPS:"},{"line_number":235,"context_line":"                group_copy \u003d group.copy()"},{"line_number":236,"context_line":"                rv \u003d self.identity_api.create_group(group[\u0027id\u0027],"},{"line_number":237,"context_line":"                                                    group_copy.copy())"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2B3c%3D","line":234,"updated":"2012-12-17 22:12:42.000000000","message":"would vastly prefer to eliminate load_fixtures() since these have to be loaded for so many tests... if you can, do this kind of work explicitly in the setUp for the subset of tests your need them for","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":231,"context_line":"                    self.identity_api.add_user_to_tenant(tenant_id, user[\u0027id\u0027])"},{"line_number":232,"context_line":"                setattr(self, \u0027user_%s\u0027 % user[\u0027id\u0027], user_copy)"},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"            for group in fixtures.GROUPS:"},{"line_number":235,"context_line":"                group_copy \u003d group.copy()"},{"line_number":236,"context_line":"                rv \u003d self.identity_api.create_group(group[\u0027id\u0027],"},{"line_number":237,"context_line":"                                                    group_copy.copy())"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F91g%3D","line":234,"in_reply_to":"AAAAM3%2F%2F%2B3c%3D","updated":"2012-12-19 17:11:10.000000000","message":"I\u0027ll look at that.","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":234,"context_line":"            for group in fixtures.GROUPS:"},{"line_number":235,"context_line":"                group_copy \u003d group.copy()"},{"line_number":236,"context_line":"                rv \u003d self.identity_api.create_group(group[\u0027id\u0027],"},{"line_number":237,"context_line":"                                                    group_copy.copy())"},{"line_number":238,"context_line":"                setattr(self, \u0027group_%s\u0027 % group[\u0027id\u0027], group_copy)"},{"line_number":239,"context_line":""},{"line_number":240,"context_line":"            for role in fixtures.ROLES:"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2B34%3D","line":237,"updated":"2012-12-17 22:12:42.000000000","message":"you shouldn\u0027t need the .copy(), as the driver shouldn\u0027t manipulate the reference you pass in","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":234,"context_line":"            for group in fixtures.GROUPS:"},{"line_number":235,"context_line":"                group_copy \u003d group.copy()"},{"line_number":236,"context_line":"                rv \u003d self.identity_api.create_group(group[\u0027id\u0027],"},{"line_number":237,"context_line":"                                                    group_copy.copy())"},{"line_number":238,"context_line":"                setattr(self, \u0027group_%s\u0027 % group[\u0027id\u0027], group_copy)"},{"line_number":239,"context_line":""},{"line_number":240,"context_line":"            for role in fixtures.ROLES:"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F91s%3D","line":237,"in_reply_to":"AAAAM3%2F%2F%2B34%3D","updated":"2012-12-19 17:11:10.000000000","message":"Done","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"}],"keystone/token/controllers.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":171,"context_line":"        tenant_ref \u003d self._get_tenant_ref(context, user_id, tenant_id)"},{"line_number":172,"context_line":"        metadata_ref \u003d self._get_metadata_ref(context, user_id, tenant_id)"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"        # TODO (henry-nash) This is the example code we would enable to"},{"line_number":175,"context_line":"        # include whatever group roles are in place for the project"},{"line_number":176,"context_line":"        #"},{"line_number":177,"context_line":"        # group_refs \u003d self.identity_api.list_groups_for_user(context\u003dcontext,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2B3Y%3D","line":174,"updated":"2012-12-17 22:12:42.000000000","message":"this definitely belongs in its own method rather than appearing in all 3 cases; i assume this will be implemented prior to merge?","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":171,"context_line":"        tenant_ref \u003d self._get_tenant_ref(context, user_id, tenant_id)"},{"line_number":172,"context_line":"        metadata_ref \u003d self._get_metadata_ref(context, user_id, tenant_id)"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"        # TODO (henry-nash) This is the example code we would enable to"},{"line_number":175,"context_line":"        # include whatever group roles are in place for the project"},{"line_number":176,"context_line":"        #"},{"line_number":177,"context_line":"        # group_refs \u003d self.identity_api.list_groups_for_user(context\u003dcontext,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F91c%3D","line":174,"in_reply_to":"AAAAM3%2F%2F%2B3Y%3D","updated":"2012-12-19 17:11:10.000000000","message":"Done","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":345,"context_line":"                    metadata_ref \u003d self.identity_api.get_metadata("},{"line_number":346,"context_line":"                        context\u003dcontext,"},{"line_number":347,"context_line":"                        group_id\u003dgroup_id,"},{"line_number":348,"context_line":"                        tenant_id\u003dtenant_id)"},{"line_number":349,"context_line":"            except exception.MetadataNotFound:"},{"line_number":350,"context_line":"                metadata_ref \u003d {}"},{"line_number":351,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2B24%3D","line":348,"updated":"2012-12-17 22:12:42.000000000","message":"also need to pull all domain group roles!","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":345,"context_line":"                    metadata_ref \u003d self.identity_api.get_metadata("},{"line_number":346,"context_line":"                        context\u003dcontext,"},{"line_number":347,"context_line":"                        group_id\u003dgroup_id,"},{"line_number":348,"context_line":"                        tenant_id\u003dtenant_id)"},{"line_number":349,"context_line":"            except exception.MetadataNotFound:"},{"line_number":350,"context_line":"                metadata_ref \u003d {}"},{"line_number":351,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F91M%3D","line":348,"in_reply_to":"AAAAM3%2F%2F%2B24%3D","updated":"2012-12-19 17:11:10.000000000","message":"I was waiting on response to modified proposal on domain role assignment (which would effect such code): https://blueprints.launchpad.net/keystone/+spec/domain-role-assignment","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"26c715f0c593c7c41cc94b792a4256278154618f","unresolved":false,"context_lines":[{"line_number":1,"context_line":"import uuid"},{"line_number":2,"context_line":"import json"},{"line_number":3,"context_line":""},{"line_number":4,"context_line":"from sets import Set"},{"line_number":5,"context_line":""},{"line_number":6,"context_line":"from keystone import config"},{"line_number":7,"context_line":"from keystone.common import cms"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2Fyy8%3D","line":4,"updated":"2013-01-04 21:05:21.000000000","message":"sets is deprecated as of 2.6 in favor of using the builtin data structures","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"14cd9ac7867ba23ac9c081ed7858e72d3a1e4d4c","unresolved":false,"context_lines":[{"line_number":365,"context_line":"        # any domain grants apply.  Bug #1093248"},{"line_number":366,"context_line":"        return {}"},{"line_number":367,"context_line":""},{"line_number":368,"context_line":"    def _add_additional_roles(self, initial_metadata,"},{"line_number":369,"context_line":"                              additional_metadata):"},{"line_number":370,"context_line":"        \"\"\""},{"line_number":371,"context_line":"        Update the role metadata in initial_metadata to be the union of the"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2Fvuw%3D","line":368,"updated":"2013-01-07 21:21:31.000000000","message":"\"add_additional\" is kind of redundant ;P\n\n  def _append_roles(self, metadata, additional_metadata)?","commit_id":"01af38686a726d8c27d371c5771b1413f3825475"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"0352b4e98ea42569c7669954865ee39e666eb03c","unresolved":false,"context_lines":[{"line_number":365,"context_line":"        # any domain grants apply.  Bug #1093248"},{"line_number":366,"context_line":"        return {}"},{"line_number":367,"context_line":""},{"line_number":368,"context_line":"    def _add_additional_roles(self, initial_metadata,"},{"line_number":369,"context_line":"                              additional_metadata):"},{"line_number":370,"context_line":"        \"\"\""},{"line_number":371,"context_line":"        Update the role metadata in initial_metadata to be the union of the"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2Fvik%3D","line":368,"in_reply_to":"AAAAM3%2F%2Fvuw%3D","updated":"2013-01-08 01:34:27.000000000","message":"Done","commit_id":"01af38686a726d8c27d371c5771b1413f3825475"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"14cd9ac7867ba23ac9c081ed7858e72d3a1e4d4c","unresolved":false,"context_lines":[{"line_number":382,"context_line":""},{"line_number":383,"context_line":"        new_role_list \u003d first + [i for i in second if i not in first]"},{"line_number":384,"context_line":"        if len(new_role_list):"},{"line_number":385,"context_line":"            initial_metadata[\u0027roles\u0027] \u003d new_role_list"},{"line_number":386,"context_line":""},{"line_number":387,"context_line":"    def _get_token_ref(self, context, token_id, belongs_to\u003dNone):"},{"line_number":388,"context_line":"        \"\"\"Returns a token if a valid one exists."}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2FvuY%3D","line":385,"updated":"2013-01-07 21:21:31.000000000","message":"Instead of re-implementing set behaviors:\n\n  first \u003d set(metadata.get(\u0027roles\u0027, []))\n  second \u003d set(additional_metadata.get(\u0027roles\u0027, []))\n  metadata[\u0027roles\u0027] \u003d list(first.union(second))","commit_id":"01af38686a726d8c27d371c5771b1413f3825475"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"0352b4e98ea42569c7669954865ee39e666eb03c","unresolved":false,"context_lines":[{"line_number":382,"context_line":""},{"line_number":383,"context_line":"        new_role_list \u003d first + [i for i in second if i not in first]"},{"line_number":384,"context_line":"        if len(new_role_list):"},{"line_number":385,"context_line":"            initial_metadata[\u0027roles\u0027] \u003d new_role_list"},{"line_number":386,"context_line":""},{"line_number":387,"context_line":"    def _get_token_ref(self, context, token_id, belongs_to\u003dNone):"},{"line_number":388,"context_line":"        \"\"\"Returns a token if a valid one exists."}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAM3%2F%2FviU%3D","line":385,"in_reply_to":"AAAAM3%2F%2FvuY%3D","updated":"2013-01-08 01:34:27.000000000","message":"Sure.  Although maybe I mis-understood your comment on a previous review - when you said that sets were depreciated from 2.6?","commit_id":"01af38686a726d8c27d371c5771b1413f3825475"}],"tests/default_fixtures.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":15,"context_line":"# under the License."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"# NOTE(dolph): please try to avoid additional fixtures if possible; test suite"},{"line_number":18,"context_line":"#              performance may be negatively affected."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"TENANTS \u003d ["},{"line_number":21,"context_line":"    {"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2B2s%3D","line":18,"updated":"2012-12-17 22:12:42.000000000","message":"^^","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        \u0027name\u0027: \u0027gBAR\u0027,"},{"line_number":67,"context_line":"        \u0027description\u0027: \u0027very descriptive\u0027,"},{"line_number":68,"context_line":"    }"},{"line_number":69,"context_line":"]"},{"line_number":70,"context_line":"METADATA \u003d ["},{"line_number":71,"context_line":"    {"},{"line_number":72,"context_line":"        \u0027user_id\u0027: \u0027foo\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2B2w%3D","line":69,"updated":"2012-12-17 22:12:42.000000000","message":"as mentioned, avoid this if possible!","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        \u0027name\u0027: \u0027gBAR\u0027,"},{"line_number":67,"context_line":"        \u0027description\u0027: \u0027very descriptive\u0027,"},{"line_number":68,"context_line":"    }"},{"line_number":69,"context_line":"]"},{"line_number":70,"context_line":"METADATA \u003d ["},{"line_number":71,"context_line":"    {"},{"line_number":72,"context_line":"        \u0027user_id\u0027: \u0027foo\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F91A%3D","line":69,"in_reply_to":"AAAAM3%2F%2F%2B2w%3D","updated":"2012-12-19 17:11:10.000000000","message":"Ok, let me look at it","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"}],"tests/test_auth.py":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"1067128e5af79aaba8e53cb8e307f4de66ce03a1","unresolved":false,"context_lines":[{"line_number":187,"context_line":"        self.assertEquals(roles[0], self.role_member[\u0027id\u0027])"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"    def test_auth_token_tenant_group_role(self):"},{"line_number":190,"context_line":"        \"\"\"Verify getting a token in a tenant with an group roles\"\"\""},{"line_number":191,"context_line":"        # Add a v2 style role in so we can check we get this back"},{"line_number":192,"context_line":"        self.identity_api.add_role_to_user_and_tenant("},{"line_number":193,"context_line":"            self.user_foo[\u0027id\u0027],"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2FzXs%3D","line":190,"updated":"2013-01-04 16:38:18.000000000","message":"\"with an group roles\" -\u003e \"with group roles\"","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":187,"context_line":"        self.assertEquals(roles[0], self.role_member[\u0027id\u0027])"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"    def test_auth_token_tenant_group_role(self):"},{"line_number":190,"context_line":"        \"\"\"Verify getting a token in a tenant with an group roles\"\"\""},{"line_number":191,"context_line":"        # Add a v2 style role in so we can check we get this back"},{"line_number":192,"context_line":"        self.identity_api.add_role_to_user_and_tenant("},{"line_number":193,"context_line":"            self.user_foo[\u0027id\u0027],"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2FyM0%3D","line":190,"in_reply_to":"AAAAM3%2F%2FzXs%3D","updated":"2013-01-05 01:36:18.000000000","message":"Done","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"}],"tests/test_backend.py":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"1067128e5af79aaba8e53cb8e307f4de66ce03a1","unresolved":false,"context_lines":[{"line_number":908,"context_line":"                          self.identity_api.add_user_to_group,"},{"line_number":909,"context_line":"                          uuid.uuid4().hex,"},{"line_number":910,"context_line":"                          new_group[\u0027id\u0027])"},{"line_number":911,"context_line":""},{"line_number":912,"context_line":"    def test_check_user_in_group(self):"},{"line_number":913,"context_line":"        new_group \u003d {\u0027id\u0027: uuid.uuid4().hex, \u0027domain_id\u0027: uuid.uuid4().hex,"},{"line_number":914,"context_line":"                     \u0027name\u0027: uuid.uuid4().hex}"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2FzWs%3D","line":911,"updated":"2013-01-04 16:38:18.000000000","message":"Should there be tests for a user that\u0027s not allowed to create / delete / change a group?","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"4ad4c482be4037c9abdeaa9c6699cf568c7db64d","unresolved":false,"context_lines":[{"line_number":908,"context_line":"                          self.identity_api.add_user_to_group,"},{"line_number":909,"context_line":"                          uuid.uuid4().hex,"},{"line_number":910,"context_line":"                          new_group[\u0027id\u0027])"},{"line_number":911,"context_line":""},{"line_number":912,"context_line":"    def test_check_user_in_group(self):"},{"line_number":913,"context_line":"        new_group \u003d {\u0027id\u0027: uuid.uuid4().hex, \u0027domain_id\u0027: uuid.uuid4().hex,"},{"line_number":914,"context_line":"                     \u0027name\u0027: uuid.uuid4().hex}"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAM3%2F%2FyQg%3D","line":911,"in_reply_to":"AAAAM3%2F%2FzWs%3D","updated":"2013-01-05 01:36:18.000000000","message":"Do you mean test the RBAC for a user that does not have the role assignment to execute a create/delete/change group?  If so, then although I agree we need this - I don\u0027t think we have any of those tests yet for any of the apis.  I suggest I raise a separate bug for that area?","commit_id":"5be9be8be4d2bbc82dfe2e79af528e920c25c6be"}],"tests/test_sql_upgrade.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":85,"context_line":"        self.assertTableExists(\u0027policy\u0027)"},{"line_number":86,"context_line":"        self.assertTableColumns(\u0027policy\u0027, [\u0027id\u0027, \u0027type\u0027, \u0027blob\u0027, \u0027extra\u0027])"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def test_upgrade_7_to_10(self):"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"        self.assertEqual(self.schema.version, 0)"},{"line_number":91,"context_line":"        self._migrate(self.repo_path, 7)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2B2Y%3D","line":88,"updated":"2012-12-17 22:12:42.000000000","message":"isolate your tests in new test methods, e.g. test_upgrade_9_to_10 / test_downgrade_10_to_9","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":85,"context_line":"        self.assertTableExists(\u0027policy\u0027)"},{"line_number":86,"context_line":"        self.assertTableColumns(\u0027policy\u0027, [\u0027id\u0027, \u0027type\u0027, \u0027blob\u0027, \u0027extra\u0027])"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def test_upgrade_7_to_10(self):"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"        self.assertEqual(self.schema.version, 0)"},{"line_number":91,"context_line":"        self._migrate(self.repo_path, 7)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F904%3D","line":88,"in_reply_to":"AAAAM3%2F%2F%2B2Y%3D","updated":"2012-12-19 17:11:10.000000000","message":"Done","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"}],"tests/test_v3.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":122,"context_line":"    def post(self, path, **kwargs):"},{"line_number":123,"context_line":"        return self.v3_request(method\u003d\u0027POST\u0027, path\u003dpath, **kwargs)"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def put(self, path, **kwargs):"},{"line_number":126,"context_line":"        return self.v3_request(method\u003d\u0027PUT\u0027, path\u003dpath, **kwargs)"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"    def patch(self, path, **kwargs):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2B2M%3D","line":125,"updated":"2012-12-17 22:12:42.000000000","message":"hrm, were role grants not tested? oops :\u0027(","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":122,"context_line":"    def post(self, path, **kwargs):"},{"line_number":123,"context_line":"        return self.v3_request(method\u003d\u0027POST\u0027, path\u003dpath, **kwargs)"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def put(self, path, **kwargs):"},{"line_number":126,"context_line":"        return self.v3_request(method\u003d\u0027PUT\u0027, path\u003dpath, **kwargs)"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"    def patch(self, path, **kwargs):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F90s%3D","line":125,"in_reply_to":"AAAAM3%2F%2F%2B2M%3D","updated":"2012-12-19 17:11:10.000000000","message":"I\u0027ll help here","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"}],"tests/test_v3_identity.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"259f3449e9a259b0bf7a4e6981b188d2edc387eb","unresolved":false,"context_lines":[{"line_number":36,"context_line":"        self.group_id \u003d uuid.uuid4().hex"},{"line_number":37,"context_line":"        self.group \u003d self.new_group_ref("},{"line_number":38,"context_line":"            domain_id\u003dself.domain_id)"},{"line_number":39,"context_line":"#        self.group.pop([\u0027enabled\u0027])"},{"line_number":40,"context_line":"        self.group[\u0027id\u0027] \u003d self.group_id"},{"line_number":41,"context_line":"        self.identity_api.create_group("},{"line_number":42,"context_line":"            self.group_id,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F%2B2A%3D","line":39,"updated":"2012-12-17 22:12:42.000000000","message":"i didn\u0027t think you were addressing enabling/disabling groups?","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"381bfaf77bf42ace1b53c808af13883f344fcedd","unresolved":false,"context_lines":[{"line_number":36,"context_line":"        self.group_id \u003d uuid.uuid4().hex"},{"line_number":37,"context_line":"        self.group \u003d self.new_group_ref("},{"line_number":38,"context_line":"            domain_id\u003dself.domain_id)"},{"line_number":39,"context_line":"#        self.group.pop([\u0027enabled\u0027])"},{"line_number":40,"context_line":"        self.group[\u0027id\u0027] \u003d self.group_id"},{"line_number":41,"context_line":"        self.identity_api.create_group("},{"line_number":42,"context_line":"            self.group_id,"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAM3%2F%2F90c%3D","line":39,"in_reply_to":"AAAAM3%2F%2F%2B2A%3D","updated":"2012-12-19 17:11:10.000000000","message":"sorry, test code, will remove","commit_id":"0e523643e2129abf03d22ced36501b1be26bfecb"}]}
