)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b882f029298a678b8c4f69cc8ac9741e76e1c60e","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Support TOTP credential"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Support credential type \u0027totp\u0027. In addition, introduce an option to generate"},{"line_number":10,"context_line":"provisioning uri where users can use to provision their mobile device via"},{"line_number":11,"context_line":"the QR barcode method."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"7af24918_daabbb73","line":9,"range":{"start_line":9,"start_character":72,"end_line":9,"end_character":76},"updated":"2016-03-03 15:37:51.000000000","message":"a little long?","commit_id":"781e522eef368eb9ada9047e0009a46adc64bd2b"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"421b0a86488e12bdae38e3cc44a9425a7b6a540c","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Support TOTP credential"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Support credential type \u0027totp\u0027. In addition, introduce an option to generate"},{"line_number":10,"context_line":"provisioning uri where users can use to provision their mobile device via"},{"line_number":11,"context_line":"the QR barcode method."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"7af24918_ccc81b58","line":9,"range":{"start_line":9,"start_character":72,"end_line":9,"end_character":76},"in_reply_to":"7af24918_daabbb73","updated":"2016-03-03 18:22:05.000000000","message":"Done","commit_id":"781e522eef368eb9ada9047e0009a46adc64bd2b"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b882f029298a678b8c4f69cc8ac9741e76e1c60e","unresolved":false,"context_lines":[{"line_number":10,"context_line":"provisioning uri where users can use to provision their mobile device via"},{"line_number":11,"context_line":"the QR barcode method."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"User also have an option to specify an already base32-encoded credential. This"},{"line_number":14,"context_line":"is useful in a situation where one needs to import a credential that\u0027s been"},{"line_number":15,"context_line":"provisioned elsewhere."},{"line_number":16,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"7af24918_9acc936b","line":13,"range":{"start_line":13,"start_character":72,"end_line":13,"end_character":78},"updated":"2016-03-03 15:37:51.000000000","message":"and here","commit_id":"781e522eef368eb9ada9047e0009a46adc64bd2b"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"421b0a86488e12bdae38e3cc44a9425a7b6a540c","unresolved":false,"context_lines":[{"line_number":10,"context_line":"provisioning uri where users can use to provision their mobile device via"},{"line_number":11,"context_line":"the QR barcode method."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"User also have an option to specify an already base32-encoded credential. This"},{"line_number":14,"context_line":"is useful in a situation where one needs to import a credential that\u0027s been"},{"line_number":15,"context_line":"provisioned elsewhere."},{"line_number":16,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"7af24918_2cc41f3e","line":13,"range":{"start_line":13,"start_character":72,"end_line":13,"end_character":78},"in_reply_to":"7af24918_9acc936b","updated":"2016-03-03 18:22:05.000000000","message":"Done","commit_id":"781e522eef368eb9ada9047e0009a46adc64bd2b"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b882f029298a678b8c4f69cc8ac9741e76e1c60e","unresolved":false,"context_lines":[{"line_number":11,"context_line":"the QR barcode method."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"User also have an option to specify an already base32-encoded credential. This"},{"line_number":14,"context_line":"is useful in a situation where one needs to import a credential that\u0027s been"},{"line_number":15,"context_line":"provisioned elsewhere."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Change-Id: I7e4f773f381e62c1a6af419634469095cbbe02be"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"7af24918_7ac9c758","line":14,"range":{"start_line":14,"start_character":72,"end_line":14,"end_character":75},"updated":"2016-03-03 15:37:51.000000000","message":"and here","commit_id":"781e522eef368eb9ada9047e0009a46adc64bd2b"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"421b0a86488e12bdae38e3cc44a9425a7b6a540c","unresolved":false,"context_lines":[{"line_number":11,"context_line":"the QR barcode method."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"User also have an option to specify an already base32-encoded credential. This"},{"line_number":14,"context_line":"is useful in a situation where one needs to import a credential that\u0027s been"},{"line_number":15,"context_line":"provisioned elsewhere."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Change-Id: I7e4f773f381e62c1a6af419634469095cbbe02be"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"7af24918_0cbfa3aa","line":14,"range":{"start_line":14,"start_character":72,"end_line":14,"end_character":75},"in_reply_to":"7af24918_7ac9c758","updated":"2016-03-03 18:22:05.000000000","message":"Done","commit_id":"781e522eef368eb9ada9047e0009a46adc64bd2b"}],"openstackclient/identity/v3/credential.py":[{"author":{"_account_id":11434,"name":"werner mendizabal","email":"nonameentername@gmail.com","username":"nonameentername"},"change_message_id":"4120577b4d1518042df106b0b17d7bea12c61eb1","unresolved":false,"context_lines":[{"line_number":119,"context_line":"            # FIXME(gyee): totp credentials should be base32 encoded. We"},{"line_number":120,"context_line":"            # probably need another parameter to support already encoded"},{"line_number":121,"context_line":"            # blob so we are not restricted to printable characters only."},{"line_number":122,"context_line":"            blob \u003d base64.b32encode(blob)"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"        credential \u003d identity_client.credentials.create("},{"line_number":125,"context_line":"            user\u003duser_id,"}],"source_content_type":"text/x-python","patch_set":1,"id":"dae33548_c59eb855","line":122,"updated":"2016-02-15 18:53:52.000000000","message":"cryptography totp does the base32 encoding.  I don\u0027t think you need to base32 encode it.\n\nAlso, the blob doesn\u0027t match current keystone implementation.","commit_id":"e4eba09d0a5a07a7873114726161747edd785c31"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"792dbd1cfb79e7adc33fe94852ab7ecb2b0a6731","unresolved":false,"context_lines":[{"line_number":119,"context_line":"            # FIXME(gyee): totp credentials should be base32 encoded. We"},{"line_number":120,"context_line":"            # probably need another parameter to support already encoded"},{"line_number":121,"context_line":"            # blob so we are not restricted to printable characters only."},{"line_number":122,"context_line":"            blob \u003d base64.b32encode(blob)"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"        credential \u003d identity_client.credentials.create("},{"line_number":125,"context_line":"            user\u003duser_id,"}],"source_content_type":"text/x-python","patch_set":1,"id":"dae33548_280dab37","line":122,"in_reply_to":"dae33548_c59eb855","updated":"2016-02-16 04:41:59.000000000","message":"Correct, we need to pass the decoded secret key into hazmat TOTP. But it should be base32 encoded for ease of management and transport. See\n\nhttps://github.com/google/google-authenticator/wiki/Key-Uri-Format\n\nWithout base32 encode, the amount of entropy we can use to create the shared secrete key is very limited.","commit_id":"e4eba09d0a5a07a7873114726161747edd785c31"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b3a53b5901455d794459a778ee63baaa0d6972ef","unresolved":false,"context_lines":[{"line_number":16,"context_line":"\"\"\"Identity v3 Credential action implementations\"\"\""},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"import base64"},{"line_number":19,"context_line":"import binascii"},{"line_number":20,"context_line":"import six"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from cryptography.hazmat.backends import default_backend"}],"source_content_type":"text/x-python","patch_set":5,"id":"bae84128_1a0b43d7","line":19,"updated":"2016-02-24 03:54:44.000000000","message":"Separate stdlib from third party with a newline","commit_id":"cd14b884313c954bd4b9aa626e6903e117d4ea05"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b3a53b5901455d794459a778ee63baaa0d6972ef","unresolved":false,"context_lines":[{"line_number":18,"context_line":"import base64"},{"line_number":19,"context_line":"import binascii"},{"line_number":20,"context_line":"import six"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from cryptography.hazmat.backends import default_backend"},{"line_number":23,"context_line":"from cryptography.hazmat.primitives.hashes import SHA1"},{"line_number":24,"context_line":"from cryptography.hazmat.primitives.twofactor.totp import TOTP"}],"source_content_type":"text/x-python","patch_set":5,"id":"bae84128_bafcd7b8","line":21,"updated":"2016-02-24 03:54:44.000000000","message":"Not sure why this new line is here :-(","commit_id":"cd14b884313c954bd4b9aa626e6903e117d4ea05"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b3a53b5901455d794459a778ee63baaa0d6972ef","unresolved":false,"context_lines":[{"line_number":20,"context_line":"import six"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from cryptography.hazmat.backends import default_backend"},{"line_number":23,"context_line":"from cryptography.hazmat.primitives.hashes import SHA1"},{"line_number":24,"context_line":"from cryptography.hazmat.primitives.twofactor.totp import TOTP"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"from openstackclient.common import command"}],"source_content_type":"text/x-python","patch_set":5,"id":"bae84128_da99db7a","line":23,"updated":"2016-02-24 03:54:44.000000000","message":"Shouldn\u0027t we only be importing modules?","commit_id":"cd14b884313c954bd4b9aa626e6903e117d4ea05"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b3a53b5901455d794459a778ee63baaa0d6972ef","unresolved":false,"context_lines":[{"line_number":78,"context_line":"        )"},{"line_number":79,"context_line":"        return parser"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    # FIXME(gyee): this stuff probably need to be in python-keystoneclient as"},{"line_number":82,"context_line":"    # they are being shared here and in Keystone totp auth plugin. Ideally, we"},{"line_number":83,"context_line":"    # should enhance Keystone V3 credential APIs to support provisioning."},{"line_number":84,"context_line":"    # Meaning, if blob is absent and depending on credential type, server"}],"source_content_type":"text/x-python","patch_set":5,"id":"bae84128_1aa7c3bd","line":81,"updated":"2016-02-24 03:54:44.000000000","message":"needs","commit_id":"cd14b884313c954bd4b9aa626e6903e117d4ea05"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b3a53b5901455d794459a778ee63baaa0d6972ef","unresolved":false,"context_lines":[{"line_number":91,"context_line":"    def _generate_provisioning_url(self, user_id, secret_key):"},{"line_number":92,"context_line":"        # NOTE(gyee): Google Authenticator uses 6 digits. And for TOTP, we use"},{"line_number":93,"context_line":"        # the standard 30 second time step."},{"line_number":94,"context_line":"        totp \u003d TOTP(secret_key.encode(\u0027utf-8\u0027), 6, SHA1(), 30,"},{"line_number":95,"context_line":"                    backend\u003ddefault_backend())"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        # NOTE(gyee): use user_id as account name as it is unique and Keystone"}],"source_content_type":"text/x-python","patch_set":5,"id":"bae84128_9acc738a","line":94,"updated":"2016-02-24 03:54:44.000000000","message":"Do we need to utf-8 encode? The allowed characters are a small subset of ASCII","commit_id":"cd14b884313c954bd4b9aa626e6903e117d4ea05"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b3a53b5901455d794459a778ee63baaa0d6972ef","unresolved":false,"context_lines":[{"line_number":225,"context_line":"        return parser"},{"line_number":226,"context_line":""},{"line_number":227,"context_line":"    def take_action(self, parsed_args):"},{"line_number":228,"context_line":"        # NOTE(gyee): totp credential, once provision, should not be updated"},{"line_number":229,"context_line":"        # within its lifecycle. It will either be re-provision (i.e. delete"},{"line_number":230,"context_line":"        # and create) or remove."},{"line_number":231,"context_line":"        if parsed_args.type.lower() \u003d\u003d \u0027totp\u0027:"}],"source_content_type":"text/x-python","patch_set":5,"id":"bae84128_5ab2ebe5","line":228,"updated":"2016-02-24 03:54:44.000000000","message":"provisioned","commit_id":"cd14b884313c954bd4b9aa626e6903e117d4ea05"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b3a53b5901455d794459a778ee63baaa0d6972ef","unresolved":false,"context_lines":[{"line_number":226,"context_line":""},{"line_number":227,"context_line":"    def take_action(self, parsed_args):"},{"line_number":228,"context_line":"        # NOTE(gyee): totp credential, once provision, should not be updated"},{"line_number":229,"context_line":"        # within its lifecycle. It will either be re-provision (i.e. delete"},{"line_number":230,"context_line":"        # and create) or remove."},{"line_number":231,"context_line":"        if parsed_args.type.lower() \u003d\u003d \u0027totp\u0027:"},{"line_number":232,"context_line":"            msg \u003d (\u0027Setting a totp credential is not supported.\u0027)"}],"source_content_type":"text/x-python","patch_set":5,"id":"bae84128_9ac8f356","line":229,"updated":"2016-02-24 03:54:44.000000000","message":"same...","commit_id":"cd14b884313c954bd4b9aa626e6903e117d4ea05"},{"author":{"_account_id":11434,"name":"werner mendizabal","email":"nonameentername@gmail.com","username":"nonameentername"},"change_message_id":"49dc8058adabe7efb7f197e8e0d223117ba33e0f","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        # If needed, we may need to create a new set of commands for totp"},{"line_number":50,"context_line":"        # credential, the same way we handle ec2 credentials."},{"line_number":51,"context_line":"        parser.add_argument("},{"line_number":52,"context_line":"            \u0027--include-google-authenticator-provisioning-url\u0027,"},{"line_number":53,"context_line":"            action\u003d\u0027store_true\u0027,"},{"line_number":54,"context_line":"            help\u003d\u0027This option is applicable to \"totp\" credentials only. If \u0027"},{"line_number":55,"context_line":"                 \u0027specified, the Google Authenticator QR code provisioning \u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"9aed3d3a_b9e10a9d","line":52,"updated":"2016-02-26 17:14:55.000000000","message":"This should not be google authenticator specific.  Maybe change it to --include-totp-provisioning-url","commit_id":"bfde49574e1e06dd09b5594c7b888c704b1cdafa"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"00b2a1d4593457741d88b189462976af78b695b3","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        # If needed, we may need to create a new set of commands for totp"},{"line_number":50,"context_line":"        # credential, the same way we handle ec2 credentials."},{"line_number":51,"context_line":"        parser.add_argument("},{"line_number":52,"context_line":"            \u0027--include-google-authenticator-provisioning-url\u0027,"},{"line_number":53,"context_line":"            action\u003d\u0027store_true\u0027,"},{"line_number":54,"context_line":"            help\u003d\u0027This option is applicable to \"totp\" credentials only. If \u0027"},{"line_number":55,"context_line":"                 \u0027specified, the Google Authenticator QR code provisioning \u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"9aed3d3a_690c993b","line":52,"in_reply_to":"9aed3d3a_b9e10a9d","updated":"2016-02-29 05:24:09.000000000","message":"I agreed.","commit_id":"bfde49574e1e06dd09b5594c7b888c704b1cdafa"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b882f029298a678b8c4f69cc8ac9741e76e1c60e","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from cryptography.hazmat.backends import default_backend"},{"line_number":22,"context_line":"from cryptography.hazmat.primitives import hashes"},{"line_number":23,"context_line":"from cryptography.hazmat.primitives.twofactor.totp import TOTP"},{"line_number":24,"context_line":"import six"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"from openstackclient.common import command"}],"source_content_type":"text/x-python","patch_set":10,"id":"7af24918_3a23bfa8","line":23,"updated":"2016-03-03 15:37:51.000000000","message":"Importing class instead of module","commit_id":"781e522eef368eb9ada9047e0009a46adc64bd2b"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"421b0a86488e12bdae38e3cc44a9425a7b6a540c","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from cryptography.hazmat.backends import default_backend"},{"line_number":22,"context_line":"from cryptography.hazmat.primitives import hashes"},{"line_number":23,"context_line":"from cryptography.hazmat.primitives.twofactor.totp import TOTP"},{"line_number":24,"context_line":"import six"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"from openstackclient.common import command"}],"source_content_type":"text/x-python","patch_set":10,"id":"7af24918_2cdb7f1c","line":23,"in_reply_to":"7af24918_3a23bfa8","updated":"2016-03-03 18:22:05.000000000","message":"Done","commit_id":"781e522eef368eb9ada9047e0009a46adc64bd2b"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b882f029298a678b8c4f69cc8ac9741e76e1c60e","unresolved":false,"context_lines":[{"line_number":57,"context_line":"                 \u0027their mobile device via the QR barcode method.\u0027,"},{"line_number":58,"context_line":"        )"},{"line_number":59,"context_line":"        parser.add_argument("},{"line_number":60,"context_line":"            \u0027--no-base32\u0027,"},{"line_number":61,"context_line":"            action\u003d\u0027store_true\u0027,"},{"line_number":62,"context_line":"            help\u003d\u0027This option is applicable to \"totp\" credentials only. If \u0027"},{"line_number":63,"context_line":"                 \u0027specified, it indicates that the given credential is \u0027"}],"source_content_type":"text/x-python","patch_set":10,"id":"7af24918_9ad01321","line":60,"updated":"2016-03-03 15:37:51.000000000","message":"should this include totp in the name to make it more obvious? I like \u0027--totp-include-provisioning-url\u0027 and \u0027--totp-no-base32\u0027, but I don\u0027t care that much as long as they are consistent.","commit_id":"781e522eef368eb9ada9047e0009a46adc64bd2b"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"421b0a86488e12bdae38e3cc44a9425a7b6a540c","unresolved":false,"context_lines":[{"line_number":57,"context_line":"                 \u0027their mobile device via the QR barcode method.\u0027,"},{"line_number":58,"context_line":"        )"},{"line_number":59,"context_line":"        parser.add_argument("},{"line_number":60,"context_line":"            \u0027--no-base32\u0027,"},{"line_number":61,"context_line":"            action\u003d\u0027store_true\u0027,"},{"line_number":62,"context_line":"            help\u003d\u0027This option is applicable to \"totp\" credentials only. If \u0027"},{"line_number":63,"context_line":"                 \u0027specified, it indicates that the given credential is \u0027"}],"source_content_type":"text/x-python","patch_set":10,"id":"7af24918_af082129","line":60,"in_reply_to":"7af24918_9ad01321","updated":"2016-03-03 18:22:05.000000000","message":"sure, lets change it to --totp-no-base32","commit_id":"781e522eef368eb9ada9047e0009a46adc64bd2b"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b882f029298a678b8c4f69cc8ac9741e76e1c60e","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        )"},{"line_number":78,"context_line":"        return parser"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    # FIXME(gyee): this stuff probably needs to be in python-keystoneclient as"},{"line_number":81,"context_line":"    # they are being shared here and in Keystone totp auth plugin. Ideally, we"},{"line_number":82,"context_line":"    # should enhance Keystone V3 credential APIs to support provisioning."},{"line_number":83,"context_line":"    # Meaning, if blob is absent and depending on credential type, server"}],"source_content_type":"text/x-python","patch_set":10,"id":"7af24918_1ad2435c","line":80,"updated":"2016-03-03 15:37:51.000000000","message":"(nit :) This","commit_id":"781e522eef368eb9ada9047e0009a46adc64bd2b"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"421b0a86488e12bdae38e3cc44a9425a7b6a540c","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        )"},{"line_number":78,"context_line":"        return parser"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    # FIXME(gyee): this stuff probably needs to be in python-keystoneclient as"},{"line_number":81,"context_line":"    # they are being shared here and in Keystone totp auth plugin. Ideally, we"},{"line_number":82,"context_line":"    # should enhance Keystone V3 credential APIs to support provisioning."},{"line_number":83,"context_line":"    # Meaning, if blob is absent and depending on credential type, server"}],"source_content_type":"text/x-python","patch_set":10,"id":"7af24918_6f50d90b","line":80,"in_reply_to":"7af24918_1ad2435c","updated":"2016-03-03 18:22:05.000000000","message":"Done","commit_id":"781e522eef368eb9ada9047e0009a46adc64bd2b"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b882f029298a678b8c4f69cc8ac9741e76e1c60e","unresolved":false,"context_lines":[{"line_number":89,"context_line":"    # they need to abide by."},{"line_number":90,"context_line":"    def _generate_provisioning_uri(self, user_id, secret_key):"},{"line_number":91,"context_line":"        # NOTE(gyee): Google Authenticator uses 6 digits. And for TOTP, we use"},{"line_number":92,"context_line":"        # the standard 30 second time step."},{"line_number":93,"context_line":"        totp \u003d TOTP(secret_key.encode(\u0027utf-8\u0027), 6, hashes.SHA1(), 30,"},{"line_number":94,"context_line":"                    backend\u003ddefault_backend())"},{"line_number":95,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"7af24918_da8e1b78","line":92,"updated":"2016-03-03 15:37:51.000000000","message":"Really we need to say that these settings need to match what we have in keystone right?","commit_id":"781e522eef368eb9ada9047e0009a46adc64bd2b"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"421b0a86488e12bdae38e3cc44a9425a7b6a540c","unresolved":false,"context_lines":[{"line_number":89,"context_line":"    # they need to abide by."},{"line_number":90,"context_line":"    def _generate_provisioning_uri(self, user_id, secret_key):"},{"line_number":91,"context_line":"        # NOTE(gyee): Google Authenticator uses 6 digits. And for TOTP, we use"},{"line_number":92,"context_line":"        # the standard 30 second time step."},{"line_number":93,"context_line":"        totp \u003d TOTP(secret_key.encode(\u0027utf-8\u0027), 6, hashes.SHA1(), 30,"},{"line_number":94,"context_line":"                    backend\u003ddefault_backend())"},{"line_number":95,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"7af24918_ef6b49b5","line":92,"in_reply_to":"7af24918_da8e1b78","updated":"2016-03-03 18:22:05.000000000","message":"k, let me change that","commit_id":"781e522eef368eb9ada9047e0009a46adc64bd2b"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b882f029298a678b8c4f69cc8ac9741e76e1c60e","unresolved":false,"context_lines":[{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        credential._info.pop(\u0027links\u0027)"},{"line_number":146,"context_line":"        if provisioning_uri:"},{"line_number":147,"context_line":"            credential._info[\u0027provisioning_uri\u0027] \u003d provisioning_uri"},{"line_number":148,"context_line":"        return zip(*sorted(six.iteritems(credential._info)))"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"7af24918_556bfcf0","line":147,"updated":"2016-03-03 15:37:51.000000000","message":"Uh, oh. Accessing private attributes.","commit_id":"781e522eef368eb9ada9047e0009a46adc64bd2b"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"421b0a86488e12bdae38e3cc44a9425a7b6a540c","unresolved":false,"context_lines":[{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        credential._info.pop(\u0027links\u0027)"},{"line_number":146,"context_line":"        if provisioning_uri:"},{"line_number":147,"context_line":"            credential._info[\u0027provisioning_uri\u0027] \u003d provisioning_uri"},{"line_number":148,"context_line":"        return zip(*sorted(six.iteritems(credential._info)))"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"7af24918_2f6c119b","line":147,"in_reply_to":"7af24918_556bfcf0","updated":"2016-03-03 18:22:05.000000000","message":"we do that at the previous line too so I am not seeing any issue with it","commit_id":"781e522eef368eb9ada9047e0009a46adc64bd2b"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"0b38fd93f3e8e6ae490c5c4a1d08b4e41ee40cae","unresolved":false,"context_lines":[{"line_number":119,"context_line":"                # https://cryptography.io/en/latest"},{"line_number":120,"context_line":"                #"},{"line_number":121,"context_line":"                # TOTP credential/secret key must be at least 128-bits"},{"line_number":122,"context_line":"                msg \u003d (\u0027TOTP credentials must be at least 128-bit (16 bytes)\u0027)"},{"line_number":123,"context_line":"                raise exceptions.CommandError(msg)"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"            if parsed_args.include_totp_provisioning_uri:"}],"source_content_type":"text/x-python","patch_set":18,"id":"7aa08908_30b73986","line":122,"range":{"start_line":122,"start_character":22,"end_line":122,"end_character":78},"updated":"2016-06-14 20:02:12.000000000","message":"use _() to mark it for translation","commit_id":"3b39ee4016c509e4d6364ec68ffe41648ce903aa"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"1ebfb9b2dd9105b6fa6799264326b549e0b8bff6","unresolved":false,"context_lines":[{"line_number":119,"context_line":"                # https://cryptography.io/en/latest"},{"line_number":120,"context_line":"                #"},{"line_number":121,"context_line":"                # TOTP credential/secret key must be at least 128-bits"},{"line_number":122,"context_line":"                msg \u003d (\u0027TOTP credentials must be at least 128-bit (16 bytes)\u0027)"},{"line_number":123,"context_line":"                raise exceptions.CommandError(msg)"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"            if parsed_args.include_totp_provisioning_uri:"}],"source_content_type":"text/x-python","patch_set":18,"id":"7aa08908_6a850258","line":122,"range":{"start_line":122,"start_character":22,"end_line":122,"end_character":78},"in_reply_to":"7aa08908_30b73986","updated":"2016-06-16 06:01:20.000000000","message":"Done","commit_id":"3b39ee4016c509e4d6364ec68ffe41648ce903aa"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"0b38fd93f3e8e6ae490c5c4a1d08b4e41ee40cae","unresolved":false,"context_lines":[{"line_number":112,"context_line":""},{"line_number":113,"context_line":"        provisioning_uri \u003d None"},{"line_number":114,"context_line":"        blob \u003d parsed_args.data"},{"line_number":115,"context_line":"        if parsed_args.type.lower() \u003d\u003d \u0027totp\u0027:"},{"line_number":116,"context_line":"            if len(blob) \u003c 16:"},{"line_number":117,"context_line":"                # NOTE(gyee): according to"},{"line_number":118,"context_line":"                #"},{"line_number":119,"context_line":"                # https://cryptography.io/en/latest"},{"line_number":120,"context_line":"                #"},{"line_number":121,"context_line":"                # TOTP credential/secret key must be at least 128-bits"},{"line_number":122,"context_line":"                msg \u003d (\u0027TOTP credentials must be at least 128-bit (16 bytes)\u0027)"},{"line_number":123,"context_line":"                raise exceptions.CommandError(msg)"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"            if parsed_args.include_totp_provisioning_uri:"},{"line_number":126,"context_line":"                provisioning_uri \u003d self._generate_provisioning_uri("},{"line_number":127,"context_line":"                    user_id, parsed_args.data)"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"            if parsed_args.totp_no_base32:"},{"line_number":130,"context_line":"                # check to make sure it is properly encoded"},{"line_number":131,"context_line":"                try:"},{"line_number":132,"context_line":"                    base64.b32decode(blob.encode(\u0027utf-8\u0027))"},{"line_number":133,"context_line":"                except (TypeError, binascii.Error) as e:"},{"line_number":134,"context_line":"                    msg \u003d (\u0027TOTP credential is not base32-encoded: %s\u0027 % (e))"},{"line_number":135,"context_line":"                    raise exceptions.CommandError(msg)"},{"line_number":136,"context_line":"            else:"},{"line_number":137,"context_line":"                # NOTE(gyee): these are coming from user command-line input so"},{"line_number":138,"context_line":"                # they can be encoded as UTF-8"},{"line_number":139,"context_line":"                blob \u003d base64.b32encode(blob.encode(\u0027utf-8\u0027))"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"        credential \u003d identity_client.credentials.create("},{"line_number":142,"context_line":"            user\u003duser_id,"}],"source_content_type":"text/x-python","patch_set":18,"id":"7aa08908_b08cc9d7","line":139,"range":{"start_line":115,"start_character":8,"end_line":139,"end_character":61},"updated":"2016-06-14 20:02:12.000000000","message":"make this a private function _validate_totp() or something","commit_id":"3b39ee4016c509e4d6364ec68ffe41648ce903aa"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"1ebfb9b2dd9105b6fa6799264326b549e0b8bff6","unresolved":false,"context_lines":[{"line_number":112,"context_line":""},{"line_number":113,"context_line":"        provisioning_uri \u003d None"},{"line_number":114,"context_line":"        blob \u003d parsed_args.data"},{"line_number":115,"context_line":"        if parsed_args.type.lower() \u003d\u003d \u0027totp\u0027:"},{"line_number":116,"context_line":"            if len(blob) \u003c 16:"},{"line_number":117,"context_line":"                # NOTE(gyee): according to"},{"line_number":118,"context_line":"                #"},{"line_number":119,"context_line":"                # https://cryptography.io/en/latest"},{"line_number":120,"context_line":"                #"},{"line_number":121,"context_line":"                # TOTP credential/secret key must be at least 128-bits"},{"line_number":122,"context_line":"                msg \u003d (\u0027TOTP credentials must be at least 128-bit (16 bytes)\u0027)"},{"line_number":123,"context_line":"                raise exceptions.CommandError(msg)"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"            if parsed_args.include_totp_provisioning_uri:"},{"line_number":126,"context_line":"                provisioning_uri \u003d self._generate_provisioning_uri("},{"line_number":127,"context_line":"                    user_id, parsed_args.data)"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"            if parsed_args.totp_no_base32:"},{"line_number":130,"context_line":"                # check to make sure it is properly encoded"},{"line_number":131,"context_line":"                try:"},{"line_number":132,"context_line":"                    base64.b32decode(blob.encode(\u0027utf-8\u0027))"},{"line_number":133,"context_line":"                except (TypeError, binascii.Error) as e:"},{"line_number":134,"context_line":"                    msg \u003d (\u0027TOTP credential is not base32-encoded: %s\u0027 % (e))"},{"line_number":135,"context_line":"                    raise exceptions.CommandError(msg)"},{"line_number":136,"context_line":"            else:"},{"line_number":137,"context_line":"                # NOTE(gyee): these are coming from user command-line input so"},{"line_number":138,"context_line":"                # they can be encoded as UTF-8"},{"line_number":139,"context_line":"                blob \u003d base64.b32encode(blob.encode(\u0027utf-8\u0027))"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"        credential \u003d identity_client.credentials.create("},{"line_number":142,"context_line":"            user\u003duser_id,"}],"source_content_type":"text/x-python","patch_set":18,"id":"7aa08908_0a71de77","line":139,"range":{"start_line":115,"start_character":8,"end_line":139,"end_character":61},"in_reply_to":"7aa08908_b08cc9d7","updated":"2016-06-16 06:01:20.000000000","message":"Done","commit_id":"3b39ee4016c509e4d6364ec68ffe41648ce903aa"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"ae7a8d76bd03481f3da21ffd1e0d6075a6dbbdb3","unresolved":false,"context_lines":[{"line_number":18,"context_line":"import base64"},{"line_number":19,"context_line":"import binascii"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from cryptography.hazmat.backends import default_backend"},{"line_number":22,"context_line":"from cryptography.hazmat.primitives import hashes"},{"line_number":23,"context_line":"from cryptography.hazmat.primitives.twofactor import totp"},{"line_number":24,"context_line":"from osc_lib.command import command"}],"source_content_type":"text/x-python","patch_set":19,"id":"7aa08908_57dc1b46","line":21,"range":{"start_line":21,"start_character":5,"end_line":21,"end_character":17},"updated":"2016-07-07 20:34:22.000000000","message":"this should need to be added to requirements.txt","commit_id":"07180ea7e17fe2418fd4f2958cb9a364b09db8a4"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"02bbfdeb6c8e541f11d7f8de8bc2dda3f2cb1b4e","unresolved":false,"context_lines":[{"line_number":18,"context_line":"import base64"},{"line_number":19,"context_line":"import binascii"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from cryptography.hazmat.backends import default_backend"},{"line_number":22,"context_line":"from cryptography.hazmat.primitives import hashes"},{"line_number":23,"context_line":"from cryptography.hazmat.primitives.twofactor import totp"},{"line_number":24,"context_line":"from osc_lib.command import command"}],"source_content_type":"text/x-python","patch_set":19,"id":"1aa78d24_ae993c7b","line":21,"range":{"start_line":21,"start_character":5,"end_line":21,"end_character":17},"in_reply_to":"7aa08908_57dc1b46","updated":"2016-07-12 16:18:07.000000000","message":"cryptography is in requirements.txt","commit_id":"07180ea7e17fe2418fd4f2958cb9a364b09db8a4"},{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"f0c233395462422a87fd2d22d021476e2d37500c","unresolved":false,"context_lines":[{"line_number":44,"context_line":"            default\u003d\"cert\","},{"line_number":45,"context_line":"            metavar\u003d\u0027\u003ctype\u003e\u0027,"},{"line_number":46,"context_line":"            choices\u003d[\u0027ec2\u0027, \u0027cert\u0027, \u0027totp\u0027],"},{"line_number":47,"context_line":"            help\u003d\u0027New credential type\u0027,"},{"line_number":48,"context_line":"        )"},{"line_number":49,"context_line":"        # FIXME(gyee): these options are specific to totp credentials only."},{"line_number":50,"context_line":"        # If needed, we may need to create a new set of commands for totp"}],"source_content_type":"text/x-python","patch_set":19,"id":"3aaa91ec_0f958ce3","line":47,"range":{"start_line":47,"start_character":12,"end_line":47,"end_character":39},"updated":"2016-07-12 07:53:08.000000000","message":"nits, these help message also need to be translated, also apply to other occurrences.","commit_id":"07180ea7e17fe2418fd4f2958cb9a364b09db8a4"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"02bbfdeb6c8e541f11d7f8de8bc2dda3f2cb1b4e","unresolved":false,"context_lines":[{"line_number":44,"context_line":"            default\u003d\"cert\","},{"line_number":45,"context_line":"            metavar\u003d\u0027\u003ctype\u003e\u0027,"},{"line_number":46,"context_line":"            choices\u003d[\u0027ec2\u0027, \u0027cert\u0027, \u0027totp\u0027],"},{"line_number":47,"context_line":"            help\u003d\u0027New credential type\u0027,"},{"line_number":48,"context_line":"        )"},{"line_number":49,"context_line":"        # FIXME(gyee): these options are specific to totp credentials only."},{"line_number":50,"context_line":"        # If needed, we may need to create a new set of commands for totp"}],"source_content_type":"text/x-python","patch_set":19,"id":"1aa78d24_4ead3883","line":47,"range":{"start_line":47,"start_character":12,"end_line":47,"end_character":39},"in_reply_to":"3aaa91ec_0f958ce3","updated":"2016-07-12 16:18:07.000000000","message":"Done","commit_id":"07180ea7e17fe2418fd4f2958cb9a364b09db8a4"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"ae7a8d76bd03481f3da21ffd1e0d6075a6dbbdb3","unresolved":false,"context_lines":[{"line_number":227,"context_line":"        # within its lifecycle. It will either be re-provisionied (i.e. delete"},{"line_number":228,"context_line":"        # and create) or removed."},{"line_number":229,"context_line":"        if parsed_args.type.lower() \u003d\u003d \u0027totp\u0027:"},{"line_number":230,"context_line":"            msg \u003d (\u0027Setting a totp credential is not supported.\u0027)"},{"line_number":231,"context_line":"            raise exceptions.CommandError(msg)"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"        identity_client \u003d self.app.client_manager.identity"}],"source_content_type":"text/x-python","patch_set":19,"id":"1aa78d24_814a1353","line":230,"range":{"start_line":230,"start_character":18,"end_line":230,"end_character":65},"updated":"2016-07-07 20:34:22.000000000","message":"use _() for translation\n\nalso, TOTP","commit_id":"07180ea7e17fe2418fd4f2958cb9a364b09db8a4"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"02bbfdeb6c8e541f11d7f8de8bc2dda3f2cb1b4e","unresolved":false,"context_lines":[{"line_number":227,"context_line":"        # within its lifecycle. It will either be re-provisionied (i.e. delete"},{"line_number":228,"context_line":"        # and create) or removed."},{"line_number":229,"context_line":"        if parsed_args.type.lower() \u003d\u003d \u0027totp\u0027:"},{"line_number":230,"context_line":"            msg \u003d (\u0027Setting a totp credential is not supported.\u0027)"},{"line_number":231,"context_line":"            raise exceptions.CommandError(msg)"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"        identity_client \u003d self.app.client_manager.identity"}],"source_content_type":"text/x-python","patch_set":19,"id":"1aa78d24_ee098496","line":230,"range":{"start_line":230,"start_character":18,"end_line":230,"end_character":65},"in_reply_to":"1aa78d24_814a1353","updated":"2016-07-12 16:18:07.000000000","message":"Done","commit_id":"07180ea7e17fe2418fd4f2958cb9a364b09db8a4"}],"openstackclient/tests/identity/v3/test_credential.py":[{"author":{"_account_id":11434,"name":"werner mendizabal","email":"nonameentername@gmail.com","username":"nonameentername"},"change_message_id":"3e407c4fb70bfb1464354be70ccff9266aede7b9","unresolved":false,"context_lines":[{"line_number":70,"context_line":"        )"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def test_created_with_google_authenticator_url(self):"},{"line_number":73,"context_line":"        arglist \u003d ["},{"line_number":74,"context_line":"            \u0027--type\u0027, \u0027totp\u0027,"},{"line_number":75,"context_line":"            \u0027--include-google-authenticator-provisioning-url\u0027,"},{"line_number":76,"context_line":"            identity_fakes.user_name,"}],"source_content_type":"text/x-python","patch_set":2,"id":"dae33548_4c2d7045","line":73,"updated":"2016-02-16 21:53:11.000000000","message":"How can this be called from the openstack command line tool?","commit_id":"e6b50c26708aaf830e914253eb891a48ac242c4a"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"27dbf61cd5bac0c44f817f7597baccf0c14f6f1b","unresolved":false,"context_lines":[{"line_number":70,"context_line":"        )"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def test_created_with_google_authenticator_url(self):"},{"line_number":73,"context_line":"        arglist \u003d ["},{"line_number":74,"context_line":"            \u0027--type\u0027, \u0027totp\u0027,"},{"line_number":75,"context_line":"            \u0027--include-google-authenticator-provisioning-url\u0027,"},{"line_number":76,"context_line":"            identity_fakes.user_name,"}],"source_content_type":"text/x-python","patch_set":2,"id":"dae33548_96d94386","line":73,"in_reply_to":"dae33548_4c2d7045","updated":"2016-02-17 00:29:02.000000000","message":"openstack --os-auth-url http://localhost:35357/v3 --os-username admin --os-password somepassword --os-user-domain-id default --os-project-name admin --os-project-domain-id default --os-identity-api-version 3 credential create --type totp --include-google-authenticator-provisioning-url \u003cuser_id or name\u003e \u003ctotp secret\u003e","commit_id":"e6b50c26708aaf830e914253eb891a48ac242c4a"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b3a53b5901455d794459a778ee63baaa0d6972ef","unresolved":false,"context_lines":[{"line_number":52,"context_line":""},{"line_number":53,"context_line":"class TestCreateTOTPCredential(TestCredential):"},{"line_number":54,"context_line":"    data \u003d \u00270123456789123456\u0027"},{"line_number":55,"context_line":"    b32_data \u003d base64.b32encode(data.encode(\u0027utf-8\u0027))"},{"line_number":56,"context_line":"    expected_google_authenticator_url \u003d ("},{"line_number":57,"context_line":"        \u0027https://www.google.com/chart?chs\u003d200x200\u0026chld\u003dM|0\u0026cht\u003dqr\u0026chl\u003d\u0027 +"},{"line_number":58,"context_line":"        \u0027otpauth%3A//totp/Keystone%3A\u0027 + identity_fakes.user_id +"}],"source_content_type":"text/x-python","patch_set":5,"id":"bae84128_3a15679b","line":55,"updated":"2016-02-24 03:54:44.000000000","message":"No need to encode this","commit_id":"cd14b884313c954bd4b9aa626e6903e117d4ea05"}],"releasenotes/notes/support-totp-credentials-6e92b7fa5f3b8fdc.yaml":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b3a53b5901455d794459a778ee63baaa0d6972ef","unresolved":false,"context_lines":[{"line_number":10,"context_line":""},{"line_number":11,"context_line":"    - ``--include-google-authenticator-provisioning-url``: This option is"},{"line_number":12,"context_line":"       applicable to ``totp`` credentials only. If specified, the Google"},{"line_number":13,"context_line":"       Authenticator QR code provisioning URL will be returned. User can"},{"line_number":14,"context_line":"       use this URL to provision the TOTP credential in their mobile device"},{"line_number":15,"context_line":"       using the barcode scan method."},{"line_number":16,"context_line":"    - ``--no-base32``: This option is applicable to ``totp`` credentials only."}],"source_content_type":"text/x-yaml","patch_set":5,"id":"bae84128_3af1e76b","line":13,"updated":"2016-02-24 03:54:44.000000000","message":"Users","commit_id":"cd14b884313c954bd4b9aa626e6903e117d4ea05"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b3a53b5901455d794459a778ee63baaa0d6972ef","unresolved":false,"context_lines":[{"line_number":15,"context_line":"       using the barcode scan method."},{"line_number":16,"context_line":"    - ``--no-base32``: This option is applicable to ``totp`` credentials only."},{"line_number":17,"context_line":"      If specified, it indicates that the given credential is already"},{"line_number":18,"context_line":"      base32-encoded. TOTP credential are just arbitrary bytes, and therefore,"},{"line_number":19,"context_line":"      must be managed and displayed in base32-encoded format."},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    For example:"}],"source_content_type":"text/x-yaml","patch_set":5,"id":"bae84128_1a66a350","line":18,"updated":"2016-02-24 03:54:44.000000000","message":"credentials","commit_id":"cd14b884313c954bd4b9aa626e6903e117d4ea05"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b3a53b5901455d794459a778ee63baaa0d6972ef","unresolved":false,"context_lines":[{"line_number":23,"context_line":"    ::"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"        openstack --os-auth-url http://localhost:35357/v3 --os-username admin"},{"line_number":26,"context_line":"        --os-password secrete --os-user-domain-id default"},{"line_number":27,"context_line":"        --os-project-name admin --os-project-domain-id default"},{"line_number":28,"context_line":"        --os-identity-api-version 3 credential create --type totp"},{"line_number":29,"context_line":"        --include-google-authenticator-provisioning-url"}],"source_content_type":"text/x-yaml","patch_set":5,"id":"bae84128_9a52b365","line":26,"updated":"2016-02-24 03:54:44.000000000","message":"Should we use extra indentation or end lines with \\ to show this as a single command?","commit_id":"cd14b884313c954bd4b9aa626e6903e117d4ea05"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b3a53b5901455d794459a778ee63baaa0d6972ef","unresolved":false,"context_lines":[{"line_number":30,"context_line":"        demo test_credential_blah_blah"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"        openstack --os-auth-url http://localhost:35357/v3 --os-username admin"},{"line_number":33,"context_line":"        --os-password secrete --os-user-domain-id default"},{"line_number":34,"context_line":"        --os-project-name admin --os-project-domain-id default"},{"line_number":35,"context_line":"        --os-identity-api-version 3 credential create --type totp"},{"line_number":36,"context_line":"        --include-google-authenticator-provisioning-url --no-base32"}],"source_content_type":"text/x-yaml","patch_set":5,"id":"bae84128_3aca871b","line":33,"updated":"2016-02-24 03:54:44.000000000","message":"same...","commit_id":"cd14b884313c954bd4b9aa626e6903e117d4ea05"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"0b38fd93f3e8e6ae490c5c4a1d08b4e41ee40cae","unresolved":false,"context_lines":[{"line_number":4,"context_line":"    Add support for Time-Based One-Time Password (TOTP) credential"},{"line_number":5,"context_line":"    provisioning. This is done via Keystone V3 ``credential create`` command,"},{"line_number":6,"context_line":"    by specifying ``totp`` as credential type (i.e. ``--type totp``)."},{"line_number":7,"context_line":"    Notice that TOTP credentials must be at least 148-bit, or 16 bytes."},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"    Two additional options are support:"},{"line_number":10,"context_line":""}],"source_content_type":"text/x-yaml","patch_set":18,"id":"7aa08908_50100559","line":7,"range":{"start_line":7,"start_character":50,"end_line":7,"end_character":53},"updated":"2016-06-14 20:02:12.000000000","message":"128 or 148?","commit_id":"3b39ee4016c509e4d6364ec68ffe41648ce903aa"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"1ebfb9b2dd9105b6fa6799264326b549e0b8bff6","unresolved":false,"context_lines":[{"line_number":4,"context_line":"    Add support for Time-Based One-Time Password (TOTP) credential"},{"line_number":5,"context_line":"    provisioning. This is done via Keystone V3 ``credential create`` command,"},{"line_number":6,"context_line":"    by specifying ``totp`` as credential type (i.e. ``--type totp``)."},{"line_number":7,"context_line":"    Notice that TOTP credentials must be at least 148-bit, or 16 bytes."},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"    Two additional options are support:"},{"line_number":10,"context_line":""}],"source_content_type":"text/x-yaml","patch_set":18,"id":"7aa08908_2a477a4c","line":7,"range":{"start_line":7,"start_character":50,"end_line":7,"end_character":53},"in_reply_to":"7aa08908_50100559","updated":"2016-06-16 06:01:20.000000000","message":"good catch! its 128-bit","commit_id":"3b39ee4016c509e4d6364ec68ffe41648ce903aa"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"0b38fd93f3e8e6ae490c5c4a1d08b4e41ee40cae","unresolved":false,"context_lines":[{"line_number":11,"context_line":"    - ``--include-totp-provisioning-url``: This option is applicable to"},{"line_number":12,"context_line":"      ``totp`` credentials only. If specified, the TOTP provisioning URI will"},{"line_number":13,"context_line":"      be returned. Users may use this URI to provision the TOTP credential in"},{"line_number":14,"context_line":"      their mobile device via the QR barcode method. "},{"line_number":15,"context_line":"    - ``--totp-no-base32``: This option is applicable to ``totp`` credentials"},{"line_number":16,"context_line":"      only. If specified, it indicates that the given credential is already"},{"line_number":17,"context_line":"      base32-encoded. TOTP credentialis are arbitrary bytes, and therefore,"}],"source_content_type":"text/x-yaml","patch_set":18,"id":"7aa08908_b07a09b8","line":14,"range":{"start_line":14,"start_character":52,"end_line":14,"end_character":53},"updated":"2016-06-14 20:02:12.000000000","message":"white space","commit_id":"3b39ee4016c509e4d6364ec68ffe41648ce903aa"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"1ebfb9b2dd9105b6fa6799264326b549e0b8bff6","unresolved":false,"context_lines":[{"line_number":11,"context_line":"    - ``--include-totp-provisioning-url``: This option is applicable to"},{"line_number":12,"context_line":"      ``totp`` credentials only. If specified, the TOTP provisioning URI will"},{"line_number":13,"context_line":"      be returned. Users may use this URI to provision the TOTP credential in"},{"line_number":14,"context_line":"      their mobile device via the QR barcode method. "},{"line_number":15,"context_line":"    - ``--totp-no-base32``: This option is applicable to ``totp`` credentials"},{"line_number":16,"context_line":"      only. If specified, it indicates that the given credential is already"},{"line_number":17,"context_line":"      base32-encoded. TOTP credentialis are arbitrary bytes, and therefore,"}],"source_content_type":"text/x-yaml","patch_set":18,"id":"7aa08908_8a72eeae","line":14,"range":{"start_line":14,"start_character":52,"end_line":14,"end_character":53},"in_reply_to":"7aa08908_b07a09b8","updated":"2016-06-16 06:01:20.000000000","message":"Done","commit_id":"3b39ee4016c509e4d6364ec68ffe41648ce903aa"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"0b38fd93f3e8e6ae490c5c4a1d08b4e41ee40cae","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"    ::"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"        openstack --os-auth-url http://localhost:35357/v3 --os-username admin \\"},{"line_number":25,"context_line":"        --os-password secrete --os-user-domain-id default \\"},{"line_number":26,"context_line":"        --os-project-name admin --os-project-domain-id default \\"},{"line_number":27,"context_line":"        --os-identity-api-version 3 credential create --type totp \\"},{"line_number":28,"context_line":"        --include-totp-provisioning-uri demo test_credential_blah_blah"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"        openstack --os-auth-url http://localhost:35357/v3 --os-username admin \\"}],"source_content_type":"text/x-yaml","patch_set":18,"id":"7aa08908_10331d15","line":27,"range":{"start_line":24,"start_character":18,"end_line":27,"end_character":35},"updated":"2016-06-14 20:02:12.000000000","message":"you can get rid of these","commit_id":"3b39ee4016c509e4d6364ec68ffe41648ce903aa"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"1ebfb9b2dd9105b6fa6799264326b549e0b8bff6","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"    ::"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"        openstack --os-auth-url http://localhost:35357/v3 --os-username admin \\"},{"line_number":25,"context_line":"        --os-password secrete --os-user-domain-id default \\"},{"line_number":26,"context_line":"        --os-project-name admin --os-project-domain-id default \\"},{"line_number":27,"context_line":"        --os-identity-api-version 3 credential create --type totp \\"},{"line_number":28,"context_line":"        --include-totp-provisioning-uri demo test_credential_blah_blah"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"        openstack --os-auth-url http://localhost:35357/v3 --os-username admin \\"}],"source_content_type":"text/x-yaml","patch_set":18,"id":"7aa08908_6a77c29f","line":27,"range":{"start_line":24,"start_character":18,"end_line":27,"end_character":35},"in_reply_to":"7aa08908_10331d15","updated":"2016-06-16 06:01:20.000000000","message":"Done","commit_id":"3b39ee4016c509e4d6364ec68ffe41648ce903aa"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"0b38fd93f3e8e6ae490c5c4a1d08b4e41ee40cae","unresolved":false,"context_lines":[{"line_number":27,"context_line":"        --os-identity-api-version 3 credential create --type totp \\"},{"line_number":28,"context_line":"        --include-totp-provisioning-uri demo test_credential_blah_blah"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"        openstack --os-auth-url http://localhost:35357/v3 --os-username admin \\"},{"line_number":31,"context_line":"        --os-password secrete --os-user-domain-id default \\"},{"line_number":32,"context_line":"        --os-project-name admin --os-project-domain-id default \\"},{"line_number":33,"context_line":"        --os-identity-api-version 3 credential create --type totp \\"},{"line_number":34,"context_line":"        --include-totp-provisioning-uri --totp-no-base32 \\"},{"line_number":35,"context_line":"        demo ORSXG5C7MNZGKZDFNZ2GSYLML5RGYYLIL5RGYYLI"}],"source_content_type":"text/x-yaml","patch_set":18,"id":"7aa08908_90270dc9","line":33,"range":{"start_line":30,"start_character":18,"end_line":33,"end_character":35},"updated":"2016-06-14 20:02:12.000000000","message":"same","commit_id":"3b39ee4016c509e4d6364ec68ffe41648ce903aa"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"1ebfb9b2dd9105b6fa6799264326b549e0b8bff6","unresolved":false,"context_lines":[{"line_number":27,"context_line":"        --os-identity-api-version 3 credential create --type totp \\"},{"line_number":28,"context_line":"        --include-totp-provisioning-uri demo test_credential_blah_blah"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"        openstack --os-auth-url http://localhost:35357/v3 --os-username admin \\"},{"line_number":31,"context_line":"        --os-password secrete --os-user-domain-id default \\"},{"line_number":32,"context_line":"        --os-project-name admin --os-project-domain-id default \\"},{"line_number":33,"context_line":"        --os-identity-api-version 3 credential create --type totp \\"},{"line_number":34,"context_line":"        --include-totp-provisioning-uri --totp-no-base32 \\"},{"line_number":35,"context_line":"        demo ORSXG5C7MNZGKZDFNZ2GSYLML5RGYYLIL5RGYYLI"}],"source_content_type":"text/x-yaml","patch_set":18,"id":"7aa08908_ca6cf6d2","line":33,"range":{"start_line":30,"start_character":18,"end_line":33,"end_character":35},"in_reply_to":"7aa08908_90270dc9","updated":"2016-06-16 06:01:20.000000000","message":"Done","commit_id":"3b39ee4016c509e4d6364ec68ffe41648ce903aa"}]}
