)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"b69d393006144d643f70da5ad5a3689308a7e1c4","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add failed auth attempts logic to meet PCI-DSS"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This patch creates new table failed auth attempts table in a new auth backend"},{"line_number":10,"context_line":"used by new auth manager to log failed authentication attempts, check this"},{"line_number":11,"context_line":"log, and lock out suspicious accounts for configured duration  in order"},{"line_number":12,"context_line":"to support PCI-DSS limit repeated access attempts requirements:"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"3aaa91ec_a3e2109e","line":9,"range":{"start_line":9,"start_character":23,"end_line":9,"end_character":28},"updated":"2016-06-29 22:55:00.000000000","message":"nit: remove \"table\"","commit_id":"74c64b1de20585ce48ab502c217583dd7722fec3"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"b69d393006144d643f70da5ad5a3689308a7e1c4","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add failed auth attempts logic to meet PCI-DSS"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This patch creates new table failed auth attempts table in a new auth backend"},{"line_number":10,"context_line":"used by new auth manager to log failed authentication attempts, check this"},{"line_number":11,"context_line":"log, and lock out suspicious accounts for configured duration  in order"},{"line_number":12,"context_line":"to support PCI-DSS limit repeated access attempts requirements:"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"3aaa91ec_03a16446","line":9,"range":{"start_line":9,"start_character":0,"end_line":9,"end_character":77},"updated":"2016-06-29 22:55:00.000000000","message":"nit: suggest instead, \"This patch creates a new auth backend to capture failed authentication attempt...\"","commit_id":"74c64b1de20585ce48ab502c217583dd7722fec3"}],"keystone/auth/backends/base.py":[{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"b69d393006144d643f70da5ad5a3689308a7e1c4","unresolved":false,"context_lines":[{"line_number":16,"context_line":""},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"@six.add_metaclass(abc.ABCMeta)"},{"line_number":19,"context_line":"class AuthDriverV8(object):"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    def list_auth_attempts(self, user_id):"},{"line_number":22,"context_line":"        raise NotImplementedError"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_e3bc186e","line":19,"range":{"start_line":19,"start_character":6,"end_line":19,"end_character":18},"updated":"2016-06-29 22:55:00.000000000","message":"++ Thanks for moving this","commit_id":"74c64b1de20585ce48ab502c217583dd7722fec3"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"e7d9ab90779aec8bbc209a2bb4d861de983044f1","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2016 OpenStack Foundation"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":4,"context_line":"#    not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_74bb95c4","line":1,"updated":"2016-06-30 15:58:27.000000000","message":"Do not attribute copyright in new files with the OpenStack Foundation, unless you work directly for the OpenStack Foundation.","commit_id":"2a75963d6a3996b66c126fd749cdc54bfee21d97"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"641e57a16a7a53f82cd1f9ac77acc9ac56ea9ca7","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2016 OpenStack Foundation"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":4,"context_line":"#    not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_b1134f64","line":1,"updated":"2016-06-30 15:56:12.000000000","message":"Unless you work for the foundation remove this.","commit_id":"2a75963d6a3996b66c126fd749cdc54bfee21d97"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"641e57a16a7a53f82cd1f9ac77acc9ac56ea9ca7","unresolved":false,"context_lines":[{"line_number":11,"context_line":"#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":12,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":13,"context_line":"#    under the License."},{"line_number":14,"context_line":"import abc"},{"line_number":15,"context_line":"import six"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_9401e107","line":14,"updated":"2016-06-30 15:56:12.000000000","message":"Missing newline above and below this line","commit_id":"2a75963d6a3996b66c126fd749cdc54bfee21d97"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"e7d9ab90779aec8bbc209a2bb4d861de983044f1","unresolved":false,"context_lines":[{"line_number":16,"context_line":""},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"@six.add_metaclass(abc.ABCMeta)"},{"line_number":19,"context_line":"class AuthDriverV8(object):"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    def list_auth_attempts(self, user_id):"},{"line_number":22,"context_line":"        raise NotImplementedError"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_d4b40983","line":19,"updated":"2016-06-30 15:58:27.000000000","message":"This feels like it should just be a few new methods in the existing identity backend - I don\u0027t see a reason why this is \"auth\" specific, especially when the authenticate() method is part of identity, etc.","commit_id":"2a75963d6a3996b66c126fd749cdc54bfee21d97"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"641e57a16a7a53f82cd1f9ac77acc9ac56ea9ca7","unresolved":false,"context_lines":[{"line_number":18,"context_line":"@six.add_metaclass(abc.ABCMeta)"},{"line_number":19,"context_line":"class AuthDriverV8(object):"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    def list_auth_attempts(self, user_id):"},{"line_number":22,"context_line":"        raise NotImplementedError"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    def reset_auth_attempts(self, user_id):"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_d407e915","line":21,"updated":"2016-06-30 15:56:12.000000000","message":"abstractmethods?","commit_id":"2a75963d6a3996b66c126fd749cdc54bfee21d97"}],"keystone/auth/backends/sql.py":[{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"b69d393006144d643f70da5ad5a3689308a7e1c4","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from keystone.common import sql"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class Auth(base.AuthDriverV8):"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    def list_auth_attempts(self, user_id):"},{"line_number":25,"context_line":"        with sql.session_for_read() as session:"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_a355f01e","line":22,"range":{"start_line":22,"start_character":6,"end_line":22,"end_character":10},"updated":"2016-06-29 22:55:00.000000000","message":"Not crazy about the \"Auth\" name, I think FailedAuthTracker or something would be more appropriate. \"Auth\" is too generic.","commit_id":"74c64b1de20585ce48ab502c217583dd7722fec3"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"cd1346eba2deb62e60124e8775b927515bef2d88","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from keystone.common import sql"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class Auth(base.AuthDriverV8):"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    def list_auth_attempts(self, user_id):"},{"line_number":25,"context_line":"        with sql.session_for_read() as session:"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_1a70853f","line":22,"range":{"start_line":22,"start_character":6,"end_line":22,"end_character":10},"in_reply_to":"3aaa91ec_a355f01e","updated":"2016-06-30 14:50:14.000000000","message":"I think it rather be generic as it is the only driver for auth component. We can\u0027t predict what will it do in the future...\nBesides, naming something a \"doer\" usually is not the best idea.","commit_id":"74c64b1de20585ce48ab502c217583dd7722fec3"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"b69d393006144d643f70da5ad5a3689308a7e1c4","unresolved":false,"context_lines":[{"line_number":30,"context_line":"    def reset_auth_attempts(self, user_id):"},{"line_number":31,"context_line":"        with sql.session_for_write() as session:"},{"line_number":32,"context_line":"            query \u003d session.query(model.FailedAuthAttempts)"},{"line_number":33,"context_line":"            return query.filter_by(user_id\u003duser_id).delete()"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    def register_failed_auth_attempt(self, user_id):"},{"line_number":36,"context_line":"        with sql.session_for_write() as session:"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_a6b69e3b","line":33,"range":{"start_line":33,"start_character":12,"end_line":33,"end_character":18},"updated":"2016-06-29 22:55:00.000000000","message":"nit: I don\u0027t think you need a return here","commit_id":"74c64b1de20585ce48ab502c217583dd7722fec3"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"cd1346eba2deb62e60124e8775b927515bef2d88","unresolved":false,"context_lines":[{"line_number":30,"context_line":"    def reset_auth_attempts(self, user_id):"},{"line_number":31,"context_line":"        with sql.session_for_write() as session:"},{"line_number":32,"context_line":"            query \u003d session.query(model.FailedAuthAttempts)"},{"line_number":33,"context_line":"            return query.filter_by(user_id\u003duser_id).delete()"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    def register_failed_auth_attempt(self, user_id):"},{"line_number":36,"context_line":"        with sql.session_for_write() as session:"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_5ad5ed40","line":33,"range":{"start_line":33,"start_character":12,"end_line":33,"end_character":18},"in_reply_to":"3aaa91ec_a6b69e3b","updated":"2016-06-30 14:50:14.000000000","message":"Done","commit_id":"74c64b1de20585ce48ab502c217583dd7722fec3"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"641e57a16a7a53f82cd1f9ac77acc9ac56ea9ca7","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2016 OpenStack Foundation"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":4,"context_line":"#    not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_d41ec95d","line":1,"updated":"2016-06-30 15:56:12.000000000","message":"same","commit_id":"2a75963d6a3996b66c126fd749cdc54bfee21d97"}],"keystone/auth/backends/sql_model.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"2667ea28fd49634ae0d1410e695a30845baf3d78","unresolved":false,"context_lines":[{"line_number":16,"context_line":""},{"line_number":17,"context_line":"class FailedAuthAttempts(sql.ModelBase, sql.DictBase):"},{"line_number":18,"context_line":"    __tablename__ \u003d \u0027failed_auth_attempts\u0027"},{"line_number":19,"context_line":"    attributes \u003d [\u0027id\u0027, \u0027user_id\u0027, \u0027timestamp\u0027]"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":22,"context_line":"    user_id \u003d sql.Column(sql.String(64), index\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abb7d3a_a040c408","line":19,"updated":"2016-06-02 18:23:51.000000000","message":"Failed authentication attempts seems like a user attribute.While this works, it seems a little heavy-handed to make failed_auth_attempts it\u0027s own table.","commit_id":"cc76f3e8b9def69bbec701857d4f840d3ed1e00c"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"759a5f62d26d0c968430b1c8447efbb77375ea16","unresolved":false,"context_lines":[{"line_number":18,"context_line":"    __tablename__ \u003d \u0027failed_auth_attempts\u0027"},{"line_number":19,"context_line":"    attributes \u003d [\u0027id\u0027, \u0027user_id\u0027, \u0027timestamp\u0027]"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":22,"context_line":"    user_id \u003d sql.Column(sql.String(64), index\u003dTrue)"},{"line_number":23,"context_line":"    timestamp \u003d sql.Column(sql.DateTime())"},{"line_number":24,"context_line":"    extra \u003d sql.Column(sql.JsonBlob())"}],"source_content_type":"text/x-python","patch_set":7,"id":"7aa08908_906e912d","line":21,"range":{"start_line":21,"start_character":4,"end_line":21,"end_character":6},"updated":"2016-06-06 19:30:33.000000000","message":"If this isn\u0027t an id that will be exposed to users, it should be an integer.","commit_id":"9002d08b52dd35808af8dcef33e540f6f329aa57"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"f561d1dc68929e3fbe92482d0c345d2359e55779","unresolved":false,"context_lines":[{"line_number":18,"context_line":"    __tablename__ \u003d \u0027failed_auth_attempts\u0027"},{"line_number":19,"context_line":"    attributes \u003d [\u0027id\u0027, \u0027user_id\u0027, \u0027timestamp\u0027]"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":22,"context_line":"    user_id \u003d sql.Column(sql.String(64), index\u003dTrue)"},{"line_number":23,"context_line":"    timestamp \u003d sql.Column(sql.DateTime())"},{"line_number":24,"context_line":"    extra \u003d sql.Column(sql.JsonBlob())"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_567621d9","line":21,"range":{"start_line":21,"start_character":4,"end_line":21,"end_character":6},"in_reply_to":"7aa08908_906e912d","updated":"2016-06-27 14:26:32.000000000","message":"Done","commit_id":"9002d08b52dd35808af8dcef33e540f6f329aa57"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"759a5f62d26d0c968430b1c8447efbb77375ea16","unresolved":false,"context_lines":[{"line_number":21,"context_line":"    id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":22,"context_line":"    user_id \u003d sql.Column(sql.String(64), index\u003dTrue)"},{"line_number":23,"context_line":"    timestamp \u003d sql.Column(sql.DateTime())"},{"line_number":24,"context_line":"    extra \u003d sql.Column(sql.JsonBlob())"}],"source_content_type":"text/x-python","patch_set":7,"id":"7aa08908_f015559b","line":24,"range":{"start_line":24,"start_character":4,"end_line":24,"end_character":9},"updated":"2016-06-06 19:30:33.000000000","message":"Why do we need extra?","commit_id":"9002d08b52dd35808af8dcef33e540f6f329aa57"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"f561d1dc68929e3fbe92482d0c345d2359e55779","unresolved":false,"context_lines":[{"line_number":21,"context_line":"    id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":22,"context_line":"    user_id \u003d sql.Column(sql.String(64), index\u003dTrue)"},{"line_number":23,"context_line":"    timestamp \u003d sql.Column(sql.DateTime())"},{"line_number":24,"context_line":"    extra \u003d sql.Column(sql.JsonBlob())"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_f6474d75","line":24,"range":{"start_line":24,"start_character":4,"end_line":24,"end_character":9},"in_reply_to":"7aa08908_f015559b","updated":"2016-06-27 14:26:32.000000000","message":"It\u0027s a requirement for DictBase","commit_id":"9002d08b52dd35808af8dcef33e540f6f329aa57"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"47f00650babbf9bc3002d1a7e0552ba259fac96a","unresolved":false,"context_lines":[{"line_number":18,"context_line":"    __tablename__ \u003d \u0027failed_auth_attempts\u0027"},{"line_number":19,"context_line":"    attributes \u003d [\u0027id\u0027, \u0027user_id\u0027, \u0027timestamp\u0027]"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    # id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":22,"context_line":"    id \u003d sql.Column(sql.Integer, primary_key\u003dTrue)"},{"line_number":23,"context_line":"    user_id \u003d sql.Column(sql.String(64), index\u003dTrue)"},{"line_number":24,"context_line":"    timestamp \u003d sql.Column(sql.DateTime())"}],"source_content_type":"text/x-python","patch_set":9,"id":"3aaa91ec_05e36134","line":21,"range":{"start_line":21,"start_character":4,"end_line":21,"end_character":5},"updated":"2016-06-29 03:09:06.000000000","message":"nit: take out this comment","commit_id":"4925ca21c1e975be1c637eb0ed8fc66dd2ff4501"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"a0c04bfd85466127c9d4fae30d81d08997532d84","unresolved":false,"context_lines":[{"line_number":18,"context_line":"    __tablename__ \u003d \u0027failed_auth_attempts\u0027"},{"line_number":19,"context_line":"    attributes \u003d [\u0027id\u0027, \u0027user_id\u0027, \u0027timestamp\u0027]"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    # id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":22,"context_line":"    id \u003d sql.Column(sql.Integer, primary_key\u003dTrue)"},{"line_number":23,"context_line":"    user_id \u003d sql.Column(sql.String(64), index\u003dTrue)"},{"line_number":24,"context_line":"    timestamp \u003d sql.Column(sql.DateTime())"}],"source_content_type":"text/x-python","patch_set":9,"id":"3aaa91ec_d780c4c1","line":21,"range":{"start_line":21,"start_character":4,"end_line":21,"end_character":5},"in_reply_to":"3aaa91ec_05e36134","updated":"2016-06-29 17:07:41.000000000","message":"Done","commit_id":"4925ca21c1e975be1c637eb0ed8fc66dd2ff4501"}],"keystone/auth/controllers.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"2667ea28fd49634ae0d1410e695a30845baf3d78","unresolved":false,"context_lines":[{"line_number":413,"context_line":"                else:"},{"line_number":414,"context_line":"                    self.auth_api.reset_auth_attempts(user_id)"},{"line_number":415,"context_line":"            else:"},{"line_number":416,"context_line":"                self.authenticate(context, auth_info, auth_context)"},{"line_number":417,"context_line":""},{"line_number":418,"context_line":"            if auth_context.get(\u0027access_token_id\u0027):"},{"line_number":419,"context_line":"                auth_info.set_scope(None, auth_context[\u0027project_id\u0027], None)"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abb7d3a_4008f891","line":416,"updated":"2016-06-02 18:23:51.000000000","message":"What if I pass a token to keystone over and over to try and get access to something? Will that be caught by this? This change seems specific to only password authentication attempts. The PCI-DSS 8.1.6 statement doesn\u0027t specifically say password access does it? It seems like PCI-DSS 8.1.6 would still apply to token authentication.","commit_id":"cc76f3e8b9def69bbec701857d4f840d3ed1e00c"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"543ce65003c4c27cb079ad28b784740951072273","unresolved":false,"context_lines":[{"line_number":413,"context_line":"                else:"},{"line_number":414,"context_line":"                    self.auth_api.reset_auth_attempts(user_id)"},{"line_number":415,"context_line":"            else:"},{"line_number":416,"context_line":"                self.authenticate(context, auth_info, auth_context)"},{"line_number":417,"context_line":""},{"line_number":418,"context_line":"            if auth_context.get(\u0027access_token_id\u0027):"},{"line_number":419,"context_line":"                auth_info.set_scope(None, auth_context[\u0027project_id\u0027], None)"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abb7d3a_575c3bed","line":416,"in_reply_to":"9abb7d3a_4008f891","updated":"2016-06-02 18:56:49.000000000","message":"I agree, and to implement it for all other methods we have to change plugin interface: it have to return user_id despite of authN success or failure.","commit_id":"cc76f3e8b9def69bbec701857d4f840d3ed1e00c"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"759a5f62d26d0c968430b1c8447efbb77375ea16","unresolved":false,"context_lines":[{"line_number":399,"context_line":""},{"line_number":400,"context_line":"            # Get user_id using auth method, check lockout, and authenticate"},{"line_number":401,"context_line":"            # registering failed attempts"},{"line_number":402,"context_line":"            if \u0027password\u0027 in auth_info.get_method_names():"},{"line_number":403,"context_line":"                method \u003d \u0027password\u0027"},{"line_number":404,"context_line":"                auth_payload \u003d auth_info.get_method_data(method)"},{"line_number":405,"context_line":"                user_info \u003d plugins.UserAuthInfo.create(auth_payload, method)"}],"source_content_type":"text/x-python","patch_set":7,"id":"7aa08908_b08f4dcb","line":402,"range":{"start_line":402,"start_character":29,"end_line":402,"end_character":38},"updated":"2016-06-06 19:30:33.000000000","message":"If you are only looking for password, why not put this check under keystone/identity?","commit_id":"9002d08b52dd35808af8dcef33e540f6f329aa57"},{"author":{"_account_id":8797,"name":"Andrew Woodward","email":"xarses@gmail.com","username":"xarses"},"change_message_id":"813f7c1273fa4d6300e35a27a743376071c1f8fc","unresolved":false,"context_lines":[{"line_number":399,"context_line":""},{"line_number":400,"context_line":"            # Get user_id using auth method, check lockout, and authenticate"},{"line_number":401,"context_line":"            # registering failed attempts"},{"line_number":402,"context_line":"            if \u0027password\u0027 in auth_info.get_method_names():"},{"line_number":403,"context_line":"                method \u003d \u0027password\u0027"},{"line_number":404,"context_line":"                auth_payload \u003d auth_info.get_method_data(method)"},{"line_number":405,"context_line":"                user_info \u003d plugins.UserAuthInfo.create(auth_payload, method)"}],"source_content_type":"text/x-python","patch_set":7,"id":"7aa08908_fe716645","line":402,"range":{"start_line":402,"start_character":16,"end_line":402,"end_character":24},"updated":"2016-06-07 17:27:11.000000000","message":"Shouldn\u0027t we support disabling bad token usage too? It\u0027s technically a credential","commit_id":"9002d08b52dd35808af8dcef33e540f6f329aa57"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"d27e8617a3b24071d4d6b0762f216cf61af8cd8c","unresolved":false,"context_lines":[{"line_number":399,"context_line":""},{"line_number":400,"context_line":"            # Get user_id using auth method, check lockout, and authenticate"},{"line_number":401,"context_line":"            # registering failed attempts"},{"line_number":402,"context_line":"            if \u0027password\u0027 in auth_info.get_method_names():"},{"line_number":403,"context_line":"                method \u003d \u0027password\u0027"},{"line_number":404,"context_line":"                auth_payload \u003d auth_info.get_method_data(method)"},{"line_number":405,"context_line":"                user_info \u003d plugins.UserAuthInfo.create(auth_payload, method)"}],"source_content_type":"text/x-python","patch_set":7,"id":"7aa08908_ec76d9d5","line":402,"range":{"start_line":402,"start_character":16,"end_line":402,"end_character":24},"in_reply_to":"7aa08908_fe716645","updated":"2016-06-07 19:06:43.000000000","message":"Andrew, technically we can do it for all of auth plugins, but I\u0027m afraid it will involve changing plugin interface: it should support returning user_id even after failure. And it will be plugin\u0027s duty as every plugin discovers user it\u0027s own way.","commit_id":"9002d08b52dd35808af8dcef33e540f6f329aa57"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"6d3760edba1335b4af5da2f39f616945914929a8","unresolved":false,"context_lines":[{"line_number":406,"context_line":"            # Get user_id using auth method, check lockout, and authenticate"},{"line_number":407,"context_line":"            # registering failed attempts"},{"line_number":408,"context_line":"            if \u0027password\u0027 in auth_info.get_method_names():"},{"line_number":409,"context_line":"                method \u003d \u0027password\u0027"},{"line_number":410,"context_line":"                auth_payload \u003d auth_info.get_method_data(method)"},{"line_number":411,"context_line":"                user_info \u003d plugins.UserAuthInfo.create(auth_payload, method)"},{"line_number":412,"context_line":"                user_id \u003d user_info.user_id"}],"source_content_type":"text/x-python","patch_set":11,"id":"1aa78d24_5eb97814","line":409,"updated":"2016-07-06 15:13:18.000000000","message":"Minor suggestion: This could be pulled out into a constant, maybe something like PASSWORD_METHOD?","commit_id":"2a75963d6a3996b66c126fd749cdc54bfee21d97"}],"keystone/auth/core.py":[{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"b09937e5e4f730be7e030bb550e9cf1e381ef7e8","unresolved":false,"context_lines":[{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"@dependency.provider(\u0027auth_api\u0027)"},{"line_number":105,"context_line":"class Manager(manager.Manager):"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"    driver_namespace \u003d \u0027keystone.auth\u0027"},{"line_number":108,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9abb7d3a_2394ebe6","line":105,"range":{"start_line":105,"start_character":6,"end_line":105,"end_character":13},"updated":"2016-06-02 15:09:53.000000000","message":"I think identity would be a better place for this than auth, so here for example:\nhttps://github.com/openstack/keystone/blob/master/keystone/identity/core.py#L824\n\nJust think that we want to track failed authentication attempts for LDAP, SQL, and custom identity drivers, but wouldn\u0027t want to track for federation.","commit_id":"5cd1484317a6a48f8b636ca131eb61c4ec81e12b"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"2667ea28fd49634ae0d1410e695a30845baf3d78","unresolved":false,"context_lines":[{"line_number":112,"context_line":"    def check_auth_attempts(self, user_id):"},{"line_number":113,"context_line":"        if CONF.security_compliance.lockout_failure_attempts \u003d\u003d 0:"},{"line_number":114,"context_line":"            # The check is disabled"},{"line_number":115,"context_line":"            return"},{"line_number":116,"context_line":"        attempts \u003d self.driver.list_auth_attempts(user_id)"},{"line_number":117,"context_line":"        if len(attempts) \u003e\u003d CONF.security_compliance.lockout_failure_attempts:"},{"line_number":118,"context_line":"            # Account was locked out"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abb7d3a_209334fc","line":115,"updated":"2016-06-02 18:23:51.000000000","message":"nit: I feel like this should be done in the layer above. Should we be in this code unless the feature is enabled?","commit_id":"cc76f3e8b9def69bbec701857d4f840d3ed1e00c"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"543ce65003c4c27cb079ad28b784740951072273","unresolved":false,"context_lines":[{"line_number":112,"context_line":"    def check_auth_attempts(self, user_id):"},{"line_number":113,"context_line":"        if CONF.security_compliance.lockout_failure_attempts \u003d\u003d 0:"},{"line_number":114,"context_line":"            # The check is disabled"},{"line_number":115,"context_line":"            return"},{"line_number":116,"context_line":"        attempts \u003d self.driver.list_auth_attempts(user_id)"},{"line_number":117,"context_line":"        if len(attempts) \u003e\u003d CONF.security_compliance.lockout_failure_attempts:"},{"line_number":118,"context_line":"            # Account was locked out"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abb7d3a_57b8bbe5","line":115,"in_reply_to":"9abb7d3a_209334fc","updated":"2016-06-02 18:56:49.000000000","message":"I had same concerns. This is a business logic and usually belongs to a manager: controller works with web-related stuff, driver - with a storage.","commit_id":"cc76f3e8b9def69bbec701857d4f840d3ed1e00c"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"2667ea28fd49634ae0d1410e695a30845baf3d78","unresolved":false,"context_lines":[{"line_number":120,"context_line":"                # Check lockout expiration"},{"line_number":121,"context_line":"                delta \u003d datetime.timedelta("},{"line_number":122,"context_line":"                    seconds\u003dCONF.security_compliance.lockout_duration)"},{"line_number":123,"context_line":"                latest \u003d max(*(item[\u0027timestamp\u0027] for item in attempts))"},{"line_number":124,"context_line":"                if (latest + delta) \u003c datetime.datetime.now():"},{"line_number":125,"context_line":"                    # lockout is expired"},{"line_number":126,"context_line":"                    return"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abb7d3a_807140e3","line":123,"updated":"2016-06-02 18:23:51.000000000","message":"nit: s/latest/most_recent_failed_attempt/ ?\n\nWhat does * do here?","commit_id":"cc76f3e8b9def69bbec701857d4f840d3ed1e00c"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"543ce65003c4c27cb079ad28b784740951072273","unresolved":false,"context_lines":[{"line_number":120,"context_line":"                # Check lockout expiration"},{"line_number":121,"context_line":"                delta \u003d datetime.timedelta("},{"line_number":122,"context_line":"                    seconds\u003dCONF.security_compliance.lockout_duration)"},{"line_number":123,"context_line":"                latest \u003d max(*(item[\u0027timestamp\u0027] for item in attempts))"},{"line_number":124,"context_line":"                if (latest + delta) \u003c datetime.datetime.now():"},{"line_number":125,"context_line":"                    # lockout is expired"},{"line_number":126,"context_line":"                    return"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abb7d3a_b7948744","line":123,"in_reply_to":"9abb7d3a_807140e3","updated":"2016-06-02 18:56:49.000000000","message":"Agree: max() accepts iterable too while I\u0027ve used the form I\u0027m more familiar with.","commit_id":"cc76f3e8b9def69bbec701857d4f840d3ed1e00c"},{"author":{"_account_id":11434,"name":"werner mendizabal","email":"nonameentername@gmail.com","username":"nonameentername"},"change_message_id":"3cef2e080d85c738f098df5b6d8773f0980d8d8f","unresolved":false,"context_lines":[{"line_number":16,"context_line":"import datetime"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"import six"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from oslo_config import cfg"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from keystone.common import dependency"}],"source_content_type":"text/x-python","patch_set":6,"id":"9abb7d3a_d2e75ee2","line":19,"updated":"2016-06-03 16:05:26.000000000","message":"nit: this blank line can be removed.","commit_id":"5687403e18ec64e7d59db9e880a0ba0a6df4c9b7"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"759a5f62d26d0c968430b1c8447efbb77375ea16","unresolved":false,"context_lines":[{"line_number":128,"context_line":""},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"@six.add_metaclass(abc.ABCMeta)"},{"line_number":131,"context_line":"class AuthDriverV8(object):"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    def list_auth_attempts(self, user_id):"},{"line_number":134,"context_line":"        raise NotImplementedError"}],"source_content_type":"text/x-python","patch_set":7,"id":"7aa08908_c31e9162","line":131,"range":{"start_line":131,"start_character":6,"end_line":131,"end_character":18},"updated":"2016-06-06 19:30:33.000000000","message":"This should now be removed from core and put under /backends/base.py\n\nHere is an example of this:\nhttps://review.openstack.org/#/c/317045/","commit_id":"9002d08b52dd35808af8dcef33e540f6f329aa57"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"47f00650babbf9bc3002d1a7e0552ba259fac96a","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        super(Manager, self).__init__(CONF.auth.driver)"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    def check_auth_attempts(self, user_id):"},{"line_number":113,"context_line":"        if CONF.security_compliance.lockout_failure_attempts \u003d\u003d 0:"},{"line_number":114,"context_line":"            # The check is disabled"},{"line_number":115,"context_line":"            return"},{"line_number":116,"context_line":"        attempts \u003d self.driver.list_auth_attempts(user_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3aaa91ec_c52159fe","line":113,"range":{"start_line":113,"start_character":36,"end_line":113,"end_character":60},"updated":"2016-06-29 03:09:06.000000000","message":"Should change this config option to default to None with a minimum of 1, e.g.:\ndefault\u003dNone,\nmin\u003d1,","commit_id":"4925ca21c1e975be1c637eb0ed8fc66dd2ff4501"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"a0c04bfd85466127c9d4fae30d81d08997532d84","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        super(Manager, self).__init__(CONF.auth.driver)"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    def check_auth_attempts(self, user_id):"},{"line_number":113,"context_line":"        if CONF.security_compliance.lockout_failure_attempts \u003d\u003d 0:"},{"line_number":114,"context_line":"            # The check is disabled"},{"line_number":115,"context_line":"            return"},{"line_number":116,"context_line":"        attempts \u003d self.driver.list_auth_attempts(user_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3aaa91ec_3772e811","line":113,"range":{"start_line":113,"start_character":36,"end_line":113,"end_character":60},"in_reply_to":"3aaa91ec_c52159fe","updated":"2016-06-29 17:07:41.000000000","message":"Done","commit_id":"4925ca21c1e975be1c637eb0ed8fc66dd2ff4501"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"47f00650babbf9bc3002d1a7e0552ba259fac96a","unresolved":false,"context_lines":[{"line_number":128,"context_line":""},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"@six.add_metaclass(abc.ABCMeta)"},{"line_number":131,"context_line":"class AuthDriverV8(object):"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    def list_auth_attempts(self, user_id):"},{"line_number":134,"context_line":"        raise NotImplementedError"}],"source_content_type":"text/x-python","patch_set":9,"id":"3aaa91ec_45b9e9ca","line":131,"range":{"start_line":131,"start_character":6,"end_line":131,"end_character":18},"updated":"2016-06-29 03:09:06.000000000","message":"Move the abstract base class to keystone/auth/backends/base.py\n\nThis is the new standard. For example, see identity:\nhttps://github.com/openstack/keystone/blob/master/keystone/identity/backends/base.py","commit_id":"4925ca21c1e975be1c637eb0ed8fc66dd2ff4501"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"a0c04bfd85466127c9d4fae30d81d08997532d84","unresolved":false,"context_lines":[{"line_number":128,"context_line":""},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"@six.add_metaclass(abc.ABCMeta)"},{"line_number":131,"context_line":"class AuthDriverV8(object):"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    def list_auth_attempts(self, user_id):"},{"line_number":134,"context_line":"        raise NotImplementedError"}],"source_content_type":"text/x-python","patch_set":9,"id":"3aaa91ec_97611c3c","line":131,"range":{"start_line":131,"start_character":6,"end_line":131,"end_character":18},"in_reply_to":"3aaa91ec_45b9e9ca","updated":"2016-06-29 17:07:41.000000000","message":"Done","commit_id":"4925ca21c1e975be1c637eb0ed8fc66dd2ff4501"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"b69d393006144d643f70da5ad5a3689308a7e1c4","unresolved":false,"context_lines":[{"line_number":116,"context_line":"        attempts \u003d self.driver.list_auth_attempts(user_id)"},{"line_number":117,"context_line":"        if len(attempts) \u003e\u003d CONF.security_compliance.lockout_failure_attempts:"},{"line_number":118,"context_line":"            # Account was locked out"},{"line_number":119,"context_line":"            if CONF.security_compliance.lockout_duration:"},{"line_number":120,"context_line":"                # Check lockout expiration"},{"line_number":121,"context_line":"                delta \u003d datetime.timedelta("},{"line_number":122,"context_line":"                    seconds\u003dCONF.security_compliance.lockout_duration)"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_a6521edc","line":119,"range":{"start_line":119,"start_character":40,"end_line":119,"end_character":56},"updated":"2016-06-29 22:55:00.000000000","message":"Do if lock duration is not set, the account is permanently locked?","commit_id":"74c64b1de20585ce48ab502c217583dd7722fec3"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"cd1346eba2deb62e60124e8775b927515bef2d88","unresolved":false,"context_lines":[{"line_number":116,"context_line":"        attempts \u003d self.driver.list_auth_attempts(user_id)"},{"line_number":117,"context_line":"        if len(attempts) \u003e\u003d CONF.security_compliance.lockout_failure_attempts:"},{"line_number":118,"context_line":"            # Account was locked out"},{"line_number":119,"context_line":"            if CONF.security_compliance.lockout_duration:"},{"line_number":120,"context_line":"                # Check lockout expiration"},{"line_number":121,"context_line":"                delta \u003d datetime.timedelta("},{"line_number":122,"context_line":"                    seconds\u003dCONF.security_compliance.lockout_duration)"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_8928b187","line":119,"range":{"start_line":119,"start_character":40,"end_line":119,"end_character":56},"in_reply_to":"3aaa91ec_a6521edc","updated":"2016-06-30 14:50:14.000000000","message":"Done","commit_id":"74c64b1de20585ce48ab502c217583dd7722fec3"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"b69d393006144d643f70da5ad5a3689308a7e1c4","unresolved":false,"context_lines":[{"line_number":124,"context_line":"                if (latest + delta) \u003c datetime.datetime.now():"},{"line_number":125,"context_line":"                    # lockout is expired"},{"line_number":126,"context_line":"                    return"},{"line_number":127,"context_line":"            raise exception.Unauthorized()"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_86fd62b3","line":127,"range":{"start_line":127,"start_character":28,"end_line":127,"end_character":40},"updated":"2016-06-29 22:55:00.000000000","message":"Why not raise a more specific exception, e.g.:\nraise exception.AccountLocked(user_id\u003duser_id)\n\nYou could create a new exception here: \nkeystone/exception.py\n\nclass AccountLocked(Unauthorized):\n    message_format \u003d _(\"The account is locked for user: %(user_id)s\")","commit_id":"74c64b1de20585ce48ab502c217583dd7722fec3"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"cd1346eba2deb62e60124e8775b927515bef2d88","unresolved":false,"context_lines":[{"line_number":124,"context_line":"                if (latest + delta) \u003c datetime.datetime.now():"},{"line_number":125,"context_line":"                    # lockout is expired"},{"line_number":126,"context_line":"                    return"},{"line_number":127,"context_line":"            raise exception.Unauthorized()"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_c95599fa","line":127,"range":{"start_line":127,"start_character":28,"end_line":127,"end_character":40},"in_reply_to":"3aaa91ec_86fd62b3","updated":"2016-06-30 14:50:14.000000000","message":"Done","commit_id":"74c64b1de20585ce48ab502c217583dd7722fec3"}],"keystone/common/config.py":[{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"b09937e5e4f730be7e030bb550e9cf1e381ef7e8","unresolved":false,"context_lines":[{"line_number":817,"context_line":"        cfg.StrOpt(\u0027oauth1\u0027,"},{"line_number":818,"context_line":"                   help\u003d\u0027Entrypoint for the oAuth1.0 auth plugin module in \u0027"},{"line_number":819,"context_line":"                        \u0027the keystone.auth.oauth1 namespace.\u0027),"},{"line_number":820,"context_line":"        cfg.StrOpt(\u0027driver\u0027,"},{"line_number":821,"context_line":"                   default\u003d\u0027sql\u0027,"},{"line_number":822,"context_line":"                   help\u003d\u0027Entrypoint for the authentication backend driver in \u0027"},{"line_number":823,"context_line":"                        \u0027the keystone.auth namespace. The only supplied \u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"9abb7d3a_839f974f","line":820,"range":{"start_line":820,"start_character":12,"end_line":820,"end_character":18},"updated":"2016-06-02 15:09:53.000000000","message":"Do we really need a custom driver option for this?","commit_id":"5cd1484317a6a48f8b636ca131eb61c4ec81e12b"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"759a5f62d26d0c968430b1c8447efbb77375ea16","unresolved":false,"context_lines":[{"line_number":817,"context_line":"        cfg.StrOpt(\u0027oauth1\u0027,"},{"line_number":818,"context_line":"                   help\u003d\u0027Entrypoint for the oAuth1.0 auth plugin module in \u0027"},{"line_number":819,"context_line":"                        \u0027the keystone.auth.oauth1 namespace.\u0027),"},{"line_number":820,"context_line":"        cfg.StrOpt(\u0027driver\u0027,"},{"line_number":821,"context_line":"                   default\u003d\u0027sql\u0027,"},{"line_number":822,"context_line":"                   help\u003d\u0027Entrypoint for the authentication backend driver in \u0027"},{"line_number":823,"context_line":"                        \u0027the keystone.auth namespace. The only supplied \u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"7aa08908_437d816d","line":820,"range":{"start_line":820,"start_character":20,"end_line":820,"end_character":26},"updated":"2016-06-06 19:30:33.000000000","message":"Do we really need to make this a driver to be customized?  I mean, do we really see operators creating their own implementation for this?  If not, lets not do this.","commit_id":"9002d08b52dd35808af8dcef33e540f6f329aa57"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"310444d1b655fe35b0620bb785078f393756e98f","unresolved":false,"context_lines":[{"line_number":817,"context_line":"        cfg.StrOpt(\u0027oauth1\u0027,"},{"line_number":818,"context_line":"                   help\u003d\u0027Entrypoint for the oAuth1.0 auth plugin module in \u0027"},{"line_number":819,"context_line":"                        \u0027the keystone.auth.oauth1 namespace.\u0027),"},{"line_number":820,"context_line":"        cfg.StrOpt(\u0027driver\u0027,"},{"line_number":821,"context_line":"                   default\u003d\u0027sql\u0027,"},{"line_number":822,"context_line":"                   help\u003d\u0027Entrypoint for the authentication backend driver in \u0027"},{"line_number":823,"context_line":"                        \u0027the keystone.auth namespace. The only supplied \u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"7aa08908_d12bed31","line":820,"range":{"start_line":820,"start_character":20,"end_line":820,"end_character":26},"in_reply_to":"7aa08908_437d816d","updated":"2016-06-10 16:45:36.000000000","message":"Nevermind, I\u0027m okay with this","commit_id":"9002d08b52dd35808af8dcef33e540f6f329aa57"}],"keystone/common/sql/migrate_repo/versions/103_placeholder.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"2667ea28fd49634ae0d1410e695a30845baf3d78","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":2,"context_line":"#    not use this file except in compliance with the License. You may obtain"},{"line_number":3,"context_line":"#    a copy of the License at"},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abb7d3a_74569d07","line":1,"updated":"2016-06-02 18:23:51.000000000","message":"I\u0027m thinking maybe this should be done in a separate patch. Typically, we leave room for 4 - 5 of these.","commit_id":"cc76f3e8b9def69bbec701857d4f840d3ed1e00c"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"543ce65003c4c27cb079ad28b784740951072273","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":2,"context_line":"#    not use this file except in compliance with the License. You may obtain"},{"line_number":3,"context_line":"#    a copy of the License at"},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abb7d3a_f79e0f62","line":1,"in_reply_to":"9abb7d3a_74569d07","updated":"2016-06-02 18:56:49.000000000","message":"103 update is already claimed by Ron\u0027s change, so I\u0027ve added this for tests to pass.","commit_id":"cc76f3e8b9def69bbec701857d4f840d3ed1e00c"}],"keystone/common/sql/migrate_repo/versions/104_add_failed_attempts_table.py":[{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"759a5f62d26d0c968430b1c8447efbb77375ea16","unresolved":false,"context_lines":[{"line_number":25,"context_line":"        sql.Column(\u0027id\u0027, sql.String(64), primary_key\u003dTrue, nullable\u003dFalse),"},{"line_number":26,"context_line":"        sql.Column(\u0027user_id\u0027, sql.String(64), nullable\u003dFalse, index\u003dTrue),"},{"line_number":27,"context_line":"        sql.Column(\u0027timestamp\u0027, sql.DateTime()),"},{"line_number":28,"context_line":"        sql.Column(\u0027extra\u0027, sql.Text(), nullable\u003dFalse)"},{"line_number":29,"context_line":"    )"},{"line_number":30,"context_line":"    failed_auth_attempts_table.create(migrate_engine, checkfirst\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":7,"id":"7aa08908_a38c2580","line":28,"range":{"start_line":28,"start_character":20,"end_line":28,"end_character":25},"updated":"2016-06-06 19:30:33.000000000","message":"Again, why extra?","commit_id":"9002d08b52dd35808af8dcef33e540f6f329aa57"}],"keystone/common/sql/migrate_repo/versions/107_add_failed_attempts_table.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"641e57a16a7a53f82cd1f9ac77acc9ac56ea9ca7","unresolved":false,"context_lines":[{"line_number":25,"context_line":"        sql.Column(\u0027id\u0027, sql.Integer, primary_key\u003dTrue, nullable\u003dFalse),"},{"line_number":26,"context_line":"        sql.Column(\u0027user_id\u0027, sql.String(64), nullable\u003dFalse, index\u003dTrue),"},{"line_number":27,"context_line":"        sql.Column(\u0027timestamp\u0027, sql.DateTime()),"},{"line_number":28,"context_line":"        sql.Column(\u0027extra\u0027, sql.Text(), nullable\u003dFalse)"},{"line_number":29,"context_line":"    )"},{"line_number":30,"context_line":"    failed_auth_attempts_table.create(migrate_engine, checkfirst\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_f49305a1","line":28,"updated":"2016-06-30 15:56:12.000000000","message":"why this?","commit_id":"2a75963d6a3996b66c126fd749cdc54bfee21d97"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"3eff9d0712bfffee09813704940f398005940b4d","unresolved":false,"context_lines":[{"line_number":25,"context_line":"        sql.Column(\u0027id\u0027, sql.Integer, primary_key\u003dTrue, nullable\u003dFalse),"},{"line_number":26,"context_line":"        sql.Column(\u0027user_id\u0027, sql.String(64), nullable\u003dFalse, index\u003dTrue),"},{"line_number":27,"context_line":"        sql.Column(\u0027timestamp\u0027, sql.DateTime()),"},{"line_number":28,"context_line":"        sql.Column(\u0027extra\u0027, sql.Text(), nullable\u003dFalse)"},{"line_number":29,"context_line":"    )"},{"line_number":30,"context_line":"    failed_auth_attempts_table.create(migrate_engine, checkfirst\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":11,"id":"dada55a8_c34e216e","line":28,"in_reply_to":"3aaa91ec_f49305a1","updated":"2016-07-25 09:58:39.000000000","message":"It is required for sql.DictBase","commit_id":"2a75963d6a3996b66c126fd749cdc54bfee21d97"}],"keystone/conf/security_compliance.py":[{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"b69d393006144d643f70da5ad5a3689308a7e1c4","unresolved":false,"context_lines":[{"line_number":25,"context_line":""},{"line_number":26,"context_line":"lockout_failure_attempts \u003d cfg.IntOpt("},{"line_number":27,"context_line":"    \u0027lockout_failure_attempts\u0027,"},{"line_number":28,"context_line":"    default\u003dNone,"},{"line_number":29,"context_line":"    min\u003d1,"},{"line_number":30,"context_line":"    help\u003dutils.fmt(\"\"\""},{"line_number":31,"context_line":"Number of times a user can fail login attempts until the user account is"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_06285232","line":28,"range":{"start_line":28,"start_character":12,"end_line":28,"end_character":16},"updated":"2016-06-29 22:55:00.000000000","message":"++","commit_id":"74c64b1de20585ce48ab502c217583dd7722fec3"}],"keystone/tests/unit/test_v3_auth.py":[{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"b69d393006144d643f70da5ad5a3689308a7e1c4","unresolved":false,"context_lines":[{"line_number":5062,"context_line":"            user_id\u003dself.user[\u0027id\u0027],"},{"line_number":5063,"context_line":"            password\u003dself.user[\u0027password\u0027])"},{"line_number":5064,"context_line":"        self.v3_create_token(auth_data)"},{"line_number":5065,"context_line":""},{"line_number":5066,"context_line":"        # 6 failed attempts"},{"line_number":5067,"context_line":"        for _ in range(CONF.security_compliance.lockout_failure_attempts):"},{"line_number":5068,"context_line":"            # Log in with right credentials: must fail"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_a6733e4d","line":5065,"updated":"2016-06-29 22:55:00.000000000","message":"How about confirming reset_auth_attempts here?","commit_id":"74c64b1de20585ce48ab502c217583dd7722fec3"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"cd1346eba2deb62e60124e8775b927515bef2d88","unresolved":false,"context_lines":[{"line_number":5062,"context_line":"            user_id\u003dself.user[\u0027id\u0027],"},{"line_number":5063,"context_line":"            password\u003dself.user[\u0027password\u0027])"},{"line_number":5064,"context_line":"        self.v3_create_token(auth_data)"},{"line_number":5065,"context_line":""},{"line_number":5066,"context_line":"        # 6 failed attempts"},{"line_number":5067,"context_line":"        for _ in range(CONF.security_compliance.lockout_failure_attempts):"},{"line_number":5068,"context_line":"            # Log in with right credentials: must fail"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_49e6c944","line":5065,"in_reply_to":"3aaa91ec_a6733e4d","updated":"2016-06-30 14:50:14.000000000","message":"Done","commit_id":"74c64b1de20585ce48ab502c217583dd7722fec3"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"796826904cf146e9037ff742cdd554adef31bfe7","unresolved":false,"context_lines":[{"line_number":5062,"context_line":"            user_id\u003dself.user[\u0027id\u0027],"},{"line_number":5063,"context_line":"            password\u003dself.user[\u0027password\u0027])"},{"line_number":5064,"context_line":"        self.v3_create_token(auth_data)"},{"line_number":5065,"context_line":""},{"line_number":5066,"context_line":"        # 6 failed attempts"},{"line_number":5067,"context_line":"        for _ in range(CONF.security_compliance.lockout_failure_attempts):"},{"line_number":5068,"context_line":"            # Log in with right credentials: must fail"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_08579f58","line":5065,"in_reply_to":"3aaa91ec_a6733e4d","updated":"2016-06-30 14:06:59.000000000","message":"Or, add a new test case for this.","commit_id":"74c64b1de20585ce48ab502c217583dd7722fec3"}],"setup.cfg":[{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"b09937e5e4f730be7e030bb550e9cf1e381ef7e8","unresolved":false,"context_lines":[{"line_number":80,"context_line":"keystone.assignment \u003d"},{"line_number":81,"context_line":"    sql \u003d keystone.assignment.backends.sql:Assignment"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"keystone.auth \u003d"},{"line_number":84,"context_line":"    sql \u003d keystone.auth.backends.sql:Auth"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"keystone.auth.external \u003d"}],"source_content_type":"text/x-ttcn-cfg","patch_set":2,"id":"9abb7d3a_23306b07","line":83,"range":{"start_line":83,"start_character":8,"end_line":83,"end_character":9},"updated":"2016-06-02 15:09:53.000000000","message":"Again, I just don\u0027t think we need to custom backend driver for this.","commit_id":"5cd1484317a6a48f8b636ca131eb61c4ec81e12b"}]}
