)]}'
{"keystone/cmd/cli.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"261b3e57b25b8b7ccebdea9ac5a46a439483f9ff","unresolved":false,"context_lines":[{"line_number":445,"context_line":"            futils.rotate_keys(keystone_user_id, keystone_group_id)"},{"line_number":446,"context_line":""},{"line_number":447,"context_line":""},{"line_number":448,"context_line":"class JWTSetup(BasePermissionsSetup):"},{"line_number":449,"context_line":"    \"\"\"Setup a key repository for JSON Web Tokens."},{"line_number":450,"context_line":""},{"line_number":451,"context_line":"    This command creates a public and private key pair to use for issuing and"}],"source_content_type":"text/x-python","patch_set":4,"id":"3f79a3b5_cedd32df","line":448,"updated":"2018-11-02 19:50:30.000000000","message":"This could be its own change.","commit_id":"ebfa114456f86dd0712b29dcfa7f7e3efae7556f"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"3b4587f7a40f5b0b8f6249b389f5fcc6a730140e","unresolved":false,"context_lines":[{"line_number":445,"context_line":"            futils.rotate_keys(keystone_user_id, keystone_group_id)"},{"line_number":446,"context_line":""},{"line_number":447,"context_line":""},{"line_number":448,"context_line":"class JWTSetup(BasePermissionsSetup):"},{"line_number":449,"context_line":"    \"\"\"Setup a key repository for JSON Web Tokens."},{"line_number":450,"context_line":""},{"line_number":451,"context_line":"    This command creates a public and private key pair to use for issuing and"}],"source_content_type":"text/x-python","patch_set":4,"id":"3f79a3b5_e9da6874","line":448,"in_reply_to":"3f79a3b5_cedd32df","updated":"2018-11-02 20:13:26.000000000","message":"Done","commit_id":"ebfa114456f86dd0712b29dcfa7f7e3efae7556f"}],"keystone/common/file_utils.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"261b3e57b25b8b7ccebdea9ac5a46a439483f9ff","unresolved":false,"context_lines":[{"line_number":17,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"def create_directory(directory, keystone_user_id\u003dNone, keystone_group_id\u003dNone):"},{"line_number":21,"context_line":"    \"\"\"Attempt to create a directory if it doesn\u0027t exist."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    :param directory: string containing the path of the directory to create."}],"source_content_type":"text/x-python","patch_set":4,"id":"3f79a3b5_6ee65eb2","line":20,"updated":"2018-11-02 19:50:30.000000000","message":"This should be its own change.","commit_id":"ebfa114456f86dd0712b29dcfa7f7e3efae7556f"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"54338f04b7879f2a5dae6f45008ae0ba9b0f4f64","unresolved":false,"context_lines":[{"line_number":17,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"def create_directory(directory, keystone_user_id\u003dNone, keystone_group_id\u003dNone):"},{"line_number":21,"context_line":"    \"\"\"Attempt to create a directory if it doesn\u0027t exist."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    :param directory: string containing the path of the directory to create."}],"source_content_type":"text/x-python","patch_set":4,"id":"3f79a3b5_2e6b86ee","line":20,"in_reply_to":"3f79a3b5_6ee65eb2","updated":"2018-11-02 19:53:51.000000000","message":"Done","commit_id":"ebfa114456f86dd0712b29dcfa7f7e3efae7556f"}],"keystone/conf/__init__.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"f8c3a429184e30e22632a7930dffaabf7e8e3148","unresolved":false,"context_lines":[{"line_number":35,"context_line":"from keystone.conf import fernet_tokens"},{"line_number":36,"context_line":"from keystone.conf import identity"},{"line_number":37,"context_line":"from keystone.conf import identity_mapping"},{"line_number":38,"context_line":"from keystone.conf import jwt_tokens"},{"line_number":39,"context_line":"from keystone.conf import ldap"},{"line_number":40,"context_line":"from keystone.conf import memcache"},{"line_number":41,"context_line":"from keystone.conf import oauth1"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_de3512f9","line":38,"range":{"start_line":38,"start_character":26,"end_line":38,"end_character":36},"updated":"2019-01-21 17:27:43.000000000","message":"This was pulled into its own change.\n\nhttps://review.openstack.org/#/c/628676/","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"9ca5f97292dfea86b6ac6ab880bbc9f0b5b7f026","unresolved":false,"context_lines":[{"line_number":35,"context_line":"from keystone.conf import fernet_tokens"},{"line_number":36,"context_line":"from keystone.conf import identity"},{"line_number":37,"context_line":"from keystone.conf import identity_mapping"},{"line_number":38,"context_line":"from keystone.conf import jwt_tokens"},{"line_number":39,"context_line":"from keystone.conf import ldap"},{"line_number":40,"context_line":"from keystone.conf import memcache"},{"line_number":41,"context_line":"from keystone.conf import oauth1"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_fe2d76a8","line":38,"range":{"start_line":38,"start_character":26,"end_line":38,"end_character":36},"in_reply_to":"9fdfeff1_de3512f9","updated":"2019-01-21 17:52:48.000000000","message":"Done","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"}],"keystone/conf/jwt_tokens.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"723a11e9f47dcc841ce317757d973c36777a86dc","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":7,"id":"9fdfeff1_3e03fe44","line":1,"updated":"2019-01-21 17:26:53.000000000","message":"This file should be removed since it was refactored out into its own change.\n\nhttps://review.openstack.org/#/c/628676/","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"9ca5f97292dfea86b6ac6ab880bbc9f0b5b7f026","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":7,"id":"9fdfeff1_1e2b9a94","line":1,"in_reply_to":"9fdfeff1_3e03fe44","updated":"2019-01-21 17:52:48.000000000","message":"Done","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"}],"keystone/conf/token.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"261b3e57b25b8b7ccebdea9ac5a46a439483f9ff","unresolved":false,"context_lines":[{"line_number":53,"context_line":"    help\u003dutils.fmt(\"\"\""},{"line_number":54,"context_line":"Entry point for the token provider in the `keystone.token.provider` namespace."},{"line_number":55,"context_line":"The token provider controls the token construction, validation, and revocation"},{"line_number":56,"context_line":"operations. Keystone includes `fernet` token provider."},{"line_number":57,"context_line":"`fernet` tokens do not need to be persisted at all, but require that you run"},{"line_number":58,"context_line":"`keystone-manage fernet_setup` (also see the `keystone-manage fernet_rotate`"},{"line_number":59,"context_line":"command)."}],"source_content_type":"text/x-python","patch_set":4,"id":"3f79a3b5_4e984219","line":56,"range":{"start_line":56,"start_character":11,"end_line":56,"end_character":54},"updated":"2018-11-02 19:50:30.000000000","message":"This should be amended and should include a statement about the difference in the two implementations.","commit_id":"ebfa114456f86dd0712b29dcfa7f7e3efae7556f"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"723a11e9f47dcc841ce317757d973c36777a86dc","unresolved":false,"context_lines":[{"line_number":52,"context_line":"    help\u003dutils.fmt(\"\"\""},{"line_number":53,"context_line":"Entry point for the token provider in the `keystone.token.provider` namespace."},{"line_number":54,"context_line":"The token provider controls the token construction, validation, and revocation"},{"line_number":55,"context_line":"operations. Supported upstream providers are `fernet` and `jwt`. Neither"},{"line_number":56,"context_line":"`fernet` or `jwt` tokens require persistence and both require additional setup."},{"line_number":57,"context_line":"If using `fernet`, you\u0027re required to run `keystone-manage fernet_setup`, which"},{"line_number":58,"context_line":"creates symmetric keys used to encrypt tokens. If using `jwt`, you\u0027re required"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_5e004235","line":55,"range":{"start_line":55,"start_character":59,"end_line":55,"end_character":62},"updated":"2019-01-21 17:26:53.000000000","message":"Update this to use `jws` instead of `jwt`.","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"9ca5f97292dfea86b6ac6ab880bbc9f0b5b7f026","unresolved":false,"context_lines":[{"line_number":52,"context_line":"    help\u003dutils.fmt(\"\"\""},{"line_number":53,"context_line":"Entry point for the token provider in the `keystone.token.provider` namespace."},{"line_number":54,"context_line":"The token provider controls the token construction, validation, and revocation"},{"line_number":55,"context_line":"operations. Supported upstream providers are `fernet` and `jwt`. Neither"},{"line_number":56,"context_line":"`fernet` or `jwt` tokens require persistence and both require additional setup."},{"line_number":57,"context_line":"If using `fernet`, you\u0027re required to run `keystone-manage fernet_setup`, which"},{"line_number":58,"context_line":"creates symmetric keys used to encrypt tokens. If using `jwt`, you\u0027re required"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_5e0a8226","line":55,"range":{"start_line":55,"start_character":59,"end_line":55,"end_character":62},"in_reply_to":"9fdfeff1_5e004235","updated":"2019-01-21 17:52:48.000000000","message":"Done","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"}],"keystone/tests/unit/ksfixtures/jwt_key_repository.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"261b3e57b25b8b7ccebdea9ac5a46a439483f9ff","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        file_utils.create_directory(directory)"},{"line_number":34,"context_line":"        private_key_path \u003d os.path.join(directory, \u0027private.pem\u0027)"},{"line_number":35,"context_line":"        public_key_path \u003d os.path.join(directory, \u0027public.pem\u0027)"},{"line_number":36,"context_line":"        jwt_utils.create_key_pair(private_key_path, public_key_path)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3f79a3b5_2e7dc6c2","line":36,"updated":"2018-11-02 19:50:30.000000000","message":"Add this to the previous patch for the fixture.","commit_id":"ebfa114456f86dd0712b29dcfa7f7e3efae7556f"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"c6fe3a808ca29c54bc5a755e78f5ae05005629f8","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        file_utils.create_directory(directory)"},{"line_number":34,"context_line":"        private_key_path \u003d os.path.join(directory, \u0027private.pem\u0027)"},{"line_number":35,"context_line":"        public_key_path \u003d os.path.join(directory, \u0027public.pem\u0027)"},{"line_number":36,"context_line":"        jwt_utils.create_key_pair(private_key_path, public_key_path)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3f79a3b5_e96b4851","line":36,"in_reply_to":"3f79a3b5_2e7dc6c2","updated":"2018-11-02 20:34:33.000000000","message":"Done","commit_id":"ebfa114456f86dd0712b29dcfa7f7e3efae7556f"}],"keystone/tests/unit/test_v3_auth.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"723a11e9f47dcc841ce317757d973c36777a86dc","unresolved":false,"context_lines":[{"line_number":2809,"context_line":"        super(TestJSONWebTokenAPIs, self).config_overrides()"},{"line_number":2810,"context_line":"        self.config_fixture.config(group\u003d\u0027token\u0027, provider\u003d\u0027jwt\u0027,"},{"line_number":2811,"context_line":"                                   cache_on_issue\u003dTrue)"},{"line_number":2812,"context_line":"        self.useFixture(ksfixtures.JWTKeyRepository(self.config_fixture))"},{"line_number":2813,"context_line":""},{"line_number":2814,"context_line":"    def setUp(self):"},{"line_number":2815,"context_line":"        super(TestJSONWebTokenAPIs, self).setUp()"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_1efaba41","line":2812,"range":{"start_line":2812,"start_character":37,"end_line":2812,"end_character":38},"updated":"2019-01-21 17:26:53.000000000","message":"Use the JWSKeyRepository instead.","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"9ca5f97292dfea86b6ac6ab880bbc9f0b5b7f026","unresolved":false,"context_lines":[{"line_number":2809,"context_line":"        super(TestJSONWebTokenAPIs, self).config_overrides()"},{"line_number":2810,"context_line":"        self.config_fixture.config(group\u003d\u0027token\u0027, provider\u003d\u0027jwt\u0027,"},{"line_number":2811,"context_line":"                                   cache_on_issue\u003dTrue)"},{"line_number":2812,"context_line":"        self.useFixture(ksfixtures.JWTKeyRepository(self.config_fixture))"},{"line_number":2813,"context_line":""},{"line_number":2814,"context_line":"    def setUp(self):"},{"line_number":2815,"context_line":"        super(TestJSONWebTokenAPIs, self).setUp()"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_19197478","line":2812,"range":{"start_line":2812,"start_character":37,"end_line":2812,"end_character":38},"in_reply_to":"9fdfeff1_1efaba41","updated":"2019-01-21 17:52:48.000000000","message":"Done","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"}],"keystone/tests/unit/token/test_jwt_provider.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"723a11e9f47dcc841ce317757d973c36777a86dc","unresolved":false,"context_lines":[{"line_number":23,"context_line":"PROVIDERS \u003d provider_api.ProviderAPIs"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"class TestJWTProvider(unit.TestCase):"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    def setUp(self):"},{"line_number":29,"context_line":"        super(TestJWTProvider, self).setUp()"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_9ea30a50","line":26,"range":{"start_line":26,"start_character":12,"end_line":26,"end_character":13},"updated":"2019-01-21 17:26:53.000000000","message":"Use JWS instead, since it\u0027s more specific than JWT.","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"9ca5f97292dfea86b6ac6ab880bbc9f0b5b7f026","unresolved":false,"context_lines":[{"line_number":23,"context_line":"PROVIDERS \u003d provider_api.ProviderAPIs"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"class TestJWTProvider(unit.TestCase):"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    def setUp(self):"},{"line_number":29,"context_line":"        super(TestJWTProvider, self).setUp()"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_f934b0e0","line":26,"range":{"start_line":26,"start_character":12,"end_line":26,"end_character":13},"in_reply_to":"9fdfeff1_9ea30a50","updated":"2019-01-21 17:52:48.000000000","message":"Done","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"723a11e9f47dcc841ce317757d973c36777a86dc","unresolved":false,"context_lines":[{"line_number":28,"context_line":"    def setUp(self):"},{"line_number":29,"context_line":"        super(TestJWTProvider, self).setUp()"},{"line_number":30,"context_line":"        self.config_fixture.config(group\u003d\u0027token\u0027, provider\u003d\u0027jwt\u0027)"},{"line_number":31,"context_line":"        self.useFixture(ksfixtures.JWTKeyRepository(self.config_fixture))"},{"line_number":32,"context_line":"        self.provider \u003d jwt.Provider()"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    def test_invalid_token_raises_token_not_found(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_1e8f1acd","line":31,"range":{"start_line":31,"start_character":37,"end_line":31,"end_character":38},"updated":"2019-01-21 17:26:53.000000000","message":"Update this, too.","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"9ca5f97292dfea86b6ac6ab880bbc9f0b5b7f026","unresolved":false,"context_lines":[{"line_number":28,"context_line":"    def setUp(self):"},{"line_number":29,"context_line":"        super(TestJWTProvider, self).setUp()"},{"line_number":30,"context_line":"        self.config_fixture.config(group\u003d\u0027token\u0027, provider\u003d\u0027jwt\u0027)"},{"line_number":31,"context_line":"        self.useFixture(ksfixtures.JWTKeyRepository(self.config_fixture))"},{"line_number":32,"context_line":"        self.provider \u003d jwt.Provider()"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    def test_invalid_token_raises_token_not_found(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_1932d4f2","line":31,"range":{"start_line":31,"start_character":37,"end_line":31,"end_character":38},"in_reply_to":"9fdfeff1_1e8f1acd","updated":"2019-01-21 17:52:48.000000000","message":"Done","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"}],"keystone/token/providers/jws/__init__.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"081f6d1b0e360f02ebbf82fd2d1fd7b23aa3d06b","unresolved":false,"context_lines":[{"line_number":10,"context_line":"# License for the specific language governing permissions and limitations"},{"line_number":11,"context_line":"# under the License."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"from keystone.token.providers.jws.core import *  # noqa"}],"source_content_type":"text/x-python","patch_set":16,"id":"9fdfeff1_a73b9ee7","line":13,"range":{"start_line":13,"start_character":0,"end_line":13,"end_character":55},"updated":"2019-02-15 20:36:01.000000000","message":"Please don\u0027t do this. It\u0027s pointless, it was a bad practice when we did it before and there is no reason to do this now.","commit_id":"96adccd0ec0398251268f9ae89732005e340035c"}],"keystone/token/providers/jws/core.py":[{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"150e968966f27c00f387ca0d4eb9fea5f77c105c","unresolved":false,"context_lines":[{"line_number":36,"context_line":"        # keystone and just 500 because we can\u0027t do anything with an empty or"},{"line_number":37,"context_line":"        # non-existant key repository."},{"line_number":38,"context_line":"        private_key \u003d os.path.join("},{"line_number":39,"context_line":"            CONF.jws_tokens.private_key_repository, \u0027private.pem\u0027"},{"line_number":40,"context_line":"        )"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"        if not os.path.exists(private_key) and CONF.token.provider \u003d\u003d \u0027jws\u0027:"}],"source_content_type":"text/x-python","patch_set":11,"id":"9fdfeff1_1b6b08b7","line":39,"updated":"2019-01-30 16:24:10.000000000","message":"Might need to change this \u0027jws_tokens\u0027 to \u0027jwt_tokens\u0027 after the change in previous patch.","commit_id":"5c001d9d22b45506cba7d75ae5afd191f29332a2"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"bd39c51e757003bb8fa09d41b0550373cc8aa951","unresolved":false,"context_lines":[{"line_number":36,"context_line":"        # keystone and just 500 because we can\u0027t do anything with an empty or"},{"line_number":37,"context_line":"        # non-existant key repository."},{"line_number":38,"context_line":"        private_key \u003d os.path.join("},{"line_number":39,"context_line":"            CONF.jws_tokens.private_key_repository, \u0027private.pem\u0027"},{"line_number":40,"context_line":"        )"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"        if not os.path.exists(private_key) and CONF.token.provider \u003d\u003d \u0027jws\u0027:"}],"source_content_type":"text/x-python","patch_set":11,"id":"9fdfeff1_579de463","line":39,"in_reply_to":"9fdfeff1_1b6b08b7","updated":"2019-01-30 17:23:39.000000000","message":"Done","commit_id":"5c001d9d22b45506cba7d75ae5afd191f29332a2"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"150e968966f27c00f387ca0d4eb9fea5f77c105c","unresolved":false,"context_lines":[{"line_number":44,"context_line":"            raise SystemExit(_(\u0027%(private_key)s does not exist\u0027) % subs)"},{"line_number":45,"context_line":"        if os.listdir(CONF.jws_tokens.public_key_repository) \u003d\u003d 0:"},{"line_number":46,"context_line":"            subs \u003d {"},{"line_number":47,"context_line":"                \u0027public_key_repository\u0027: CONF.jws_tokens.public_key_repository"},{"line_number":48,"context_line":"            }"},{"line_number":49,"context_line":"            msg \u003d _("},{"line_number":50,"context_line":"                \u0027%(public_key_repository)s must contain at least one public \u0027"}],"source_content_type":"text/x-python","patch_set":11,"id":"9fdfeff1_5ba2f0fd","line":47,"updated":"2019-01-30 16:24:10.000000000","message":"ditto","commit_id":"5c001d9d22b45506cba7d75ae5afd191f29332a2"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"bd39c51e757003bb8fa09d41b0550373cc8aa951","unresolved":false,"context_lines":[{"line_number":44,"context_line":"            raise SystemExit(_(\u0027%(private_key)s does not exist\u0027) % subs)"},{"line_number":45,"context_line":"        if os.listdir(CONF.jws_tokens.public_key_repository) \u003d\u003d 0:"},{"line_number":46,"context_line":"            subs \u003d {"},{"line_number":47,"context_line":"                \u0027public_key_repository\u0027: CONF.jws_tokens.public_key_repository"},{"line_number":48,"context_line":"            }"},{"line_number":49,"context_line":"            msg \u003d _("},{"line_number":50,"context_line":"                \u0027%(public_key_repository)s must contain at least one public \u0027"}],"source_content_type":"text/x-python","patch_set":11,"id":"9fdfeff1_178d1c31","line":47,"in_reply_to":"9fdfeff1_5ba2f0fd","updated":"2019-01-30 17:23:39.000000000","message":"Done","commit_id":"5c001d9d22b45506cba7d75ae5afd191f29332a2"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"f0eb960cd9be6282a1441f56707f68190855ef1a","unresolved":false,"context_lines":[{"line_number":39,"context_line":"            CONF.jwt_tokens.jws_private_key_repository, \u0027private.pem\u0027"},{"line_number":40,"context_line":"        )"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"        if not os.path.exists(private_key) and CONF.token.provider \u003d\u003d \u0027jws\u0027:"},{"line_number":43,"context_line":"            subs \u003d {\u0027private_key\u0027: private_key}"},{"line_number":44,"context_line":"            raise SystemExit(_(\u0027%(private_key)s does not exist\u0027) % subs)"},{"line_number":45,"context_line":"        if os.listdir(CONF.jwt_tokens.jws_public_key_repository) \u003d\u003d 0:"},{"line_number":46,"context_line":"            subs \u003d {"},{"line_number":47,"context_line":"                \u0027public_key_repo\u0027: CONF.jwt_tokens.jws_public_key_repository"}],"source_content_type":"text/x-python","patch_set":12,"id":"9fdfeff1_63cdc52f","line":44,"range":{"start_line":42,"start_character":7,"end_line":44,"end_character":72},"updated":"2019-01-31 05:30:24.000000000","message":"A little confused here, as according to [1] , we have a default path set for private as well as public key in keystone.conf [jwt_tokens]. So According to this code we will look the keys in their default paths. Whereas if the user tries to setup with  keystone-manage create_jws_keypair [2], it will generate the keys in the current directory which can be anything. Wouldn\u0027t it will end up in SystemExit ?\n\n\n\n[1] https://review.openstack.org/#/c/628676/5/keystone/conf/jwt_tokens.py\n[2]https://review.openstack.org/#/c/615315/9/keystone/cmd/cli.py","commit_id":"92c3672b145370c5d5b57c3dfc4de43054c966cf"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"0a39d337855da4dd87af55e8d61dda157cbee0df","unresolved":false,"context_lines":[{"line_number":39,"context_line":"            CONF.jwt_tokens.jws_private_key_repository, \u0027private.pem\u0027"},{"line_number":40,"context_line":"        )"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"        if not os.path.exists(private_key) and CONF.token.provider \u003d\u003d \u0027jws\u0027:"},{"line_number":43,"context_line":"            subs \u003d {\u0027private_key\u0027: private_key}"},{"line_number":44,"context_line":"            raise SystemExit(_(\u0027%(private_key)s does not exist\u0027) % subs)"},{"line_number":45,"context_line":"        if os.listdir(CONF.jwt_tokens.jws_public_key_repository) \u003d\u003d 0:"},{"line_number":46,"context_line":"            subs \u003d {"},{"line_number":47,"context_line":"                \u0027public_key_repo\u0027: CONF.jwt_tokens.jws_public_key_repository"}],"source_content_type":"text/x-python","patch_set":12,"id":"9fdfeff1_a3288d96","line":44,"range":{"start_line":42,"start_character":7,"end_line":44,"end_character":72},"in_reply_to":"9fdfeff1_63cdc52f","updated":"2019-01-31 05:55:15.000000000","message":"Is it like users have to copy the keys to the default paths?\nIf so Can we enhance the exception message like So that user can get a hint about it?","commit_id":"92c3672b145370c5d5b57c3dfc4de43054c966cf"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"3a52d78bfb88ff13ab7ce77c456fac631898ffd4","unresolved":false,"context_lines":[{"line_number":39,"context_line":"            CONF.jwt_tokens.jws_private_key_repository, \u0027private.pem\u0027"},{"line_number":40,"context_line":"        )"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"        if not os.path.exists(private_key) and CONF.token.provider \u003d\u003d \u0027jws\u0027:"},{"line_number":43,"context_line":"            subs \u003d {\u0027private_key\u0027: private_key}"},{"line_number":44,"context_line":"            raise SystemExit(_(\u0027%(private_key)s does not exist\u0027) % subs)"},{"line_number":45,"context_line":"        if os.listdir(CONF.jwt_tokens.jws_public_key_repository) \u003d\u003d 0:"},{"line_number":46,"context_line":"            subs \u003d {"},{"line_number":47,"context_line":"                \u0027public_key_repo\u0027: CONF.jwt_tokens.jws_public_key_repository"}],"source_content_type":"text/x-python","patch_set":12,"id":"9fdfeff1_cb3fd684","line":44,"range":{"start_line":42,"start_character":7,"end_line":44,"end_character":72},"in_reply_to":"9fdfeff1_a3288d96","updated":"2019-01-31 23:54:41.000000000","message":"\u003e Is it like users have to copy the keys to the default paths?\n \u003e If so Can we enhance the exception message like So that user can\n \u003e get a hint about it?\n\n\nYep - exactly. If we implement create_jws_keypair to put the keys in the repositories listed in the configuration options, we run the risk of overloading the logic by assuming odd naming conventions, which might not be general enough for each deployment.\n\nBy requiring users to generate key pairs and copy them to locations manually, we can assume they know where the keys go and how they\u0027re generated. The public repository also has to be sync\u0027d across all keystone nodes in order for each API server to validation tokens for the cluster. This makes the naming difficult since we don\u0027t know what a safe convention is to avoid naming conflicts. Instead, the least we can do is generate a key pair and tell the user to name/move them to the proper repositories.\n\nI can add some clarification to the log message though.","commit_id":"92c3672b145370c5d5b57c3dfc4de43054c966cf"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"5f65aef43934c1cd272045289b771ea9890cd221","unresolved":false,"context_lines":[{"line_number":39,"context_line":"            CONF.jwt_tokens.jws_private_key_repository, \u0027private.pem\u0027"},{"line_number":40,"context_line":"        )"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"        if not os.path.exists(private_key) and CONF.token.provider \u003d\u003d \u0027jws\u0027:"},{"line_number":43,"context_line":"            subs \u003d {\u0027private_key\u0027: private_key}"},{"line_number":44,"context_line":"            raise SystemExit(_(\u0027%(private_key)s does not exist\u0027) % subs)"},{"line_number":45,"context_line":"        if os.listdir(CONF.jwt_tokens.jws_public_key_repository) \u003d\u003d 0:"},{"line_number":46,"context_line":"            subs \u003d {"},{"line_number":47,"context_line":"                \u0027public_key_repo\u0027: CONF.jwt_tokens.jws_public_key_repository"}],"source_content_type":"text/x-python","patch_set":12,"id":"9fdfeff1_59ce575a","line":44,"range":{"start_line":42,"start_character":7,"end_line":44,"end_character":72},"in_reply_to":"9fdfeff1_cb3fd684","updated":"2019-02-01 05:55:57.000000000","message":"++. Great Thanks.","commit_id":"92c3672b145370c5d5b57c3dfc4de43054c966cf"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"c1ff86532263b0e524ec373110764f3c3a0c2167","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    # of supported algorithms."},{"line_number":85,"context_line":"    algorithm \u003d \u0027ES256\u0027"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    @property"},{"line_number":88,"context_line":"    def private_key(self):"},{"line_number":89,"context_line":"        private_key_path \u003d os.path.join("},{"line_number":90,"context_line":"            CONF.jwt_tokens.jws_private_key_repository, \u0027private.pem\u0027"},{"line_number":91,"context_line":"        )"},{"line_number":92,"context_line":"        with open(private_key_path, \u0027r\u0027) as f:"},{"line_number":93,"context_line":"            key \u003d f.read()"},{"line_number":94,"context_line":"        return key"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    @property"},{"line_number":97,"context_line":"    def public_keys(self):"},{"line_number":98,"context_line":"        keys \u003d []"},{"line_number":99,"context_line":"        key_repo \u003d CONF.jwt_tokens.jws_public_key_repository"},{"line_number":100,"context_line":"        for keyfile in os.listdir(key_repo):"},{"line_number":101,"context_line":"            with open(os.path.join(key_repo, keyfile), \u0027r\u0027) as f:"},{"line_number":102,"context_line":"                keys.append(f.read())"},{"line_number":103,"context_line":"        return keys"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def create_token(self, user_id, expires_at, audit_ids, methods,"},{"line_number":106,"context_line":"                     system\u003dNone, domain_id\u003dNone, project_id\u003dNone,"}],"source_content_type":"text/x-python","patch_set":13,"id":"9fdfeff1_ce758d33","line":103,"range":{"start_line":87,"start_character":0,"end_line":103,"end_character":19},"updated":"2019-02-02 03:21:25.000000000","message":"So the same with Fernet, every time users issue or verify a token, it\u0027ll read the key files. I suppose this\u0027ll lead to a performance issue? especially for public keys, Is it possible to use cache here?","commit_id":"98b83d463dece62f428ad6e7ca88b7f7e20fdd03"},{"author":{"_account_id":27621,"name":"Vishakha Agarwal","email":"agarwalvishakha18@gmail.com","username":"Vishakha"},"change_message_id":"7935fd5c8c13d55e9a87b0ac15d0cf75b8a4f44d","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    # of supported algorithms."},{"line_number":85,"context_line":"    algorithm \u003d \u0027ES256\u0027"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    @property"},{"line_number":88,"context_line":"    def private_key(self):"},{"line_number":89,"context_line":"        private_key_path \u003d os.path.join("},{"line_number":90,"context_line":"            CONF.jwt_tokens.jws_private_key_repository, \u0027private.pem\u0027"},{"line_number":91,"context_line":"        )"},{"line_number":92,"context_line":"        with open(private_key_path, \u0027r\u0027) as f:"},{"line_number":93,"context_line":"            key \u003d f.read()"},{"line_number":94,"context_line":"        return key"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    @property"},{"line_number":97,"context_line":"    def public_keys(self):"},{"line_number":98,"context_line":"        keys \u003d []"},{"line_number":99,"context_line":"        key_repo \u003d CONF.jwt_tokens.jws_public_key_repository"},{"line_number":100,"context_line":"        for keyfile in os.listdir(key_repo):"},{"line_number":101,"context_line":"            with open(os.path.join(key_repo, keyfile), \u0027r\u0027) as f:"},{"line_number":102,"context_line":"                keys.append(f.read())"},{"line_number":103,"context_line":"        return keys"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def create_token(self, user_id, expires_at, audit_ids, methods,"},{"line_number":106,"context_line":"                     system\u003dNone, domain_id\u003dNone, project_id\u003dNone,"}],"source_content_type":"text/x-python","patch_set":13,"id":"9fdfeff1_607c7cb5","line":103,"range":{"start_line":87,"start_character":0,"end_line":103,"end_character":19},"in_reply_to":"9fdfeff1_1edbb14f","updated":"2019-02-06 05:16:24.000000000","message":"++","commit_id":"98b83d463dece62f428ad6e7ca88b7f7e20fdd03"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"095df5b3f0e165fb737eb0500b2052c0b233580e","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    # of supported algorithms."},{"line_number":85,"context_line":"    algorithm \u003d \u0027ES256\u0027"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    @property"},{"line_number":88,"context_line":"    def private_key(self):"},{"line_number":89,"context_line":"        private_key_path \u003d os.path.join("},{"line_number":90,"context_line":"            CONF.jwt_tokens.jws_private_key_repository, \u0027private.pem\u0027"},{"line_number":91,"context_line":"        )"},{"line_number":92,"context_line":"        with open(private_key_path, \u0027r\u0027) as f:"},{"line_number":93,"context_line":"            key \u003d f.read()"},{"line_number":94,"context_line":"        return key"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    @property"},{"line_number":97,"context_line":"    def public_keys(self):"},{"line_number":98,"context_line":"        keys \u003d []"},{"line_number":99,"context_line":"        key_repo \u003d CONF.jwt_tokens.jws_public_key_repository"},{"line_number":100,"context_line":"        for keyfile in os.listdir(key_repo):"},{"line_number":101,"context_line":"            with open(os.path.join(key_repo, keyfile), \u0027r\u0027) as f:"},{"line_number":102,"context_line":"                keys.append(f.read())"},{"line_number":103,"context_line":"        return keys"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def create_token(self, user_id, expires_at, audit_ids, methods,"},{"line_number":106,"context_line":"                     system\u003dNone, domain_id\u003dNone, project_id\u003dNone,"}],"source_content_type":"text/x-python","patch_set":13,"id":"9fdfeff1_e8260ebb","line":103,"range":{"start_line":87,"start_character":0,"end_line":103,"end_character":19},"in_reply_to":"9fdfeff1_607c7cb5","updated":"2019-02-06 11:56:41.000000000","message":"I don\u0027t have a clear idea. maybe something like what \t\nKristi did for mutable config: https://review.openstack.org/#/c/585417/2/keystone/conf/__init__.py L195 \nwhile Colleen and Morgan had left some concern there for this way.\n\nWhat I\u0027m sure is that this kind of performance issue is happed indeed in our public cloud. We may leave to a TODO here at least.","commit_id":"98b83d463dece62f428ad6e7ca88b7f7e20fdd03"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"99b7805b6031d8ed9a68b5fd83d97c4c7093fb78","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    # of supported algorithms."},{"line_number":85,"context_line":"    algorithm \u003d \u0027ES256\u0027"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    @property"},{"line_number":88,"context_line":"    def private_key(self):"},{"line_number":89,"context_line":"        private_key_path \u003d os.path.join("},{"line_number":90,"context_line":"            CONF.jwt_tokens.jws_private_key_repository, \u0027private.pem\u0027"},{"line_number":91,"context_line":"        )"},{"line_number":92,"context_line":"        with open(private_key_path, \u0027r\u0027) as f:"},{"line_number":93,"context_line":"            key \u003d f.read()"},{"line_number":94,"context_line":"        return key"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    @property"},{"line_number":97,"context_line":"    def public_keys(self):"},{"line_number":98,"context_line":"        keys \u003d []"},{"line_number":99,"context_line":"        key_repo \u003d CONF.jwt_tokens.jws_public_key_repository"},{"line_number":100,"context_line":"        for keyfile in os.listdir(key_repo):"},{"line_number":101,"context_line":"            with open(os.path.join(key_repo, keyfile), \u0027r\u0027) as f:"},{"line_number":102,"context_line":"                keys.append(f.read())"},{"line_number":103,"context_line":"        return keys"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def create_token(self, user_id, expires_at, audit_ids, methods,"},{"line_number":106,"context_line":"                     system\u003dNone, domain_id\u003dNone, project_id\u003dNone,"}],"source_content_type":"text/x-python","patch_set":13,"id":"9fdfeff1_1edbb14f","line":103,"range":{"start_line":87,"start_character":0,"end_line":103,"end_character":19},"in_reply_to":"9fdfeff1_ce758d33","updated":"2019-02-04 17:31:25.000000000","message":"We talked about doing that in the original fernet implementation. IIRC, we didn\u0027t implement caching initially because we wanted new keys to be picked up immediately.\n\nIt\u0027s been a while since that optimization has been discussed. I\u0027ll see if I can come up with a way to do this. Do you mind if I experiment with that in a follow on or do you want it implemented in this patch?","commit_id":"98b83d463dece62f428ad6e7ca88b7f7e20fdd03"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"bffae3cdc8c67d9249a14e1c740cd4dcd4a1b877","unresolved":false,"context_lines":[{"line_number":119,"context_line":"            \u0027exp\u0027: expires_at_int,"},{"line_number":120,"context_line":"            # private claims"},{"line_number":121,"context_line":"            \u0027openstack_methods\u0027: methods,"},{"line_number":122,"context_line":"            \u0027openstack_audit_ids\u0027: audit_ids,"},{"line_number":123,"context_line":"            \u0027openstack_system\u0027: system,"},{"line_number":124,"context_line":"            \u0027openstack_domain_id\u0027: domain_id,"},{"line_number":125,"context_line":"            \u0027openstack_project_id\u0027: project_id,"}],"source_content_type":"text/x-python","patch_set":13,"id":"9fdfeff1_aea049f5","line":122,"range":{"start_line":122,"start_character":13,"end_line":122,"end_character":32},"updated":"2019-02-02 02:25:28.000000000","message":"Should this be \"aud\" to follow jwt standard?","commit_id":"98b83d463dece62f428ad6e7ca88b7f7e20fdd03"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"99b7805b6031d8ed9a68b5fd83d97c4c7093fb78","unresolved":false,"context_lines":[{"line_number":119,"context_line":"            \u0027exp\u0027: expires_at_int,"},{"line_number":120,"context_line":"            # private claims"},{"line_number":121,"context_line":"            \u0027openstack_methods\u0027: methods,"},{"line_number":122,"context_line":"            \u0027openstack_audit_ids\u0027: audit_ids,"},{"line_number":123,"context_line":"            \u0027openstack_system\u0027: system,"},{"line_number":124,"context_line":"            \u0027openstack_domain_id\u0027: domain_id,"},{"line_number":125,"context_line":"            \u0027openstack_project_id\u0027: project_id,"}],"source_content_type":"text/x-python","patch_set":13,"id":"9fdfeff1_dece895a","line":122,"range":{"start_line":122,"start_character":13,"end_line":122,"end_character":32},"in_reply_to":"9fdfeff1_aea049f5","updated":"2019-02-04 17:31:25.000000000","message":"Good question. Based on my interpretation of the specification [0], \"aud\" is the intended audience of the token. In the case of OpenStack, would that be the user or service users?\n\nI\u0027m not sure what we would put here since multiple actors can validate a token (e.g., administrators, services users, users themselves).\n\nOpenStack audit IDs are a bit different and specific to OpenStack in my opinion. I\u0027m not sure they exactly match up with any of the claims described in the specification, but I\u0027m curious if you have a different view point.\n\n[0] https://tools.ietf.org/html/rfc7519#section-4.1.3","commit_id":"98b83d463dece62f428ad6e7ca88b7f7e20fdd03"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"c1ff86532263b0e524ec373110764f3c3a0c2167","unresolved":false,"context_lines":[{"line_number":183,"context_line":"            except (jwt.InvalidSignatureError, jwt.DecodeError,"},{"line_number":184,"context_line":"                    jwt.ExpiredSignatureError):"},{"line_number":185,"context_line":"                pass    # nosec: We want to exhaustively try all public keys"},{"line_number":186,"context_line":"            raise exception.TokenNotFound(token_id\u003dtoken_id)"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    def _convert_time_string_to_int(self, time_str):"},{"line_number":189,"context_line":"        time_object \u003d timeutils.parse_isotime(time_str)"}],"source_content_type":"text/x-python","patch_set":13,"id":"9fdfeff1_0e8075f4","line":186,"range":{"start_line":186,"start_character":12,"end_line":186,"end_character":60},"updated":"2019-02-02 03:21:25.000000000","message":"this should be at the same level with L178, otherwise, any public key decode failed, it\u0027ll raise TokenNotFound.","commit_id":"98b83d463dece62f428ad6e7ca88b7f7e20fdd03"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"99b7805b6031d8ed9a68b5fd83d97c4c7093fb78","unresolved":false,"context_lines":[{"line_number":183,"context_line":"            except (jwt.InvalidSignatureError, jwt.DecodeError,"},{"line_number":184,"context_line":"                    jwt.ExpiredSignatureError):"},{"line_number":185,"context_line":"                pass    # nosec: We want to exhaustively try all public keys"},{"line_number":186,"context_line":"            raise exception.TokenNotFound(token_id\u003dtoken_id)"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    def _convert_time_string_to_int(self, time_str):"},{"line_number":189,"context_line":"        time_object \u003d timeutils.parse_isotime(time_str)"}],"source_content_type":"text/x-python","patch_set":13,"id":"9fdfeff1_6474b09d","line":186,"range":{"start_line":186,"start_character":12,"end_line":186,"end_character":60},"in_reply_to":"9fdfeff1_0e8075f4","updated":"2019-02-04 17:31:25.000000000","message":"Done","commit_id":"98b83d463dece62f428ad6e7ca88b7f7e20fdd03"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"081f6d1b0e360f02ebbf82fd2d1fd7b23aa3d06b","unresolved":false,"context_lines":[{"line_number":79,"context_line":""},{"line_number":80,"context_line":"class JWSFormatter(object):"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    # NOTE(lbragstad): If in the future we expand support for different"},{"line_number":83,"context_line":"    # algorithms, make this configurable and validate it against a blessed list"},{"line_number":84,"context_line":"    # of supported algorithms."},{"line_number":85,"context_line":"    algorithm \u003d \u0027ES256\u0027"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    @property"},{"line_number":88,"context_line":"    def private_key(self):"}],"source_content_type":"text/x-python","patch_set":16,"id":"9fdfeff1_e71e866e","line":85,"range":{"start_line":82,"start_character":0,"end_line":85,"end_character":23},"updated":"2019-02-15 20:36:01.000000000","message":"Thanks for the note here.","commit_id":"96adccd0ec0398251268f9ae89732005e340035c"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"081f6d1b0e360f02ebbf82fd2d1fd7b23aa3d06b","unresolved":false,"context_lines":[{"line_number":131,"context_line":"            \u0027openstack_app_cred_id\u0027: app_cred_id"},{"line_number":132,"context_line":"        }"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"        # NOTE(lbragstad): Calling .items() on a dictionary in python 2 returns"},{"line_number":135,"context_line":"        # a list but returns an iterable in python 3. Casting to a list makes"},{"line_number":136,"context_line":"        # it safe to modify the dictionary while iterating over it, regardless"},{"line_number":137,"context_line":"        # of the python version."},{"line_number":138,"context_line":"        for k, v in list(payload.items()):"},{"line_number":139,"context_line":"            if v is None:"},{"line_number":140,"context_line":"                payload.pop(k)"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"        token_id \u003d jwt.encode("},{"line_number":143,"context_line":"            payload,"}],"source_content_type":"text/x-python","patch_set":16,"id":"9fdfeff1_623da4b9","line":140,"range":{"start_line":134,"start_character":0,"end_line":140,"end_character":30},"updated":"2019-02-15 20:36:01.000000000","message":"It is probably easier to just use a straight comprehension and avoid py2-isms vs py3-isms:\n\n  payload \u003d {k: v for k, v in payload.items() if v is not None}\n\nThis is fine as is, and this is not a reason to change the code.","commit_id":"96adccd0ec0398251268f9ae89732005e340035c"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"46728bfd8fb347abafb716a826cfa121ea974020","unresolved":false,"context_lines":[{"line_number":182,"context_line":"                )"},{"line_number":183,"context_line":"            except (jwt.InvalidSignatureError, jwt.DecodeError,"},{"line_number":184,"context_line":"                    jwt.ExpiredSignatureError):"},{"line_number":185,"context_line":"                pass    # nosec: We want to exhaustively try all public keys"},{"line_number":186,"context_line":"        raise exception.TokenNotFound(token_id\u003dtoken_id)"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    def _convert_time_string_to_int(self, time_str):"}],"source_content_type":"text/x-python","patch_set":16,"id":"9fdfeff1_1f55a1fa","line":185,"range":{"start_line":185,"start_character":16,"end_line":185,"end_character":76},"updated":"2019-02-21 18:37:08.000000000","message":"Would we want to log here that a pub key is invalid?","commit_id":"96adccd0ec0398251268f9ae89732005e340035c"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"8eb3b4a8871f6c92218bdd8fde1e688aa01fd3db","unresolved":false,"context_lines":[{"line_number":182,"context_line":"                )"},{"line_number":183,"context_line":"            except (jwt.InvalidSignatureError, jwt.DecodeError,"},{"line_number":184,"context_line":"                    jwt.ExpiredSignatureError):"},{"line_number":185,"context_line":"                pass    # nosec: We want to exhaustively try all public keys"},{"line_number":186,"context_line":"        raise exception.TokenNotFound(token_id\u003dtoken_id)"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    def _convert_time_string_to_int(self, time_str):"}],"source_content_type":"text/x-python","patch_set":16,"id":"9fdfeff1_9fb6713e","line":185,"range":{"start_line":185,"start_character":16,"end_line":185,"end_character":76},"in_reply_to":"9fdfeff1_1f55a1fa","updated":"2019-02-21 18:40:19.000000000","message":"Maybe debug logging at the very least?","commit_id":"96adccd0ec0398251268f9ae89732005e340035c"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"2c6b500f0e25d823fdfcc08847bf27642ddc3b1e","unresolved":false,"context_lines":[{"line_number":182,"context_line":"                )"},{"line_number":183,"context_line":"            except (jwt.InvalidSignatureError, jwt.DecodeError,"},{"line_number":184,"context_line":"                    jwt.ExpiredSignatureError):"},{"line_number":185,"context_line":"                pass    # nosec: We want to exhaustively try all public keys"},{"line_number":186,"context_line":"        raise exception.TokenNotFound(token_id\u003dtoken_id)"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    def _convert_time_string_to_int(self, time_str):"}],"source_content_type":"text/x-python","patch_set":16,"id":"9fdfeff1_5f880921","line":185,"range":{"start_line":185,"start_character":16,"end_line":185,"end_character":76},"in_reply_to":"9fdfeff1_1f5841f8","updated":"2019-02-21 18:58:06.000000000","message":"After discussion in IRC, lets leave this for now and look into it with a follow-up. Logging here would indeed be very chatty.","commit_id":"96adccd0ec0398251268f9ae89732005e340035c"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"43ff5f6d50511de642d47e2491360052ac8a2ea7","unresolved":false,"context_lines":[{"line_number":182,"context_line":"                )"},{"line_number":183,"context_line":"            except (jwt.InvalidSignatureError, jwt.DecodeError,"},{"line_number":184,"context_line":"                    jwt.ExpiredSignatureError):"},{"line_number":185,"context_line":"                pass    # nosec: We want to exhaustively try all public keys"},{"line_number":186,"context_line":"        raise exception.TokenNotFound(token_id\u003dtoken_id)"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    def _convert_time_string_to_int(self, time_str):"}],"source_content_type":"text/x-python","patch_set":16,"id":"9fdfeff1_1f5841f8","line":185,"range":{"start_line":185,"start_character":16,"end_line":185,"end_character":76},"in_reply_to":"9fdfeff1_9fb6713e","updated":"2019-02-21 18:44:34.000000000","message":"FWIW - this could get noisy if you enable debug logging and have several public keys in this repository. Especially since it\u0027s likely to try multiple keys on every validation.","commit_id":"96adccd0ec0398251268f9ae89732005e340035c"}],"keystone/token/providers/jwt/__init__.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"723a11e9f47dcc841ce317757d973c36777a86dc","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":7,"id":"9fdfeff1_dec2f2e9","line":1,"updated":"2019-01-21 17:26:53.000000000","message":"This should be a jws provider instead of jwt.","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"9ca5f97292dfea86b6ac6ab880bbc9f0b5b7f026","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":7,"id":"9fdfeff1_d993ec4e","line":1,"in_reply_to":"9fdfeff1_dec2f2e9","updated":"2019-01-21 17:52:48.000000000","message":"Done","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"}],"keystone/token/providers/jwt/core.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"723a11e9f47dcc841ce317757d973c36777a86dc","unresolved":false,"context_lines":[{"line_number":40,"context_line":"        )"},{"line_number":41,"context_line":"        public_key \u003d os.path.join("},{"line_number":42,"context_line":"            CONF.jwt_tokens.key_repository, \u0027private.pem\u0027"},{"line_number":43,"context_line":"        )"},{"line_number":44,"context_line":"        if not os.path.exists(private_key) and CONF.token.provider \u003d\u003d \u0027jwt\u0027:"},{"line_number":45,"context_line":"            subs \u003d {\u0027private_key\u0027: private_key}"},{"line_number":46,"context_line":"            raise SystemExit(_(\u0027%(private_key)s does not exist\u0027) % subs)"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_7eb74688","line":43,"updated":"2019-01-21 17:26:53.000000000","message":"These options need to be updated.","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"9ca5f97292dfea86b6ac6ab880bbc9f0b5b7f026","unresolved":false,"context_lines":[{"line_number":40,"context_line":"        )"},{"line_number":41,"context_line":"        public_key \u003d os.path.join("},{"line_number":42,"context_line":"            CONF.jwt_tokens.key_repository, \u0027private.pem\u0027"},{"line_number":43,"context_line":"        )"},{"line_number":44,"context_line":"        if not os.path.exists(private_key) and CONF.token.provider \u003d\u003d \u0027jwt\u0027:"},{"line_number":45,"context_line":"            subs \u003d {\u0027private_key\u0027: private_key}"},{"line_number":46,"context_line":"            raise SystemExit(_(\u0027%(private_key)s does not exist\u0027) % subs)"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_7998c069","line":43,"in_reply_to":"9fdfeff1_7eb74688","updated":"2019-01-21 17:52:48.000000000","message":"Done","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"723a11e9f47dcc841ce317757d973c36777a86dc","unresolved":false,"context_lines":[{"line_number":83,"context_line":"        return key"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"    @property"},{"line_number":86,"context_line":"    def public_key(self):"},{"line_number":87,"context_line":"        # TODO(lbragstad): Add support for multiple public keys"},{"line_number":88,"context_line":"        public_key_path \u003d os.path.join("},{"line_number":89,"context_line":"            CONF.jwt_tokens.key_repository, \u0027public.pem\u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_1ea87a1d","line":86,"range":{"start_line":86,"start_character":8,"end_line":86,"end_character":18},"updated":"2019-01-21 17:26:53.000000000","message":"public_keys","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"9ca5f97292dfea86b6ac6ab880bbc9f0b5b7f026","unresolved":false,"context_lines":[{"line_number":83,"context_line":"        return key"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"    @property"},{"line_number":86,"context_line":"    def public_key(self):"},{"line_number":87,"context_line":"        # TODO(lbragstad): Add support for multiple public keys"},{"line_number":88,"context_line":"        public_key_path \u003d os.path.join("},{"line_number":89,"context_line":"            CONF.jwt_tokens.key_repository, \u0027public.pem\u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_999d645b","line":86,"range":{"start_line":86,"start_character":8,"end_line":86,"end_character":18},"in_reply_to":"9fdfeff1_1ea87a1d","updated":"2019-01-21 17:52:48.000000000","message":"Done","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"723a11e9f47dcc841ce317757d973c36777a86dc","unresolved":false,"context_lines":[{"line_number":84,"context_line":""},{"line_number":85,"context_line":"    @property"},{"line_number":86,"context_line":"    def public_key(self):"},{"line_number":87,"context_line":"        # TODO(lbragstad): Add support for multiple public keys"},{"line_number":88,"context_line":"        public_key_path \u003d os.path.join("},{"line_number":89,"context_line":"            CONF.jwt_tokens.key_repository, \u0027public.pem\u0027"},{"line_number":90,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_feaa5617","line":87,"updated":"2019-01-21 17:26:53.000000000","message":"This property should return an iterator, which is a list of keys (at least a list of one key). Then we can just iterate the list of public keys against a token.","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"9ca5f97292dfea86b6ac6ab880bbc9f0b5b7f026","unresolved":false,"context_lines":[{"line_number":84,"context_line":""},{"line_number":85,"context_line":"    @property"},{"line_number":86,"context_line":"    def public_key(self):"},{"line_number":87,"context_line":"        # TODO(lbragstad): Add support for multiple public keys"},{"line_number":88,"context_line":"        public_key_path \u003d os.path.join("},{"line_number":89,"context_line":"            CONF.jwt_tokens.key_repository, \u0027public.pem\u0027"},{"line_number":90,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_39a2389c","line":87,"in_reply_to":"9fdfeff1_feaa5617","updated":"2019-01-21 17:52:48.000000000","message":"Done","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"723a11e9f47dcc841ce317757d973c36777a86dc","unresolved":false,"context_lines":[{"line_number":133,"context_line":"        return token_id, issued_at"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"    def validate_token(self, token_id):"},{"line_number":136,"context_line":"        try:"},{"line_number":137,"context_line":"            payload \u003d jwt.decode("},{"line_number":138,"context_line":"                token_id, self.public_key, algorithms\u003dJWTFormatter.algorithm"},{"line_number":139,"context_line":"            )"},{"line_number":140,"context_line":"        except (jwt.InvalidSignatureError, jwt.DecodeError) as e:"},{"line_number":141,"context_line":"            raise exception.TokenNotFound(e)"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"        user_id \u003d payload[\u0027sub\u0027]"},{"line_number":144,"context_line":"        expires_at_int \u003d payload[\u0027exp\u0027]"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_be4b6e85","line":141,"range":{"start_line":136,"start_character":8,"end_line":141,"end_character":44},"updated":"2019-01-21 17:26:53.000000000","message":"This should be inside of a for loop for each public key","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"9ca5f97292dfea86b6ac6ab880bbc9f0b5b7f026","unresolved":false,"context_lines":[{"line_number":133,"context_line":"        return token_id, issued_at"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"    def validate_token(self, token_id):"},{"line_number":136,"context_line":"        try:"},{"line_number":137,"context_line":"            payload \u003d jwt.decode("},{"line_number":138,"context_line":"                token_id, self.public_key, algorithms\u003dJWTFormatter.algorithm"},{"line_number":139,"context_line":"            )"},{"line_number":140,"context_line":"        except (jwt.InvalidSignatureError, jwt.DecodeError) as e:"},{"line_number":141,"context_line":"            raise exception.TokenNotFound(e)"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"        user_id \u003d payload[\u0027sub\u0027]"},{"line_number":144,"context_line":"        expires_at_int \u003d payload[\u0027exp\u0027]"}],"source_content_type":"text/x-python","patch_set":7,"id":"9fdfeff1_599ffc4f","line":141,"range":{"start_line":136,"start_character":8,"end_line":141,"end_character":44},"in_reply_to":"9fdfeff1_be4b6e85","updated":"2019-01-21 17:52:48.000000000","message":"Done","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"}],"setup.cfg":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"723a11e9f47dcc841ce317757d973c36777a86dc","unresolved":false,"context_lines":[{"line_number":144,"context_line":""},{"line_number":145,"context_line":"keystone.token.provider \u003d"},{"line_number":146,"context_line":"    fernet \u003d keystone.token.providers.fernet:Provider"},{"line_number":147,"context_line":"    jwt \u003d keystone.token.providers.jwt:Provider"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"keystone.receipt.provider \u003d"},{"line_number":150,"context_line":"    fernet \u003d keystone.receipt.providers.fernet:Provider"}],"source_content_type":"text/x-ttcn-cfg","patch_set":7,"id":"9fdfeff1_7e450670","line":147,"range":{"start_line":147,"start_character":4,"end_line":147,"end_character":7},"updated":"2019-01-21 17:26:53.000000000","message":"jws","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"723a11e9f47dcc841ce317757d973c36777a86dc","unresolved":false,"context_lines":[{"line_number":144,"context_line":""},{"line_number":145,"context_line":"keystone.token.provider \u003d"},{"line_number":146,"context_line":"    fernet \u003d keystone.token.providers.fernet:Provider"},{"line_number":147,"context_line":"    jwt \u003d keystone.token.providers.jwt:Provider"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"keystone.receipt.provider \u003d"},{"line_number":150,"context_line":"    fernet \u003d keystone.receipt.providers.fernet:Provider"}],"source_content_type":"text/x-ttcn-cfg","patch_set":7,"id":"9fdfeff1_de50b235","line":147,"range":{"start_line":147,"start_character":35,"end_line":147,"end_character":38},"updated":"2019-01-21 17:26:53.000000000","message":"jws*","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"9ca5f97292dfea86b6ac6ab880bbc9f0b5b7f026","unresolved":false,"context_lines":[{"line_number":144,"context_line":""},{"line_number":145,"context_line":"keystone.token.provider \u003d"},{"line_number":146,"context_line":"    fernet \u003d keystone.token.providers.fernet:Provider"},{"line_number":147,"context_line":"    jwt \u003d keystone.token.providers.jwt:Provider"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"keystone.receipt.provider \u003d"},{"line_number":150,"context_line":"    fernet \u003d keystone.receipt.providers.fernet:Provider"}],"source_content_type":"text/x-ttcn-cfg","patch_set":7,"id":"9fdfeff1_d9bc4cbd","line":147,"range":{"start_line":147,"start_character":4,"end_line":147,"end_character":7},"in_reply_to":"9fdfeff1_7e450670","updated":"2019-01-21 17:52:48.000000000","message":"Done","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"9ca5f97292dfea86b6ac6ab880bbc9f0b5b7f026","unresolved":false,"context_lines":[{"line_number":144,"context_line":""},{"line_number":145,"context_line":"keystone.token.provider \u003d"},{"line_number":146,"context_line":"    fernet \u003d keystone.token.providers.fernet:Provider"},{"line_number":147,"context_line":"    jwt \u003d keystone.token.providers.jwt:Provider"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"keystone.receipt.provider \u003d"},{"line_number":150,"context_line":"    fernet \u003d keystone.receipt.providers.fernet:Provider"}],"source_content_type":"text/x-ttcn-cfg","patch_set":7,"id":"9fdfeff1_79b1a0e1","line":147,"range":{"start_line":147,"start_character":35,"end_line":147,"end_character":38},"in_reply_to":"9fdfeff1_de50b235","updated":"2019-01-21 17:52:48.000000000","message":"Done","commit_id":"d61a94c216e2f31101a81b4b0208eb904e430ec8"}]}
