)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":29313,"name":"Vishal Manchanda","email":"manchandavishal143@gmail.com","username":"vishalmanchanda"},"change_message_id":"bee7f7f9e8f6cefeb0783ea38cb2933679769b75","unresolved":true,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add TOTP support"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This patch adds support for MFA TOTP on openstack dashboard."},{"line_number":10,"context_line":"A new configuration variable OPENSTACK_KEYSTONE_MFA_TOTP_ENABLED"},{"line_number":11,"context_line":"was added false by default."},{"line_number":12,"context_line":"If enabled, users needing TOTP are prompted with a new form."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"0928b73c_6e794281","line":9,"range":{"start_line":9,"start_character":11,"end_line":9,"end_character":36},"updated":"2023-07-26 16:06:01.000000000","message":"Hi, Could you add the keystone doc. link for this feature, keystone api-ref., and what conf. I need to change in Keystone to enable this feature in my local env..\n\nPlease open a new bp [1]or launchpad bug[2] so we can track it and add that bp/bug link in this commit-msg.\n\n[1] https://blueprints.launchpad.net/horizon/+addspec\n[1] https://bugs.launchpad.net/horizon/+filebug","commit_id":"f200f9863383ba8be91118388db9f8d2abce1c8d"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"aee0af52dfdaf69f0c868d1ab71ebb6a17696f4b","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add TOTP support"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This patch adds support for MFA TOTP on openstack dashboard."},{"line_number":10,"context_line":"A new configuration variable OPENSTACK_KEYSTONE_MFA_TOTP_ENABLED"},{"line_number":11,"context_line":"was added false by default."},{"line_number":12,"context_line":"If enabled, users needing TOTP are prompted with a new form."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"6e376285_883b012a","line":9,"range":{"start_line":9,"start_character":11,"end_line":9,"end_character":36},"in_reply_to":"0928b73c_6e794281","updated":"2023-08-07 09:20:02.000000000","message":"Done","commit_id":"f200f9863383ba8be91118388db9f8d2abce1c8d"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":29313,"name":"Vishal Manchanda","email":"manchandavishal143@gmail.com","username":"vishalmanchanda"},"change_message_id":"bee7f7f9e8f6cefeb0783ea38cb2933679769b75","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"54297714_c04280f6","updated":"2023-07-26 16:06:01.000000000","message":"Please add some documentation link or let me know here or on irc, how can I test your patch. I mean what changes I have to do in my devstack setup to test your patch.","commit_id":"f200f9863383ba8be91118388db9f8d2abce1c8d"},{"author":{"_account_id":6476,"name":"Thomas Goirand","email":"thomas@goirand.fr","username":"thomas-goirand"},"change_message_id":"a12cf8981505be502d8af0c50acd550d11054bde","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"4374ca67_d7eb10cf","updated":"2023-06-08 10:11:39.000000000","message":"The failure is unrelated, it\u0027s a problem in the CI, and could be ignored.","commit_id":"f200f9863383ba8be91118388db9f8d2abce1c8d"},{"author":{"_account_id":6476,"name":"Thomas Goirand","email":"thomas@goirand.fr","username":"thomas-goirand"},"change_message_id":"b73676d560ef6490bce209f83aeae1e97f9297bf","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"f22fabcd_3f2e8d3b","updated":"2023-06-19 08:24:04.000000000","message":"recheck","commit_id":"f200f9863383ba8be91118388db9f8d2abce1c8d"},{"author":{"_account_id":6476,"name":"Thomas Goirand","email":"thomas@goirand.fr","username":"thomas-goirand"},"change_message_id":"aadceb679797f6a04f03e8bd35f71ba626c0efa9","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"f66dc8c8_a1e6c332","updated":"2023-07-14 10:58:12.000000000","message":"recheck","commit_id":"f200f9863383ba8be91118388db9f8d2abce1c8d"},{"author":{"_account_id":29313,"name":"Vishal Manchanda","email":"manchandavishal143@gmail.com","username":"vishalmanchanda"},"change_message_id":"7d13c5a0abe6c89214b73e6acfdabd24c7f583b2","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":19,"id":"2a322451_4eaf1007","updated":"2023-08-10 10:05:28.000000000","message":"Hi, I am trying to test your patch in my devstack env. but can\u0027t see \"TOTP prompted\" for the user. Please find below the steps I have performed to test your patch:\n\n1. Added in my keystone.conf file:\n[auth]\nmethods \u003d external,password,token,oauth1,totp\n\n2. created a user mfa-user and enabled totp for that user with curl request https://paste.openstack.org/show/821055/\n\n3.then followed all the steps mentioned in this video https://www.youtube.com/watch?v\u003dJEniPHp1l74\n\n4.Now I can see totp for mfa-user in \"Aegis\" application on my mobile but where I have to enter that totp in horizon dashboard.\n\nCould you attach some screenshots if this feature is working in your env.","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"45ce7b19bd4110a63e3a14f1fa21184ee9269410","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"16118c68_f111c3b5","updated":"2023-08-08 13:17:12.000000000","message":"One typo and some nitpicks and questions. I didn\u0027t test it yet.","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":6476,"name":"Thomas Goirand","email":"thomas@goirand.fr","username":"thomas-goirand"},"change_message_id":"52bca070e56be5e3d5a29121a96bea3d8b74114c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"28f103b8_e149bc95","updated":"2023-08-07 14:09:00.000000000","message":"recheck","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"786f2df92f9b980d2fe4ef2b9893f3500f15cdc1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"651d0f90_fcccd41d","updated":"2023-08-08 08:09:53.000000000","message":"recheck","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":6476,"name":"Thomas Goirand","email":"thomas@goirand.fr","username":"thomas-goirand"},"change_message_id":"c72f3ff54440e271cd2a7a31cf76c360739f8322","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"7c3637e1_b17c9080","updated":"2023-08-07 11:49:03.000000000","message":"recheck","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":6476,"name":"Thomas Goirand","email":"thomas@goirand.fr","username":"thomas-goirand"},"change_message_id":"1fadba53a5404cf5b2e332faf0d094b68f904c0f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"c8a2fbc2_5f51b61f","updated":"2023-08-07 13:05:05.000000000","message":"recheck","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"1612502d13546fedfc658155d56f7a48ba288381","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"f8baec2a_78b7da00","updated":"2023-08-08 06:39:28.000000000","message":"recheck","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":29313,"name":"Vishal Manchanda","email":"manchandavishal143@gmail.com","username":"vishalmanchanda"},"change_message_id":"fbe175d93f475bbe0c345181480aa40f787e7c58","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":19,"id":"67b1aa47_2f99cfff","in_reply_to":"1bd4b6f5_1587063b","updated":"2023-08-10 15:00:48.000000000","message":"thanks, Could you also drop command line which you used to make the user use \u0027totp\u0027 for authentication on \"https://paste.openstack.org/\" \nIt will help reviewers to test your patch in local env.\nPlease mention all changes required in keystone.conf and ``openstack_auth/defaults.py`` in the horizon side.","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"3795439a711a29c410ffa8fa15a37f13831cfdcd","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":19,"id":"1bd4b6f5_1587063b","in_reply_to":"2a322451_4eaf1007","updated":"2023-08-10 14:39:04.000000000","message":"Here\u0027s a video I just made to show how it works in the dashboard:\nhttps://youtu.be/prDJJdFoMpM","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":29313,"name":"Vishal Manchanda","email":"manchandavishal143@gmail.com","username":"vishalmanchanda"},"change_message_id":"7ac5fade1cf58c123764e15b726326866578e199","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":19,"id":"bed1e741_5d7dab2a","in_reply_to":"67b1aa47_2f99cfff","updated":"2023-08-10 16:28:06.000000000","message":"Also which authenticator you use to generate \u0027totp\u0027","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"a441055bbf14d9e6525f74a2d4a214470c2c31d6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"5c70baca_5b332ef9","in_reply_to":"7b7ff643_0c46e8ff","updated":"2023-08-18 12:05:30.000000000","message":"Done","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":29313,"name":"Vishal Manchanda","email":"manchandavishal143@gmail.com","username":"vishalmanchanda"},"change_message_id":"ee058ea436e2581fb4625a0766451b84f8c4894e","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":19,"id":"bb894ad0_2eae5c4b","in_reply_to":"7e3351aa_de280d06","updated":"2023-08-17 17:26:04.000000000","message":"thanks, it worked. Now I am getting the \"TOTP authentification\" form for the myuser.\n\nOne last thing how I should use \"https://totp.app\" for totp generation.\nI can see two fields in the website that I have to enter \u0027Secret Key\u0027 and \u0027Application Name\u0027. what I have to enter there if you can give me some example like you given above.","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"5de512e1ccd7da368bae057be1cb2795049eedfb","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"7e3351aa_de280d06","in_reply_to":"a78b3e5e_f23cba44","updated":"2023-08-17 12:23:20.000000000","message":"keystone commande to make that user use password and totp:\n\n```\nopenstack credential create --type totp myuser GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ\n```\n```\nopenstack user set --multi-factor-auth-rule password,totp myuser\n```\n```\nopenstack user set --enable-multi-factor-auth myuser\n```\nDon\u0027t forget to add the totp plugin to horizon in `local_setting.py` :\n```\nAUTHENTICATION_PLUGINS \u003d [\u0027openstack_auth.plugin.password.PasswordPlugin\u0027,\n                          \u0027openstack_auth.plugin.token.TokenPlugin\u0027,\n                          \u0027openstack_auth.plugin.totp.TotpPlugin\u0027]\n```\n\nUse the latest version of the patch, an error insert at the beginning.","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"bbdb5b9fee0f67e2139ad731f92a70fd257d3d7d","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":19,"id":"7b7ff643_0c46e8ff","in_reply_to":"bb894ad0_2eae5c4b","updated":"2023-08-17 17:46:45.000000000","message":"The Time based One Time Password is based on the generation of a unique password (secret key) that changes at regular intervals, usually every 30 seconds.\n\nOn \"https://totp.app\" you can enter your secret key in the corresponding field. The secret key is the one you used when ordering \"openstack credential create\", the \u0027Application Name\u0027 is just so you know what your 6 digits correspond to.\n\nIf you want you can write the Secret Key in the Google Authentificator or other TOTP generator.\n\nI hope I\u0027ve helped you 😊","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"f0131664232309bd280f35eb74232ab815ccb535","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":19,"id":"cb71b534_5ef2f9fa","in_reply_to":"bed1e741_5d7dab2a","updated":"2023-08-14 12:11:38.000000000","message":"In ``keystone.conf`` you need to add ``totp`` in auth methods, example:\n```\n[auth]\nmethods \u003d external,password,token,oauth1,totp\n```\n\nIn ``openstack-dashboard/local_settings.py`` you need to add `TotpPlugin` and the value True to ``OPENSTACK_KEYSTONE_MFA_TOTP_ENABLED``, like that: \n```\nOPENSTACK_KEYSTONE_MFA_TOTP_ENABLED \u003d True\n\nAUTHENTICATION_PLUGINS \u003d [\u0027openstack_auth.plugin.password.PasswordPlugin\u0027,\n                          \u0027openstack_auth.plugin.token.TokenPlugin\u0027,\n                          \u0027openstack_auth.plugin.totp.TotpPlugin\u0027]\n```\nYou can write it directly into ``openstack_auth/defaults.py``.\n\n\nI use the website https://totp.app for testing.","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":29313,"name":"Vishal Manchanda","email":"manchandavishal143@gmail.com","username":"vishalmanchanda"},"change_message_id":"5423aaadc81ce624ae355fc227a478ba971cc62f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"a78b3e5e_f23cba44","in_reply_to":"ca287af5_14d230d2","updated":"2023-08-16 14:54:24.000000000","message":"Could you also add some information how can I enable \u0027totp\u0027 for a user. I have already done all the changes in `keystone.conf` and openstack-dashboard/local_settings.py file. But When I try to login I am geeting error \"An error occurred authenticating. Please try again later.\" in horizon login page and can\u0027t see passcode option where I can enter totp. If I look at debug logs https://paste.openstack.org/show/821158/\n\nI want to know keystone command or curl request you used to make that user use password and totp both.","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"17a9e4bd221d29487fb90913fe70f137942f13ee","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"ca287af5_14d230d2","in_reply_to":"cb71b534_5ef2f9fa","updated":"2023-08-15 12:55:55.000000000","message":"Done","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":29313,"name":"Vishal Manchanda","email":"manchandavishal143@gmail.com","username":"vishalmanchanda"},"change_message_id":"4d01a1979bfdc275776ad0f6e8439e591c67f851","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":28,"id":"d6f37ecf_ea8fa46b","updated":"2023-08-18 11:53:26.000000000","message":"Nice work, LGTM. I have two nit comment once it fixed, i will +2 on the patch.","commit_id":"e3b9edb1542e62398a7d44dc0128c7fa7fe35012"},{"author":{"_account_id":6476,"name":"Thomas Goirand","email":"thomas@goirand.fr","username":"thomas-goirand"},"change_message_id":"d3c998a74381c50923d2e7ec6a81f051285ca138","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":28,"id":"5afcf2fa_b91ab11a","updated":"2023-08-15 14:58:33.000000000","message":"recheck","commit_id":"e3b9edb1542e62398a7d44dc0128c7fa7fe35012"},{"author":{"_account_id":29313,"name":"Vishal Manchanda","email":"manchandavishal143@gmail.com","username":"vishalmanchanda"},"change_message_id":"627ea6af6f3d7b60b2b6dd7bf9fc267829aac7ce","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":29,"id":"f5927347_04356a4e","updated":"2023-08-18 12:03:16.000000000","message":"LGTM, thanks.","commit_id":"cb74c8c08f44a227e5f5f51fef8ea670d34e9f11"},{"author":{"_account_id":6476,"name":"Thomas Goirand","email":"thomas@goirand.fr","username":"thomas-goirand"},"change_message_id":"337ac27cf983d23bada8b04f20af6ca8d96264a0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":29,"id":"9402db8b_116bedb6","updated":"2023-08-22 13:45:48.000000000","message":"recheck","commit_id":"cb74c8c08f44a227e5f5f51fef8ea670d34e9f11"},{"author":{"_account_id":6476,"name":"Thomas Goirand","email":"thomas@goirand.fr","username":"thomas-goirand"},"change_message_id":"0bbab8dfefbdd76bc63cbe1303e94cb7fb4a202a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":29,"id":"e56e5bcd_2d192969","updated":"2023-08-22 15:37:56.000000000","message":"recheck","commit_id":"cb74c8c08f44a227e5f5f51fef8ea670d34e9f11"}],"doc/source/configuration/settings.rst":[{"author":{"_account_id":29313,"name":"Vishal Manchanda","email":"manchandavishal143@gmail.com","username":"vishalmanchanda"},"change_message_id":"bee7f7f9e8f6cefeb0783ea38cb2933679769b75","unresolved":true,"context_lines":[{"line_number":610,"context_line":"OPENSTACK_KEYSTONE_MFA_TOTP_ENABLED"},{"line_number":611,"context_line":"-----------------------------------"},{"line_number":612,"context_line":""},{"line_number":613,"context_line":".. versionadded:: 23.2.0(Bobcat)"},{"line_number":614,"context_line":""},{"line_number":615,"context_line":"Default: ``False``"},{"line_number":616,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"e6fb4a60_561f6941","line":613,"range":{"start_line":613,"start_character":18,"end_line":613,"end_character":24},"updated":"2023-07-26 16:06:01.000000000","message":"As \"23.2.0(Bocat) is already released now, please use the next version \"23.2.1\".\nhttps://review.opendev.org/c/openstack/releases/+/888128","commit_id":"f200f9863383ba8be91118388db9f8d2abce1c8d"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"aee0af52dfdaf69f0c868d1ab71ebb6a17696f4b","unresolved":false,"context_lines":[{"line_number":610,"context_line":"OPENSTACK_KEYSTONE_MFA_TOTP_ENABLED"},{"line_number":611,"context_line":"-----------------------------------"},{"line_number":612,"context_line":""},{"line_number":613,"context_line":".. versionadded:: 23.2.0(Bobcat)"},{"line_number":614,"context_line":""},{"line_number":615,"context_line":"Default: ``False``"},{"line_number":616,"context_line":""}],"source_content_type":"text/x-rst","patch_set":6,"id":"036c8e86_ceb5266f","line":613,"range":{"start_line":613,"start_character":18,"end_line":613,"end_character":24},"in_reply_to":"e6fb4a60_561f6941","updated":"2023-08-07 09:20:02.000000000","message":"Done","commit_id":"f200f9863383ba8be91118388db9f8d2abce1c8d"}],"openstack_auth/exceptions.py":[{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"45ce7b19bd4110a63e3a14f1fa21184ee9269410","unresolved":true,"context_lines":[{"line_number":48,"context_line":"    \"\"\"The password is expired and needs to be changed.\"\"\""},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"class KeystoneToptRequired(KeystoneAuthException):"},{"line_number":52,"context_line":"    \"\"\"The passcode TOTP is requirede to authentificate.\"\"\""}],"source_content_type":"text/x-python","patch_set":19,"id":"4846137a_d9dce6dd","line":51,"updated":"2023-08-08 13:17:12.000000000","message":"Should this be called KeystoneTotpRequired? Or even better, KeystoneTOTPRequired?","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"f0131664232309bd280f35eb74232ab815ccb535","unresolved":false,"context_lines":[{"line_number":48,"context_line":"    \"\"\"The password is expired and needs to be changed.\"\"\""},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"class KeystoneToptRequired(KeystoneAuthException):"},{"line_number":52,"context_line":"    \"\"\"The passcode TOTP is requirede to authentificate.\"\"\""}],"source_content_type":"text/x-python","patch_set":19,"id":"b09f3678_ee095823","line":51,"in_reply_to":"4846137a_d9dce6dd","updated":"2023-08-14 12:11:38.000000000","message":"Done","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"}],"openstack_auth/forms.py":[{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"45ce7b19bd4110a63e3a14f1fa21184ee9269410","unresolved":true,"context_lines":[{"line_number":155,"context_line":"            if utils.allow_expired_passowrd_change():"},{"line_number":156,"context_line":"                raise"},{"line_number":157,"context_line":"            raise forms.ValidationError(exc)"},{"line_number":158,"context_line":"        except exceptions.KeystoneToptRequired as exc:"},{"line_number":159,"context_line":"            LOG.info(\u0027Login failed for user \"%(username)s\" using domain \u0027"},{"line_number":160,"context_line":"                     \u0027\"%(domain)s\", remote address %(remote_ip)s: TOTP\u0027"},{"line_number":161,"context_line":"                     \u0027required.\u0027,"}],"source_content_type":"text/x-python","patch_set":19,"id":"a2b6bdd4_0f2cd5d4","line":158,"updated":"2023-08-08 13:17:12.000000000","message":"ditto","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"17a9e4bd221d29487fb90913fe70f137942f13ee","unresolved":false,"context_lines":[{"line_number":155,"context_line":"            if utils.allow_expired_passowrd_change():"},{"line_number":156,"context_line":"                raise"},{"line_number":157,"context_line":"            raise forms.ValidationError(exc)"},{"line_number":158,"context_line":"        except exceptions.KeystoneToptRequired as exc:"},{"line_number":159,"context_line":"            LOG.info(\u0027Login failed for user \"%(username)s\" using domain \u0027"},{"line_number":160,"context_line":"                     \u0027\"%(domain)s\", remote address %(remote_ip)s: TOTP\u0027"},{"line_number":161,"context_line":"                     \u0027required.\u0027,"}],"source_content_type":"text/x-python","patch_set":19,"id":"ff0ec2ad_090b7c9b","line":158,"in_reply_to":"a2b6bdd4_0f2cd5d4","updated":"2023-08-15 12:55:55.000000000","message":"Done","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"45ce7b19bd4110a63e3a14f1fa21184ee9269410","unresolved":true,"context_lines":[{"line_number":255,"context_line":"        return self.cleaned_data"},{"line_number":256,"context_line":""},{"line_number":257,"context_line":""},{"line_number":258,"context_line":"class Totp(forms.Form):"},{"line_number":259,"context_line":"    \"\"\"Form used for TOTP authentification\"\"\""},{"line_number":260,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":261,"context_line":"        super().__init__(*args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":19,"id":"22920fde_d4b62080","line":258,"updated":"2023-08-08 13:17:12.000000000","message":"nitpick: I would call this TimeBasedOneTimePassword, to make it clearer, but I suppose this name is fine too.","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"f0131664232309bd280f35eb74232ab815ccb535","unresolved":false,"context_lines":[{"line_number":255,"context_line":"        return self.cleaned_data"},{"line_number":256,"context_line":""},{"line_number":257,"context_line":""},{"line_number":258,"context_line":"class Totp(forms.Form):"},{"line_number":259,"context_line":"    \"\"\"Form used for TOTP authentification\"\"\""},{"line_number":260,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":261,"context_line":"        super().__init__(*args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":19,"id":"54def587_cdd0c353","line":258,"in_reply_to":"22920fde_d4b62080","updated":"2023-08-14 12:11:38.000000000","message":"Done","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"45ce7b19bd4110a63e3a14f1fa21184ee9269410","unresolved":true,"context_lines":[{"line_number":264,"context_line":"                \u0027totp\u0027,"},{"line_number":265,"context_line":"                forms.CharField(label\u003d_(\"Passcode\"),"},{"line_number":266,"context_line":"                                required\u003dTrue,"},{"line_number":267,"context_line":"                                widget\u003dforms.TextInput("},{"line_number":268,"context_line":"                                attrs\u003d{\"autofocus\": \"autofocus\"}))"},{"line_number":269,"context_line":"            )"},{"line_number":270,"context_line":"        ])"}],"source_content_type":"text/x-python","patch_set":19,"id":"ec9033f2_774b1b7b","line":267,"updated":"2023-08-08 13:17:12.000000000","message":"Do we want to use the forms.PasswordInput widget in here?","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"5682859fc58e2a10d519c36ccce3d609c4ed6d54","unresolved":true,"context_lines":[{"line_number":264,"context_line":"                \u0027totp\u0027,"},{"line_number":265,"context_line":"                forms.CharField(label\u003d_(\"Passcode\"),"},{"line_number":266,"context_line":"                                required\u003dTrue,"},{"line_number":267,"context_line":"                                widget\u003dforms.TextInput("},{"line_number":268,"context_line":"                                attrs\u003d{\"autofocus\": \"autofocus\"}))"},{"line_number":269,"context_line":"            )"},{"line_number":270,"context_line":"        ])"}],"source_content_type":"text/x-python","patch_set":19,"id":"f6d0abc3_7e753f0b","line":267,"in_reply_to":"ec9033f2_774b1b7b","updated":"2023-08-08 14:06:09.000000000","message":"For most TOTP connections, the 6-digit passcode is visible to the user. However, we could add a maximum number of characters to the text-input and limit it to digits only.","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"17a9e4bd221d29487fb90913fe70f137942f13ee","unresolved":false,"context_lines":[{"line_number":264,"context_line":"                \u0027totp\u0027,"},{"line_number":265,"context_line":"                forms.CharField(label\u003d_(\"Passcode\"),"},{"line_number":266,"context_line":"                                required\u003dTrue,"},{"line_number":267,"context_line":"                                widget\u003dforms.TextInput("},{"line_number":268,"context_line":"                                attrs\u003d{\"autofocus\": \"autofocus\"}))"},{"line_number":269,"context_line":"            )"},{"line_number":270,"context_line":"        ])"}],"source_content_type":"text/x-python","patch_set":19,"id":"e37fce39_adc3f2b6","line":267,"in_reply_to":"f6d0abc3_7e753f0b","updated":"2023-08-15 12:55:55.000000000","message":"Done","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"45ce7b19bd4110a63e3a14f1fa21184ee9269410","unresolved":true,"context_lines":[{"line_number":274,"context_line":"        default_domain \u003d settings.OPENSTACK_KEYSTONE_DEFAULT_DOMAIN"},{"line_number":275,"context_line":"        request \u003d self.initial[\u0027request\u0027]"},{"line_number":276,"context_line":"        domain \u003d self.initial[\u0027domain\u0027]"},{"line_number":277,"context_line":"        if domain \u003d\u003d \"\":"},{"line_number":278,"context_line":"            domain \u003d default_domain"},{"line_number":279,"context_line":"        username \u003d self.initial[\u0027username\u0027]"},{"line_number":280,"context_line":"        receipt \u003d self.initial[\u0027receipt\u0027]"}],"source_content_type":"text/x-python","patch_set":19,"id":"fc42b92a_a54d9ad5","line":277,"updated":"2023-08-08 13:17:12.000000000","message":"nitpick: I would do \"if not domain:\" here, so that None is also handled.","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"17a9e4bd221d29487fb90913fe70f137942f13ee","unresolved":false,"context_lines":[{"line_number":274,"context_line":"        default_domain \u003d settings.OPENSTACK_KEYSTONE_DEFAULT_DOMAIN"},{"line_number":275,"context_line":"        request \u003d self.initial[\u0027request\u0027]"},{"line_number":276,"context_line":"        domain \u003d self.initial[\u0027domain\u0027]"},{"line_number":277,"context_line":"        if domain \u003d\u003d \"\":"},{"line_number":278,"context_line":"            domain \u003d default_domain"},{"line_number":279,"context_line":"        username \u003d self.initial[\u0027username\u0027]"},{"line_number":280,"context_line":"        receipt \u003d self.initial[\u0027receipt\u0027]"}],"source_content_type":"text/x-python","patch_set":19,"id":"8bca956f_96a91f1d","line":277,"in_reply_to":"fc42b92a_a54d9ad5","updated":"2023-08-15 12:55:55.000000000","message":"Done","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"}],"openstack_auth/tests/data_v3.py":[{"author":{"_account_id":29313,"name":"Vishal Manchanda","email":"manchandavishal143@gmail.com","username":"vishalmanchanda"},"change_message_id":"4d01a1979bfdc275776ad0f6e8439e591c67f851","unresolved":true,"context_lines":[{"line_number":102,"context_line":"    test_data.user \u003d users.User(users.UserManager(None),"},{"line_number":103,"context_line":"                                user_dict, loaded\u003dTrue)"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    # Projects"},{"line_number":106,"context_line":"    project_dict_1 \u003d {\u0027id\u0027: uuid.uuid4().hex,"},{"line_number":107,"context_line":"                      \u0027name\u0027: \u0027tenant_one\u0027,"},{"line_number":108,"context_line":"                      \u0027description\u0027: \u0027\u0027,"}],"source_content_type":"text/x-python","patch_set":28,"id":"5bce7e4b_e21b3392","side":"PARENT","line":105,"range":{"start_line":105,"start_character":4,"end_line":105,"end_character":14},"updated":"2023-08-18 11:53:26.000000000","message":"super nit: there is no need to remove this comment.","commit_id":"3c5006efb4533e1cf0815fb80ede86b7a38a40bf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"5417a4eab62f810d8901e2840b483a9b222c6d3e","unresolved":false,"context_lines":[{"line_number":102,"context_line":"    test_data.user \u003d users.User(users.UserManager(None),"},{"line_number":103,"context_line":"                                user_dict, loaded\u003dTrue)"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    # Projects"},{"line_number":106,"context_line":"    project_dict_1 \u003d {\u0027id\u0027: uuid.uuid4().hex,"},{"line_number":107,"context_line":"                      \u0027name\u0027: \u0027tenant_one\u0027,"},{"line_number":108,"context_line":"                      \u0027description\u0027: \u0027\u0027,"}],"source_content_type":"text/x-python","patch_set":28,"id":"26dab146_3ed6f31b","side":"PARENT","line":105,"range":{"start_line":105,"start_character":4,"end_line":105,"end_character":14},"in_reply_to":"5bce7e4b_e21b3392","updated":"2023-08-18 12:03:19.000000000","message":"Done","commit_id":"3c5006efb4533e1cf0815fb80ede86b7a38a40bf"}],"openstack_auth/tests/unit/test_auth.py":[{"author":{"_account_id":29313,"name":"Vishal Manchanda","email":"manchandavishal143@gmail.com","username":"vishalmanchanda"},"change_message_id":"4d01a1979bfdc275776ad0f6e8439e591c67f851","unresolved":true,"context_lines":[{"line_number":1500,"context_line":""},{"line_number":1501,"context_line":"        # POST to the page to acces at TOTP authentification page."},{"line_number":1502,"context_line":"        response \u003d self.client.post(url, form_data)"},{"line_number":1503,"context_line":"        print(response)"},{"line_number":1504,"context_line":"        self.assertEqual(response.status_code, 302)"},{"line_number":1505,"context_line":"        self.assertEqual(response.url, \"/totp/%s/\" % user.name)"},{"line_number":1506,"context_line":""}],"source_content_type":"text/x-python","patch_set":28,"id":"3f48b6b1_776fbd24","line":1503,"range":{"start_line":1503,"start_character":8,"end_line":1503,"end_character":23},"updated":"2023-08-18 11:53:26.000000000","message":"there is no need to print response, please remove it.","commit_id":"e3b9edb1542e62398a7d44dc0128c7fa7fe35012"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"5417a4eab62f810d8901e2840b483a9b222c6d3e","unresolved":false,"context_lines":[{"line_number":1500,"context_line":""},{"line_number":1501,"context_line":"        # POST to the page to acces at TOTP authentification page."},{"line_number":1502,"context_line":"        response \u003d self.client.post(url, form_data)"},{"line_number":1503,"context_line":"        print(response)"},{"line_number":1504,"context_line":"        self.assertEqual(response.status_code, 302)"},{"line_number":1505,"context_line":"        self.assertEqual(response.url, \"/totp/%s/\" % user.name)"},{"line_number":1506,"context_line":""}],"source_content_type":"text/x-python","patch_set":28,"id":"3915bc2f_7e811842","line":1503,"range":{"start_line":1503,"start_character":8,"end_line":1503,"end_character":23},"in_reply_to":"3f48b6b1_776fbd24","updated":"2023-08-18 12:03:19.000000000","message":"Done","commit_id":"e3b9edb1542e62398a7d44dc0128c7fa7fe35012"}],"openstack_auth/views.py":[{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"45ce7b19bd4110a63e3a14f1fa21184ee9269410","unresolved":true,"context_lines":[{"line_number":166,"context_line":"    except exceptions.KeystoneToptRequired as exc:"},{"line_number":167,"context_line":"        res \u003d django_http.HttpResponseRedirect("},{"line_number":168,"context_line":"            reverse(\u0027totp\u0027, args\u003d[request.POST.get(\u0027username\u0027)]))"},{"line_number":169,"context_line":"        request.session[\u0027receipt\u0027] \u003d exc.receipt"},{"line_number":170,"context_line":"        request.session[\u0027domain\u0027] \u003d request.POST.get(\u0027domain\u0027)"},{"line_number":171,"context_line":"    except exceptions.KeystonePassExpiredException as exc:"},{"line_number":172,"context_line":"        res \u003d django_http.HttpResponseRedirect("}],"source_content_type":"text/x-python","patch_set":19,"id":"a1aaacbb_9e98b987","line":169,"updated":"2023-08-08 13:17:12.000000000","message":"I wonder if we should use the logout message mechanism here instead?","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"6394c52895dff28195d1b4385c81244a96e1e4b0","unresolved":true,"context_lines":[{"line_number":166,"context_line":"    except exceptions.KeystoneToptRequired as exc:"},{"line_number":167,"context_line":"        res \u003d django_http.HttpResponseRedirect("},{"line_number":168,"context_line":"            reverse(\u0027totp\u0027, args\u003d[request.POST.get(\u0027username\u0027)]))"},{"line_number":169,"context_line":"        request.session[\u0027receipt\u0027] \u003d exc.receipt"},{"line_number":170,"context_line":"        request.session[\u0027domain\u0027] \u003d request.POST.get(\u0027domain\u0027)"},{"line_number":171,"context_line":"    except exceptions.KeystonePassExpiredException as exc:"},{"line_number":172,"context_line":"        res \u003d django_http.HttpResponseRedirect("}],"source_content_type":"text/x-python","patch_set":19,"id":"76cf7f23_23982164","line":169,"in_reply_to":"5b1ec97b_41a95b2b","updated":"2023-08-16 14:02:57.000000000","message":"You are creating a new session variable just to be able to retain a potential error message. But we already have a mechanism for retaining and displaying an error message on the login screen: the logout reason variable. I wonder if you could use that instead. See \n https://github.com/openstack/horizon/blob/master/horizon/utils/functions.py#L41\n \n I might be wrong about what you need here exactly, in that case just ignore this.","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"03aeb56760c53c4c04139a60e0bbab16053b02c4","unresolved":false,"context_lines":[{"line_number":166,"context_line":"    except exceptions.KeystoneToptRequired as exc:"},{"line_number":167,"context_line":"        res \u003d django_http.HttpResponseRedirect("},{"line_number":168,"context_line":"            reverse(\u0027totp\u0027, args\u003d[request.POST.get(\u0027username\u0027)]))"},{"line_number":169,"context_line":"        request.session[\u0027receipt\u0027] \u003d exc.receipt"},{"line_number":170,"context_line":"        request.session[\u0027domain\u0027] \u003d request.POST.get(\u0027domain\u0027)"},{"line_number":171,"context_line":"    except exceptions.KeystonePassExpiredException as exc:"},{"line_number":172,"context_line":"        res \u003d django_http.HttpResponseRedirect("}],"source_content_type":"text/x-python","patch_set":19,"id":"2fcd7554_82d89ee2","line":169,"in_reply_to":"76cf7f23_23982164","updated":"2023-08-16 14:29:06.000000000","message":"I need here exactly because I need this error message to redirect the user to the TOTP forms. If the user doesn\u0027t use their correct login credentials, they\u0027ll stay on the basic login form","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"17a9e4bd221d29487fb90913fe70f137942f13ee","unresolved":true,"context_lines":[{"line_number":166,"context_line":"    except exceptions.KeystoneToptRequired as exc:"},{"line_number":167,"context_line":"        res \u003d django_http.HttpResponseRedirect("},{"line_number":168,"context_line":"            reverse(\u0027totp\u0027, args\u003d[request.POST.get(\u0027username\u0027)]))"},{"line_number":169,"context_line":"        request.session[\u0027receipt\u0027] \u003d exc.receipt"},{"line_number":170,"context_line":"        request.session[\u0027domain\u0027] \u003d request.POST.get(\u0027domain\u0027)"},{"line_number":171,"context_line":"    except exceptions.KeystonePassExpiredException as exc:"},{"line_number":172,"context_line":"        res \u003d django_http.HttpResponseRedirect("}],"source_content_type":"text/x-python","patch_set":19,"id":"5b1ec97b_41a95b2b","line":169,"in_reply_to":"a1aaacbb_9e98b987","updated":"2023-08-15 12:55:55.000000000","message":"I don\u0027t understand what you mean.","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"45ce7b19bd4110a63e3a14f1fa21184ee9269410","unresolved":true,"context_lines":[{"line_number":492,"context_line":""},{"line_number":493,"context_line":""},{"line_number":494,"context_line":"class TotpView(edit_views.FormView):"},{"line_number":495,"context_line":"    \"\"\"Los\u0027s user with the TOTP authentification\"\"\""},{"line_number":496,"context_line":"    template_name \u003d \u0027auth/totp.html\u0027"},{"line_number":497,"context_line":"    form_class \u003d forms.Totp"},{"line_number":498,"context_line":"    success_url \u003d settings.LOGIN_REDIRECT_URL"}],"source_content_type":"text/x-python","patch_set":19,"id":"8a3d8ca6_4f388856","line":495,"updated":"2023-08-08 13:17:12.000000000","message":"What does \"Los\u0027s\" mean?","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"f0131664232309bd280f35eb74232ab815ccb535","unresolved":false,"context_lines":[{"line_number":492,"context_line":""},{"line_number":493,"context_line":""},{"line_number":494,"context_line":"class TotpView(edit_views.FormView):"},{"line_number":495,"context_line":"    \"\"\"Los\u0027s user with the TOTP authentification\"\"\""},{"line_number":496,"context_line":"    template_name \u003d \u0027auth/totp.html\u0027"},{"line_number":497,"context_line":"    form_class \u003d forms.Totp"},{"line_number":498,"context_line":"    success_url \u003d settings.LOGIN_REDIRECT_URL"}],"source_content_type":"text/x-python","patch_set":19,"id":"e26fe326_6ab3ba2f","line":495,"in_reply_to":"8a3d8ca6_4f388856","updated":"2023-08-14 12:11:38.000000000","message":"Done","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"}],"releasenotes/notes/add-totp-support-d14d01b038e5deea.yaml":[{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"45ce7b19bd4110a63e3a14f1fa21184ee9269410","unresolved":true,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Add suport for TOTP."}],"source_content_type":"text/x-yaml","patch_set":19,"id":"c2c3cf2b_c9d78367","line":4,"updated":"2023-08-08 13:17:12.000000000","message":"nitpick: I would spell out TOTP as Time-based One-time Passwords, to make it easier to understand","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"},{"author":{"_account_id":36012,"name":"Benjamin Lasseye","display_name":"Benjamin Lasseye","email":"blasseye@ikmail.com","username":"blasseye"},"change_message_id":"19a80d3059a5b365f360a368de5faa42a2723f08","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":"    Add suport for TOTP."}],"source_content_type":"text/x-yaml","patch_set":19,"id":"8cb07140_c89cce18","line":4,"in_reply_to":"c2c3cf2b_c9d78367","updated":"2023-08-14 12:23:13.000000000","message":"Done","commit_id":"16e5e373a00be3547d9e6f9f18fd3332d49dafaf"}]}
