)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"1667b502f252f611ba5ef393caf18a77c2c86f74","unresolved":false,"context_lines":[{"line_number":5,"context_line":"CommitDate: 2019-08-09 08:45:49 +1200"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"add support for auth_receipts and multi-method auth"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Change-Id: Ie6601a50011118e3a07be9752f747c2298ff5230"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"7faddb67_b3c62d49","line":8,"updated":"2019-08-09 18:53:56.000000000","message":"more words please","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"e15e47077c465de12f8e3449ab82aa82c3ef17c3","unresolved":false,"context_lines":[{"line_number":5,"context_line":"CommitDate: 2019-08-09 08:45:49 +1200"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"add support for auth_receipts and multi-method auth"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Change-Id: Ie6601a50011118e3a07be9752f747c2298ff5230"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"7faddb67_eeb83ae6","line":8,"in_reply_to":"7faddb67_b3c62d49","updated":"2019-08-09 20:13:03.000000000","message":"Needs RFE for bug tracking as well.","commit_id":"41ebe17e46a11efe54983357df9399185a473589"}],"doc/source/authentication-plugins.rst":[{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"1667b502f252f611ba5ef393caf18a77c2c86f74","unresolved":false,"context_lines":[{"line_number":155,"context_line":"    sess \u003d session.Session(auth\u003dauth)"},{"line_number":156,"context_line":"    try:"},{"line_number":157,"context_line":"       sess.get_token()"},{"line_number":158,"context_line":"    except exceptions.MissingAuthRules as e:"},{"line_number":159,"context_line":"        receipt \u003d e.receipt"},{"line_number":160,"context_line":"        methods \u003d e.methods"},{"line_number":161,"context_line":"        required_methods \u003d e.required_auth_methods"}],"source_content_type":"text/x-rst","patch_set":10,"id":"7faddb67_d843c86b","line":158,"range":{"start_line":158,"start_character":22,"end_line":158,"end_character":38},"updated":"2019-08-09 18:53:56.000000000","message":"MissingAuthMethods","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"8821c8c0515454cabcea0790f26e444b7b20c92d","unresolved":false,"context_lines":[{"line_number":155,"context_line":"    sess \u003d session.Session(auth\u003dauth)"},{"line_number":156,"context_line":"    try:"},{"line_number":157,"context_line":"       sess.get_token()"},{"line_number":158,"context_line":"    except exceptions.MissingAuthRules as e:"},{"line_number":159,"context_line":"        receipt \u003d e.receipt"},{"line_number":160,"context_line":"        methods \u003d e.methods"},{"line_number":161,"context_line":"        required_methods \u003d e.required_auth_methods"}],"source_content_type":"text/x-rst","patch_set":10,"id":"7faddb67_7d239ba8","line":158,"range":{"start_line":158,"start_character":22,"end_line":158,"end_character":38},"in_reply_to":"7faddb67_d843c86b","updated":"2019-08-11 05:29:53.000000000","message":"Dammit, didn\u0027t search and replace the docs.\n\nDone.","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"1667b502f252f611ba5ef393caf18a77c2c86f74","unresolved":false,"context_lines":[{"line_number":189,"context_line":"    auth.add_method(v3.ReceiptMethod(receipt\u003dreceipt))"},{"line_number":190,"context_line":"    sess \u003d session.Session(auth\u003dauth)"},{"line_number":191,"context_line":"    sess.get_token()"},{"line_number":192,"context_line":""},{"line_number":193,"context_line":"Federation"},{"line_number":194,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":195,"context_line":""}],"source_content_type":"text/x-rst","patch_set":10,"id":"7faddb67_936771eb","line":192,"updated":"2019-08-09 18:53:56.000000000","message":"V3MultiFactor isn\u0027t documented here?","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"e15e47077c465de12f8e3449ab82aa82c3ef17c3","unresolved":false,"context_lines":[{"line_number":189,"context_line":"    auth.add_method(v3.ReceiptMethod(receipt\u003dreceipt))"},{"line_number":190,"context_line":"    sess \u003d session.Session(auth\u003dauth)"},{"line_number":191,"context_line":"    sess.get_token()"},{"line_number":192,"context_line":""},{"line_number":193,"context_line":"Federation"},{"line_number":194,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":195,"context_line":""}],"source_content_type":"text/x-rst","patch_set":10,"id":"7faddb67_4ec70e66","line":192,"in_reply_to":"7faddb67_936771eb","updated":"2019-08-09 20:13:03.000000000","message":"V3MultiFactor could also be a separate patch (Easier to review). it def. needs documentation.","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"074f72fe12ebb4d4c4dc71c7f5b27bf86956e2f3","unresolved":false,"context_lines":[{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    auth \u003d v3.Auth("},{"line_number":125,"context_line":"        auth_url\u003d\u0027http://my.keystone.com:5000/v3\u0027,"},{"line_number":126,"context_line":"        methods\u003d["},{"line_number":127,"context_line":"            v3.PasswordMethod("},{"line_number":128,"context_line":"                username\u003d\u0027user\u0027,"},{"line_number":129,"context_line":"                password\u003d\u0027password\u0027,"}],"source_content_type":"text/x-rst","patch_set":11,"id":"7faddb67_f96a2a19","line":126,"range":{"start_line":126,"start_character":8,"end_line":126,"end_character":15},"updated":"2019-08-12 21:40:24.000000000","message":"This is auth_methods","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"839105fabab74f4d8460da236dfcd1e66cfd4b19","unresolved":false,"context_lines":[{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    auth \u003d v3.Auth("},{"line_number":125,"context_line":"        auth_url\u003d\u0027http://my.keystone.com:5000/v3\u0027,"},{"line_number":126,"context_line":"        methods\u003d["},{"line_number":127,"context_line":"            v3.PasswordMethod("},{"line_number":128,"context_line":"                username\u003d\u0027user\u0027,"},{"line_number":129,"context_line":"                password\u003d\u0027password\u0027,"}],"source_content_type":"text/x-rst","patch_set":11,"id":"7faddb67_b275a734","line":126,"range":{"start_line":126,"start_character":8,"end_line":126,"end_character":15},"in_reply_to":"7faddb67_f96a2a19","updated":"2019-08-13 02:37:31.000000000","message":"Done","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"074f72fe12ebb4d4c4dc71c7f5b27bf86956e2f3","unresolved":false,"context_lines":[{"line_number":151,"context_line":"                       username\u003d\u0027username\u0027,"},{"line_number":152,"context_line":"                       password\u003d\u0027password\u0027,"},{"line_number":153,"context_line":"                       project_id\u003d\u0027projectid\u0027,"},{"line_number":154,"context_line":"                       user_domain_name\u003d\u0027default\u0027)"},{"line_number":155,"context_line":"    sess \u003d session.Session(auth\u003dauth)"},{"line_number":156,"context_line":"    try:"},{"line_number":157,"context_line":"       sess.get_token()"}],"source_content_type":"text/x-rst","patch_set":11,"id":"7faddb67_59eb3e77","line":154,"range":{"start_line":154,"start_character":23,"end_line":154,"end_character":39},"updated":"2019-08-12 21:40:24.000000000","message":"user_domain_id","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"839105fabab74f4d8460da236dfcd1e66cfd4b19","unresolved":false,"context_lines":[{"line_number":151,"context_line":"                       username\u003d\u0027username\u0027,"},{"line_number":152,"context_line":"                       password\u003d\u0027password\u0027,"},{"line_number":153,"context_line":"                       project_id\u003d\u0027projectid\u0027,"},{"line_number":154,"context_line":"                       user_domain_name\u003d\u0027default\u0027)"},{"line_number":155,"context_line":"    sess \u003d session.Session(auth\u003dauth)"},{"line_number":156,"context_line":"    try:"},{"line_number":157,"context_line":"       sess.get_token()"}],"source_content_type":"text/x-rst","patch_set":11,"id":"7faddb67_d2706343","line":154,"range":{"start_line":154,"start_character":23,"end_line":154,"end_character":39},"in_reply_to":"7faddb67_59eb3e77","updated":"2019-08-13 02:37:31.000000000","message":"Done","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"074f72fe12ebb4d4c4dc71c7f5b27bf86956e2f3","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        v3.TOTPMethod("},{"line_number":170,"context_line":"            username\u003d\u0027user\u0027,"},{"line_number":171,"context_line":"            passcode\u003d\u0027123456\u0027,"},{"line_number":172,"context_line":"            user_domain_id\u003d\"default\","},{"line_number":173,"context_line":"        )"},{"line_number":174,"context_line":"    )"},{"line_number":175,"context_line":"    sess.get_token()"}],"source_content_type":"text/x-rst","patch_set":11,"id":"7faddb67_1982a6a6","line":172,"range":{"start_line":172,"start_character":27,"end_line":172,"end_character":28},"updated":"2019-08-12 21:40:24.000000000","message":"(nit) inconsistent quoting style","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"839105fabab74f4d8460da236dfcd1e66cfd4b19","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        v3.TOTPMethod("},{"line_number":170,"context_line":"            username\u003d\u0027user\u0027,"},{"line_number":171,"context_line":"            passcode\u003d\u0027123456\u0027,"},{"line_number":172,"context_line":"            user_domain_id\u003d\"default\","},{"line_number":173,"context_line":"        )"},{"line_number":174,"context_line":"    )"},{"line_number":175,"context_line":"    sess.get_token()"}],"source_content_type":"text/x-rst","patch_set":11,"id":"7faddb67_728def28","line":172,"range":{"start_line":172,"start_character":27,"end_line":172,"end_character":28},"in_reply_to":"7faddb67_1982a6a6","updated":"2019-08-13 02:37:31.000000000","message":"Done","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"074f72fe12ebb4d4c4dc71c7f5b27bf86956e2f3","unresolved":false,"context_lines":[{"line_number":189,"context_line":"    auth.add_method(v3.ReceiptMethod(receipt\u003dreceipt))"},{"line_number":190,"context_line":"    sess \u003d session.Session(auth\u003dauth)"},{"line_number":191,"context_line":"    sess.get_token()"},{"line_number":192,"context_line":""},{"line_number":193,"context_line":"Federation"},{"line_number":194,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":195,"context_line":""}],"source_content_type":"text/x-rst","patch_set":11,"id":"7faddb67_bc48205c","line":192,"updated":"2019-08-12 21:40:24.000000000","message":"Still no example of V3MultiFactor, are you planning on adding it here?","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"839105fabab74f4d8460da236dfcd1e66cfd4b19","unresolved":false,"context_lines":[{"line_number":189,"context_line":"    auth.add_method(v3.ReceiptMethod(receipt\u003dreceipt))"},{"line_number":190,"context_line":"    sess \u003d session.Session(auth\u003dauth)"},{"line_number":191,"context_line":"    sess.get_token()"},{"line_number":192,"context_line":""},{"line_number":193,"context_line":"Federation"},{"line_number":194,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":195,"context_line":""}],"source_content_type":"text/x-rst","patch_set":11,"id":"7faddb67_d2a5c3a0","line":192,"in_reply_to":"7faddb67_bc48205c","updated":"2019-08-13 02:37:31.000000000","message":"I was partly thinking of avoiding it because the internal logic is a mess, but it\u0027s actually a more elegant option that the above in some cases, so may as well.","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"5c01fbd067aa797273dc9cc2b5ed86ba754db0c4","unresolved":false,"context_lines":[{"line_number":80,"context_line":"    ...                project_id\u003d\u0027projectid\u0027)"},{"line_number":81,"context_line":"    \u003e\u003e\u003e sess \u003d session.Session(auth\u003dauth)"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"As in the majority of cases you will only want to use one"},{"line_number":84,"context_line":":py:class:`~keystoneauth1.identity.v3.AuthMethod` there are also helper"},{"line_number":85,"context_line":"authentication plugins for the various"},{"line_number":86,"context_line":":py:class:`~keystoneauth1.identity.v3.AuthMethod` which can be used more"}],"source_content_type":"text/x-rst","patch_set":13,"id":"7faddb67_a872087b","line":83,"range":{"start_line":83,"start_character":0,"end_line":83,"end_character":57},"updated":"2019-08-13 17:43:39.000000000","message":"Could add another paragraph explaining the one case where this is not true and listing the v3.MultiFactor plugin","commit_id":"4b044b49f9cd1a95021db424b5ae85a1f3644878"}],"keystoneauth1/exceptions/auth.py":[{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"1667b502f252f611ba5ef393caf18a77c2c86f74","unresolved":false,"context_lines":[{"line_number":24,"context_line":"        self.receipt \u003d response.headers.get(\"Openstack-Auth-Receipt\")"},{"line_number":25,"context_line":"        body \u003d response.json()"},{"line_number":26,"context_line":"        self.methods \u003d body[\u0027receipt\u0027][\u0027methods\u0027]"},{"line_number":27,"context_line":"        # NOTE(adriant): should we parse these into datetime objects?:"},{"line_number":28,"context_line":"        self.expires_at \u003d body[\u0027receipt\u0027][\u0027expires_at\u0027]"},{"line_number":29,"context_line":"        self.issued_at \u003d body[\u0027receipt\u0027][\u0027issued_at\u0027]"},{"line_number":30,"context_line":"        self.user \u003d body[\u0027receipt\u0027][\u0027user\u0027]"},{"line_number":31,"context_line":"        self.required_auth_methods \u003d body[\u0027required_auth_methods\u0027]"},{"line_number":32,"context_line":"        self.message \u003d \"Required auth methods: %s\" % self.required_auth_methods"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_b3a94dde","line":29,"range":{"start_line":27,"start_character":8,"end_line":29,"end_character":53},"updated":"2019-08-09 18:53:56.000000000","message":"What would they be needed for?","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"8821c8c0515454cabcea0790f26e444b7b20c92d","unresolved":false,"context_lines":[{"line_number":24,"context_line":"        self.receipt \u003d response.headers.get(\"Openstack-Auth-Receipt\")"},{"line_number":25,"context_line":"        body \u003d response.json()"},{"line_number":26,"context_line":"        self.methods \u003d body[\u0027receipt\u0027][\u0027methods\u0027]"},{"line_number":27,"context_line":"        # NOTE(adriant): should we parse these into datetime objects?:"},{"line_number":28,"context_line":"        self.expires_at \u003d body[\u0027receipt\u0027][\u0027expires_at\u0027]"},{"line_number":29,"context_line":"        self.issued_at \u003d body[\u0027receipt\u0027][\u0027issued_at\u0027]"},{"line_number":30,"context_line":"        self.user \u003d body[\u0027receipt\u0027][\u0027user\u0027]"},{"line_number":31,"context_line":"        self.required_auth_methods \u003d body[\u0027required_auth_methods\u0027]"},{"line_number":32,"context_line":"        self.message \u003d \"Required auth methods: %s\" % self.required_auth_methods"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_dd33aff5","line":29,"range":{"start_line":27,"start_character":8,"end_line":29,"end_character":53},"in_reply_to":"7faddb67_ae8fa22c","updated":"2019-08-11 05:29:53.000000000","message":"I\u0027ve dropped issued_at, but kept the response object itself so someone can look deeper for these values if they really want.","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"e15e47077c465de12f8e3449ab82aa82c3ef17c3","unresolved":false,"context_lines":[{"line_number":24,"context_line":"        self.receipt \u003d response.headers.get(\"Openstack-Auth-Receipt\")"},{"line_number":25,"context_line":"        body \u003d response.json()"},{"line_number":26,"context_line":"        self.methods \u003d body[\u0027receipt\u0027][\u0027methods\u0027]"},{"line_number":27,"context_line":"        # NOTE(adriant): should we parse these into datetime objects?:"},{"line_number":28,"context_line":"        self.expires_at \u003d body[\u0027receipt\u0027][\u0027expires_at\u0027]"},{"line_number":29,"context_line":"        self.issued_at \u003d body[\u0027receipt\u0027][\u0027issued_at\u0027]"},{"line_number":30,"context_line":"        self.user \u003d body[\u0027receipt\u0027][\u0027user\u0027]"},{"line_number":31,"context_line":"        self.required_auth_methods \u003d body[\u0027required_auth_methods\u0027]"},{"line_number":32,"context_line":"        self.message \u003d \"Required auth methods: %s\" % self.required_auth_methods"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_ae8fa22c","line":29,"range":{"start_line":27,"start_character":8,"end_line":29,"end_character":53},"in_reply_to":"7faddb67_b3a94dde","updated":"2019-08-09 20:13:03.000000000","message":"expires at is important, i don\u0027t know why we need issued at explicitly in the result.","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"1667b502f252f611ba5ef393caf18a77c2c86f74","unresolved":false,"context_lines":[{"line_number":27,"context_line":"        # NOTE(adriant): should we parse these into datetime objects?:"},{"line_number":28,"context_line":"        self.expires_at \u003d body[\u0027receipt\u0027][\u0027expires_at\u0027]"},{"line_number":29,"context_line":"        self.issued_at \u003d body[\u0027receipt\u0027][\u0027issued_at\u0027]"},{"line_number":30,"context_line":"        self.user \u003d body[\u0027receipt\u0027][\u0027user\u0027]"},{"line_number":31,"context_line":"        self.required_auth_methods \u003d body[\u0027required_auth_methods\u0027]"},{"line_number":32,"context_line":"        self.message \u003d \"Required auth methods: %s\" % self.required_auth_methods"},{"line_number":33,"context_line":"        super(MissingAuthMethods, self).__init__(self.message)"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_73b3d54e","line":30,"range":{"start_line":30,"start_character":8,"end_line":30,"end_character":43},"updated":"2019-08-09 18:53:56.000000000","message":"Is this needed? the user already knows who they are","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"8821c8c0515454cabcea0790f26e444b7b20c92d","unresolved":false,"context_lines":[{"line_number":27,"context_line":"        # NOTE(adriant): should we parse these into datetime objects?:"},{"line_number":28,"context_line":"        self.expires_at \u003d body[\u0027receipt\u0027][\u0027expires_at\u0027]"},{"line_number":29,"context_line":"        self.issued_at \u003d body[\u0027receipt\u0027][\u0027issued_at\u0027]"},{"line_number":30,"context_line":"        self.user \u003d body[\u0027receipt\u0027][\u0027user\u0027]"},{"line_number":31,"context_line":"        self.required_auth_methods \u003d body[\u0027required_auth_methods\u0027]"},{"line_number":32,"context_line":"        self.message \u003d \"Required auth methods: %s\" % self.required_auth_methods"},{"line_number":33,"context_line":"        super(MissingAuthMethods, self).__init__(self.message)"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_1d3aa7cc","line":30,"range":{"start_line":30,"start_character":8,"end_line":30,"end_character":43},"in_reply_to":"7faddb67_0e883620","updated":"2019-08-11 05:29:53.000000000","message":"My potential but not all that important use case here was for Horizon, where the MFA login form (after password) could now include the name of the user potentially.\n\n\"Hello \u003cinsertnamehere\u003e, please enter your TOTP details\" etc.\"","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"e15e47077c465de12f8e3449ab82aa82c3ef17c3","unresolved":false,"context_lines":[{"line_number":27,"context_line":"        # NOTE(adriant): should we parse these into datetime objects?:"},{"line_number":28,"context_line":"        self.expires_at \u003d body[\u0027receipt\u0027][\u0027expires_at\u0027]"},{"line_number":29,"context_line":"        self.issued_at \u003d body[\u0027receipt\u0027][\u0027issued_at\u0027]"},{"line_number":30,"context_line":"        self.user \u003d body[\u0027receipt\u0027][\u0027user\u0027]"},{"line_number":31,"context_line":"        self.required_auth_methods \u003d body[\u0027required_auth_methods\u0027]"},{"line_number":32,"context_line":"        self.message \u003d \"Required auth methods: %s\" % self.required_auth_methods"},{"line_number":33,"context_line":"        super(MissingAuthMethods, self).__init__(self.message)"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_0e883620","line":30,"range":{"start_line":30,"start_character":8,"end_line":30,"end_character":43},"in_reply_to":"7faddb67_73b3d54e","updated":"2019-08-09 20:13:03.000000000","message":"I agree, unless this is used for say the message, i\u0027d drop it.","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"1667b502f252f611ba5ef393caf18a77c2c86f74","unresolved":false,"context_lines":[{"line_number":29,"context_line":"        self.issued_at \u003d body[\u0027receipt\u0027][\u0027issued_at\u0027]"},{"line_number":30,"context_line":"        self.user \u003d body[\u0027receipt\u0027][\u0027user\u0027]"},{"line_number":31,"context_line":"        self.required_auth_methods \u003d body[\u0027required_auth_methods\u0027]"},{"line_number":32,"context_line":"        self.message \u003d \"Required auth methods: %s\" % self.required_auth_methods"},{"line_number":33,"context_line":"        super(MissingAuthMethods, self).__init__(self.message)"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_1382a153","line":32,"updated":"2019-08-09 18:53:56.000000000","message":"Won\u0027t this override the message on line 21?","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"e15e47077c465de12f8e3449ab82aa82c3ef17c3","unresolved":false,"context_lines":[{"line_number":29,"context_line":"        self.issued_at \u003d body[\u0027receipt\u0027][\u0027issued_at\u0027]"},{"line_number":30,"context_line":"        self.user \u003d body[\u0027receipt\u0027][\u0027user\u0027]"},{"line_number":31,"context_line":"        self.required_auth_methods \u003d body[\u0027required_auth_methods\u0027]"},{"line_number":32,"context_line":"        self.message \u003d \"Required auth methods: %s\" % self.required_auth_methods"},{"line_number":33,"context_line":"        super(MissingAuthMethods, self).__init__(self.message)"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_ae9d6258","line":32,"in_reply_to":"7faddb67_1382a153","updated":"2019-08-09 20:13:03.000000000","message":"++ this should be line 21 and the .build_message (or whatever that method is called) can subst in the required_auth_methods.","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"074f72fe12ebb4d4c4dc71c7f5b27bf86956e2f3","unresolved":false,"context_lines":[{"line_number":29,"context_line":"        self.issued_at \u003d body[\u0027receipt\u0027][\u0027issued_at\u0027]"},{"line_number":30,"context_line":"        self.user \u003d body[\u0027receipt\u0027][\u0027user\u0027]"},{"line_number":31,"context_line":"        self.required_auth_methods \u003d body[\u0027required_auth_methods\u0027]"},{"line_number":32,"context_line":"        self.message \u003d \"Required auth methods: %s\" % self.required_auth_methods"},{"line_number":33,"context_line":"        super(MissingAuthMethods, self).__init__(self.message)"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_fc953889","line":32,"in_reply_to":"7faddb67_3d3523dc","updated":"2019-08-12 21:40:24.000000000","message":"Morgan - the _build_message thing is only in keystone, not sure it\u0027s worth reimplementing here","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"8821c8c0515454cabcea0790f26e444b7b20c92d","unresolved":false,"context_lines":[{"line_number":29,"context_line":"        self.issued_at \u003d body[\u0027receipt\u0027][\u0027issued_at\u0027]"},{"line_number":30,"context_line":"        self.user \u003d body[\u0027receipt\u0027][\u0027user\u0027]"},{"line_number":31,"context_line":"        self.required_auth_methods \u003d body[\u0027required_auth_methods\u0027]"},{"line_number":32,"context_line":"        self.message \u003d \"Required auth methods: %s\" % self.required_auth_methods"},{"line_number":33,"context_line":"        super(MissingAuthMethods, self).__init__(self.message)"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_3d3523dc","line":32,"in_reply_to":"7faddb67_ae9d6258","updated":"2019-08-11 05:29:53.000000000","message":"in the init function is how the base class does it. So I\u0027ll just pass it to the base class and let it handle it.","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"074f72fe12ebb4d4c4dc71c7f5b27bf86956e2f3","unresolved":false,"context_lines":[{"line_number":18,"context_line":""},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"class MissingAuthMethods(base.ClientException):"},{"line_number":21,"context_line":"    message \u003d \"Not all required auth rules were satisfied.\""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    def __init__(self, response):"},{"line_number":24,"context_line":"        self.response \u003d response"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_dc8abc62","line":21,"updated":"2019-08-12 21:40:24.000000000","message":"This is a nice message but the message in __init__ is overriding it, maybe have line 31 concatenate this with the required auth methods?","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"839105fabab74f4d8460da236dfcd1e66cfd4b19","unresolved":false,"context_lines":[{"line_number":18,"context_line":""},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"class MissingAuthMethods(base.ClientException):"},{"line_number":21,"context_line":"    message \u003d \"Not all required auth rules were satisfied.\""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    def __init__(self, response):"},{"line_number":24,"context_line":"        self.response \u003d response"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_d28b83bd","line":21,"in_reply_to":"7faddb67_dc8abc62","updated":"2019-08-13 02:37:31.000000000","message":"Done","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"074f72fe12ebb4d4c4dc71c7f5b27bf86956e2f3","unresolved":false,"context_lines":[{"line_number":26,"context_line":"        body \u003d response.json()"},{"line_number":27,"context_line":"        self.methods \u003d body[\u0027receipt\u0027][\u0027methods\u0027]"},{"line_number":28,"context_line":"        self.required_auth_methods \u003d body[\u0027required_auth_methods\u0027]"},{"line_number":29,"context_line":"        # NOTE(adriant): should we parse this into a datetime object?:"},{"line_number":30,"context_line":"        self.expires_at \u003d body[\u0027receipt\u0027][\u0027expires_at\u0027]"},{"line_number":31,"context_line":"        message \u003d \"Required auth methods: %s\" % self.required_auth_methods"},{"line_number":32,"context_line":"        super(MissingAuthMethods, self).__init__(message)"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_9c7764a0","line":29,"range":{"start_line":29,"start_character":25,"end_line":29,"end_character":70},"updated":"2019-08-12 21:40:24.000000000","message":"Might as well, I suppose? If it\u0027s meant to be usable to a programmer then it\u0027s probably better off as a datetime object.","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"839105fabab74f4d8460da236dfcd1e66cfd4b19","unresolved":false,"context_lines":[{"line_number":26,"context_line":"        body \u003d response.json()"},{"line_number":27,"context_line":"        self.methods \u003d body[\u0027receipt\u0027][\u0027methods\u0027]"},{"line_number":28,"context_line":"        self.required_auth_methods \u003d body[\u0027required_auth_methods\u0027]"},{"line_number":29,"context_line":"        # NOTE(adriant): should we parse this into a datetime object?:"},{"line_number":30,"context_line":"        self.expires_at \u003d body[\u0027receipt\u0027][\u0027expires_at\u0027]"},{"line_number":31,"context_line":"        message \u003d \"Required auth methods: %s\" % self.required_auth_methods"},{"line_number":32,"context_line":"        super(MissingAuthMethods, self).__init__(message)"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_72bc0f6c","line":29,"range":{"start_line":29,"start_character":25,"end_line":29,"end_character":70},"in_reply_to":"7faddb67_9c7764a0","updated":"2019-08-13 02:37:31.000000000","message":"Done","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"}],"keystoneauth1/identity/v3/__init__.py":[{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"2a2d09deb39e62d25578a60f0102bf53a9d590ca","unresolved":false,"context_lines":[{"line_number":50,"context_line":"           \u0027TOTP\u0027,"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"           \u0027TokenlessAuth\u0027,"},{"line_number":53,"context_line":"           "},{"line_number":54,"context_line":"           \u0027ReceiptMethod\u0027, "},{"line_number":55,"context_line":"           "},{"line_number":56,"context_line":"           \u0027MultiMethod\u0027, )"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_8ca9cb7d","line":55,"range":{"start_line":53,"start_character":0,"end_line":55,"end_character":11},"updated":"2019-08-07 08:07:31.000000000","message":"whitespace...","commit_id":"84d39c33e9b12f5f96aee647c299555223017488"}],"keystoneauth1/identity/v3/base.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"e15e47077c465de12f8e3449ab82aa82c3ef17c3","unresolved":false,"context_lines":[{"line_number":128,"context_line":"                ident.setdefault(\u0027methods\u0027, []).append(name)"},{"line_number":129,"context_line":"                ident[name] \u003d auth_data"},{"line_number":130,"context_line":"            except TypeError:"},{"line_number":131,"context_line":"                # NOTE(adriant): for special cases where \u0027get_auth_data\u0027"},{"line_number":132,"context_line":"                # returns none and doesn\u0027t want to be included as a method"},{"line_number":133,"context_line":"                # or in the request body."},{"line_number":134,"context_line":"                pass"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"        if not ident:"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_8ec9865b","line":133,"range":{"start_line":131,"start_character":0,"end_line":133,"end_character":41},"updated":"2019-08-09 20:13:03.000000000","message":"Please be more explicit on the \"special cases\". This comment/note is for maintainability (long term).","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"8821c8c0515454cabcea0790f26e444b7b20c92d","unresolved":false,"context_lines":[{"line_number":128,"context_line":"                ident.setdefault(\u0027methods\u0027, []).append(name)"},{"line_number":129,"context_line":"                ident[name] \u003d auth_data"},{"line_number":130,"context_line":"            except TypeError:"},{"line_number":131,"context_line":"                # NOTE(adriant): for special cases where \u0027get_auth_data\u0027"},{"line_number":132,"context_line":"                # returns none and doesn\u0027t want to be included as a method"},{"line_number":133,"context_line":"                # or in the request body."},{"line_number":134,"context_line":"                pass"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"        if not ident:"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_9d4bf75d","line":133,"range":{"start_line":131,"start_character":0,"end_line":133,"end_character":41},"in_reply_to":"7faddb67_8ec9865b","updated":"2019-08-11 05:29:53.000000000","message":"Done","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"1667b502f252f611ba5ef393caf18a77c2c86f74","unresolved":false,"context_lines":[{"line_number":131,"context_line":"                # NOTE(adriant): for special cases where \u0027get_auth_data\u0027"},{"line_number":132,"context_line":"                # returns none and doesn\u0027t want to be included as a method"},{"line_number":133,"context_line":"                # or in the request body."},{"line_number":134,"context_line":"                pass"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"        if not ident:"},{"line_number":137,"context_line":"            raise exceptions.AuthorizationFailure("}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_f3434512","line":134,"updated":"2019-08-09 18:53:56.000000000","message":"This is way too complicated, why not just\n\n if name:\n    ident.setdefault(\u0027methods\u0027, []).append(name)\n    ident[name] \u003d auth_data","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"8821c8c0515454cabcea0790f26e444b7b20c92d","unresolved":false,"context_lines":[{"line_number":131,"context_line":"                # NOTE(adriant): for special cases where \u0027get_auth_data\u0027"},{"line_number":132,"context_line":"                # returns none and doesn\u0027t want to be included as a method"},{"line_number":133,"context_line":"                # or in the request body."},{"line_number":134,"context_line":"                pass"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"        if not ident:"},{"line_number":137,"context_line":"            raise exceptions.AuthorizationFailure("}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_fd2eab8a","line":134,"in_reply_to":"7faddb67_f3434512","updated":"2019-08-11 05:29:53.000000000","message":"because I would still need to return a tuple (or other iterable) for \u0027name, auth_data \u003d \u0027 to not throw a typeerror. And that felt less clear than a single None and a typeerror, but I\u0027m not too fussed either way.","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"074f72fe12ebb4d4c4dc71c7f5b27bf86956e2f3","unresolved":false,"context_lines":[{"line_number":131,"context_line":"                # NOTE(adriant): for special cases where \u0027get_auth_data\u0027"},{"line_number":132,"context_line":"                # returns none and doesn\u0027t want to be included as a method"},{"line_number":133,"context_line":"                # or in the request body."},{"line_number":134,"context_line":"                pass"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"        if not ident:"},{"line_number":137,"context_line":"            raise exceptions.AuthorizationFailure("}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_3c5510fb","line":134,"in_reply_to":"7faddb67_fd2eab8a","updated":"2019-08-12 21:40:24.000000000","message":"I think you\u0027re stuck returning a tuple anyway, because it\u0027s part of the base class interface: https://docs.openstack.org/keystoneauth/latest/api/keystoneauth1.identity.v3.html#keystoneauth1.identity.v3.base.AuthMethod.get_auth_data","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"074f72fe12ebb4d4c4dc71c7f5b27bf86956e2f3","unresolved":false,"context_lines":[{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    def add_method(self, method):"},{"line_number":114,"context_line":"        \"\"\"Add an additional initialized AuthMethod instance.\"\"\""},{"line_number":115,"context_line":"        # NOTE(adriant): do we want to check for class type explicitly?"},{"line_number":116,"context_line":"        self.auth_methods.append(method)"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    def get_auth_ref(self, session, **kwargs):"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_dc2e3c8b","line":115,"range":{"start_line":115,"start_character":8,"end_line":115,"end_character":71},"updated":"2019-08-12 21:40:24.000000000","message":"Not sure what the benefit of checking for the class type here would be. It might be nice to have a nice way of converting the keystone auth method to a keystoneauth method class somewhere else. It\u0027s unfortunate that we don\u0027t have a proper mapping already in keystoneauth, but maybe a future optimization could be to create that mapping somehow, perhaps by having each method class declare a method name attribute and registering it somewhere.","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"5c01fbd067aa797273dc9cc2b5ed86ba754db0c4","unresolved":false,"context_lines":[{"line_number":128,"context_line":"                ident[name] \u003d auth_data"},{"line_number":129,"context_line":"            except TypeError:"},{"line_number":130,"context_line":"                # NOTE(adriant): for ReceiptMethod where \u0027get_auth_data\u0027"},{"line_number":131,"context_line":"                # returns None and doesn\u0027t want to be included as a method"},{"line_number":132,"context_line":"                # or in the request body."},{"line_number":133,"context_line":"                pass"},{"line_number":134,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"7faddb67_483914a1","line":131,"updated":"2019-08-13 17:43:39.000000000","message":"I don\u0027t think returning None is an option, the tuple as rtype is part of the interface https://docs.openstack.org/keystoneauth/latest/api/keystoneauth1.identity.v3.html#keystoneauth1.identity.v3.base.AuthMethod.get_auth_data","commit_id":"4b044b49f9cd1a95021db424b5ae85a1f3644878"}],"keystoneauth1/identity/v3/multi_factor.py":[{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"be9757a08fa3ee8370e72dd0cebb6fc602fe02cd","unresolved":false,"context_lines":[{"line_number":16,"context_line":"__all__ \u003d (\u0027MultiFactor\u0027, )"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"class MultiFactor(base.Auth):"},{"line_number":20,"context_line":"    \"\"\"A plugin for authenticating with multiple auth methods."},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"    :param string auth_url: Identity service endpoint for authentication."}],"source_content_type":"text/x-python","patch_set":3,"id":"7faddb67_a378428f","line":19,"range":{"start_line":19,"start_character":0,"end_line":19,"end_character":29},"updated":"2019-08-08 04:00:44.000000000","message":"We may not even really need this... people can use just base.Auth directly as this class doesn\u0027t really anything to it...","commit_id":"2a19fdb71409c05ee8694b321de79bfb0129ab64"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"6f4308ab93c33e1566cd9e1563259bb51867b11e","unresolved":false,"context_lines":[{"line_number":36,"context_line":"    Also accepts various keyword args based on which methods are specified."},{"line_number":37,"context_line":"    \"\"\""},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    def __init__(self, auth_url, methods, **kwargs):"},{"line_number":40,"context_line":"        method_instances \u003d []"},{"line_number":41,"context_line":"        method_keys \u003d set()"},{"line_number":42,"context_line":"        for method in methods:"},{"line_number":43,"context_line":"            plugin \u003d loading.get_plugin_loader(method).plugin_class"},{"line_number":44,"context_line":"            plugin_kwargs \u003d {}"},{"line_number":45,"context_line":"            for key in plugin._auth_method_class._method_parameters:"},{"line_number":46,"context_line":"                method_keys.add(key)"},{"line_number":47,"context_line":"                plugin_kwargs[key] \u003d kwargs.get(key, None)"},{"line_number":48,"context_line":"            method_instances.append(plugin._auth_method_class(**plugin_kwargs))"},{"line_number":49,"context_line":"        for key in method_keys:"},{"line_number":50,"context_line":"            kwargs.pop(key, None)"},{"line_number":51,"context_line":"        super(MultiFactor, self).__init__(auth_url, method_instances, **kwargs)"}],"source_content_type":"text/x-python","patch_set":8,"id":"7faddb67_09e4d70d","line":51,"range":{"start_line":39,"start_character":4,"end_line":51,"end_character":79},"updated":"2019-08-08 07:45:05.000000000","message":"I am so so so sorry about this hack, please give me alternatives.","commit_id":"ed62e6a6d73cb1666f39c1975d8b08b23004933a"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"a92e87682e4cd2c5c72fa61ee8044468584d688e","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    def __init__(self, auth_url, methods, **kwargs):"},{"line_number":40,"context_line":"        method_instances \u003d []"},{"line_number":41,"context_line":"        method_keys \u003d set()"},{"line_number":42,"context_line":"        for method in methods:"},{"line_number":43,"context_line":"            plugin \u003d loading.get_plugin_loader(method).plugin_class"},{"line_number":44,"context_line":"            plugin_kwargs \u003d {}"},{"line_number":45,"context_line":"            for key in plugin._auth_method_class._method_parameters:"},{"line_number":46,"context_line":"                method_keys.add(key)"},{"line_number":47,"context_line":"                plugin_kwargs[key] \u003d kwargs.get(key, None)"},{"line_number":48,"context_line":"            method_instances.append(plugin._auth_method_class(**plugin_kwargs))"},{"line_number":49,"context_line":"        for key in method_keys:"},{"line_number":50,"context_line":"            kwargs.pop(key, None)"},{"line_number":51,"context_line":"        super(MultiFactor, self).__init__(auth_url, method_instances, **kwargs)"}],"source_content_type":"text/x-python","patch_set":8,"id":"7faddb67_d05c18ef","line":51,"range":{"start_line":42,"start_character":5,"end_line":51,"end_character":79},"updated":"2019-08-08 15:53:37.000000000","message":"The error in testing you\u0027re seeing is because you\u0027re passing class info to stevedore not the string names.\n\nLook closely at the plugin loader(s) WRT the tests and what is happening here","commit_id":"ed62e6a6d73cb1666f39c1975d8b08b23004933a"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"869e256c0e321c9bc8851b595098b5126c351dd8","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    def __init__(self, auth_url, methods, **kwargs):"},{"line_number":40,"context_line":"        method_instances \u003d []"},{"line_number":41,"context_line":"        method_keys \u003d set()"},{"line_number":42,"context_line":"        for method in methods:"},{"line_number":43,"context_line":"            plugin \u003d loading.get_plugin_loader(method).plugin_class"},{"line_number":44,"context_line":"            plugin_kwargs \u003d {}"},{"line_number":45,"context_line":"            for key in plugin._auth_method_class._method_parameters:"},{"line_number":46,"context_line":"                method_keys.add(key)"},{"line_number":47,"context_line":"                plugin_kwargs[key] \u003d kwargs.get(key, None)"},{"line_number":48,"context_line":"            method_instances.append(plugin._auth_method_class(**plugin_kwargs))"},{"line_number":49,"context_line":"        for key in method_keys:"},{"line_number":50,"context_line":"            kwargs.pop(key, None)"},{"line_number":51,"context_line":"        super(MultiFactor, self).__init__(auth_url, method_instances, **kwargs)"}],"source_content_type":"text/x-python","patch_set":8,"id":"7faddb67_9f830baa","line":51,"range":{"start_line":42,"start_character":5,"end_line":51,"end_character":79},"in_reply_to":"7faddb67_d05c18ef","updated":"2019-08-08 20:27:12.000000000","message":"I forgot to rewrite that test after rewriting this plugin, and I had issues installing requests kerberous on my machine so I selectively run tests locally.\n\nOriginally this plugin was just a light wrapper around base.Auth, which made it useless and I was going to drop it. But when doing the loading I realised that to do MFA via loaders I need a plugin which had methods (string names) as an option.","commit_id":"ed62e6a6d73cb1666f39c1975d8b08b23004933a"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"e15e47077c465de12f8e3449ab82aa82c3ef17c3","unresolved":false,"context_lines":[{"line_number":36,"context_line":"    Also accepts various keyword args based on which methods are specified."},{"line_number":37,"context_line":"    \"\"\""},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    def __init__(self, auth_url, methods, **kwargs):"},{"line_number":40,"context_line":"        method_instances \u003d []"},{"line_number":41,"context_line":"        method_keys \u003d set()"},{"line_number":42,"context_line":"        for method in methods:"},{"line_number":43,"context_line":"            plugin \u003d loading.get_plugin_loader(method).plugin_class"},{"line_number":44,"context_line":"            plugin_kwargs \u003d {}"},{"line_number":45,"context_line":"            for key in plugin._auth_method_class._method_parameters:"},{"line_number":46,"context_line":"                method_keys.add(key)"},{"line_number":47,"context_line":"                plugin_kwargs[key] \u003d kwargs.get(key, None)"},{"line_number":48,"context_line":"            method_instances.append(plugin._auth_method_class(**plugin_kwargs))"},{"line_number":49,"context_line":"        for key in method_keys:"},{"line_number":50,"context_line":"            kwargs.pop(key, None)"},{"line_number":51,"context_line":"        super(MultiFactor, self).__init__(auth_url, method_instances, **kwargs)"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_6ec0ca2b","line":51,"range":{"start_line":39,"start_character":0,"end_line":51,"end_character":79},"updated":"2019-08-09 20:13:03.000000000","message":"This is pretty dense to read, comments might help future folks reading this.","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"8821c8c0515454cabcea0790f26e444b7b20c92d","unresolved":false,"context_lines":[{"line_number":36,"context_line":"    Also accepts various keyword args based on which methods are specified."},{"line_number":37,"context_line":"    \"\"\""},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    def __init__(self, auth_url, methods, **kwargs):"},{"line_number":40,"context_line":"        method_instances \u003d []"},{"line_number":41,"context_line":"        method_keys \u003d set()"},{"line_number":42,"context_line":"        for method in methods:"},{"line_number":43,"context_line":"            plugin \u003d loading.get_plugin_loader(method).plugin_class"},{"line_number":44,"context_line":"            plugin_kwargs \u003d {}"},{"line_number":45,"context_line":"            for key in plugin._auth_method_class._method_parameters:"},{"line_number":46,"context_line":"                method_keys.add(key)"},{"line_number":47,"context_line":"                plugin_kwargs[key] \u003d kwargs.get(key, None)"},{"line_number":48,"context_line":"            method_instances.append(plugin._auth_method_class(**plugin_kwargs))"},{"line_number":49,"context_line":"        for key in method_keys:"},{"line_number":50,"context_line":"            kwargs.pop(key, None)"},{"line_number":51,"context_line":"        super(MultiFactor, self).__init__(auth_url, method_instances, **kwargs)"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_5d557ff9","line":51,"range":{"start_line":39,"start_character":0,"end_line":51,"end_character":79},"in_reply_to":"7faddb67_6ec0ca2b","updated":"2019-08-11 05:29:53.000000000","message":"Yeah, was thinking I should do that, since the \u0027why\u0027 of this logic is hard to outright gauge.","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"074f72fe12ebb4d4c4dc71c7f5b27bf86956e2f3","unresolved":false,"context_lines":[{"line_number":21,"context_line":"    \"\"\"A plugin for authenticating with multiple auth methods."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    :param string auth_url: Identity service endpoint for authentication."},{"line_number":24,"context_line":"    :param string methods: names of the methods to authenticate with."},{"line_number":25,"context_line":"    :param string trust_id: Trust ID for trust scoping."},{"line_number":26,"context_line":"    :param string system_scope: System information to scope to."},{"line_number":27,"context_line":"    :param string domain_id: Domain ID for domain scoping."}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_79607a36","line":24,"range":{"start_line":24,"start_character":18,"end_line":24,"end_character":25},"updated":"2019-08-12 21:40:24.000000000","message":"Needs to be auth_methods","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"839105fabab74f4d8460da236dfcd1e66cfd4b19","unresolved":false,"context_lines":[{"line_number":21,"context_line":"    \"\"\"A plugin for authenticating with multiple auth methods."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    :param string auth_url: Identity service endpoint for authentication."},{"line_number":24,"context_line":"    :param string methods: names of the methods to authenticate with."},{"line_number":25,"context_line":"    :param string trust_id: Trust ID for trust scoping."},{"line_number":26,"context_line":"    :param string system_scope: System information to scope to."},{"line_number":27,"context_line":"    :param string domain_id: Domain ID for domain scoping."}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_d2a4e34d","line":24,"range":{"start_line":24,"start_character":18,"end_line":24,"end_character":25},"in_reply_to":"7faddb67_79607a36","updated":"2019-08-13 02:37:31.000000000","message":"Done","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"074f72fe12ebb4d4c4dc71c7f5b27bf86956e2f3","unresolved":false,"context_lines":[{"line_number":36,"context_line":"    Also accepts various keyword args based on which methods are specified."},{"line_number":37,"context_line":"    \"\"\""},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    def __init__(self, auth_url, methods, **kwargs):"},{"line_number":40,"context_line":"        method_instances \u003d []"},{"line_number":41,"context_line":"        method_keys \u003d set()"},{"line_number":42,"context_line":"        for method in methods:"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_1c0cd437","line":39,"range":{"start_line":39,"start_character":33,"end_line":39,"end_character":40},"updated":"2019-08-12 21:40:24.000000000","message":"auth_methods","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"839105fabab74f4d8460da236dfcd1e66cfd4b19","unresolved":false,"context_lines":[{"line_number":36,"context_line":"    Also accepts various keyword args based on which methods are specified."},{"line_number":37,"context_line":"    \"\"\""},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    def __init__(self, auth_url, methods, **kwargs):"},{"line_number":40,"context_line":"        method_instances \u003d []"},{"line_number":41,"context_line":"        method_keys \u003d set()"},{"line_number":42,"context_line":"        for method in methods:"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_72616f11","line":39,"range":{"start_line":39,"start_character":33,"end_line":39,"end_character":40},"in_reply_to":"7faddb67_1c0cd437","updated":"2019-08-13 02:37:31.000000000","message":"Done","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"}],"keystoneauth1/identity/v3/receipt.py":[{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"1667b502f252f611ba5ef393caf18a77c2c86f74","unresolved":false,"context_lines":[{"line_number":31,"context_line":"        methods, or body."},{"line_number":32,"context_line":"        \"\"\""},{"line_number":33,"context_line":"        headers[\u0027Openstack-Auth-Receipt\u0027] \u003d self.receipt"},{"line_number":34,"context_line":"        return None"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    def get_cache_id_elements(self):"},{"line_number":37,"context_line":"        return {\u0027receipt_receipt\u0027: self.receipt}"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_33923d4d","line":34,"range":{"start_line":34,"start_character":8,"end_line":34,"end_character":19},"updated":"2019-08-09 18:53:56.000000000","message":"technically not including a return statement would also do the same thing but I guess it\u0027s good to be explicit","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"8821c8c0515454cabcea0790f26e444b7b20c92d","unresolved":false,"context_lines":[{"line_number":31,"context_line":"        methods, or body."},{"line_number":32,"context_line":"        \"\"\""},{"line_number":33,"context_line":"        headers[\u0027Openstack-Auth-Receipt\u0027] \u003d self.receipt"},{"line_number":34,"context_line":"        return None"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    def get_cache_id_elements(self):"},{"line_number":37,"context_line":"        return {\u0027receipt_receipt\u0027: self.receipt}"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_5d6edfc9","line":34,"range":{"start_line":34,"start_character":8,"end_line":34,"end_character":19},"in_reply_to":"7faddb67_33923d4d","updated":"2019-08-11 05:29:53.000000000","message":"Yeah, I was thinking exactly the same thing, but being explicit felt safer.","commit_id":"41ebe17e46a11efe54983357df9399185a473589"}],"keystoneauth1/loading/_plugins/identity/v3.py":[{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"6f4308ab93c33e1566cd9e1563259bb51867b11e","unresolved":false,"context_lines":[{"line_number":205,"context_line":"            loading.Opt("},{"line_number":206,"context_line":"                \u0027passcode\u0027,"},{"line_number":207,"context_line":"                secret\u003dTrue,"},{"line_number":208,"context_line":"                prompt\u003d\u0027TOTP passcode: \u0027,"},{"line_number":209,"context_line":"                help\u003d\"User\u0027s TOTP passcode\"),"},{"line_number":210,"context_line":"        ])"},{"line_number":211,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"7faddb67_09cdb785","line":208,"range":{"start_line":208,"start_character":16,"end_line":208,"end_character":41},"updated":"2019-08-08 07:45:05.000000000","message":"the cli ought to be able to prompt for the passcode.","commit_id":"ed62e6a6d73cb1666f39c1975d8b08b23004933a"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"839105fabab74f4d8460da236dfcd1e66cfd4b19","unresolved":false,"context_lines":[{"line_number":315,"context_line":""},{"line_number":316,"context_line":"        options.extend(["},{"line_number":317,"context_line":"            loading.Opt("},{"line_number":318,"context_line":"                \u0027auth_methods\u0027,"},{"line_number":319,"context_line":"                dest\u003d\u0027methods\u0027,"},{"line_number":320,"context_line":"                required\u003dTrue,"},{"line_number":321,"context_line":"                help\u003d\"Methods to authenticate with.\"),"},{"line_number":322,"context_line":"        ])"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_12ab5b1e","line":319,"range":{"start_line":318,"start_character":16,"end_line":319,"end_character":31},"updated":"2019-08-13 02:37:31.000000000","message":"auth_methods","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"074f72fe12ebb4d4c4dc71c7f5b27bf86956e2f3","unresolved":false,"context_lines":[{"line_number":333,"context_line":"    def load_from_options(self, **kwargs):"},{"line_number":334,"context_line":"        _assert_identity_options(kwargs)"},{"line_number":335,"context_line":""},{"line_number":336,"context_line":"        if \u0027methods\u0027 not in kwargs:"},{"line_number":337,"context_line":"            raise exceptions.OptionError(\"methods is a required option.\")"},{"line_number":338,"context_line":""},{"line_number":339,"context_line":"        self._methods \u003d kwargs[\u0027methods\u0027]"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_7cfdc806","line":336,"range":{"start_line":336,"start_character":12,"end_line":336,"end_character":19},"updated":"2019-08-12 21:40:24.000000000","message":"auth_methods I think?","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"839105fabab74f4d8460da236dfcd1e66cfd4b19","unresolved":false,"context_lines":[{"line_number":333,"context_line":"    def load_from_options(self, **kwargs):"},{"line_number":334,"context_line":"        _assert_identity_options(kwargs)"},{"line_number":335,"context_line":""},{"line_number":336,"context_line":"        if \u0027methods\u0027 not in kwargs:"},{"line_number":337,"context_line":"            raise exceptions.OptionError(\"methods is a required option.\")"},{"line_number":338,"context_line":""},{"line_number":339,"context_line":"        self._methods \u003d kwargs[\u0027methods\u0027]"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_f2af9f28","line":336,"range":{"start_line":336,"start_character":12,"end_line":336,"end_character":19},"in_reply_to":"7faddb67_7cfdc806","updated":"2019-08-13 02:37:31.000000000","message":"Done","commit_id":"5cb4a371c1a00170a2be1d4ec20dbe5ea1e1cefc"}],"releasenotes/notes/bug-1839748-5d8dfc99c43aaefc.yaml":[{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"5c01fbd067aa797273dc9cc2b5ed86ba754db0c4","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Keystoneauth now supports MFA authentication and Auth Receipts."},{"line_number":5,"context_line":"    Responses from Keystone containing and auth receipt will now"},{"line_number":6,"context_line":"    raise a ``MissingAuthMethods`` exception which will contain the"}],"source_content_type":"text/x-yaml","patch_set":13,"id":"7faddb67_6853b0e3","line":3,"updated":"2019-08-13 17:43:39.000000000","message":"Reference the rfe bug here","commit_id":"4b044b49f9cd1a95021db424b5ae85a1f3644878"},{"author":{"_account_id":2,"name":"Monty Taylor","email":"mordred@inaugust.com","username":"mordred"},"change_message_id":"c4dd554fe9aedb4a89abfcc4c6c1fdb4e6f5be70","unresolved":false,"context_lines":[{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    [`bug 1839748 \u003chttps://bugs.launchpad.net/keystoneauth/+bug/1839748\u003e`_]"},{"line_number":5,"context_line":"    Keystoneauth now supports MFA authentication and Auth Receipts."},{"line_number":6,"context_line":"    Responses from Keystone containing and auth receipt will now"},{"line_number":7,"context_line":"    raise a ``MissingAuthMethods`` exception which will contain the"},{"line_number":8,"context_line":"    auth receipt itself, and information about the missing methods."},{"line_number":9,"context_line":"    There are now also ways to easily do more than one method when"}],"source_content_type":"text/x-yaml","patch_set":14,"id":"7faddb67_1d47d2be","line":6,"range":{"start_line":6,"start_character":39,"end_line":6,"end_character":42},"updated":"2019-08-14 11:13:35.000000000","message":"an\n\n#notaminusone","commit_id":"6a69e4dfbdc2762445b0f16a9e2c66e06f3b2bab"}],"setup.cfg":[{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"1667b502f252f611ba5ef393caf18a77c2c86f74","unresolved":false,"context_lines":[{"line_number":58,"context_line":"    v3adfspassword \u003d keystoneauth1.extras._saml2._loading:ADFSPassword"},{"line_number":59,"context_line":"    v3samlpassword \u003d keystoneauth1.extras._saml2._loading:Saml2Password"},{"line_number":60,"context_line":"    v3applicationcredential \u003d keystoneauth1.loading._plugins.identity.v3:ApplicationCredential"},{"line_number":61,"context_line":"    v3multifactor \u003d keystoneauth1.loading._plugins.identity.v3:MultiFactor"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"[build_sphinx]"},{"line_number":64,"context_line":"source-dir \u003d doc/source"}],"source_content_type":"text/x-ttcn-cfg","patch_set":10,"id":"7faddb67_d3af297b","line":61,"updated":"2019-08-09 18:53:56.000000000","message":"Do we need the receipt auth method too?","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":10420,"name":"Adrian Turjak","email":"devs+openstack@uncaught-exceptions.com","username":"adriant"},"change_message_id":"8821c8c0515454cabcea0790f26e444b7b20c92d","unresolved":false,"context_lines":[{"line_number":58,"context_line":"    v3adfspassword \u003d keystoneauth1.extras._saml2._loading:ADFSPassword"},{"line_number":59,"context_line":"    v3samlpassword \u003d keystoneauth1.extras._saml2._loading:Saml2Password"},{"line_number":60,"context_line":"    v3applicationcredential \u003d keystoneauth1.loading._plugins.identity.v3:ApplicationCredential"},{"line_number":61,"context_line":"    v3multifactor \u003d keystoneauth1.loading._plugins.identity.v3:MultiFactor"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"[build_sphinx]"},{"line_number":64,"context_line":"source-dir \u003d doc/source"}],"source_content_type":"text/x-ttcn-cfg","patch_set":10,"id":"7faddb67_7d715ba8","line":61,"in_reply_to":"7faddb67_aecb2248","updated":"2019-08-11 05:29:53.000000000","message":"No because there is no auth receipt loader, nor even an auth receipt plugin. It is explicitly just a Method, so it will never make sense outside of the context of either in code auth, or error handling to continue auth.\n\nThere will probably never be an AuthReceipt loader or plugin just because it won\u0027t make sense in the context of the places where the loaders are used.","commit_id":"41ebe17e46a11efe54983357df9399185a473589"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"e15e47077c465de12f8e3449ab82aa82c3ef17c3","unresolved":false,"context_lines":[{"line_number":58,"context_line":"    v3adfspassword \u003d keystoneauth1.extras._saml2._loading:ADFSPassword"},{"line_number":59,"context_line":"    v3samlpassword \u003d keystoneauth1.extras._saml2._loading:Saml2Password"},{"line_number":60,"context_line":"    v3applicationcredential \u003d keystoneauth1.loading._plugins.identity.v3:ApplicationCredential"},{"line_number":61,"context_line":"    v3multifactor \u003d keystoneauth1.loading._plugins.identity.v3:MultiFactor"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"[build_sphinx]"},{"line_number":64,"context_line":"source-dir \u003d doc/source"}],"source_content_type":"text/x-ttcn-cfg","patch_set":10,"id":"7faddb67_aecb2248","line":61,"in_reply_to":"7faddb67_d3af297b","updated":"2019-08-09 20:13:03.000000000","message":"Probably.","commit_id":"41ebe17e46a11efe54983357df9399185a473589"}]}
