)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"2b8e05e9d46cfad900607eb8a30a459f87981521","unresolved":false,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes description in configuration file comments."},{"line_number":14,"context_line":"Now it is explicitly stated that additional attributes are used"},{"line_number":15,"context_line":"for creation purpose only."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Change-Id: I2e855a2abf763ec8c947d6355063d2fd2dcdc8d1"},{"line_number":18,"context_line":"Closes-Bug: #1336769"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"9aa7fdbe_4c2b8eeb","line":15,"updated":"2014-10-20 00:17:48.000000000","message":"the additional attribute mappings are also used when the object is returned, so this is incorrect. See http://git.openstack.org/cgit/openstack/keystone/tree/keystone/common/ldap/core.py#n1421 and http://git.openstack.org/cgit/openstack/keystone/tree/keystone/common/ldap/core.py#n1441","commit_id":"8a3f81b352543b26a8db0901c735d2e63c3633de"},{"author":{"_account_id":9098,"name":"Nathan Kinder","email":"nkinder@redhat.com","username":"nkinder"},"change_message_id":"2cc87390c1974abd5358006a8f3052e5a1003bd0","unresolved":false,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes description in configuration file comments."},{"line_number":14,"context_line":"Now it is explicitly stated that additional attributes are used"},{"line_number":15,"context_line":"for creation purpose only."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Change-Id: I2e855a2abf763ec8c947d6355063d2fd2dcdc8d1"},{"line_number":18,"context_line":"Closes-Bug: #1336769"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"9aa7fdbe_3dff5203","line":15,"in_reply_to":"9aa7fdbe_22a73351","updated":"2014-10-20 04:57:36.000000000","message":"One additional thing to note is that the \u0027test_user_extra_attribute_mapping_description_is_returned\u0027 test will need to be removed if we change the search code.  It is expecting that the returned user object has the additional attributes.","commit_id":"8a3f81b352543b26a8db0901c735d2e63c3633de"},{"author":{"_account_id":9098,"name":"Nathan Kinder","email":"nkinder@redhat.com","username":"nkinder"},"change_message_id":"d01ef81b8a7c88c52d30c3e20ab7e6a271572cab","unresolved":false,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes description in configuration file comments."},{"line_number":14,"context_line":"Now it is explicitly stated that additional attributes are used"},{"line_number":15,"context_line":"for creation purpose only."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Change-Id: I2e855a2abf763ec8c947d6355063d2fd2dcdc8d1"},{"line_number":18,"context_line":"Closes-Bug: #1336769"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"9aa7fdbe_c253c76a","line":15,"in_reply_to":"9aa7fdbe_4c2b8eeb","updated":"2014-10-20 04:26:46.000000000","message":"For what purpose?  Are the additional mapping attributes actually used for anything?  If not, I think we should actually not request that those attributes be returned in the first place.","commit_id":"8a3f81b352543b26a8db0901c735d2e63c3633de"},{"author":{"_account_id":9098,"name":"Nathan Kinder","email":"nkinder@redhat.com","username":"nkinder"},"change_message_id":"d03c0824a63e9110808bdd467759bf653e3d12e8","unresolved":false,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes description in configuration file comments."},{"line_number":14,"context_line":"Now it is explicitly stated that additional attributes are used"},{"line_number":15,"context_line":"for creation purpose only."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Change-Id: I2e855a2abf763ec8c947d6355063d2fd2dcdc8d1"},{"line_number":18,"context_line":"Closes-Bug: #1336769"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"9aa7fdbe_22a73351","line":15,"in_reply_to":"9aa7fdbe_c253c76a","updated":"2014-10-20 04:41:49.000000000","message":"A code inspection shows that we are searching for the extra attributes for no reason, as they aren\u0027t actually used for anything.  The only place where the extra attribute mapping should be used is in the create() method here:\n\n  http://git.openstack.org/cgit/openstack/keystone/tree/keystone/common/ldap/core.py#n1397\n\nPlease remove the extra attributes from _ldap_get() and _ldap_get_all() in the areas that Brant pointed out.  The behavior will then match your commit message, which is the correct behavior IMHO.  Thanks to Brant for catching this additional area that should be cleaned up!","commit_id":"8a3f81b352543b26a8db0901c735d2e63c3633de"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"289bd67251588342bbd8afc9326cfec54b15a0d8","unresolved":false,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes description in configuration file comments."},{"line_number":14,"context_line":"Now it is explicitly stated that additional attributes are used"},{"line_number":15,"context_line":"for creation purpose only."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Change-Id: I2e855a2abf763ec8c947d6355063d2fd2dcdc8d1"},{"line_number":18,"context_line":"Closes-Bug: #1336769"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":27,"id":"3a961159_3695bf32","line":15,"updated":"2014-12-15 16:34:54.000000000","message":"additional attributes are also used on query, so this is inaccurate.","commit_id":"9a98413858737c5fb63a9dd558df07f2139e877e"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"98a887eb6c97d1af464c17d342e3be4bd87c70e4","unresolved":false,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes description in configuration file comments."},{"line_number":14,"context_line":"Now it is explicitly stated that additional attributes are used"},{"line_number":15,"context_line":"for creation purpose only."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Change-Id: I2e855a2abf763ec8c947d6355063d2fd2dcdc8d1"},{"line_number":18,"context_line":"Closes-Bug: #1336769"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":27,"id":"3a961159_d6d9db22","line":15,"in_reply_to":"3a961159_3695bf32","updated":"2014-12-15 16:36:44.000000000","message":"It\u0027s used here, on _ldap_get: http://git.openstack.org/cgit/openstack/keystone/tree/keystone/common/ldap/core.py#n1450","commit_id":"9a98413858737c5fb63a9dd558df07f2139e877e"}],"keystone/common/config.py":[{"author":{"_account_id":11387,"name":"Sam Leong","email":"chio-fai-sam.leong@hpe.com","username":"Chioleong"},"change_message_id":"2f24a93cf6fea7b2e973f945fb7334726ff13ed8","unresolved":false,"context_lines":[{"line_number":737,"context_line":"        cfg.ListOpt(\u0027role_additional_attribute_mapping\u0027,"},{"line_number":738,"context_line":"                    default\u003d[],"},{"line_number":739,"context_line":"                    help\u003d\u0027List of additional LDAP attributes for required \u0027"},{"line_number":740,"context_line":"                         \u0027fields when creating new for roles. Attribute \u0027"},{"line_number":741,"context_line":"                         \u0027mapping format is \u003cldap_attr\u003e:\u003cuser_attr\u003e, where \u0027"},{"line_number":742,"context_line":"                         \u0027ldap_attr is the attribute in the LDAP entry and \u0027"},{"line_number":743,"context_line":"                         \u0027user_attr is the Identity API attribute.\u0027),"}],"source_content_type":"text/x-python","patch_set":34,"id":"da86d52c_315e2b77","line":740,"updated":"2015-02-04 06:57:30.000000000","message":"Meant creating new roles?","commit_id":"2c045786f7e4e86e3dbb9e5a03e4a4918b022698"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"4882b844f327579e0a7fa8030810e8942df58179","unresolved":false,"context_lines":[{"line_number":737,"context_line":"        cfg.ListOpt(\u0027role_additional_attribute_mapping\u0027,"},{"line_number":738,"context_line":"                    default\u003d[],"},{"line_number":739,"context_line":"                    help\u003d\u0027List of additional LDAP attributes for required \u0027"},{"line_number":740,"context_line":"                         \u0027fields when creating new for roles. Attribute \u0027"},{"line_number":741,"context_line":"                         \u0027mapping format is \u003cldap_attr\u003e:\u003cuser_attr\u003e, where \u0027"},{"line_number":742,"context_line":"                         \u0027ldap_attr is the attribute in the LDAP entry and \u0027"},{"line_number":743,"context_line":"                         \u0027user_attr is the Identity API attribute.\u0027),"}],"source_content_type":"text/x-python","patch_set":34,"id":"da86d52c_73717ddf","line":740,"in_reply_to":"da86d52c_315e2b77","updated":"2015-02-04 13:11:02.000000000","message":"Done","commit_id":"2c045786f7e4e86e3dbb9e5a03e4a4918b022698"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"e09daa50367c3760a29c0e796df6de3943c0bf75","unresolved":false,"context_lines":[{"line_number":737,"context_line":"        cfg.ListOpt(\u0027role_additional_attribute_mapping\u0027,"},{"line_number":738,"context_line":"                    default\u003d[],"},{"line_number":739,"context_line":"                    help\u003d\u0027List of additional LDAP attributes for required \u0027"},{"line_number":740,"context_line":"                         \u0027fields when creating new roles. Attribute \u0027"},{"line_number":741,"context_line":"                         \u0027mapping format is \u003cldap_attr\u003e:\u003cuser_attr\u003e, where \u0027"},{"line_number":742,"context_line":"                         \u0027ldap_attr is the attribute in the LDAP entry and \u0027"},{"line_number":743,"context_line":"                         \u0027user_attr is the Identity API attribute.\u0027),"}],"source_content_type":"text/x-python","patch_set":35,"id":"fa1b9901_30041514","line":740,"updated":"2015-08-17 14:46:18.000000000","message":"is not only when \"creating\", right?","commit_id":"88209fd5a16b0c4ed34b6e5c4e5994735db7d2d2"}],"keystone/common/ldap/core.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"c62d1774e7423b0d89049219ed4af6fd8adc2d82","unresolved":false,"context_lines":[{"line_number":4,"context_line":"# not use this file except in compliance with the License. You may obtain"},{"line_number":5,"context_line":"# a copy of the License at"},{"line_number":6,"context_line":"#"},{"line_number":7,"context_line":"# http://www.apache.org/licenses/LICENSE-2.0"},{"line_number":8,"context_line":"#"},{"line_number":9,"context_line":"# Unless required by applicable law or agreed to in writing, software"},{"line_number":10,"context_line":"# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_886b8784","line":7,"updated":"2014-09-08 16:15:07.000000000","message":"Unrelated whitespace change.\n\nWhitespace changes should be in a separate commit \n\nhttps://wiki.openstack.org/wiki/GitCommitMessages (see \"Things to avoid when creating commits\" section)","commit_id":"f3a3c4f6c9de47fe721f1b54f5a5447d04a4416b"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"1b032b2dc6edbae30e7dcf8978ff103e28664532","unresolved":false,"context_lines":[{"line_number":4,"context_line":"# not use this file except in compliance with the License. You may obtain"},{"line_number":5,"context_line":"# a copy of the License at"},{"line_number":6,"context_line":"#"},{"line_number":7,"context_line":"# http://www.apache.org/licenses/LICENSE-2.0"},{"line_number":8,"context_line":"#"},{"line_number":9,"context_line":"# Unless required by applicable law or agreed to in writing, software"},{"line_number":10,"context_line":"# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_75547b21","line":7,"in_reply_to":"fa98f980_886b8784","updated":"2014-10-20 14:16:19.000000000","message":"Done","commit_id":"f3a3c4f6c9de47fe721f1b54f5a5447d04a4416b"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"c62d1774e7423b0d89049219ed4af6fd8adc2d82","unresolved":false,"context_lines":[{"line_number":66,"context_line":"    else:"},{"line_number":67,"context_line":"        raise TypeError(\"value must be basestring, \""},{"line_number":68,"context_line":"                        \"not %s\" % value.__class__.__name__)"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"_utf8_decoder \u003d codecs.getdecoder(\u0027utf-8\u0027)"},{"line_number":72,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_c804afc8","line":69,"updated":"2014-09-08 16:15:07.000000000","message":"Same as above","commit_id":"f3a3c4f6c9de47fe721f1b54f5a5447d04a4416b"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"1b032b2dc6edbae30e7dcf8978ff103e28664532","unresolved":false,"context_lines":[{"line_number":66,"context_line":"    else:"},{"line_number":67,"context_line":"        raise TypeError(\"value must be basestring, \""},{"line_number":68,"context_line":"                        \"not %s\" % value.__class__.__name__)"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"_utf8_decoder \u003d codecs.getdecoder(\u0027utf-8\u0027)"},{"line_number":72,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_b53503f9","line":69,"in_reply_to":"fa98f980_c804afc8","updated":"2014-10-20 14:16:19.000000000","message":"Done","commit_id":"f3a3c4f6c9de47fe721f1b54f5a5447d04a4416b"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"c62d1774e7423b0d89049219ed4af6fd8adc2d82","unresolved":false,"context_lines":[{"line_number":403,"context_line":"    to load and run making it impossible to forget updating all the"},{"line_number":404,"context_line":"    derived classes."},{"line_number":405,"context_line":"    \u0027\u0027\u0027"},{"line_number":406,"context_line":""},{"line_number":407,"context_line":"    @abc.abstractmethod"},{"line_number":408,"context_line":"    def __init__(self, conn\u003dNone):"},{"line_number":409,"context_line":"        self.conn \u003d conn"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_28145bf4","line":406,"updated":"2014-09-08 16:15:07.000000000","message":"Same as above","commit_id":"f3a3c4f6c9de47fe721f1b54f5a5447d04a4416b"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"1b032b2dc6edbae30e7dcf8978ff103e28664532","unresolved":false,"context_lines":[{"line_number":403,"context_line":"    to load and run making it impossible to forget updating all the"},{"line_number":404,"context_line":"    derived classes."},{"line_number":405,"context_line":"    \u0027\u0027\u0027"},{"line_number":406,"context_line":""},{"line_number":407,"context_line":"    @abc.abstractmethod"},{"line_number":408,"context_line":"    def __init__(self, conn\u003dNone):"},{"line_number":409,"context_line":"        self.conn \u003d conn"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_f53f8bd4","line":406,"in_reply_to":"fa98f980_28145bf4","updated":"2014-10-20 14:16:19.000000000","message":"Done","commit_id":"f3a3c4f6c9de47fe721f1b54f5a5447d04a4416b"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"c62d1774e7423b0d89049219ed4af6fd8adc2d82","unresolved":false,"context_lines":[{"line_number":1421,"context_line":"        \"\"\"LDAP search"},{"line_number":1422,"context_line":""},{"line_number":1423,"context_line":"        Found records keys are \"as is\" and to be remapped to use in model"},{"line_number":1424,"context_line":"        \"\"\""},{"line_number":1425,"context_line":"        conn \u003d self.get_connection()"},{"line_number":1426,"context_line":"        query \u003d \u0027(\u0026%s(objectClass\u003d%s))\u0027 % (ldap_filter or"},{"line_number":1427,"context_line":"                                           self.ldap_filter or"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_48251f09","line":1424,"updated":"2014-09-08 16:15:07.000000000","message":"This looks to be an unrelated change.","commit_id":"f3a3c4f6c9de47fe721f1b54f5a5447d04a4416b"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"1b032b2dc6edbae30e7dcf8978ff103e28664532","unresolved":false,"context_lines":[{"line_number":1421,"context_line":"        \"\"\"LDAP search"},{"line_number":1422,"context_line":""},{"line_number":1423,"context_line":"        Found records keys are \"as is\" and to be remapped to use in model"},{"line_number":1424,"context_line":"        \"\"\""},{"line_number":1425,"context_line":"        conn \u003d self.get_connection()"},{"line_number":1426,"context_line":"        query \u003d \u0027(\u0026%s(objectClass\u003d%s))\u0027 % (ldap_filter or"},{"line_number":1427,"context_line":"                                           self.ldap_filter or"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_552e97a6","line":1424,"in_reply_to":"fa98f980_48251f09","updated":"2014-10-20 14:16:19.000000000","message":"Done","commit_id":"f3a3c4f6c9de47fe721f1b54f5a5447d04a4416b"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"c62d1774e7423b0d89049219ed4af6fd8adc2d82","unresolved":false,"context_lines":[{"line_number":1425,"context_line":"        conn \u003d self.get_connection()"},{"line_number":1426,"context_line":"        query \u003d \u0027(\u0026%s(objectClass\u003d%s))\u0027 % (ldap_filter or"},{"line_number":1427,"context_line":"                                           self.ldap_filter or"},{"line_number":1428,"context_line":"                                           \u0027\u0027, self.object_class)"},{"line_number":1429,"context_line":"        try:"},{"line_number":1430,"context_line":"            attrs \u003d list(set((self.attribute_mapping.values() +"},{"line_number":1431,"context_line":"                              self.extra_attr_mapping.keys())))"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_a845abb4","line":1428,"updated":"2014-09-08 16:15:07.000000000","message":"This looks to be an unrelated change","commit_id":"f3a3c4f6c9de47fe721f1b54f5a5447d04a4416b"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"1b032b2dc6edbae30e7dcf8978ff103e28664532","unresolved":false,"context_lines":[{"line_number":1425,"context_line":"        conn \u003d self.get_connection()"},{"line_number":1426,"context_line":"        query \u003d \u0027(\u0026%s(objectClass\u003d%s))\u0027 % (ldap_filter or"},{"line_number":1427,"context_line":"                                           self.ldap_filter or"},{"line_number":1428,"context_line":"                                           \u0027\u0027, self.object_class)"},{"line_number":1429,"context_line":"        try:"},{"line_number":1430,"context_line":"            attrs \u003d list(set((self.attribute_mapping.values() +"},{"line_number":1431,"context_line":"                              self.extra_attr_mapping.keys())))"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_b51c2379","line":1428,"in_reply_to":"fa98f980_a845abb4","updated":"2014-10-20 14:16:19.000000000","message":"Done","commit_id":"f3a3c4f6c9de47fe721f1b54f5a5447d04a4416b"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"c62d1774e7423b0d89049219ed4af6fd8adc2d82","unresolved":false,"context_lines":[{"line_number":1676,"context_line":"            except ldap.NO_SUCH_OBJECT:"},{"line_number":1677,"context_line":"                attr_list \u003d [(\u0027objectClass\u0027, [\u0027groupOfNames\u0027]),"},{"line_number":1678,"context_line":"                             (\u0027member\u0027,"},{"line_number":1679,"context_line":"                              [self._id_to_dn(object_id)])]"},{"line_number":1680,"context_line":"                if self.use_dumb_member:"},{"line_number":1681,"context_line":"                    attr_list[1][1].append(self.dumb_member)"},{"line_number":1682,"context_line":"                conn.add_s(self.enabled_emulation_dn, attr_list)"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_080cf793","line":1679,"updated":"2014-09-08 16:15:07.000000000","message":"Unrelated whitespace change","commit_id":"f3a3c4f6c9de47fe721f1b54f5a5447d04a4416b"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"1b032b2dc6edbae30e7dcf8978ff103e28664532","unresolved":false,"context_lines":[{"line_number":1676,"context_line":"            except ldap.NO_SUCH_OBJECT:"},{"line_number":1677,"context_line":"                attr_list \u003d [(\u0027objectClass\u0027, [\u0027groupOfNames\u0027]),"},{"line_number":1678,"context_line":"                             (\u0027member\u0027,"},{"line_number":1679,"context_line":"                              [self._id_to_dn(object_id)])]"},{"line_number":1680,"context_line":"                if self.use_dumb_member:"},{"line_number":1681,"context_line":"                    attr_list[1][1].append(self.dumb_member)"},{"line_number":1682,"context_line":"                conn.add_s(self.enabled_emulation_dn, attr_list)"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_d511a75e","line":1679,"in_reply_to":"fa98f980_080cf793","updated":"2014-10-20 14:16:19.000000000","message":"Done","commit_id":"f3a3c4f6c9de47fe721f1b54f5a5447d04a4416b"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"80b09325b79612bb3e004cad6ca3b53fb8e00495","unresolved":false,"context_lines":[{"line_number":1306,"context_line":"        # we have to preserve model keys in initial form in the mapping"},{"line_number":1307,"context_line":"        # as values associated with lower-cased keys"},{"line_number":1308,"context_line":"        for model_key in watched_keys:"},{"line_number":1309,"context_line":"            _update_mapping(model_key, model_key)"},{"line_number":1310,"context_line":""},{"line_number":1311,"context_line":"        only \u003d set()"},{"line_number":1312,"context_line":"        # reverse attribute mapping: model_key, ldap_key \u003d\u003e ldap_key, model_key"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_e5b76ad6","line":1309,"updated":"2014-09-11 16:52:37.000000000","message":"This is strange. Why not just pass it in once?","commit_id":"4183a497f680bc26dec33fc9792342a6b81061c3"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"bd94952f66ed68016fef59128e50c0defe0c306f","unresolved":false,"context_lines":[{"line_number":1306,"context_line":"        # we have to preserve model keys in initial form in the mapping"},{"line_number":1307,"context_line":"        # as values associated with lower-cased keys"},{"line_number":1308,"context_line":"        for model_key in watched_keys:"},{"line_number":1309,"context_line":"            _update_mapping(model_key, model_key)"},{"line_number":1310,"context_line":""},{"line_number":1311,"context_line":"        only \u003d set()"},{"line_number":1312,"context_line":"        # reverse attribute mapping: model_key, ldap_key \u003d\u003e ldap_key, model_key"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_d7485d5e","line":1309,"in_reply_to":"fa98f980_e5b76ad6","updated":"2014-09-11 17:08:36.000000000","message":"Common case is _update_mapping(ldap_key, model_key) and here is default mapping to get case-insensitivity (see comment in code above)","commit_id":"4183a497f680bc26dec33fc9792342a6b81061c3"}],"keystone/common/models.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"c62d1774e7423b0d89049219ed4af6fd8adc2d82","unresolved":false,"context_lines":[{"line_number":4,"context_line":"# you may not use this file except in compliance with the License."},{"line_number":5,"context_line":"# You may obtain a copy of the License at"},{"line_number":6,"context_line":"#"},{"line_number":7,"context_line":"# http://www.apache.org/licenses/LICENSE-2.0"},{"line_number":8,"context_line":"#"},{"line_number":9,"context_line":"# Unless required by applicable law or agreed to in writing, software"},{"line_number":10,"context_line":"# distributed under the License is distributed on an \"AS IS\" BASIS,"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_a8720b47","line":7,"updated":"2014-09-08 16:15:07.000000000","message":"Unrelated whitespace change","commit_id":"f3a3c4f6c9de47fe721f1b54f5a5447d04a4416b"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"1b032b2dc6edbae30e7dcf8978ff103e28664532","unresolved":false,"context_lines":[{"line_number":4,"context_line":"# you may not use this file except in compliance with the License."},{"line_number":5,"context_line":"# You may obtain a copy of the License at"},{"line_number":6,"context_line":"#"},{"line_number":7,"context_line":"# http://www.apache.org/licenses/LICENSE-2.0"},{"line_number":8,"context_line":"#"},{"line_number":9,"context_line":"# Unless required by applicable law or agreed to in writing, software"},{"line_number":10,"context_line":"# distributed under the License is distributed on an \"AS IS\" BASIS,"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_150b2f2c","line":7,"in_reply_to":"fa98f980_a8720b47","updated":"2014-10-20 14:16:19.000000000","message":"Done","commit_id":"f3a3c4f6c9de47fe721f1b54f5a5447d04a4416b"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"c62d1774e7423b0d89049219ed4af6fd8adc2d82","unresolved":false,"context_lines":[{"line_number":26,"context_line":""},{"line_number":27,"context_line":"class Model(dict):"},{"line_number":28,"context_line":"    \"\"\"Base model class.\"\"\""},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"    def __hash__(self):"},{"line_number":31,"context_line":"        return self[\u0027id\u0027].__hash__()"},{"line_number":32,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_2887fb10","line":29,"updated":"2014-09-08 16:15:07.000000000","message":"Unrelated whitespace change.","commit_id":"f3a3c4f6c9de47fe721f1b54f5a5447d04a4416b"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"1b032b2dc6edbae30e7dcf8978ff103e28664532","unresolved":false,"context_lines":[{"line_number":26,"context_line":""},{"line_number":27,"context_line":"class Model(dict):"},{"line_number":28,"context_line":"    \"\"\"Base model class.\"\"\""},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"    def __hash__(self):"},{"line_number":31,"context_line":"        return self[\u0027id\u0027].__hash__()"},{"line_number":32,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"fa98f980_3508332d","line":29,"in_reply_to":"fa98f980_2887fb10","updated":"2014-10-20 14:16:19.000000000","message":"Done","commit_id":"f3a3c4f6c9de47fe721f1b54f5a5447d04a4416b"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"80b09325b79612bb3e004cad6ca3b53fb8e00495","unresolved":false,"context_lines":[{"line_number":25,"context_line":"        return self[\u0027id\u0027].__hash__()"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    @property"},{"line_number":28,"context_line":"    def known_keys(cls):"},{"line_number":29,"context_line":"        return cls.required_keys + cls.optional_keys"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_6527fa12","side":"PARENT","line":28,"updated":"2014-09-11 16:52:37.000000000","message":"Yes, this really should be self since the instance is passed in and not the class.","commit_id":"1cacde3f59b9b6ff5b2c810c83ea50e3e5e5cdc9"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"80b09325b79612bb3e004cad6ca3b53fb8e00495","unresolved":false,"context_lines":[{"line_number":20,"context_line":"from keystone import exception"},{"line_number":21,"context_line":"from keystone.i18n import _LW"},{"line_number":22,"context_line":"from keystone.openstack.common import log"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_e5192a89","line":23,"updated":"2014-09-11 16:52:37.000000000","message":"Missing a newline here","commit_id":"4183a497f680bc26dec33fc9792342a6b81061c3"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"80b09325b79612bb3e004cad6ca3b53fb8e00495","unresolved":false,"context_lines":[{"line_number":33,"context_line":"    def known_keys(self):"},{"line_number":34,"context_line":"        # required_keys and optional_keys are class attributes"},{"line_number":35,"context_line":"        # accessible from the instance"},{"line_number":36,"context_line":"        return (getattr(self, \u0027required_keys\u0027, tuple())"},{"line_number":37,"context_line":"                + getattr(self, \u0027optional_keys\u0027, tuple()))"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    def validate(self, only\u003dNone, strict\u003dFalse):"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_25333263","line":36,"updated":"2014-09-11 16:52:37.000000000","message":"Why do you need to do a getattr? I would think that any model should have these defined.","commit_id":"4183a497f680bc26dec33fc9792342a6b81061c3"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"bd94952f66ed68016fef59128e50c0defe0c306f","unresolved":false,"context_lines":[{"line_number":33,"context_line":"    def known_keys(self):"},{"line_number":34,"context_line":"        # required_keys and optional_keys are class attributes"},{"line_number":35,"context_line":"        # accessible from the instance"},{"line_number":36,"context_line":"        return (getattr(self, \u0027required_keys\u0027, tuple())"},{"line_number":37,"context_line":"                + getattr(self, \u0027optional_keys\u0027, tuple()))"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    def validate(self, only\u003dNone, strict\u003dFalse):"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_179d85bc","line":36,"in_reply_to":"fa98f980_25333263","updated":"2014-09-11 17:08:36.000000000","message":"It\u0027s never checked, we can\u0027t rely on it.","commit_id":"4183a497f680bc26dec33fc9792342a6b81061c3"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"80b09325b79612bb3e004cad6ca3b53fb8e00495","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    def validate(self, only\u003dNone, strict\u003dFalse):"},{"line_number":40,"context_line":"        \"\"\"Instance level model validation"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"        :type strict: boolean"},{"line_number":43,"context_line":"        :param strict: whether to raise Validation error"},{"line_number":44,"context_line":"        :type only: iterable"},{"line_number":45,"context_line":"        :param only: restricts validation to attributes provided"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_656e1a31","line":42,"updated":"2014-09-11 16:52:37.000000000","message":"These should probably be in the order that the appear in the method signature.","commit_id":"4183a497f680bc26dec33fc9792342a6b81061c3"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"80b09325b79612bb3e004cad6ca3b53fb8e00495","unresolved":false,"context_lines":[{"line_number":58,"context_line":"                    attribute\u003d\u0027, \u0027.join(missing),"},{"line_number":59,"context_line":"                    target\u003dself.get(\u0027id\u0027))"},{"line_number":60,"context_line":"            else:"},{"line_number":61,"context_line":"                LOG.warn(_LW(\u0027Expecting to find %(missing)s in %(id)s\u0027) % {"},{"line_number":62,"context_line":"                    \u0027missing\u0027: \u0027, \u0027.join(missing),"},{"line_number":63,"context_line":"                    \u0027id\u0027: self.get(\u0027id\u0027)"},{"line_number":64,"context_line":"                })"}],"source_content_type":"text/x-python","patch_set":9,"id":"fa98f980_e5c84a24","line":61,"updated":"2014-09-11 16:52:37.000000000","message":"Don\u0027t use % when logging. Use a comma instead.","commit_id":"4183a497f680bc26dec33fc9792342a6b81061c3"}],"keystone/tests/test_backend_ldap.py":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"0ea97fb68019263efc06b65b41ffe1020e8c0b59","unresolved":false,"context_lines":[{"line_number":1313,"context_line":"        dn, attrs \u003d self.identity_api.driver.user._ldap_get(user[\u0027id\u0027])"},{"line_number":1314,"context_line":"        self.assertThat([user[\u0027name\u0027]], matchers.Equals(attrs[\u0027description\u0027]))"},{"line_number":1315,"context_line":""},{"line_number":1316,"context_line":"    def test_user_extra_attribute_mapping_description_is_returned(self):"},{"line_number":1317,"context_line":"        # Given a mapping like description:description, the description is"},{"line_number":1318,"context_line":"        # returned."},{"line_number":1319,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"9aa7fdbe_b936d601","side":"PARENT","line":1316,"updated":"2014-10-21 00:03:28.000000000","message":"This test is here to ensure that we don\u0027t regress bug 1293698 . This needs to work otherwise we have a regression.","commit_id":"73ad4036d62b3aa7cf50e11ddf7bee8278bbe4d0"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"03f326ba916b426a11119a09e66a718fe5dee563","unresolved":false,"context_lines":[{"line_number":1313,"context_line":"        dn, attrs \u003d self.identity_api.driver.user._ldap_get(user[\u0027id\u0027])"},{"line_number":1314,"context_line":"        self.assertThat([user[\u0027name\u0027]], matchers.Equals(attrs[\u0027description\u0027]))"},{"line_number":1315,"context_line":""},{"line_number":1316,"context_line":"    def test_user_extra_attribute_mapping_description_is_returned(self):"},{"line_number":1317,"context_line":"        # Given a mapping like description:description, the description is"},{"line_number":1318,"context_line":"        # returned."},{"line_number":1319,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"9aa7fdbe_fdbcc96e","side":"PARENT","line":1316,"in_reply_to":"9aa7fdbe_1d534d18","updated":"2014-10-21 01:19:08.000000000","message":"It might be a mistake but changing it now will break products that are depending on it, so it\u0027ll have to go through a period of deprecation before it can be removed.\n\nIs it documented somewhere that a user object in LDAP should only ever have the id, name, description, enabled, and mail fields?","commit_id":"73ad4036d62b3aa7cf50e11ddf7bee8278bbe4d0"},{"author":{"_account_id":9098,"name":"Nathan Kinder","email":"nkinder@redhat.com","username":"nkinder"},"change_message_id":"efec13554b5b020c73c983dc1dc2a49a822591f6","unresolved":false,"context_lines":[{"line_number":1313,"context_line":"        dn, attrs \u003d self.identity_api.driver.user._ldap_get(user[\u0027id\u0027])"},{"line_number":1314,"context_line":"        self.assertThat([user[\u0027name\u0027]], matchers.Equals(attrs[\u0027description\u0027]))"},{"line_number":1315,"context_line":""},{"line_number":1316,"context_line":"    def test_user_extra_attribute_mapping_description_is_returned(self):"},{"line_number":1317,"context_line":"        # Given a mapping like description:description, the description is"},{"line_number":1318,"context_line":"        # returned."},{"line_number":1319,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"9aa7fdbe_1d534d18","side":"PARENT","line":1316,"in_reply_to":"9aa7fdbe_b936d601","updated":"2014-10-21 00:18:29.000000000","message":"I don\u0027t think that some of the expected behaviors described in bug 1293698 are correct.  The real issue in that bug was that you could not map the description attribute from keystone to an attribute in LDAP due to a missing configuration settings.\n\nBefore the fix for bug 1293698, keystone would only allow a known attribute from the keystone object to be mapped to an attribute in LDAP.  The reason for this is that the extra attribute mapping feature is only designed to allow keystone to supply additional attribute when creating an LDAP entry.  This is also why we never returned those attributes form an LDAP search.\n\nTo explain it another way, a user object in keystone should only ever have the following fields that can come from LDAP:\n\n  - id\n  - name\n  - description\n  - enabled\n  - mail\n\nIf the objectclass for a user in LDAP requires the cn, sn, and uid attributes, we need a way to provide values for all of those attributes for the LDAP add operation to be successful.  Given a mapping like the following, an \"extra\" mapping would be needed to supply a value for the \"sn\" attribute:\n\n  (keystone:ldap)\n  id:uid\n  name:cn\n  description:desc\n  enabled:enabled\n  mail:mail\n  name:sn\n\nExtra attribute mappings are not designed to add additional fields to a user object in keystone, and I think it is a mistake to do so.","commit_id":"73ad4036d62b3aa7cf50e11ddf7bee8278bbe4d0"},{"author":{"_account_id":9098,"name":"Nathan Kinder","email":"nkinder@redhat.com","username":"nkinder"},"change_message_id":"5e6bf4463430e277638cc7f0890b742a1a228356","unresolved":false,"context_lines":[{"line_number":1313,"context_line":"        dn, attrs \u003d self.identity_api.driver.user._ldap_get(user[\u0027id\u0027])"},{"line_number":1314,"context_line":"        self.assertThat([user[\u0027name\u0027]], matchers.Equals(attrs[\u0027description\u0027]))"},{"line_number":1315,"context_line":""},{"line_number":1316,"context_line":"    def test_user_extra_attribute_mapping_description_is_returned(self):"},{"line_number":1317,"context_line":"        # Given a mapping like description:description, the description is"},{"line_number":1318,"context_line":"        # returned."},{"line_number":1319,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"9aa7fdbe_e0efc2ae","side":"PARENT","line":1316,"in_reply_to":"9aa7fdbe_fdbcc96e","updated":"2014-10-21 02:30:26.000000000","message":"It is not explicitly documented as such that I have seen, but the API docs that show user resources don\u0027t say or show anything with additional attributes.  The previous design around the extra mapping functionality also strongly implies this to be true:\n\n  - limiting mapped attributes to on keystone side to known attributes\n  - no read (search) support for additional mapped attributes\n  - no update support for additional mapped attributes\n  - no client support for additional mapped attributes\n\nI don\u0027t believe that we want to push more user data into Keystone since it promotes using it as a general purpose identity store.  This seemed to be a consensus amongst most of the Keystone developers in discussions at the last Summit and it\u0027s one that personally I agree with.  This is likely worth further discussion at a Keystone team meeting.","commit_id":"73ad4036d62b3aa7cf50e11ddf7bee8278bbe4d0"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"29885e4d42e5dc07156aad5e4a8f0c6e9a2a08ae","unresolved":false,"context_lines":[{"line_number":1310,"context_line":"        self.assertFalse(self.identity_api.driver.user._is_dumb_member(dn))"},{"line_number":1311,"context_line":""},{"line_number":1312,"context_line":"    def test_user_extra_attribute_mapping(self):"},{"line_number":1313,"context_line":"        self.skip(\"There is no way to get additional attributes from LDAP\")"},{"line_number":1314,"context_line":"        self.config_fixture.config("},{"line_number":1315,"context_line":"            group\u003d\u0027ldap\u0027,"},{"line_number":1316,"context_line":"            user_additional_attribute_mapping\u003d[\u0027description:name\u0027])"}],"source_content_type":"text/x-python","patch_set":23,"id":"5a890539_684e1ac4","line":1313,"updated":"2014-12-01 22:49:21.000000000","message":"This test should either work or it should be changed to show how the backend works now. If the backend doesn\u0027t work the same way as it did before then this change isn\u0027t backwards-compatible and doesn\u0027t meet OpenStack API stability guidelines: https://wiki.openstack.org/wiki/APIChangeGuidelines","commit_id":"91fec047fe01ad6af2aa9e5d794535abfa804d23"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"9815ccb03ab8b0bfba93cd3c77cab2d83505fe39","unresolved":false,"context_lines":[{"line_number":1310,"context_line":"        self.assertFalse(self.identity_api.driver.user._is_dumb_member(dn))"},{"line_number":1311,"context_line":""},{"line_number":1312,"context_line":"    def test_user_extra_attribute_mapping(self):"},{"line_number":1313,"context_line":"        self.skip(\"There is no way to get additional attributes from LDAP\")"},{"line_number":1314,"context_line":"        self.config_fixture.config("},{"line_number":1315,"context_line":"            group\u003d\u0027ldap\u0027,"},{"line_number":1316,"context_line":"            user_additional_attribute_mapping\u003d[\u0027description:name\u0027])"}],"source_content_type":"text/x-python","patch_set":23,"id":"5a890539_6910c04e","line":1313,"in_reply_to":"5a890539_684e1ac4","updated":"2014-12-02 16:40:26.000000000","message":"Done","commit_id":"91fec047fe01ad6af2aa9e5d794535abfa804d23"}]}
