)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"902a014267d6c641c4521cd23da2427febe7a0c4","unresolved":false,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":"Change-Id: I57c099eefdca7e756d294c35cf5b70d119c5c955"},{"line_number":17,"context_line":"closes-bug: #1361306"},{"line_number":18,"context_line":"closes-bug: #1340041"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":8,"id":"fa98f980_bc4887cd","line":18,"updated":"2014-09-08 20:36:56.000000000","message":"If this is going to say that it closes this bug then there should be a unit test for it -- that verifies that the keystone server is always providing the naming attribute on create.","commit_id":"780f9106202de7026f51f7917d7832e3290f9289"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"4e8b1d4d79bfe870c09d7ab70f53863cfb6ce3eb","unresolved":false,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":"Change-Id: I57c099eefdca7e756d294c35cf5b70d119c5c955"},{"line_number":17,"context_line":"closes-bug: #1361306"},{"line_number":18,"context_line":"closes-bug: #1340041"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":8,"id":"fa98f980_bff15997","line":18,"in_reply_to":"fa98f980_bc4887cd","updated":"2014-09-08 22:01:24.000000000","message":"will do","commit_id":"780f9106202de7026f51f7917d7832e3290f9289"}],"etc/keystone.conf.sample":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"0789339dddca8f7378e553f7d4a1551f2e2fef59","unresolved":false,"context_lines":[{"line_number":891,"context_line":""},{"line_number":892,"context_line":"# LDAP attribute mapped to user id. WARNING: must not be a"},{"line_number":893,"context_line":"# multivalued attribute. (string value)"},{"line_number":894,"context_line":"#user_id_attribute\u003dcn"},{"line_number":895,"context_line":""},{"line_number":896,"context_line":"# LDAP attribute mapped to user name. (string value)"},{"line_number":897,"context_line":"#user_name_attribute\u003dsn"}],"source_content_type":"application/octet-stream","patch_set":9,"id":"fa98f980_f6622615","line":894,"updated":"2014-09-09 00:35:14.000000000","message":"the irony here is that cn is typically multivalued.","commit_id":"2c9c437e3ad16fef20c14d360cbcb010f1849e06"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"186437cba50140b66fd6e063e3a0db2e629ffb75","unresolved":false,"context_lines":[{"line_number":891,"context_line":""},{"line_number":892,"context_line":"# LDAP attribute mapped to user id. WARNING: must not be a"},{"line_number":893,"context_line":"# multivalued attribute. (string value)"},{"line_number":894,"context_line":"#user_id_attribute\u003dcn"},{"line_number":895,"context_line":""},{"line_number":896,"context_line":"# LDAP attribute mapped to user name. (string value)"},{"line_number":897,"context_line":"#user_name_attribute\u003dsn"}],"source_content_type":"application/octet-stream","patch_set":9,"id":"fa98f980_83d99785","line":894,"in_reply_to":"fa98f980_f6622615","updated":"2014-09-09 04:52:29.000000000","message":"we\u0027ll need to change the default at some point","commit_id":"2c9c437e3ad16fef20c14d360cbcb010f1849e06"}],"keystone/common/ldap/core.py":[{"author":{"_account_id":220,"name":"Haneef Ali","email":"haneef.ali@hp.com","username":"haneef"},"change_message_id":"64959562cc33df3421215daf6d4147f94e9450a8","unresolved":false,"context_lines":[{"line_number":1290,"context_line":"            id \u003d lower_res[self.id_attr.lower()]"},{"line_number":1291,"context_line":"            if isinstance(id, types.ListType):"},{"line_number":1292,"context_line":"                # NOTE(gyee): if this is a multi-value attribute and it has"},{"line_number":1293,"context_line":"                # multiple values, we can\u0027t use it as ID."},{"line_number":1294,"context_line":"                if len(id) !\u003d 1:"},{"line_number":1295,"context_line":"                    raise exception.Conflict("},{"line_number":1296,"context_line":"                        type\u003dself.id_attr,"}],"source_content_type":"text/x-python","patch_set":1,"id":"1abeadc6_31fd05b2","line":1293,"updated":"2014-08-29 01:50:55.000000000","message":"Don\u0027t understand this checking.  Just checking ListType is not enough, why do we want to check the len","commit_id":"8fb2eb4c84106c82f3fdc58e8d28030c02c909fa"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"0bfb5600cc21ab5b25ab6927a1d19219e2159c19","unresolved":false,"context_lines":[{"line_number":1290,"context_line":"            id \u003d lower_res[self.id_attr.lower()]"},{"line_number":1291,"context_line":"            if isinstance(id, types.ListType):"},{"line_number":1292,"context_line":"                # NOTE(gyee): if this is a multi-value attribute and it has"},{"line_number":1293,"context_line":"                # multiple values, we can\u0027t use it as ID."},{"line_number":1294,"context_line":"                if len(id) !\u003d 1:"},{"line_number":1295,"context_line":"                    raise exception.Conflict("},{"line_number":1296,"context_line":"                        type\u003dself.id_attr,"}],"source_content_type":"text/x-python","patch_set":1,"id":"1abeadc6_4bb1ed45","line":1293,"in_reply_to":"1abeadc6_31fd05b2","updated":"2014-08-29 02:44:52.000000000","message":"If the attribute contains more than one value, it can\u0027t be used as ID map because we can\u0027t just pick one. ID attribute has to be single value and unique.","commit_id":"8fb2eb4c84106c82f3fdc58e8d28030c02c909fa"},{"author":{"_account_id":220,"name":"Haneef Ali","email":"haneef.ali@hp.com","username":"haneef"},"change_message_id":"6a80af4d523ee829c5c542442112a80e3d3d64ff","unresolved":false,"context_lines":[{"line_number":1290,"context_line":"            id \u003d lower_res[self.id_attr.lower()]"},{"line_number":1291,"context_line":"            if isinstance(id, types.ListType):"},{"line_number":1292,"context_line":"                # NOTE(gyee): if this is a multi-value attribute and it has"},{"line_number":1293,"context_line":"                # multiple values, we can\u0027t use it as ID."},{"line_number":1294,"context_line":"                if len(id) !\u003d 1:"},{"line_number":1295,"context_line":"                    raise exception.Conflict("},{"line_number":1296,"context_line":"                        type\u003dself.id_attr,"}],"source_content_type":"text/x-python","patch_set":1,"id":"1abeadc6_9456c228","line":1293,"in_reply_to":"1abeadc6_4bb1ed45","updated":"2014-08-29 04:10:09.000000000","message":"ListType implies multiple values. Why do you want to check for len?\nAssume id is mapped to name, and there are 2 Guang and  1 Haneef in LDAP. I don\u0027t want the code to work when searched for Haneef and not work when searched for \"Guang\"","commit_id":"8fb2eb4c84106c82f3fdc58e8d28030c02c909fa"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"5cead46f3fd013935e9767c77d4ee8980fc0c52b","unresolved":false,"context_lines":[{"line_number":1290,"context_line":"            id \u003d lower_res[self.id_attr.lower()]"},{"line_number":1291,"context_line":"            if isinstance(id, types.ListType):"},{"line_number":1292,"context_line":"                # NOTE(gyee): if this is a multi-value attribute and it has"},{"line_number":1293,"context_line":"                # multiple values, we can\u0027t use it as ID."},{"line_number":1294,"context_line":"                if len(id) !\u003d 1:"},{"line_number":1295,"context_line":"                    raise exception.Conflict("},{"line_number":1296,"context_line":"                        type\u003dself.id_attr,"}],"source_content_type":"text/x-python","patch_set":1,"id":"1abeadc6_b401f9b0","line":1293,"in_reply_to":"1abeadc6_9456c228","updated":"2014-08-29 06:00:22.000000000","message":"multivalued attribute in LDAP basically means an attribute can have multiple values. Consider this (yes crazy, but possible)\n\n cn\u003dname,ou\u003dusers,cn\u003dacme,cn\u003dcom\n\nIn this case, lower_res[\u0027cn\u0027] will have [\u0027name\u0027, \u0027acme\u0027, \u0027com\u0027]. If someone is configuring\n\n user_id_attribute \u003d cn\n\nthen we have no way of knowing which one to use. In this case, we should just error out.","commit_id":"8fb2eb4c84106c82f3fdc58e8d28030c02c909fa"},{"author":{"_account_id":220,"name":"Haneef Ali","email":"haneef.ali@hp.com","username":"haneef"},"change_message_id":"64959562cc33df3421215daf6d4147f94e9450a8","unresolved":false,"context_lines":[{"line_number":1293,"context_line":"                # multiple values, we can\u0027t use it as ID."},{"line_number":1294,"context_line":"                if len(id) !\u003d 1:"},{"line_number":1295,"context_line":"                    raise exception.Conflict("},{"line_number":1296,"context_line":"                        type\u003dself.id_attr,"},{"line_number":1297,"context_line":"                        details\u003d_(\u0027Multi-value attribute cannot be used\u0027"},{"line_number":1298,"context_line":"                                  \u0027used as ID: %s \u0027) % id)"},{"line_number":1299,"context_line":"                else:"}],"source_content_type":"text/x-python","patch_set":1,"id":"1abeadc6_71bcddbb","line":1296,"updated":"2014-08-29 01:50:55.000000000","message":"Remove one \"used\"  from message","commit_id":"8fb2eb4c84106c82f3fdc58e8d28030c02c909fa"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"0bfb5600cc21ab5b25ab6927a1d19219e2159c19","unresolved":false,"context_lines":[{"line_number":1293,"context_line":"                # multiple values, we can\u0027t use it as ID."},{"line_number":1294,"context_line":"                if len(id) !\u003d 1:"},{"line_number":1295,"context_line":"                    raise exception.Conflict("},{"line_number":1296,"context_line":"                        type\u003dself.id_attr,"},{"line_number":1297,"context_line":"                        details\u003d_(\u0027Multi-value attribute cannot be used\u0027"},{"line_number":1298,"context_line":"                                  \u0027used as ID: %s \u0027) % id)"},{"line_number":1299,"context_line":"                else:"}],"source_content_type":"text/x-python","patch_set":1,"id":"1abeadc6_cb841d60","line":1296,"in_reply_to":"1abeadc6_71bcddbb","updated":"2014-08-29 02:44:52.000000000","message":"good catch!","commit_id":"8fb2eb4c84106c82f3fdc58e8d28030c02c909fa"},{"author":{"_account_id":220,"name":"Haneef Ali","email":"haneef.ali@hp.com","username":"haneef"},"change_message_id":"64959562cc33df3421215daf6d4147f94e9450a8","unresolved":false,"context_lines":[{"line_number":1295,"context_line":"                    raise exception.Conflict("},{"line_number":1296,"context_line":"                        type\u003dself.id_attr,"},{"line_number":1297,"context_line":"                        details\u003d_(\u0027Multi-value attribute cannot be used\u0027"},{"line_number":1298,"context_line":"                                  \u0027used as ID: %s \u0027) % id)"},{"line_number":1299,"context_line":"                else:"},{"line_number":1300,"context_line":"                    id \u003d id[0]"},{"line_number":1301,"context_line":"            obj \u003d self.model(id\u003did)"}],"source_content_type":"text/x-python","patch_set":1,"id":"1abeadc6_b1a7550a","line":1298,"updated":"2014-08-29 01:50:55.000000000","message":"Isn\u0027t this multi value check also true for  *_name_attribute mapping?\n\nMay be out of scope for this review, but it is better to do the same checking for name too. We also expect name mapping to be unqiue","commit_id":"8fb2eb4c84106c82f3fdc58e8d28030c02c909fa"},{"author":{"_account_id":220,"name":"Haneef Ali","email":"haneef.ali@hp.com","username":"haneef"},"change_message_id":"d639c92efc2ed22622c8317d5be2020e0d8dffaf","unresolved":false,"context_lines":[{"line_number":1295,"context_line":"                    raise exception.Conflict("},{"line_number":1296,"context_line":"                        type\u003dself.id_attr,"},{"line_number":1297,"context_line":"                        details\u003d_(\u0027Multi-value attribute cannot be used\u0027"},{"line_number":1298,"context_line":"                                  \u0027used as ID: %s \u0027) % id)"},{"line_number":1299,"context_line":"                else:"},{"line_number":1300,"context_line":"                    id \u003d id[0]"},{"line_number":1301,"context_line":"            obj \u003d self.model(id\u003did)"}],"source_content_type":"text/x-python","patch_set":1,"id":"1abeadc6_f4cc5637","line":1298,"in_reply_to":"1abeadc6_6bda2979","updated":"2014-08-29 04:06:16.000000000","message":"If you extract out that check as function, then you can call that for id and name mapping","commit_id":"8fb2eb4c84106c82f3fdc58e8d28030c02c909fa"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"0bfb5600cc21ab5b25ab6927a1d19219e2159c19","unresolved":false,"context_lines":[{"line_number":1295,"context_line":"                    raise exception.Conflict("},{"line_number":1296,"context_line":"                        type\u003dself.id_attr,"},{"line_number":1297,"context_line":"                        details\u003d_(\u0027Multi-value attribute cannot be used\u0027"},{"line_number":1298,"context_line":"                                  \u0027used as ID: %s \u0027) % id)"},{"line_number":1299,"context_line":"                else:"},{"line_number":1300,"context_line":"                    id \u003d id[0]"},{"line_number":1301,"context_line":"            obj \u003d self.model(id\u003did)"}],"source_content_type":"text/x-python","patch_set":1,"id":"1abeadc6_6bda2979","line":1298,"in_reply_to":"1abeadc6_b1a7550a","updated":"2014-08-29 02:44:52.000000000","message":"Agree. But lets fix one at a time. :)","commit_id":"8fb2eb4c84106c82f3fdc58e8d28030c02c909fa"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"5cead46f3fd013935e9767c77d4ee8980fc0c52b","unresolved":false,"context_lines":[{"line_number":1295,"context_line":"                    raise exception.Conflict("},{"line_number":1296,"context_line":"                        type\u003dself.id_attr,"},{"line_number":1297,"context_line":"                        details\u003d_(\u0027Multi-value attribute cannot be used\u0027"},{"line_number":1298,"context_line":"                                  \u0027used as ID: %s \u0027) % id)"},{"line_number":1299,"context_line":"                else:"},{"line_number":1300,"context_line":"                    id \u003d id[0]"},{"line_number":1301,"context_line":"            obj \u003d self.model(id\u003did)"}],"source_content_type":"text/x-python","patch_set":1,"id":"1abeadc6_94cebd58","line":1298,"in_reply_to":"1abeadc6_f4cc5637","updated":"2014-08-29 06:00:22.000000000","message":"But we\u0027ve already established that precedent in line 1322 so I would rather not mess with nature\u0027s harmony in this patch. :) I agree is a valid concern, but it is another discussion for another day.","commit_id":"8fb2eb4c84106c82f3fdc58e8d28030c02c909fa"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"a548eeb1f7ec8f53e34387aad41b64434f6e610e","unresolved":false,"context_lines":[{"line_number":18,"context_line":"import os.path"},{"line_number":19,"context_line":"import re"},{"line_number":20,"context_line":"import sys"},{"line_number":21,"context_line":"import types"},{"line_number":22,"context_line":"import weakref"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"import ldap"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa98f980_1b4072a4","line":21,"updated":"2014-09-02 19:13:54.000000000","message":"see comment below about py3 compat.","commit_id":"4ca398f3262c9101d047ea910d6ad84ebc14305b"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"a548eeb1f7ec8f53e34387aad41b64434f6e610e","unresolved":false,"context_lines":[{"line_number":1287,"context_line":"            # NOTE(gyee): for read-only LDAP, we have no control over the"},{"line_number":1288,"context_line":"            # DIT. We can only use the attribute maps. Therefore, we need to"},{"line_number":1289,"context_line":"            # honor the attribute map for all attributes."},{"line_number":1290,"context_line":"            id \u003d lower_res[self.id_attr.lower()]"},{"line_number":1291,"context_line":"            if isinstance(id, types.ListType):"},{"line_number":1292,"context_line":"                # NOTE(gyee): if this is a multi-value attribute and it has"},{"line_number":1293,"context_line":"                # multiple values, we can\u0027t use it as ID."}],"source_content_type":"text/x-python","patch_set":2,"id":"fa98f980_3bf45686","line":1290,"updated":"2014-09-02 19:13:54.000000000","message":"Do not shadow the built-in \u0027id\u0027, suggest naming this something other than \"id\" (id_from_attr?)","commit_id":"4ca398f3262c9101d047ea910d6ad84ebc14305b"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"a548eeb1f7ec8f53e34387aad41b64434f6e610e","unresolved":false,"context_lines":[{"line_number":1288,"context_line":"            # DIT. We can only use the attribute maps. Therefore, we need to"},{"line_number":1289,"context_line":"            # honor the attribute map for all attributes."},{"line_number":1290,"context_line":"            id \u003d lower_res[self.id_attr.lower()]"},{"line_number":1291,"context_line":"            if isinstance(id, types.ListType):"},{"line_number":1292,"context_line":"                # NOTE(gyee): if this is a multi-value attribute and it has"},{"line_number":1293,"context_line":"                # multiple values, we can\u0027t use it as ID."},{"line_number":1294,"context_line":"                if len(id) !\u003d 1:"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa98f980_5bdcba12","line":1291,"updated":"2014-09-02 19:13:54.000000000","message":"In python 3 the types module is removed,  just use:\n\n    if isinstance(id, list):","commit_id":"4ca398f3262c9101d047ea910d6ad84ebc14305b"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"7b002f671805a3d24799f6eabbf102165796476c","unresolved":false,"context_lines":[{"line_number":1288,"context_line":"            # DIT. We can only use the attribute maps. Therefore, we need to"},{"line_number":1289,"context_line":"            # honor the attribute map for all attributes."},{"line_number":1290,"context_line":"            id_from_attr \u003d lower_res[self.id_attr.lower()]"},{"line_number":1291,"context_line":"            if isinstance(id_from_attr, list):"},{"line_number":1292,"context_line":"                # NOTE(gyee): if this is a multi-value attribute and it has"},{"line_number":1293,"context_line":"                # multiple values, we can\u0027t use it as ID."},{"line_number":1294,"context_line":"                if len(id_from_attr) !\u003d 1:"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa98f980_22609e00","line":1291,"updated":"2014-09-02 23:02:10.000000000","message":"@Morgan Fainberg, I am so glad you asked me to test this part! Turns out I don\u0027t need the explicit check here. According to the doc, (http://www.python-ldap.org/doc/html/ldap.html)\n\n\"\nEach result tuple is of the form (dn, attrs), where dn is a string containing the DN (distinguished name) of the entry, and attrs is a dictionary containing the attributes associated with the entry. The keys of attrs are strings, and the associated values are lists of strings.\n\"\n\nI\u0027ll properly mock it for the testing.","commit_id":"e407363839b26bbb8840c0bc7641a3808d853036"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"0d604c5b320c1db5b1064ef2d20e84939e450f59","unresolved":false,"context_lines":[{"line_number":1283,"context_line":"        # retrieving values later."},{"line_number":1284,"context_line":"        lower_res \u003d dict((k.lower(), v) for k, v in six.iteritems(res[1]))"},{"line_number":1285,"context_line":""},{"line_number":1286,"context_line":"        if not (self.allow_create and self.allow_update and self.allow_delete):"},{"line_number":1287,"context_line":"            # NOTE(gyee): for read-only LDAP, we have no control over the"},{"line_number":1288,"context_line":"            # DIT. We can only use the attribute maps. Therefore, we need to"},{"line_number":1289,"context_line":"            # honor the attribute map for all attributes."}],"source_content_type":"text/x-python","patch_set":4,"id":"fa98f980_2a1f815c","line":1286,"updated":"2014-09-03 11:55:49.000000000","message":"Can be simplified with any()","commit_id":"fa49411141b0c2dda826de502531e2ec5a7cc386"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a2de07841d480c5b94ed1f9d73e229d8a53ccf72","unresolved":false,"context_lines":[{"line_number":1295,"context_line":""},{"line_number":1296,"context_line":"            # NOTE(gyee): if this is a multi-value attribute and it has"},{"line_number":1297,"context_line":"            # multiple values, we can\u0027t use it as ID."},{"line_number":1298,"context_line":"            if len(id_attr) !\u003d 1:"},{"line_number":1299,"context_line":"                raise exception.Conflict("},{"line_number":1300,"context_line":"                    type\u003dself.id_attr,"},{"line_number":1301,"context_line":"                    details\u003d_(\u0027Multivalued attribute cannot be used\u0027"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa98f980_3dcf8d57","line":1298,"updated":"2014-09-05 00:45:37.000000000","message":"use \u003e 1 since if the len wound up being 0 then the exception message would be incorrect since it\u0027s not multivalued in that case.","commit_id":"e050cbf383419e556042e7063342f061321dad5f"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a2de07841d480c5b94ed1f9d73e229d8a53ccf72","unresolved":false,"context_lines":[{"line_number":1368,"context_line":"            if k in self.attribute_ignore:"},{"line_number":1369,"context_line":"                continue"},{"line_number":1370,"context_line":"            if k \u003d\u003d \u0027id\u0027:"},{"line_number":1371,"context_line":"                attrs.append((self.id_attr, [v]))"},{"line_number":1372,"context_line":"            elif v is not None:"},{"line_number":1373,"context_line":"                attr_type \u003d self.attribute_mapping.get(k, k)"},{"line_number":1374,"context_line":"                if attr_type is not None:"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa98f980_1d280999","line":1371,"updated":"2014-09-05 00:45:37.000000000","message":"This could wind up adding 2 values to attrs with the same attribute, if an attribute maps to the same entry.\n\nChange line 1375 and 1380 to check if the attr_type is already in the tuple and append to the value list if it is.\n\nMaybe it would be easier to use a map of id_attr -\u003e [v] and append, then turn it into the item list the add_s.","commit_id":"e050cbf383419e556042e7063342f061321dad5f"},{"author":{"_account_id":9098,"name":"Nathan Kinder","email":"nkinder@redhat.com","username":"nkinder"},"change_message_id":"188806e227362c9a44f48deb3a104797720c2dfb","unresolved":false,"context_lines":[{"line_number":1286,"context_line":"        id_attr \u003d lower_res.get(self.id_attr.lower())"},{"line_number":1287,"context_line":"        if not id_attr or len(id_attr) \u003c 1:"},{"line_number":1288,"context_line":"            message \u003d _(\u0027ID attribute %s not found in LDAP object\u0027) % ("},{"line_number":1289,"context_line":"                self.id_attr)"},{"line_number":1290,"context_line":"            raise exception.NotFound(message\u003dmessage)"},{"line_number":1291,"context_line":"        elif len(id_attr) \u003e 1:"},{"line_number":1292,"context_line":"            # NOTE(gyee): if this is a multi-value attribute and it has"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa98f980_e6b70639","line":1289,"updated":"2014-09-07 00:16:27.000000000","message":"Should we add the DN to this message to make it more useful?","commit_id":"b9beec73839e69c909b4f2f9216e6642fb5a3bdb"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"a3b5fed5cf16ed03a7ebc9e509c076d90c65ce4b","unresolved":false,"context_lines":[{"line_number":1286,"context_line":"        id_attr \u003d lower_res.get(self.id_attr.lower())"},{"line_number":1287,"context_line":"        if not id_attr or len(id_attr) \u003c 1:"},{"line_number":1288,"context_line":"            message \u003d _(\u0027ID attribute %s not found in LDAP object\u0027) % ("},{"line_number":1289,"context_line":"                self.id_attr)"},{"line_number":1290,"context_line":"            raise exception.NotFound(message\u003dmessage)"},{"line_number":1291,"context_line":"        elif len(id_attr) \u003e 1:"},{"line_number":1292,"context_line":"            # NOTE(gyee): if this is a multi-value attribute and it has"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa98f980_cb8106fd","line":1289,"in_reply_to":"fa98f980_a3488588","updated":"2014-09-08 20:09:13.000000000","message":"done","commit_id":"b9beec73839e69c909b4f2f9216e6642fb5a3bdb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"9b5a5ed03d46d120364422e19fef1b3b1927b5c9","unresolved":false,"context_lines":[{"line_number":1286,"context_line":"        id_attr \u003d lower_res.get(self.id_attr.lower())"},{"line_number":1287,"context_line":"        if not id_attr or len(id_attr) \u003c 1:"},{"line_number":1288,"context_line":"            message \u003d _(\u0027ID attribute %s not found in LDAP object\u0027) % ("},{"line_number":1289,"context_line":"                self.id_attr)"},{"line_number":1290,"context_line":"            raise exception.NotFound(message\u003dmessage)"},{"line_number":1291,"context_line":"        elif len(id_attr) \u003e 1:"},{"line_number":1292,"context_line":"            # NOTE(gyee): if this is a multi-value attribute and it has"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa98f980_a3488588","line":1289,"in_reply_to":"fa98f980_e6b70639","updated":"2014-09-07 23:53:24.000000000","message":"that would be handy.","commit_id":"b9beec73839e69c909b4f2f9216e6642fb5a3bdb"},{"author":{"_account_id":9098,"name":"Nathan Kinder","email":"nkinder@redhat.com","username":"nkinder"},"change_message_id":"188806e227362c9a44f48deb3a104797720c2dfb","unresolved":false,"context_lines":[{"line_number":1294,"context_line":"            raise exception.Conflict("},{"line_number":1295,"context_line":"                type\u003dself.id_attr,"},{"line_number":1296,"context_line":"                details\u003d_(\u0027Multivalued attribute cannot be used\u0027"},{"line_number":1297,"context_line":"                          \u0027as ID: %s \u0027) % id_attr)"},{"line_number":1298,"context_line":"        obj \u003d self.model(id\u003did_attr[0])"},{"line_number":1299,"context_line":""},{"line_number":1300,"context_line":"        for k in obj.known_keys:"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa98f980_26810e4e","line":1297,"updated":"2014-09-07 00:16:27.000000000","message":"Add the DN to this log message too?","commit_id":"b9beec73839e69c909b4f2f9216e6642fb5a3bdb"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"a3b5fed5cf16ed03a7ebc9e509c076d90c65ce4b","unresolved":false,"context_lines":[{"line_number":1294,"context_line":"            raise exception.Conflict("},{"line_number":1295,"context_line":"                type\u003dself.id_attr,"},{"line_number":1296,"context_line":"                details\u003d_(\u0027Multivalued attribute cannot be used\u0027"},{"line_number":1297,"context_line":"                          \u0027as ID: %s \u0027) % id_attr)"},{"line_number":1298,"context_line":"        obj \u003d self.model(id\u003did_attr[0])"},{"line_number":1299,"context_line":""},{"line_number":1300,"context_line":"        for k in obj.known_keys:"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa98f980_eb86ca12","line":1297,"in_reply_to":"fa98f980_26810e4e","updated":"2014-09-08 20:09:13.000000000","message":"done","commit_id":"b9beec73839e69c909b4f2f9216e6642fb5a3bdb"},{"author":{"_account_id":9098,"name":"Nathan Kinder","email":"nkinder@redhat.com","username":"nkinder"},"change_message_id":"188806e227362c9a44f48deb3a104797720c2dfb","unresolved":false,"context_lines":[{"line_number":1362,"context_line":"        for k, v in six.iteritems(values):"},{"line_number":1363,"context_line":"            if k in self.attribute_ignore:"},{"line_number":1364,"context_line":"                continue"},{"line_number":1365,"context_line":"            if k \u003d\u003d \u0027id\u0027:"},{"line_number":1366,"context_line":"                attrs.append((self.id_attr, [v]))"},{"line_number":1367,"context_line":"            elif v is not None:"},{"line_number":1368,"context_line":"                attr_type \u003d self.attribute_mapping.get(k, k)"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa98f980_26258eae","line":1365,"updated":"2014-09-07 00:16:27.000000000","message":"Shouldn\u0027t we also check if the value is None for the id?  This wasn\u0027t done before since we weren\u0027t even adding the id attribute to the LDAP entry, but we should be raising an exception if we have no value:\n\nif k \u003d\u003d \u0027id\u0027:\n    if v is not None:\n        attrs.append((self.id_attr, [v]))\n    else:\n        # raise exception, log error\nelif v is not None:\n    ...","commit_id":"b9beec73839e69c909b4f2f9216e6642fb5a3bdb"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"a3b5fed5cf16ed03a7ebc9e509c076d90c65ce4b","unresolved":false,"context_lines":[{"line_number":1362,"context_line":"        for k, v in six.iteritems(values):"},{"line_number":1363,"context_line":"            if k in self.attribute_ignore:"},{"line_number":1364,"context_line":"                continue"},{"line_number":1365,"context_line":"            if k \u003d\u003d \u0027id\u0027:"},{"line_number":1366,"context_line":"                attrs.append((self.id_attr, [v]))"},{"line_number":1367,"context_line":"            elif v is not None:"},{"line_number":1368,"context_line":"                attr_type \u003d self.attribute_mapping.get(k, k)"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa98f980_dc30ebea","line":1365,"in_reply_to":"fa98f980_26258eae","updated":"2014-09-08 20:09:13.000000000","message":"Done","commit_id":"b9beec73839e69c909b4f2f9216e6642fb5a3bdb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"9b5a5ed03d46d120364422e19fef1b3b1927b5c9","unresolved":false,"context_lines":[{"line_number":1363,"context_line":"            if k in self.attribute_ignore:"},{"line_number":1364,"context_line":"                continue"},{"line_number":1365,"context_line":"            if k \u003d\u003d \u0027id\u0027:"},{"line_number":1366,"context_line":"                attrs.append((self.id_attr, [v]))"},{"line_number":1367,"context_line":"            elif v is not None:"},{"line_number":1368,"context_line":"                attr_type \u003d self.attribute_mapping.get(k, k)"},{"line_number":1369,"context_line":"                if attr_type is not None and attr_type !\u003d self.id_attr:"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa98f980_4330b907","line":1366,"updated":"2014-09-07 23:53:24.000000000","message":"This fix should only be fixing gets. There shouldn\u0027t be a change in the create case. If there is then this is fixing a different problem. There shouldn\u0027t be any change in create.","commit_id":"b9beec73839e69c909b4f2f9216e6642fb5a3bdb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"cc9d759339823620b9fc0ae6d1d6fa6444d085a5","unresolved":false,"context_lines":[{"line_number":1363,"context_line":"            if k in self.attribute_ignore:"},{"line_number":1364,"context_line":"                continue"},{"line_number":1365,"context_line":"            if k \u003d\u003d \u0027id\u0027:"},{"line_number":1366,"context_line":"                attrs.append((self.id_attr, [v]))"},{"line_number":1367,"context_line":"            elif v is not None:"},{"line_number":1368,"context_line":"                attr_type \u003d self.attribute_mapping.get(k, k)"},{"line_number":1369,"context_line":"                if attr_type is not None and attr_type !\u003d self.id_attr:"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa98f980_9ef75af5","line":1366,"in_reply_to":"fa98f980_4330b907","updated":"2014-09-08 00:11:55.000000000","message":"Also, this is the same change as https://review.openstack.org/#/c/119345/1/keystone/common/ldap/core.py , so either use that one or we can abandon that one and mark this one as closing the same bug.","commit_id":"b9beec73839e69c909b4f2f9216e6642fb5a3bdb"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"a3b5fed5cf16ed03a7ebc9e509c076d90c65ce4b","unresolved":false,"context_lines":[{"line_number":1363,"context_line":"            if k in self.attribute_ignore:"},{"line_number":1364,"context_line":"                continue"},{"line_number":1365,"context_line":"            if k \u003d\u003d \u0027id\u0027:"},{"line_number":1366,"context_line":"                attrs.append((self.id_attr, [v]))"},{"line_number":1367,"context_line":"            elif v is not None:"},{"line_number":1368,"context_line":"                attr_type \u003d self.attribute_mapping.get(k, k)"},{"line_number":1369,"context_line":"                if attr_type is not None and attr_type !\u003d self.id_attr:"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa98f980_9c64a3e6","line":1366,"in_reply_to":"fa98f980_9ef75af5","updated":"2014-09-08 20:09:13.000000000","message":"I\u0027ll reference the bug in this patch. I need this fix in order for the tests to be happy.","commit_id":"b9beec73839e69c909b4f2f9216e6642fb5a3bdb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"902a014267d6c641c4521cd23da2427febe7a0c4","unresolved":false,"context_lines":[{"line_number":1283,"context_line":"        # retrieving values later."},{"line_number":1284,"context_line":"        lower_res \u003d dict((k.lower(), v) for k, v in six.iteritems(res[1]))"},{"line_number":1285,"context_line":""},{"line_number":1286,"context_line":"        id_attr \u003d lower_res.get(self.id_attr.lower())"},{"line_number":1287,"context_line":"        if not id_attr or len(id_attr) \u003c 1:"},{"line_number":1288,"context_line":"            message \u003d _(\u0027ID attribute %(id_attr)s not found in LDAP \u0027"},{"line_number":1289,"context_line":"                        \u0027object %(dn)s\u0027) % ({\u0027id_attr\u0027: self.id_attr,"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_fc784ffa","line":1286,"updated":"2014-09-08 20:36:56.000000000","message":"call this id_attrs so we know that it\u0027s a list.","commit_id":"780f9106202de7026f51f7917d7832e3290f9289"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"4e8b1d4d79bfe870c09d7ab70f53863cfb6ce3eb","unresolved":false,"context_lines":[{"line_number":1283,"context_line":"        # retrieving values later."},{"line_number":1284,"context_line":"        lower_res \u003d dict((k.lower(), v) for k, v in six.iteritems(res[1]))"},{"line_number":1285,"context_line":""},{"line_number":1286,"context_line":"        id_attr \u003d lower_res.get(self.id_attr.lower())"},{"line_number":1287,"context_line":"        if not id_attr or len(id_attr) \u003c 1:"},{"line_number":1288,"context_line":"            message \u003d _(\u0027ID attribute %(id_attr)s not found in LDAP \u0027"},{"line_number":1289,"context_line":"                        \u0027object %(dn)s\u0027) % ({\u0027id_attr\u0027: self.id_attr,"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_6203d473","line":1286,"in_reply_to":"fa98f980_fc784ffa","updated":"2014-09-08 22:01:24.000000000","message":"done","commit_id":"780f9106202de7026f51f7917d7832e3290f9289"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"902a014267d6c641c4521cd23da2427febe7a0c4","unresolved":false,"context_lines":[{"line_number":1284,"context_line":"        lower_res \u003d dict((k.lower(), v) for k, v in six.iteritems(res[1]))"},{"line_number":1285,"context_line":""},{"line_number":1286,"context_line":"        id_attr \u003d lower_res.get(self.id_attr.lower())"},{"line_number":1287,"context_line":"        if not id_attr or len(id_attr) \u003c 1:"},{"line_number":1288,"context_line":"            message \u003d _(\u0027ID attribute %(id_attr)s not found in LDAP \u0027"},{"line_number":1289,"context_line":"                        \u0027object %(dn)s\u0027) % ({\u0027id_attr\u0027: self.id_attr,"},{"line_number":1290,"context_line":"                                             \u0027dn\u0027: res[0]})"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_9c22e3ff","line":1287,"updated":"2014-09-08 20:36:56.000000000","message":"not id_attr and len(id_attr) \u003c 1 are checking the same thing. change this to\n\n if not id_attr:","commit_id":"780f9106202de7026f51f7917d7832e3290f9289"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"4e8b1d4d79bfe870c09d7ab70f53863cfb6ce3eb","unresolved":false,"context_lines":[{"line_number":1284,"context_line":"        lower_res \u003d dict((k.lower(), v) for k, v in six.iteritems(res[1]))"},{"line_number":1285,"context_line":""},{"line_number":1286,"context_line":"        id_attr \u003d lower_res.get(self.id_attr.lower())"},{"line_number":1287,"context_line":"        if not id_attr or len(id_attr) \u003c 1:"},{"line_number":1288,"context_line":"            message \u003d _(\u0027ID attribute %(id_attr)s not found in LDAP \u0027"},{"line_number":1289,"context_line":"                        \u0027object %(dn)s\u0027) % ({\u0027id_attr\u0027: self.id_attr,"},{"line_number":1290,"context_line":"                                             \u0027dn\u0027: res[0]})"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_a2f4dc87","line":1287,"in_reply_to":"fa98f980_9c22e3ff","updated":"2014-09-08 22:01:24.000000000","message":"done","commit_id":"780f9106202de7026f51f7917d7832e3290f9289"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"902a014267d6c641c4521cd23da2427febe7a0c4","unresolved":false,"context_lines":[{"line_number":1289,"context_line":"                        \u0027object %(dn)s\u0027) % ({\u0027id_attr\u0027: self.id_attr,"},{"line_number":1290,"context_line":"                                             \u0027dn\u0027: res[0]})"},{"line_number":1291,"context_line":"            raise exception.NotFound(message\u003dmessage)"},{"line_number":1292,"context_line":"        elif len(id_attr) \u003e 1:"},{"line_number":1293,"context_line":"            # NOTE(gyee): if this is a multi-value attribute and it has"},{"line_number":1294,"context_line":"            # multiple values, we can\u0027t use it as ID."},{"line_number":1295,"context_line":"            raise exception.Conflict("}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_7c88dfc6","line":1292,"updated":"2014-09-08 20:36:56.000000000","message":"change elif to if, or put \"obj \u003d self.model(id\u003did_attr[0])\" in an else leg.","commit_id":"780f9106202de7026f51f7917d7832e3290f9289"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"4e8b1d4d79bfe870c09d7ab70f53863cfb6ce3eb","unresolved":false,"context_lines":[{"line_number":1289,"context_line":"                        \u0027object %(dn)s\u0027) % ({\u0027id_attr\u0027: self.id_attr,"},{"line_number":1290,"context_line":"                                             \u0027dn\u0027: res[0]})"},{"line_number":1291,"context_line":"            raise exception.NotFound(message\u003dmessage)"},{"line_number":1292,"context_line":"        elif len(id_attr) \u003e 1:"},{"line_number":1293,"context_line":"            # NOTE(gyee): if this is a multi-value attribute and it has"},{"line_number":1294,"context_line":"            # multiple values, we can\u0027t use it as ID."},{"line_number":1295,"context_line":"            raise exception.Conflict("}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_c2f1e096","line":1292,"in_reply_to":"fa98f980_7c88dfc6","updated":"2014-09-08 22:01:24.000000000","message":"done","commit_id":"780f9106202de7026f51f7917d7832e3290f9289"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"902a014267d6c641c4521cd23da2427febe7a0c4","unresolved":false,"context_lines":[{"line_number":1292,"context_line":"        elif len(id_attr) \u003e 1:"},{"line_number":1293,"context_line":"            # NOTE(gyee): if this is a multi-value attribute and it has"},{"line_number":1294,"context_line":"            # multiple values, we can\u0027t use it as ID."},{"line_number":1295,"context_line":"            raise exception.Conflict("},{"line_number":1296,"context_line":"                type\u003dself.id_attr,"},{"line_number":1297,"context_line":"                details\u003d_(\u0027LDAP object %(dn)s has multivalued attribute \u0027"},{"line_number":1298,"context_line":"                          \u0027%(id_attr)s which cannot be used as ID\u0027) % ("}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_fffe8104","line":1295,"updated":"2014-09-08 20:36:56.000000000","message":"I think that this is going to break existing deployments that have user_id_attr\u003dcn and has multiple cn for entries. Have it use self._dn_to_id(res[0]) for the id if there\u0027s multiple values.","commit_id":"780f9106202de7026f51f7917d7832e3290f9289"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"4e8b1d4d79bfe870c09d7ab70f53863cfb6ce3eb","unresolved":false,"context_lines":[{"line_number":1292,"context_line":"        elif len(id_attr) \u003e 1:"},{"line_number":1293,"context_line":"            # NOTE(gyee): if this is a multi-value attribute and it has"},{"line_number":1294,"context_line":"            # multiple values, we can\u0027t use it as ID."},{"line_number":1295,"context_line":"            raise exception.Conflict("},{"line_number":1296,"context_line":"                type\u003dself.id_attr,"},{"line_number":1297,"context_line":"                details\u003d_(\u0027LDAP object %(dn)s has multivalued attribute \u0027"},{"line_number":1298,"context_line":"                          \u0027%(id_attr)s which cannot be used as ID\u0027) % ("}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_623af437","line":1295,"in_reply_to":"fa98f980_fffe8104","updated":"2014-09-08 22:01:24.000000000","message":"I can live with that.","commit_id":"780f9106202de7026f51f7917d7832e3290f9289"},{"author":{"_account_id":9098,"name":"Nathan Kinder","email":"nkinder@redhat.com","username":"nkinder"},"change_message_id":"0cad10017921a03d8671fa74acbcec4f01c394f8","unresolved":false,"context_lines":[{"line_number":1292,"context_line":"        elif len(id_attr) \u003e 1:"},{"line_number":1293,"context_line":"            # NOTE(gyee): if this is a multi-value attribute and it has"},{"line_number":1294,"context_line":"            # multiple values, we can\u0027t use it as ID."},{"line_number":1295,"context_line":"            raise exception.Conflict("},{"line_number":1296,"context_line":"                type\u003dself.id_attr,"},{"line_number":1297,"context_line":"                details\u003d_(\u0027LDAP object %(dn)s has multivalued attribute \u0027"},{"line_number":1298,"context_line":"                          \u0027%(id_attr)s which cannot be used as ID\u0027) % ("}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_7071de76","line":1295,"in_reply_to":"fa98f980_fffe8104","updated":"2014-09-08 22:31:20.000000000","message":"In addition, I would still log a message (warn or debug as you see fit).  The order of returned attribute values is ambiguous, so we should log something to help in troubleshooting when a multi-vauled ID attribute is encountered.","commit_id":"780f9106202de7026f51f7917d7832e3290f9289"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"902a014267d6c641c4521cd23da2427febe7a0c4","unresolved":false,"context_lines":[{"line_number":1372,"context_line":"                attrs.append((self.id_attr, [v]))"},{"line_number":1373,"context_line":"            elif v is not None:"},{"line_number":1374,"context_line":"                attr_type \u003d self.attribute_mapping.get(k, k)"},{"line_number":1375,"context_line":"                if attr_type is not None and attr_type !\u003d self.id_attr:"},{"line_number":1376,"context_line":"                    attrs.append((attr_type, [v]))"},{"line_number":1377,"context_line":"                extra_attrs \u003d [attr for attr, name"},{"line_number":1378,"context_line":"                               in six.iteritems(self.extra_attr_mapping)"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_dc7d4bb3","line":1375,"updated":"2014-09-08 20:36:56.000000000","message":"why is this new check added? add a comment.","commit_id":"780f9106202de7026f51f7917d7832e3290f9289"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"4e8b1d4d79bfe870c09d7ab70f53863cfb6ce3eb","unresolved":false,"context_lines":[{"line_number":1372,"context_line":"                attrs.append((self.id_attr, [v]))"},{"line_number":1373,"context_line":"            elif v is not None:"},{"line_number":1374,"context_line":"                attr_type \u003d self.attribute_mapping.get(k, k)"},{"line_number":1375,"context_line":"                if attr_type is not None and attr_type !\u003d self.id_attr:"},{"line_number":1376,"context_line":"                    attrs.append((attr_type, [v]))"},{"line_number":1377,"context_line":"                extra_attrs \u003d [attr for attr, name"},{"line_number":1378,"context_line":"                               in six.iteritems(self.extra_attr_mapping)"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_02dda814","line":1375,"in_reply_to":"fa98f980_dc7d4bb3","updated":"2014-09-08 22:01:24.000000000","message":"actually I don\u0027t need this check. Good catch!","commit_id":"780f9106202de7026f51f7917d7832e3290f9289"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"902a014267d6c641c4521cd23da2427febe7a0c4","unresolved":false,"context_lines":[{"line_number":1381,"context_line":"                    attrs.append((attr, [v]))"},{"line_number":1382,"context_line":""},{"line_number":1383,"context_line":"        if (\u0027groupOfNames\u0027 in object_classes and self.use_dumb_member and"},{"line_number":1384,"context_line":"                \u0027member\u0027 !\u003d self.id_attr):"},{"line_number":1385,"context_line":"            attrs.append((\u0027member\u0027, [self.dumb_member]))"},{"line_number":1386,"context_line":"        try:"},{"line_number":1387,"context_line":"            conn.add_s(self._id_to_dn(values[\u0027id\u0027]), attrs)"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_bcfb2746","line":1384,"updated":"2014-09-08 20:36:56.000000000","message":"who\u0027s going to set the id_attr to member?? that\u0027s pretty much always multi-valued anyways. Revert this change. Add a comment to the config option that says that user_id_attr can\u0027t be a multivalued attribute.","commit_id":"780f9106202de7026f51f7917d7832e3290f9289"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"4e8b1d4d79bfe870c09d7ab70f53863cfb6ce3eb","unresolved":false,"context_lines":[{"line_number":1381,"context_line":"                    attrs.append((attr, [v]))"},{"line_number":1382,"context_line":""},{"line_number":1383,"context_line":"        if (\u0027groupOfNames\u0027 in object_classes and self.use_dumb_member and"},{"line_number":1384,"context_line":"                \u0027member\u0027 !\u003d self.id_attr):"},{"line_number":1385,"context_line":"            attrs.append((\u0027member\u0027, [self.dumb_member]))"},{"line_number":1386,"context_line":"        try:"},{"line_number":1387,"context_line":"            conn.add_s(self._id_to_dn(values[\u0027id\u0027]), attrs)"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_6249148b","line":1384,"in_reply_to":"fa98f980_bcfb2746","updated":"2014-09-08 22:01:24.000000000","message":"done","commit_id":"780f9106202de7026f51f7917d7832e3290f9289"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"0789339dddca8f7378e553f7d4a1551f2e2fef59","unresolved":false,"context_lines":[{"line_number":1295,"context_line":"            # logic here so it does not potentially break existing"},{"line_number":1296,"context_line":"            # deployments. We need to fix our read-write LDAP logic so"},{"line_number":1297,"context_line":"            # it does not get the ID from DN."},{"line_number":1298,"context_line":"            message \u003d _(\u0027ID attribute %(id_attr)s for LDAP object %(dn)s has \u0027"},{"line_number":1299,"context_line":"                        \u0027multiple values and therefore cannot be used as an \u0027"},{"line_number":1300,"context_line":"                        \u0027ID. Will get the ID from DN instead\u0027) % ("},{"line_number":1301,"context_line":"                            {\u0027id_attr\u0027: self.id_attr,"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_96739ae6","line":1298,"updated":"2014-09-09 00:35:14.000000000","message":"use _LW","commit_id":"2c9c437e3ad16fef20c14d360cbcb010f1849e06"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"0789339dddca8f7378e553f7d4a1551f2e2fef59","unresolved":false,"context_lines":[{"line_number":1303,"context_line":"            LOG.warn(message)"},{"line_number":1304,"context_line":"            obj \u003d self.model(id\u003dself._dn_to_id(res[0]))"},{"line_number":1305,"context_line":"        else:"},{"line_number":1306,"context_line":"            obj \u003d self.model(id\u003did_attrs[0])"},{"line_number":1307,"context_line":""},{"line_number":1308,"context_line":"        for k in obj.known_keys:"},{"line_number":1309,"context_line":"            if k in self.attribute_ignore:"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_161dea73","line":1306,"updated":"2014-09-09 00:35:14.000000000","message":"(suggestion) since both legs doing self.model, move that out of the branching code --\n\n if len(id_attrs) \u003e 1:\n   ...\n   id_ \u003d self._dn_to_id(res[0])\n else:\n   id_ \u003d id_attrs[0]\n\n obj \u003d self.model(id\u003did_)","commit_id":"2c9c437e3ad16fef20c14d360cbcb010f1849e06"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"08924e4b4214eed5364bea8610ed0706bfd33a14","unresolved":false,"context_lines":[{"line_number":153,"context_line":""},{"line_number":154,"context_line":"        for kind, values in six.iteritems(attrs):"},{"line_number":155,"context_line":"            try:"},{"line_number":156,"context_line":"                ldap_attrs[kind] \u003d [ldap2py(x) for x in values]"},{"line_number":157,"context_line":"            except UnicodeDecodeError:"},{"line_number":158,"context_line":"                LOG.debug(\u0027Unable to decode value for attribute %s \u0027, kind)"},{"line_number":159,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"fa98f980_4d9515e3","line":156,"updated":"2014-09-09 09:47:14.000000000","message":"map(ldap2py, values) would be a bit more fitting here","commit_id":"47e09d5dda70b2da87ec5a0fc4608373418870f9"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"17c0228fe57cf4a41d19d9bfb1aa1e8ae22d9c13","unresolved":false,"context_lines":[{"line_number":153,"context_line":""},{"line_number":154,"context_line":"        for kind, values in six.iteritems(attrs):"},{"line_number":155,"context_line":"            try:"},{"line_number":156,"context_line":"                ldap_attrs[kind] \u003d [ldap2py(x) for x in values]"},{"line_number":157,"context_line":"            except UnicodeDecodeError:"},{"line_number":158,"context_line":"                LOG.debug(\u0027Unable to decode value for attribute %s \u0027, kind)"},{"line_number":159,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"fa98f980_e5d415bf","line":156,"in_reply_to":"fa98f980_4d9515e3","updated":"2014-09-09 15:08:39.000000000","message":"this code wasn\u0027t added or changed as part of this review so it\u0027s unrelated. If this needs to be changed then propose a separate change for it.","commit_id":"47e09d5dda70b2da87ec5a0fc4608373418870f9"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"08924e4b4214eed5364bea8610ed0706bfd33a14","unresolved":false,"context_lines":[{"line_number":1269,"context_line":"                 \u0027id\u0027: ldap.filter.escape_filter_chars("},{"line_number":1270,"context_line":"                     six.text_type(object_id)),"},{"line_number":1271,"context_line":"                 \u0027objclass\u0027: self.object_class},"},{"line_number":1272,"context_line":"                attrlist\u003d[\u00271.1\u0027])"},{"line_number":1273,"context_line":"        finally:"},{"line_number":1274,"context_line":"            conn.unbind_s()"},{"line_number":1275,"context_line":"        if search_result:"}],"source_content_type":"text/x-python","patch_set":10,"id":"fa98f980_9009d42e","line":1272,"updated":"2014-09-09 09:47:14.000000000","message":"Strange identifier for the attribute: \u00271.1\u0027\nAre you restricting result set to \u00271.1\u0027 key? Is this key exist or you simply want guaranteed empty result?","commit_id":"47e09d5dda70b2da87ec5a0fc4608373418870f9"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"a9fe1b32e443544f74cfaa14898d634aaaf38901","unresolved":false,"context_lines":[{"line_number":1269,"context_line":"                 \u0027id\u0027: ldap.filter.escape_filter_chars("},{"line_number":1270,"context_line":"                     six.text_type(object_id)),"},{"line_number":1271,"context_line":"                 \u0027objclass\u0027: self.object_class},"},{"line_number":1272,"context_line":"                attrlist\u003d[\u00271.1\u0027])"},{"line_number":1273,"context_line":"        finally:"},{"line_number":1274,"context_line":"            conn.unbind_s()"},{"line_number":1275,"context_line":"        if search_result:"}],"source_content_type":"text/x-python","patch_set":10,"id":"fa98f980_a51bed7e","line":1272,"in_reply_to":"fa98f980_9009d42e","updated":"2014-09-09 15:15:20.000000000","message":"Sorry, my fault: didn\u0027t know about this magic","commit_id":"47e09d5dda70b2da87ec5a0fc4608373418870f9"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"17c0228fe57cf4a41d19d9bfb1aa1e8ae22d9c13","unresolved":false,"context_lines":[{"line_number":1269,"context_line":"                 \u0027id\u0027: ldap.filter.escape_filter_chars("},{"line_number":1270,"context_line":"                     six.text_type(object_id)),"},{"line_number":1271,"context_line":"                 \u0027objclass\u0027: self.object_class},"},{"line_number":1272,"context_line":"                attrlist\u003d[\u00271.1\u0027])"},{"line_number":1273,"context_line":"        finally:"},{"line_number":1274,"context_line":"            conn.unbind_s()"},{"line_number":1275,"context_line":"        if search_result:"}],"source_content_type":"text/x-python","patch_set":10,"id":"fa98f980_45e5e1a6","line":1272,"in_reply_to":"fa98f980_9009d42e","updated":"2014-09-09 15:08:39.000000000","message":"this code wasn\u0027t added or changed as part of this review so it\u0027s unrelated. If this needs to be changed then propose a separate change for it.","commit_id":"47e09d5dda70b2da87ec5a0fc4608373418870f9"}],"keystone/tests/test_backend_ldap.py":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"9b5a5ed03d46d120364422e19fef1b3b1927b5c9","unresolved":false,"context_lines":[{"line_number":1206,"context_line":"            {"},{"line_number":1207,"context_line":"                \u0027sn\u0027: [uuid.uuid4().hex],"},{"line_number":1208,"context_line":"                \u0027email\u0027: [uuid.uuid4().hex],"},{"line_number":1209,"context_line":"                \u0027cn\u0027: [\u0027junk\u0027]"},{"line_number":1210,"context_line":"            }"},{"line_number":1211,"context_line":"        )"},{"line_number":1212,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"fa98f980_a33fa5d5","line":1209,"updated":"2014-09-07 23:53:24.000000000","message":"nice.","commit_id":"b9beec73839e69c909b4f2f9216e6642fb5a3bdb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"9b5a5ed03d46d120364422e19fef1b3b1927b5c9","unresolved":false,"context_lines":[{"line_number":1668,"context_line":""},{"line_number":1669,"context_line":"    def test_user_id_map_for_readonly_ldap(self):"},{"line_number":1670,"context_line":"        conf \u003d self.get_config(CONF.identity.default_domain_id)"},{"line_number":1671,"context_line":"        conf.ldap.user_allow_create \u003d False"},{"line_number":1672,"context_line":"        conf.ldap.user_allow_update \u003d False"},{"line_number":1673,"context_line":"        conf.ldap.user_allow_delete \u003d False"},{"line_number":1674,"context_line":"        conf.ldap.user_id_attribute \u003d \u0027mail\u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa98f980_032eb1a5","line":1671,"updated":"2014-09-07 23:53:24.000000000","message":"you got rid of the code that required setting these allow_create, etc., so you can get rid of the mess in the tests.","commit_id":"b9beec73839e69c909b4f2f9216e6642fb5a3bdb"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"a3b5fed5cf16ed03a7ebc9e509c076d90c65ce4b","unresolved":false,"context_lines":[{"line_number":1668,"context_line":""},{"line_number":1669,"context_line":"    def test_user_id_map_for_readonly_ldap(self):"},{"line_number":1670,"context_line":"        conf \u003d self.get_config(CONF.identity.default_domain_id)"},{"line_number":1671,"context_line":"        conf.ldap.user_allow_create \u003d False"},{"line_number":1672,"context_line":"        conf.ldap.user_allow_update \u003d False"},{"line_number":1673,"context_line":"        conf.ldap.user_allow_delete \u003d False"},{"line_number":1674,"context_line":"        conf.ldap.user_id_attribute \u003d \u0027mail\u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa98f980_68aca336","line":1671,"in_reply_to":"fa98f980_032eb1a5","updated":"2014-09-08 20:09:13.000000000","message":"good catch!","commit_id":"b9beec73839e69c909b4f2f9216e6642fb5a3bdb"},{"author":{"_account_id":9098,"name":"Nathan Kinder","email":"nkinder@redhat.com","username":"nkinder"},"change_message_id":"188806e227362c9a44f48deb3a104797720c2dfb","unresolved":false,"context_lines":[{"line_number":1708,"context_line":"                                   user_allow_create\u003dFalse,"},{"line_number":1709,"context_line":"                                   user_allow_delete\u003dFalse,"},{"line_number":1710,"context_line":"                                   user_allow_update\u003dFalse)"},{"line_number":1711,"context_line":"        # make \u0027email\u0027 multivalued so we can test the error condition"},{"line_number":1712,"context_line":"        mock_ldap_get.return_value \u003d ("},{"line_number":1713,"context_line":"            \u0027cn\u003dnobodycares,dc\u003dexample,dc\u003dcom\u0027,"},{"line_number":1714,"context_line":"            {"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa98f980_a6db3e7c","line":1711,"updated":"2014-09-07 00:16:27.000000000","message":"This comment doesn\u0027t apply to this test.  Remove it.","commit_id":"b9beec73839e69c909b4f2f9216e6642fb5a3bdb"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"a3b5fed5cf16ed03a7ebc9e509c076d90c65ce4b","unresolved":false,"context_lines":[{"line_number":1708,"context_line":"                                   user_allow_create\u003dFalse,"},{"line_number":1709,"context_line":"                                   user_allow_delete\u003dFalse,"},{"line_number":1710,"context_line":"                                   user_allow_update\u003dFalse)"},{"line_number":1711,"context_line":"        # make \u0027email\u0027 multivalued so we can test the error condition"},{"line_number":1712,"context_line":"        mock_ldap_get.return_value \u003d ("},{"line_number":1713,"context_line":"            \u0027cn\u003dnobodycares,dc\u003dexample,dc\u003dcom\u0027,"},{"line_number":1714,"context_line":"            {"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa98f980_086dd704","line":1711,"in_reply_to":"fa98f980_a6db3e7c","updated":"2014-09-08 20:09:13.000000000","message":"good catch!","commit_id":"b9beec73839e69c909b4f2f9216e6642fb5a3bdb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"902a014267d6c641c4521cd23da2427febe7a0c4","unresolved":false,"context_lines":[{"line_number":1678,"context_line":""},{"line_number":1679,"context_line":"    @mock.patch.object(common_ldap_core.BaseLdap, \u0027_ldap_get\u0027)"},{"line_number":1680,"context_line":"    def test_multivalued_attribute_cannot_be_used_as_id(self, mock_ldap_get):"},{"line_number":1681,"context_line":"        self.config_fixture.config(group\u003d\u0027ldap\u0027,"},{"line_number":1682,"context_line":"                                   user_allow_create\u003dFalse,"},{"line_number":1683,"context_line":"                                   user_allow_delete\u003dFalse,"},{"line_number":1684,"context_line":"                                   user_allow_update\u003dFalse,"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_3f20099b","line":1681,"updated":"2014-09-08 20:36:56.000000000","message":"I thought you were going to get rid of all these.","commit_id":"780f9106202de7026f51f7917d7832e3290f9289"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"4e8b1d4d79bfe870c09d7ab70f53863cfb6ce3eb","unresolved":false,"context_lines":[{"line_number":1678,"context_line":""},{"line_number":1679,"context_line":"    @mock.patch.object(common_ldap_core.BaseLdap, \u0027_ldap_get\u0027)"},{"line_number":1680,"context_line":"    def test_multivalued_attribute_cannot_be_used_as_id(self, mock_ldap_get):"},{"line_number":1681,"context_line":"        self.config_fixture.config(group\u003d\u0027ldap\u0027,"},{"line_number":1682,"context_line":"                                   user_allow_create\u003dFalse,"},{"line_number":1683,"context_line":"                                   user_allow_delete\u003dFalse,"},{"line_number":1684,"context_line":"                                   user_allow_update\u003dFalse,"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_c261e0d4","line":1681,"in_reply_to":"fa98f980_3f20099b","updated":"2014-09-08 22:01:24.000000000","message":"k, for real this time :)","commit_id":"780f9106202de7026f51f7917d7832e3290f9289"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"0789339dddca8f7378e553f7d4a1551f2e2fef59","unresolved":false,"context_lines":[{"line_number":1691,"context_line":"        self.assertEqual(self.user_foo[\u0027email\u0027], user_ref[\u0027id\u0027])"},{"line_number":1692,"context_line":""},{"line_number":1693,"context_line":"    @mock.patch.object(common_ldap_core.BaseLdap, \u0027_ldap_get\u0027)"},{"line_number":1694,"context_line":"    def test_multivalued_attribute_cannot_be_used_as_id(self, mock_ldap_get):"},{"line_number":1695,"context_line":"        conf \u003d self.get_config(CONF.identity.default_domain_id)"},{"line_number":1696,"context_line":"        conf.ldap.user_id_attribute \u003d \u0027mail\u0027"},{"line_number":1697,"context_line":"        self.reload_backends(CONF.identity.default_domain_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_913644e6","line":1694,"updated":"2014-09-09 00:35:14.000000000","message":"change the name since a multivalued attr can be used as id.","commit_id":"2c9c437e3ad16fef20c14d360cbcb010f1849e06"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"186437cba50140b66fd6e063e3a0db2e629ffb75","unresolved":false,"context_lines":[{"line_number":1691,"context_line":"        self.assertEqual(self.user_foo[\u0027email\u0027], user_ref[\u0027id\u0027])"},{"line_number":1692,"context_line":""},{"line_number":1693,"context_line":"    @mock.patch.object(common_ldap_core.BaseLdap, \u0027_ldap_get\u0027)"},{"line_number":1694,"context_line":"    def test_multivalued_attribute_cannot_be_used_as_id(self, mock_ldap_get):"},{"line_number":1695,"context_line":"        conf \u003d self.get_config(CONF.identity.default_domain_id)"},{"line_number":1696,"context_line":"        conf.ldap.user_id_attribute \u003d \u0027mail\u0027"},{"line_number":1697,"context_line":"        self.reload_backends(CONF.identity.default_domain_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_dc2aa0e6","line":1694,"in_reply_to":"fa98f980_913644e6","updated":"2014-09-09 04:52:29.000000000","message":"done","commit_id":"2c9c437e3ad16fef20c14d360cbcb010f1849e06"}]}
