)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"877f29723fd360a02c993c560d3182ddd47ecf08","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Adds table and model for storing rotated passwords"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"They will be used by future commits to implement"},{"line_number":10,"context_line":"bp password-rotation."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: Idc4e6174c12fd584c914fcd3670658fadbf9510d"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":11,"id":"AAAAXX%2F%2FzTI%3D","line":10,"updated":"2014-04-26 20:18:46.000000000","message":"That commit should be dependant on this one.  If the code is not yet written, we should not be adding in the Databse tables alone, as it might lead to the  \"Lava Flow\" effect;  half implemented.","commit_id":"d9f1ad7d698d407275c4c5dd5cd900c891736dc1"}],"keystone/common/sql/migrate_repo/versions/050_add_rotated_passwords_table.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"0dc583edec9ff60e345d452e7b96cae321097dfe","unresolved":false,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":"def upgrade(migrate_engine):"},{"line_number":17,"context_line":"    identity_sql.RotatedPassword.__table__.create("},{"line_number":18,"context_line":"        migrate_engine, checkfirst\u003dTrue)"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"def downgrade(migrate_engine):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAW3%2F%2Fl4k%3D","line":18,"updated":"2014-04-11 22:34:23.000000000","message":"As much as I like to use reflection because it\u0027s simple (this code is super clean!), this is a bad idea as the model definition might change and someone will forget to change this migration. Please don\u0027t use reflection to create tables in migration files it will cause nothing but pain and suffering later.","commit_id":"9c57d4df74571cb9f2d1dfb6c0074663b2ec8ee0"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"0cbdf4e9471c11d3f51b59b69cdd8ff967fa0a79","unresolved":false,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":"def upgrade(migrate_engine):"},{"line_number":17,"context_line":"    identity_sql.RotatedPassword.__table__.create("},{"line_number":18,"context_line":"        migrate_engine, checkfirst\u003dTrue)"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"def downgrade(migrate_engine):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAW3%2F%2FdW0%3D","line":18,"in_reply_to":"AAAAW3%2F%2Fl4k%3D","updated":"2014-04-14 13:25:10.000000000","message":"Done","commit_id":"9c57d4df74571cb9f2d1dfb6c0074663b2ec8ee0"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"99cee9c3fcec1968215a9a2681f5b7364b524e8f","unresolved":false,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":"def upgrade(migrate_engine):"},{"line_number":17,"context_line":"    identity_sql.RotatedPassword.__table__.create("},{"line_number":18,"context_line":"        migrate_engine, checkfirst\u003dTrue)"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"def downgrade(migrate_engine):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAW3%2F%2Fhd4%3D","line":18,"in_reply_to":"AAAAW3%2F%2Fl4k%3D","updated":"2014-04-14 00:29:55.000000000","message":"It\u0027s very unfortunate that we have to build both. There are a couple of current patches that fixes some issues with them being different and I was hoping to avoid that problem. I can restore my original work that used explicit migrations.","commit_id":"9c57d4df74571cb9f2d1dfb6c0074663b2ec8ee0"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"63ae9d175361c4c06a9a149d3cefb551d2c58879","unresolved":false,"context_lines":[{"line_number":22,"context_line":"    sql.Table(\u0027user\u0027, meta, autoload\u003dTrue)"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    rotated_password \u003d sql.Table("},{"line_number":25,"context_line":"        \u0027rotated_password\u0027,"},{"line_number":26,"context_line":"        meta,"},{"line_number":27,"context_line":"        sql.Column(\u0027id\u0027, sql.String(64), primary_key\u003dTrue),"},{"line_number":28,"context_line":"        sql.Column(\u0027user_id\u0027,"}],"source_content_type":"text/x-python","patch_set":11,"id":"bad4c104_474b4eb0","line":25,"updated":"2014-09-08 19:50:08.000000000","message":"maybe rename it to just \u0027user_password\u0027 since this table has more use cases beyond rotation","commit_id":"d9f1ad7d698d407275c4c5dd5cd900c891736dc1"}],"keystone/identity/backends/sql.py":[{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"09b5d507edc7640addb52709af7de5409b9f3078","unresolved":false,"context_lines":[{"line_number":123,"context_line":"            raise AssertionError(_(\u0027Invalid user / password\u0027))"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"        if not self._check_password(password, user_ref):"},{"line_number":126,"context_line":"            # TODO(dstanek): should we make sure that the password rotation"},{"line_number":127,"context_line":"            # extension is enabled?"},{"line_number":128,"context_line":"            rps \u003d self.list_active_rotated_passwords_by_user(user_id, None)"},{"line_number":129,"context_line":"            for rp_ref in rps:"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAW3%2F%2Fme4%3D","line":126,"updated":"2014-04-11 21:08:08.000000000","message":"for consistency with previous versions, wouldnt it it be best that the default be not be enabled.  Thus no surprises?","commit_id":"9c57d4df74571cb9f2d1dfb6c0074663b2ec8ee0"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"99cee9c3fcec1968215a9a2681f5b7364b524e8f","unresolved":false,"context_lines":[{"line_number":123,"context_line":"            raise AssertionError(_(\u0027Invalid user / password\u0027))"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"        if not self._check_password(password, user_ref):"},{"line_number":126,"context_line":"            # TODO(dstanek): should we make sure that the password rotation"},{"line_number":127,"context_line":"            # extension is enabled?"},{"line_number":128,"context_line":"            rps \u003d self.list_active_rotated_passwords_by_user(user_id, None)"},{"line_number":129,"context_line":"            for rp_ref in rps:"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAW3%2F%2FhdY%3D","line":126,"in_reply_to":"AAAAW3%2F%2Fme4%3D","updated":"2014-04-14 00:29:55.000000000","message":"That\u0027s not what this comment is saying. I\u0027m saying that before I do the extra work of looking through the rotated passwords that maybe we need to see if the extension was enabled. If it\u0027s not enabled then maybe we shouldn\u0027t even check. I\u0027ll make it more obvious in the next patch.","commit_id":"9c57d4df74571cb9f2d1dfb6c0074663b2ec8ee0"},{"author":{"_account_id":8276,"name":"kiwik","email":"chenrui.momo@gmail.com","username":"kiwik"},"change_message_id":"e104d14c82492ee1f5c9f139982c12cc5079f962","unresolved":false,"context_lines":[{"line_number":124,"context_line":""},{"line_number":125,"context_line":"        if not self._check_password(password, user_ref):"},{"line_number":126,"context_line":"            # TODO(dstanek): should we make sure that the password rotation"},{"line_number":127,"context_line":"            # extension is enabled?"},{"line_number":128,"context_line":"            rps \u003d self.list_active_rotated_passwords_by_user(user_id, None)"},{"line_number":129,"context_line":"            for rp_ref in rps:"},{"line_number":130,"context_line":"                if utils.check_password(password, rp_ref[\u0027password\u0027]):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAW3%2F%2FmLM%3D","line":127,"updated":"2014-04-11 21:49:50.000000000","message":"I also think new feature should be disabled by default. Maybe need a option.","commit_id":"9c57d4df74571cb9f2d1dfb6c0074663b2ec8ee0"},{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"09b5d507edc7640addb52709af7de5409b9f3078","unresolved":false,"context_lines":[{"line_number":129,"context_line":"            for rp_ref in rps:"},{"line_number":130,"context_line":"                if utils.check_password(password, rp_ref[\u0027password\u0027]):"},{"line_number":131,"context_line":"                    break"},{"line_number":132,"context_line":"            else:"},{"line_number":133,"context_line":"                raise AssertionError(_(\u0027Invalid user / password\u0027))"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"        return identity.filter_user(user_ref.to_dict())"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAW3%2F%2Fmdo%3D","line":132,"updated":"2014-04-11 21:08:08.000000000","message":"No matter how many times I see it, I find the for ... else: construct in python CREEPY :-).","commit_id":"9c57d4df74571cb9f2d1dfb6c0074663b2ec8ee0"},{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"09b5d507edc7640addb52709af7de5409b9f3078","unresolved":false,"context_lines":[{"line_number":363,"context_line":"        with session.begin():"},{"line_number":364,"context_line":"            q \u003d session.query(RotatedPassword)"},{"line_number":365,"context_line":"            q \u003d q.filter_by(user_id\u003duser_id)"},{"line_number":366,"context_line":"            q \u003d q.filter(RotatedPassword.expires_at \u003c\u003d now)"},{"line_number":367,"context_line":"            q.delete(False)"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAW3%2F%2FmZM%3D","line":366,"updated":"2014-04-11 21:08:08.000000000","message":"Nice. cool to see the expires checking done completely in the filter","commit_id":"9c57d4df74571cb9f2d1dfb6c0074663b2ec8ee0"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"0dc583edec9ff60e345d452e7b96cae321097dfe","unresolved":false,"context_lines":[{"line_number":363,"context_line":"        with session.begin():"},{"line_number":364,"context_line":"            q \u003d session.query(RotatedPassword)"},{"line_number":365,"context_line":"            q \u003d q.filter_by(user_id\u003duser_id)"},{"line_number":366,"context_line":"            q \u003d q.filter(RotatedPassword.expires_at \u003c\u003d now)"},{"line_number":367,"context_line":"            q.delete(False)"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAW3%2F%2Fl4M%3D","line":366,"in_reply_to":"AAAAW3%2F%2FmZM%3D","updated":"2014-04-11 22:34:23.000000000","message":"++","commit_id":"9c57d4df74571cb9f2d1dfb6c0074663b2ec8ee0"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"63ae9d175361c4c06a9a149d3cefb551d2c58879","unresolved":false,"context_lines":[{"line_number":121,"context_line":"            user_ref \u003d self._get_user(session, user_id)"},{"line_number":122,"context_line":"        except exception.UserNotFound:"},{"line_number":123,"context_line":"            raise AssertionError(_(\u0027Invalid user / password\u0027))"},{"line_number":124,"context_line":"        if not self._check_password(password, user_ref):"},{"line_number":125,"context_line":"            raise AssertionError(_(\u0027Invalid user / password\u0027))"},{"line_number":126,"context_line":"        return identity.filter_user(user_ref.to_dict())"},{"line_number":127,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"bad4c104_7931d6eb","line":124,"updated":"2014-09-08 19:50:08.000000000","message":"this should iterate over all valid passwords until a match is found or the list is exhausted","commit_id":"d9f1ad7d698d407275c4c5dd5cd900c891736dc1"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"63ae9d175361c4c06a9a149d3cefb551d2c58879","unresolved":false,"context_lines":[{"line_number":325,"context_line":"            session.add(ref)"},{"line_number":326,"context_line":"        return ref.to_dict()"},{"line_number":327,"context_line":""},{"line_number":328,"context_line":"    def list_rotated_passwords_by_user(self, user_id, hints):"},{"line_number":329,"context_line":"        session \u003d sql.get_session()"},{"line_number":330,"context_line":"        query \u003d session.query(RotatedPassword)"},{"line_number":331,"context_line":"        query \u003d query.filter_by(user_id\u003duser_id)"}],"source_content_type":"text/x-python","patch_set":11,"id":"bad4c104_e72462c8","line":328,"updated":"2014-09-08 19:50:08.000000000","message":"use case?","commit_id":"d9f1ad7d698d407275c4c5dd5cd900c891736dc1"}],"keystone/tests/integration/identity/test_crud.py":[{"author":{"_account_id":220,"name":"Haneef Ali","email":"haneef.ali@hp.com","username":"haneef"},"change_message_id":"8324810729083be5ec42d3b50e97c30f9087bb44","unresolved":false,"context_lines":[{"line_number":18,"context_line":""},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"def future_date():"},{"line_number":21,"context_line":"    \"\"\"Returns a datetime representing a date 24hrs in the future.\"\"\""},{"line_number":22,"context_line":"    return datetime.datetime.utcnow() + datetime.timedelta(hours\u003d24)"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAUX%2F%2Bx4M%3D","line":21,"updated":"2014-02-19 05:14:14.000000000","message":"You have chosen a  nice method name to explain what it does. Do we need a doc to explain that? Seems redundant.","commit_id":"310deff452cd79f1af41b0406ac9c2f9441a3ccd"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"ed026b67d95362cdba8d21ad2d641c5d455fc5d5","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        self.assertEqual(len(rotated_passwords), 1)"},{"line_number":67,"context_line":"        self.assertIn(self.future_rp, rotated_passwords)"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"    def test_deleting_expired_rotated_passwords(self):"},{"line_number":70,"context_line":"        # create another user\u0027s data to make sure we don\u0027t delete it too"},{"line_number":71,"context_line":"        other_user_id \u003d utils.new_uuid()"},{"line_number":72,"context_line":"        other_user_rp \u003d self._create_data(other_user_id, past_date())"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAUX%2F%2B0JU%3D","line":69,"updated":"2014-02-18 21:03:09.000000000","message":"Nice test case.","commit_id":"310deff452cd79f1af41b0406ac9c2f9441a3ccd"}]}
