)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"931b00887700a79aa0a3b7b93b52cf5c8367ab8d","unresolved":false,"context_lines":[{"line_number":20,"context_line":"via the self-service API."},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"The minimum password age does not impact the administrative password"},{"line_number":23,"context_line":"chane (via a USER UPDATE rest call)."},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"Change-Id: Icf1776c5fe625c2e9292bfcf40a8a9f17a002656"},{"line_number":26,"context_line":"closes-bug: #1755874"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"bf659307_64b87ec7","line":23,"range":{"start_line":23,"start_character":0,"end_line":23,"end_character":5},"updated":"2018-04-11 20:54:12.000000000","message":"change","commit_id":"0e7378225b94adb32d6b27234ad002fba27e8e91"}],"doc/source/admin/identity-security-compliance.rst":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"337e80f4e1c131eaade26eecddbfcaf8a6d9c4aa","unresolved":false,"context_lines":[{"line_number":229,"context_line":"   {"},{"line_number":230,"context_line":"       \"user\": {"},{"line_number":231,"context_line":"           \"options\": {"},{"line_number":232,"context_line":"               \"min_password_age\": \u003cinteger\u003e"},{"line_number":233,"context_line":"           }"},{"line_number":234,"context_line":"       }"},{"line_number":235,"context_line":"   }"}],"source_content_type":"text/x-rst","patch_set":3,"id":"bf659307_d03c0bc1","line":232,"range":{"start_line":232,"start_character":34,"end_line":232,"end_character":44},"updated":"2018-04-06 22:56:31.000000000","message":"must be an actual int.","commit_id":"7ce96f22e09ab1de0a93eaf6b683ab9ef019093b"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"ee04cfa875e5997f7b4bfff0c7e748aefa4527a2","unresolved":false,"context_lines":[{"line_number":229,"context_line":"   {"},{"line_number":230,"context_line":"       \"user\": {"},{"line_number":231,"context_line":"           \"options\": {"},{"line_number":232,"context_line":"               \"min_password_age\": \u003cinteger\u003e"},{"line_number":233,"context_line":"           }"},{"line_number":234,"context_line":"       }"},{"line_number":235,"context_line":"   }"}],"source_content_type":"text/x-rst","patch_set":3,"id":"bf659307_f06eefc7","line":232,"range":{"start_line":232,"start_character":34,"end_line":232,"end_character":44},"in_reply_to":"bf659307_d03c0bc1","updated":"2018-04-06 22:58:16.000000000","message":"Done","commit_id":"7ce96f22e09ab1de0a93eaf6b683ab9ef019093b"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4fec932bae1d4145dba54f8002c3c5a5dcc6b5aa","unresolved":false,"context_lines":[{"line_number":220,"context_line":"be used \"forever\"; this is typically used where passwords are managed via an"},{"line_number":221,"context_line":"external system."},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"If there exists a user whose min password age should be longer than the"},{"line_number":224,"context_line":"default, keystone supports setting that user\u0027s option ``min_password_age`` to"},{"line_number":225,"context_line":"and integer via user update API (``PATCH /v3/users/{user_id}``):"},{"line_number":226,"context_line":""}],"source_content_type":"text/x-rst","patch_set":4,"id":"bf659307_0f2484c5","line":223,"range":{"start_line":223,"start_character":29,"end_line":223,"end_character":32},"updated":"2018-04-09 17:56:59.000000000","message":"nit: minimum","commit_id":"e21d907045efa800effdc2ee124eaf824ee2b1bd"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"7a8498c31168e001d8bd493456ebad57f4580ada","unresolved":false,"context_lines":[{"line_number":220,"context_line":"be used \"forever\"; this is typically used where passwords are managed via an"},{"line_number":221,"context_line":"external system."},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"If there exists a user whose min password age should be longer than the"},{"line_number":224,"context_line":"default, keystone supports setting that user\u0027s option ``min_password_age`` to"},{"line_number":225,"context_line":"and integer via user update API (``PATCH /v3/users/{user_id}``):"},{"line_number":226,"context_line":""}],"source_content_type":"text/x-rst","patch_set":4,"id":"bf659307_70c6fb6a","line":223,"range":{"start_line":223,"start_character":29,"end_line":223,"end_character":32},"in_reply_to":"bf659307_0f2484c5","updated":"2018-04-12 19:32:27.000000000","message":"Done","commit_id":"e21d907045efa800effdc2ee124eaf824ee2b1bd"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"6a569607de563ce9fb5182ed6e2dcdbd6cd648e0","unresolved":false,"context_lines":[{"line_number":244,"context_line":""},{"line_number":245,"context_line":"The ``lock_password`` user-option is typically used in the case where passwords"},{"line_number":246,"context_line":"are managed externally to keystone. The ``lock_password`` option can be set to"},{"line_number":247,"context_line":"``True``, ``False``, or ``None``; if the option is set to ``None``, it is"},{"line_number":248,"context_line":"removed from the user\u0027s data structure."},{"line_number":249,"context_line":""},{"line_number":250,"context_line":".. _Security Hardening PCI-DSS: https://specs.openstack.org/openstack/keystone-specs/specs/keystone/newton/pci-dss.html"}],"source_content_type":"text/x-rst","patch_set":8,"id":"bf659307_ac963fef","line":247,"range":{"start_line":247,"start_character":26,"end_line":247,"end_character":30},"updated":"2018-04-13 19:08:07.000000000","message":"Testing this locally and it\u0027s not possible to pass this in from the API because it appears to fail our jsonschema validation [0]. Otherwise True and False operate as expected.\n\n[0] http://paste.openstack.org/show/719185/","commit_id":"551eaa13bf08e8559657c9655e6bbc32ed741972"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4e16db9cd0883d95176a7d1d73a478b7cd64d883","unresolved":false,"context_lines":[{"line_number":244,"context_line":""},{"line_number":245,"context_line":"The ``lock_password`` user-option is typically used in the case where passwords"},{"line_number":246,"context_line":"are managed externally to keystone. The ``lock_password`` option can be set to"},{"line_number":247,"context_line":"``True``, ``False``, or ``None``; if the option is set to ``None``, it is"},{"line_number":248,"context_line":"removed from the user\u0027s data structure."},{"line_number":249,"context_line":""},{"line_number":250,"context_line":".. _Security Hardening PCI-DSS: https://specs.openstack.org/openstack/keystone-specs/specs/keystone/newton/pci-dss.html"}],"source_content_type":"text/x-rst","patch_set":8,"id":"bf659307_e051960f","line":247,"range":{"start_line":247,"start_character":26,"end_line":247,"end_character":30},"in_reply_to":"bf659307_4f70b572","updated":"2018-04-13 21:33:03.000000000","message":"++ your other patch fixed it for me.","commit_id":"551eaa13bf08e8559657c9655e6bbc32ed741972"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"b47160214303ce51b04492daf48b8249c53f5cff","unresolved":false,"context_lines":[{"line_number":244,"context_line":""},{"line_number":245,"context_line":"The ``lock_password`` user-option is typically used in the case where passwords"},{"line_number":246,"context_line":"are managed externally to keystone. The ``lock_password`` option can be set to"},{"line_number":247,"context_line":"``True``, ``False``, or ``None``; if the option is set to ``None``, it is"},{"line_number":248,"context_line":"removed from the user\u0027s data structure."},{"line_number":249,"context_line":""},{"line_number":250,"context_line":".. _Security Hardening PCI-DSS: https://specs.openstack.org/openstack/keystone-specs/specs/keystone/newton/pci-dss.html"}],"source_content_type":"text/x-rst","patch_set":8,"id":"bf659307_4f70b572","line":247,"range":{"start_line":247,"start_character":26,"end_line":247,"end_character":30},"in_reply_to":"bf659307_ac963fef","updated":"2018-04-13 19:28:57.000000000","message":"None should be explicitly allowed for any/all resource options. If not, there is a bug in resource options code.","commit_id":"551eaa13bf08e8559657c9655e6bbc32ed741972"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"50672a29b80b64fe4cab083290cc7f868740a495","unresolved":false,"context_lines":[{"line_number":227,"context_line":"Prevent Self-Service Password Changes"},{"line_number":228,"context_line":"-------------------------------------"},{"line_number":229,"context_line":""},{"line_number":230,"context_line":"If there exists a user whose should not be able to change her own password via"},{"line_number":231,"context_line":"the keystone password change API, keystone supports setting that user\u0027s option"},{"line_number":232,"context_line":"``lock_password`` to ``True`` via the user update API"},{"line_number":233,"context_line":"(``PATCH /v3/users/{user_id}``):"}],"source_content_type":"text/x-rst","patch_set":11,"id":"9f6a8fd7_d7e17dd2","line":230,"range":{"start_line":230,"start_character":23,"end_line":230,"end_character":28},"updated":"2018-04-16 20:59:59.000000000","message":"nit: who*","commit_id":"5864145b71e707b5e61b48235d93411c4fb91279"}],"keystone/conf/security_compliance.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"04ba8f9c76d7c4741bf4ec5517ff3b4432174aa5","unresolved":false,"context_lines":[{"line_number":87,"context_line":"out their password history and reuse an old password. This feature does not"},{"line_number":88,"context_line":"prevent administrators from manually resetting passwords. It is disabled by"},{"line_number":89,"context_line":"default and allows for immediate password changes. This feature depends on the"},{"line_number":90,"context_line":"`sql` backend for the `[identity] driver`. The user option `min_password_age`"},{"line_number":91,"context_line":"will override this value for that individual user if the override is greater"},{"line_number":92,"context_line":"than the configured value. A `-1` value for the user option `min_password_age`"},{"line_number":93,"context_line":"will prevent the specific user from using the self-service password change"},{"line_number":94,"context_line":"API. Note: If `[security_compliance] password_expires_days` is set, then the"},{"line_number":95,"context_line":"value for this option should be less than the `password_expires_days`."},{"line_number":96,"context_line":"\"\"\"))"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"password_regex \u003d cfg.StrOpt("}],"source_content_type":"text/x-python","patch_set":7,"id":"bf659307_381a6c6e","line":95,"range":{"start_line":90,"start_character":43,"end_line":95,"end_character":37},"updated":"2018-04-13 16:16:08.000000000","message":"Need to revert this text.","commit_id":"3e2ed9ac5a94a41628c878ad4215e4138117faf2"}],"keystone/exception.py":[{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"660cb5b4afb814a1b9269247281ab2826db8c65b","unresolved":false,"context_lines":[{"line_number":122,"context_line":"class PasswordAgeValidationErrorForever(PasswordAgeValidationError):"},{"line_number":123,"context_line":"    message_format \u003d _(\"You cannot change your password at this time due \""},{"line_number":124,"context_line":"                       \"to password policy disallowing password changes. \""},{"line_number":125,"context_line":"                       \"Please contact your administrator reset your \""},{"line_number":126,"context_line":"                       \"password.\")"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"bf659307_6d476cbe","line":125,"range":{"start_line":125,"start_character":57,"end_line":125,"end_character":58},"updated":"2018-04-06 22:19:13.000000000","message":"May need a \"to\" here","commit_id":"7ce96f22e09ab1de0a93eaf6b683ab9ef019093b"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"ee04cfa875e5997f7b4bfff0c7e748aefa4527a2","unresolved":false,"context_lines":[{"line_number":122,"context_line":"class PasswordAgeValidationErrorForever(PasswordAgeValidationError):"},{"line_number":123,"context_line":"    message_format \u003d _(\"You cannot change your password at this time due \""},{"line_number":124,"context_line":"                       \"to password policy disallowing password changes. \""},{"line_number":125,"context_line":"                       \"Please contact your administrator reset your \""},{"line_number":126,"context_line":"                       \"password.\")"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"bf659307_1074c398","line":125,"range":{"start_line":125,"start_character":57,"end_line":125,"end_character":58},"in_reply_to":"bf659307_6d476cbe","updated":"2018-04-06 22:58:16.000000000","message":"Done","commit_id":"7ce96f22e09ab1de0a93eaf6b683ab9ef019093b"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4fec932bae1d4145dba54f8002c3c5a5dcc6b5aa","unresolved":false,"context_lines":[{"line_number":122,"context_line":"class PasswordAgeValidationErrorForever(PasswordAgeValidationError):"},{"line_number":123,"context_line":"    message_format \u003d _(\"You cannot change your password at this time due \""},{"line_number":124,"context_line":"                       \"to password policy disallowing password changes. \""},{"line_number":125,"context_line":"                       \"Please contact your administrator to reset your \""},{"line_number":126,"context_line":"                       \"password.\")"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"class SchemaValidationError(ValidationError):"}],"source_content_type":"text/x-python","patch_set":4,"id":"bf659307_924c3777","line":126,"range":{"start_line":125,"start_character":57,"end_line":126,"end_character":32},"updated":"2018-04-09 17:56:59.000000000","message":"nit: I wonder if we should leave this bit off. Only because it\u0027ll be hard for us to assume that even an administrator will change a password. If an external system is managing this stuff, then they can enforce whatever policy they want.","commit_id":"e21d907045efa800effdc2ee124eaf824ee2b1bd"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"09011470dffffd8ca0486294d314cb5e08c3d03a","unresolved":false,"context_lines":[{"line_number":122,"context_line":"class PasswordAgeValidationErrorForever(PasswordAgeValidationError):"},{"line_number":123,"context_line":"    message_format \u003d _(\"You cannot change your password at this time due \""},{"line_number":124,"context_line":"                       \"to password policy disallowing password changes. \""},{"line_number":125,"context_line":"                       \"Please contact your administrator to reset your \""},{"line_number":126,"context_line":"                       \"password.\")"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"class SchemaValidationError(ValidationError):"}],"source_content_type":"text/x-python","patch_set":4,"id":"bf659307_9c8c4980","line":126,"range":{"start_line":125,"start_character":57,"end_line":126,"end_character":32},"in_reply_to":"bf659307_7eb7ecd9","updated":"2018-04-09 20:58:00.000000000","message":"That\u0027s fair.","commit_id":"e21d907045efa800effdc2ee124eaf824ee2b1bd"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"e58f327084c16d83d705533868e54378dc60a6b1","unresolved":false,"context_lines":[{"line_number":122,"context_line":"class PasswordAgeValidationErrorForever(PasswordAgeValidationError):"},{"line_number":123,"context_line":"    message_format \u003d _(\"You cannot change your password at this time due \""},{"line_number":124,"context_line":"                       \"to password policy disallowing password changes. \""},{"line_number":125,"context_line":"                       \"Please contact your administrator to reset your \""},{"line_number":126,"context_line":"                       \"password.\")"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"class SchemaValidationError(ValidationError):"}],"source_content_type":"text/x-python","patch_set":4,"id":"bf659307_7eb7ecd9","line":126,"range":{"start_line":125,"start_character":57,"end_line":126,"end_character":32},"in_reply_to":"bf659307_924c3777","updated":"2018-04-09 20:35:18.000000000","message":"Nah, I think this is valid. If someone wants a password changed, ask the admin. They can say \"use system X\" or otherwise.","commit_id":"e21d907045efa800effdc2ee124eaf824ee2b1bd"}],"keystone/identity/backends/resource_options.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"6a569607de563ce9fb5182ed6e2dcdbd6cd648e0","unresolved":false,"context_lines":[{"line_number":80,"context_line":"    resource_options.ResourceOption("},{"line_number":81,"context_line":"        option_id\u003d\u00271003\u0027,"},{"line_number":82,"context_line":"        option_name\u003d\u0027lock_password\u0027,"},{"line_number":83,"context_line":"        validator\u003dresource_options.boolean_validator,"},{"line_number":84,"context_line":"        json_schema_validation\u003dparameter_types.boolean))"},{"line_number":85,"context_line":"MFA_RULES_OPT \u003d ("},{"line_number":86,"context_line":"    resource_options.ResourceOption("}],"source_content_type":"text/x-python","patch_set":8,"id":"bf659307_4c8523ac","line":83,"range":{"start_line":83,"start_character":18,"end_line":83,"end_character":53},"updated":"2018-04-13 19:08:07.000000000","message":"I think this is causing issues with None or null in order to remove the option from the user reference.","commit_id":"551eaa13bf08e8559657c9655e6bbc32ed741972"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"b47160214303ce51b04492daf48b8249c53f5cff","unresolved":false,"context_lines":[{"line_number":80,"context_line":"    resource_options.ResourceOption("},{"line_number":81,"context_line":"        option_id\u003d\u00271003\u0027,"},{"line_number":82,"context_line":"        option_name\u003d\u0027lock_password\u0027,"},{"line_number":83,"context_line":"        validator\u003dresource_options.boolean_validator,"},{"line_number":84,"context_line":"        json_schema_validation\u003dparameter_types.boolean))"},{"line_number":85,"context_line":"MFA_RULES_OPT \u003d ("},{"line_number":86,"context_line":"    resource_options.ResourceOption("}],"source_content_type":"text/x-python","patch_set":8,"id":"bf659307_af0631cd","line":83,"range":{"start_line":83,"start_character":18,"end_line":83,"end_character":53},"in_reply_to":"bf659307_4c8523ac","updated":"2018-04-13 19:28:57.000000000","message":"None should always be allowed in resource-options, see other comment. This is for loading from DB, the json_schema validator down below is for the API validation)","commit_id":"551eaa13bf08e8559657c9655e6bbc32ed741972"}],"keystone/identity/backends/sql.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4fec932bae1d4145dba54f8002c3c5a5dcc6b5aa","unresolved":false,"context_lines":[{"line_number":261,"context_line":"            options.MIN_PASSWORD_AGE_OPT.option_id)"},{"line_number":262,"context_line":"        if override_opt is not None:"},{"line_number":263,"context_line":"            min_password_age_override \u003d override_opt.option_value"},{"line_number":264,"context_line":"        # NOTE(notmorgan): If the override *or* the min password age is"},{"line_number":265,"context_line":"        # configured as -1, password changes are disallowed. This indicates"},{"line_number":266,"context_line":"        # the password must be used forever. This is intended to be used in"},{"line_number":267,"context_line":"        # cases where the user\u0027s password is managed via external systems or"},{"line_number":268,"context_line":"        # if the user is a short-lived user with no need for password changes."}],"source_content_type":"text/x-python","patch_set":4,"id":"bf659307_52f21f08","line":265,"range":{"start_line":264,"start_character":27,"end_line":265,"end_character":60},"updated":"2018-04-09 17:56:59.000000000","message":"Doesn\u0027t this kind of defeat the purpose of an override? I wonder if we should be more prescriptive of how this should be used. Without diving in to the implementation details, I could see this playing out a few different ways;\n\n1.) An operator sets CONF.security_compliance.minimum_password_age \u003d -1, meaning no one can change their password. Should they be able to override the global configuration option for specific users (e.g. service users?). I don\u0027t think this would allow that.\n\n2.) An operator sets CONF.security_compliance.minimum_password_age to some value, and then going through and updates each applicable user to have a value of -1 is they shouldn\u0027t be able to update their password. This would work with the above logic.\n\nIs #2 what we\u0027re shooting for and I just misinterpreted it? If #2 is the design or flow we want, we could implement this without overloading the minimum_password_age option and just have a user specific option for ``allow_password_update`` and make it a boolean.\n\nJust thinking about the usability of this and wondering if we actually need to supply multiple ways to do this, or if we can be more prescriptive.","commit_id":"e21d907045efa800effdc2ee124eaf824ee2b1bd"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"09011470dffffd8ca0486294d314cb5e08c3d03a","unresolved":false,"context_lines":[{"line_number":261,"context_line":"            options.MIN_PASSWORD_AGE_OPT.option_id)"},{"line_number":262,"context_line":"        if override_opt is not None:"},{"line_number":263,"context_line":"            min_password_age_override \u003d override_opt.option_value"},{"line_number":264,"context_line":"        # NOTE(notmorgan): If the override *or* the min password age is"},{"line_number":265,"context_line":"        # configured as -1, password changes are disallowed. This indicates"},{"line_number":266,"context_line":"        # the password must be used forever. This is intended to be used in"},{"line_number":267,"context_line":"        # cases where the user\u0027s password is managed via external systems or"},{"line_number":268,"context_line":"        # if the user is a short-lived user with no need for password changes."}],"source_content_type":"text/x-python","patch_set":4,"id":"bf659307_dce161fe","line":265,"range":{"start_line":264,"start_character":27,"end_line":265,"end_character":60},"in_reply_to":"bf659307_3ed094c9","updated":"2018-04-09 20:58:00.000000000","message":"What do you think about splitting the global toggle from the user options toggle? It might make the change simpler and still fill the requirement that users have for external systems. If the request comes back in the future, we can evaluate extending the logic to support more complicated override cases\n\n\u003cshrug/\u003e","commit_id":"e21d907045efa800effdc2ee124eaf824ee2b1bd"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"7a8498c31168e001d8bd493456ebad57f4580ada","unresolved":false,"context_lines":[{"line_number":261,"context_line":"            options.MIN_PASSWORD_AGE_OPT.option_id)"},{"line_number":262,"context_line":"        if override_opt is not None:"},{"line_number":263,"context_line":"            min_password_age_override \u003d override_opt.option_value"},{"line_number":264,"context_line":"        # NOTE(notmorgan): If the override *or* the min password age is"},{"line_number":265,"context_line":"        # configured as -1, password changes are disallowed. This indicates"},{"line_number":266,"context_line":"        # the password must be used forever. This is intended to be used in"},{"line_number":267,"context_line":"        # cases where the user\u0027s password is managed via external systems or"},{"line_number":268,"context_line":"        # if the user is a short-lived user with no need for password changes."}],"source_content_type":"text/x-python","patch_set":4,"id":"bf659307_90986f75","line":265,"range":{"start_line":264,"start_character":27,"end_line":265,"end_character":60},"in_reply_to":"bf659307_43779a3b","updated":"2018-04-12 19:32:27.000000000","message":"Done","commit_id":"e21d907045efa800effdc2ee124eaf824ee2b1bd"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"e58f327084c16d83d705533868e54378dc60a6b1","unresolved":false,"context_lines":[{"line_number":261,"context_line":"            options.MIN_PASSWORD_AGE_OPT.option_id)"},{"line_number":262,"context_line":"        if override_opt is not None:"},{"line_number":263,"context_line":"            min_password_age_override \u003d override_opt.option_value"},{"line_number":264,"context_line":"        # NOTE(notmorgan): If the override *or* the min password age is"},{"line_number":265,"context_line":"        # configured as -1, password changes are disallowed. This indicates"},{"line_number":266,"context_line":"        # the password must be used forever. This is intended to be used in"},{"line_number":267,"context_line":"        # cases where the user\u0027s password is managed via external systems or"},{"line_number":268,"context_line":"        # if the user is a short-lived user with no need for password changes."}],"source_content_type":"text/x-python","patch_set":4,"id":"bf659307_3ed094c9","line":265,"range":{"start_line":264,"start_character":27,"end_line":265,"end_character":60},"in_reply_to":"bf659307_52f21f08","updated":"2018-04-09 20:35:18.000000000","message":"I strongly believe we should support overrides for individual users, however, as the global config is set by the operator of the cloud [users may be adjusted by a domain admin], the operator should set global policy and we should not allow overrides that are less strict than the global.\n\nThe workflow is mostly #2, however, I was aiming to allow for individual users to also have a longer min-password requirement. Long term, we should also allow User-ROs to be defaulted at the domain level (all users in domain X have options set [e.g. MFA, etc]).\n\nI could drop the global -1 effect, but it felt like the best way to allow an entire installation to lean on external password management.\n\nThe design was a mix of concerns I was trying to address and avoid a ton of extra options [config/user]. I\u0027m happy to split to an explicit user option fi that is the direction you\u0027d rather go.","commit_id":"e21d907045efa800effdc2ee124eaf824ee2b1bd"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"3ba3fe3d02920657360a6e72433f15b2764638f2","unresolved":false,"context_lines":[{"line_number":261,"context_line":"            options.MIN_PASSWORD_AGE_OPT.option_id)"},{"line_number":262,"context_line":"        if override_opt is not None:"},{"line_number":263,"context_line":"            min_password_age_override \u003d override_opt.option_value"},{"line_number":264,"context_line":"        # NOTE(notmorgan): If the override *or* the min password age is"},{"line_number":265,"context_line":"        # configured as -1, password changes are disallowed. This indicates"},{"line_number":266,"context_line":"        # the password must be used forever. This is intended to be used in"},{"line_number":267,"context_line":"        # cases where the user\u0027s password is managed via external systems or"},{"line_number":268,"context_line":"        # if the user is a short-lived user with no need for password changes."}],"source_content_type":"text/x-python","patch_set":4,"id":"bf659307_43779a3b","line":265,"range":{"start_line":264,"start_character":27,"end_line":265,"end_character":60},"in_reply_to":"bf659307_dce161fe","updated":"2018-04-10 16:02:44.000000000","message":"Yeah I can drop the global toggle bit. That easily works for me.","commit_id":"e21d907045efa800effdc2ee124eaf824ee2b1bd"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"50f7e486af366096b5aeee2d0dc0283339919ccf","unresolved":false,"context_lines":[{"line_number":248,"context_line":"    def change_password(self, user_id, new_password):"},{"line_number":249,"context_line":"        with sql.session_for_write() as session:"},{"line_number":250,"context_line":"            user_ref \u003d session.query(model.User).get(user_id)"},{"line_number":251,"context_line":"            if user_ref.password_ref and user_ref.password_ref.self_service:"},{"line_number":252,"context_line":"                self._validate_minimum_password_age(user_ref)"},{"line_number":253,"context_line":"            self._validate_password_history(new_password, user_ref)"},{"line_number":254,"context_line":"            user_ref.password \u003d new_password"},{"line_number":255,"context_line":"            user_ref.password_ref.self_service \u003d True"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf659307_1758ab2e","line":252,"range":{"start_line":251,"start_character":12,"end_line":252,"end_character":61},"updated":"2018-04-13 00:55:16.000000000","message":"The -1 logic needs to go here.","commit_id":"e751811c19d33ec6d50ee432cffee6dd7e106d0f"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"d4b833ac4128356ec95072eadfe1cab52d3b564b","unresolved":false,"context_lines":[{"line_number":274,"context_line":""},{"line_number":275,"context_line":"        min_age \u003d (user_ref.password_created_at +"},{"line_number":276,"context_line":"                   datetime.timedelta(days\u003dmin_age_days))"},{"line_number":277,"context_line":"        if datetime.datetime.utcnow() \u003c min_age:"},{"line_number":278,"context_line":"            days_left \u003d (min_age - datetime.datetime.utcnow()).days"},{"line_number":279,"context_line":"            raise exception.PasswordAgeValidationError("},{"line_number":280,"context_line":"                min_age_days\u003dmin_age_days, days_left\u003ddays_left)"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf659307_e59c640f","line":277,"updated":"2018-04-13 00:39:10.000000000","message":"This needs to be \u003c\u003d min_age.","commit_id":"e751811c19d33ec6d50ee432cffee6dd7e106d0f"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"1a80e227ca4c15cd03bc4dd7e75c1b1bbc425770","unresolved":false,"context_lines":[{"line_number":274,"context_line":""},{"line_number":275,"context_line":"        min_age \u003d (user_ref.password_created_at +"},{"line_number":276,"context_line":"                   datetime.timedelta(days\u003dmin_age_days))"},{"line_number":277,"context_line":"        if datetime.datetime.utcnow() \u003c min_age:"},{"line_number":278,"context_line":"            days_left \u003d (min_age - datetime.datetime.utcnow()).days"},{"line_number":279,"context_line":"            raise exception.PasswordAgeValidationError("},{"line_number":280,"context_line":"                min_age_days\u003dmin_age_days, days_left\u003ddays_left)"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf659307_d70f932b","line":277,"in_reply_to":"bf659307_e59c640f","updated":"2018-04-13 00:52:19.000000000","message":"Or something else wonky is going on with the test(s)","commit_id":"e751811c19d33ec6d50ee432cffee6dd7e106d0f"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"9738722c4b3ed6fd5ac5029f2bd99c32f46dece6","unresolved":false,"context_lines":[{"line_number":260,"context_line":""},{"line_number":261,"context_line":"    def _validate_minimum_password_age(self, user_ref):"},{"line_number":262,"context_line":"        min_age_days \u003d CONF.security_compliance.minimum_password_age"},{"line_number":263,"context_line":""},{"line_number":264,"context_line":"        min_age \u003d (user_ref.password_created_at +"},{"line_number":265,"context_line":"                   datetime.timedelta(days\u003dmin_age_days))"},{"line_number":266,"context_line":"        if datetime.datetime.utcnow() \u003c min_age:"}],"source_content_type":"text/x-python","patch_set":7,"id":"bf659307_78146444","line":263,"updated":"2018-04-13 16:15:42.000000000","message":"Superfluous Line Change","commit_id":"3e2ed9ac5a94a41628c878ad4215e4138117faf2"}],"keystone/tests/unit/test_v3_identity.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4fec932bae1d4145dba54f8002c3c5a5dcc6b5aa","unresolved":false,"context_lines":[{"line_number":469,"context_line":"                                    domain_id\u003dself.domain[\u0027id\u0027])"},{"line_number":470,"context_line":"        min_pass_age_opt \u003d options.MIN_PASSWORD_AGE_OPT.option_name"},{"line_number":471,"context_line":"        user_ref[\u0027options\u0027][min_pass_age_opt] \u003d 1"},{"line_number":472,"context_line":"        PROVIDERS.identity_api.update_user(user_ref[\u0027id\u0027], user_ref)"},{"line_number":473,"context_line":""},{"line_number":474,"context_line":"        # administrative password reset"},{"line_number":475,"context_line":"        new_password \u003d uuid.uuid4().hex"}],"source_content_type":"text/x-python","patch_set":4,"id":"bf659307_920437c8","line":472,"range":{"start_line":472,"start_character":8,"end_line":472,"end_character":68},"updated":"2018-04-09 17:56:59.000000000","message":"super-nit: this could be done through the API to be consistent with the rest of the calls in the test.","commit_id":"e21d907045efa800effdc2ee124eaf824ee2b1bd"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"e58f327084c16d83d705533868e54378dc60a6b1","unresolved":false,"context_lines":[{"line_number":469,"context_line":"                                    domain_id\u003dself.domain[\u0027id\u0027])"},{"line_number":470,"context_line":"        min_pass_age_opt \u003d options.MIN_PASSWORD_AGE_OPT.option_name"},{"line_number":471,"context_line":"        user_ref[\u0027options\u0027][min_pass_age_opt] \u003d 1"},{"line_number":472,"context_line":"        PROVIDERS.identity_api.update_user(user_ref[\u0027id\u0027], user_ref)"},{"line_number":473,"context_line":""},{"line_number":474,"context_line":"        # administrative password reset"},{"line_number":475,"context_line":"        new_password \u003d uuid.uuid4().hex"}],"source_content_type":"text/x-python","patch_set":4,"id":"bf659307_befca43e","line":472,"range":{"start_line":472,"start_character":8,"end_line":472,"end_character":68},"in_reply_to":"bf659307_920437c8","updated":"2018-04-09 20:35:18.000000000","message":"I was originally running into some side issues with update_user and simplified by calling the provider directly.\n\nI\u0027m happy to swap this back if that is really desired.","commit_id":"e21d907045efa800effdc2ee124eaf824ee2b1bd"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4fec932bae1d4145dba54f8002c3c5a5dcc6b5aa","unresolved":false,"context_lines":[{"line_number":845,"context_line":"            # able to change password after create user"},{"line_number":846,"context_line":"            self.change_password(password\u003dnew_password,"},{"line_number":847,"context_line":"                                 original_password\u003dself.user_ref[\u0027password\u0027],"},{"line_number":848,"context_line":"                                 expected_status\u003dhttp_client.NO_CONTENT)"},{"line_number":849,"context_line":"            # 2nd change password should fail due to minimum password age and"},{"line_number":850,"context_line":"            # make sure we wait one second to avoid race conditions with Fernet"},{"line_number":851,"context_line":"            frozen_datetime.tick(delta\u003ddatetime.timedelta(seconds\u003d1))"}],"source_content_type":"text/x-python","patch_set":4,"id":"bf659307_92d2f733","line":848,"updated":"2018-04-09 17:56:59.000000000","message":"So users are allowed to reset their password at least once? Is this because changing a password after first use is allowed [0]?\n\nhttps://github.com/openstack/keystone/blob/0c5242b6184aa37968266a2fbb1d490208d6a580/keystone/conf/security_compliance.py#L114-L125","commit_id":"e21d907045efa800effdc2ee124eaf824ee2b1bd"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"931b00887700a79aa0a3b7b93b52cf5c8367ab8d","unresolved":false,"context_lines":[{"line_number":482,"context_line":"            password\u003dnew_password)"},{"line_number":483,"context_line":"        self.v3_create_token(new_password_auth)"},{"line_number":484,"context_line":""},{"line_number":485,"context_line":"    def test_admin_password_reset_with_min_password_age_forever(self):"},{"line_number":486,"context_line":"        # enable minimum_password_age to \"forever\", this should have no effect"},{"line_number":487,"context_line":"        # on admin password reset"},{"line_number":488,"context_line":"        self.config_fixture.config(group\u003d\u0027security_compliance\u0027,"}],"source_content_type":"text/x-python","patch_set":5,"id":"bf659307_e4556e51","line":485,"range":{"start_line":485,"start_character":8,"end_line":485,"end_character":63},"updated":"2018-04-11 20:54:12.000000000","message":"We\u0027re not going to support the blanket case are we? If an operator wants a user to use a specific password, they have to specify it in the user\u0027s options?","commit_id":"0e7378225b94adb32d6b27234ad002fba27e8e91"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"7a8498c31168e001d8bd493456ebad57f4580ada","unresolved":false,"context_lines":[{"line_number":482,"context_line":"            password\u003dnew_password)"},{"line_number":483,"context_line":"        self.v3_create_token(new_password_auth)"},{"line_number":484,"context_line":""},{"line_number":485,"context_line":"    def test_admin_password_reset_with_min_password_age_forever(self):"},{"line_number":486,"context_line":"        # enable minimum_password_age to \"forever\", this should have no effect"},{"line_number":487,"context_line":"        # on admin password reset"},{"line_number":488,"context_line":"        self.config_fixture.config(group\u003d\u0027security_compliance\u0027,"}],"source_content_type":"text/x-python","patch_set":5,"id":"bf659307_50fb9445","line":485,"range":{"start_line":485,"start_character":8,"end_line":485,"end_character":63},"in_reply_to":"bf659307_e4556e51","updated":"2018-04-12 19:32:27.000000000","message":"Ah yeah. missed these.","commit_id":"0e7378225b94adb32d6b27234ad002fba27e8e91"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"931b00887700a79aa0a3b7b93b52cf5c8367ab8d","unresolved":false,"context_lines":[{"line_number":485,"context_line":"    def test_admin_password_reset_with_min_password_age_forever(self):"},{"line_number":486,"context_line":"        # enable minimum_password_age to \"forever\", this should have no effect"},{"line_number":487,"context_line":"        # on admin password reset"},{"line_number":488,"context_line":"        self.config_fixture.config(group\u003d\u0027security_compliance\u0027,"},{"line_number":489,"context_line":"                                   minimum_password_age\u003d-1)"},{"line_number":490,"context_line":"        # create user"},{"line_number":491,"context_line":"        user_ref \u003d unit.create_user(PROVIDERS.identity_api,"},{"line_number":492,"context_line":"                                    domain_id\u003dself.domain[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":5,"id":"bf659307_44845ad3","line":489,"range":{"start_line":488,"start_character":8,"end_line":489,"end_character":59},"updated":"2018-04-11 20:54:12.000000000","message":"Technically - this shouldn\u0027t be possible if min\u003d0 in keystone/conf/security_compliance.py, right?","commit_id":"0e7378225b94adb32d6b27234ad002fba27e8e91"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"931b00887700a79aa0a3b7b93b52cf5c8367ab8d","unresolved":false,"context_lines":[{"line_number":840,"context_line":"            # enable minimum_password_age to \"forever\" and attempt to change"},{"line_number":841,"context_line":"            # password"},{"line_number":842,"context_line":"            new_password \u003d uuid.uuid4().hex"},{"line_number":843,"context_line":"            self.config_fixture.config(group\u003d\u0027security_compliance\u0027,"},{"line_number":844,"context_line":"                                       minimum_password_age\u003d-1)"},{"line_number":845,"context_line":"            # able to change password after create user"},{"line_number":846,"context_line":"            self.change_password(password\u003dnew_password,"},{"line_number":847,"context_line":"                                 original_password\u003dself.user_ref[\u0027password\u0027],"}],"source_content_type":"text/x-python","patch_set":5,"id":"bf659307_84f59259","line":844,"range":{"start_line":843,"start_character":12,"end_line":844,"end_character":63},"updated":"2018-04-11 20:54:12.000000000","message":"Same comment here as above. Technically this value should fail if it is set below 0 according to the definition in keystone/conf/security_compliance.py","commit_id":"0e7378225b94adb32d6b27234ad002fba27e8e91"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"781a675a4afd9e6c776fa1a3d3cc8ee191565018","unresolved":false,"context_lines":[{"line_number":840,"context_line":"            # enable minimum_password_age to \"forever\" and attempt to change"},{"line_number":841,"context_line":"            # password"},{"line_number":842,"context_line":"            new_password \u003d uuid.uuid4().hex"},{"line_number":843,"context_line":"            self.config_fixture.config(group\u003d\u0027security_compliance\u0027,"},{"line_number":844,"context_line":"                                       minimum_password_age\u003d-1)"},{"line_number":845,"context_line":"            # able to change password after create user"},{"line_number":846,"context_line":"            self.change_password(password\u003dnew_password,"},{"line_number":847,"context_line":"                                 original_password\u003dself.user_ref[\u0027password\u0027],"}],"source_content_type":"text/x-python","patch_set":5,"id":"bf659307_d306ce1c","line":844,"range":{"start_line":843,"start_character":12,"end_line":844,"end_character":63},"in_reply_to":"bf659307_84f59259","updated":"2018-04-12 19:43:09.000000000","message":"Removed","commit_id":"0e7378225b94adb32d6b27234ad002fba27e8e91"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"931b00887700a79aa0a3b7b93b52cf5c8367ab8d","unresolved":false,"context_lines":[{"line_number":879,"context_line":"            # able to change password after create user"},{"line_number":880,"context_line":"            self.change_password(password\u003dnew_password,"},{"line_number":881,"context_line":"                                 original_password\u003dself.user_ref[\u0027password\u0027],"},{"line_number":882,"context_line":"                                 expected_status\u003dhttp_client.NO_CONTENT)"},{"line_number":883,"context_line":"            # 2nd change password should fail due to minimum password age and"},{"line_number":884,"context_line":"            # make sure we wait one second to avoid race conditions with Fernet"},{"line_number":885,"context_line":"            frozen_datetime.tick(delta\u003ddatetime.timedelta(seconds\u003d1))"}],"source_content_type":"text/x-python","patch_set":5,"id":"bf659307_c4f62a5e","line":882,"updated":"2018-04-11 20:54:12.000000000","message":"This bit confuses me still. Technically we already set the user option to lock the user\u0027s password, but we can still change it?","commit_id":"0e7378225b94adb32d6b27234ad002fba27e8e91"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"781a675a4afd9e6c776fa1a3d3cc8ee191565018","unresolved":false,"context_lines":[{"line_number":879,"context_line":"            # able to change password after create user"},{"line_number":880,"context_line":"            self.change_password(password\u003dnew_password,"},{"line_number":881,"context_line":"                                 original_password\u003dself.user_ref[\u0027password\u0027],"},{"line_number":882,"context_line":"                                 expected_status\u003dhttp_client.NO_CONTENT)"},{"line_number":883,"context_line":"            # 2nd change password should fail due to minimum password age and"},{"line_number":884,"context_line":"            # make sure we wait one second to avoid race conditions with Fernet"},{"line_number":885,"context_line":"            frozen_datetime.tick(delta\u003ddatetime.timedelta(seconds\u003d1))"}],"source_content_type":"text/x-python","patch_set":5,"id":"bf659307_b30f9a2c","line":882,"in_reply_to":"bf659307_c4f62a5e","updated":"2018-04-12 19:43:09.000000000","message":"See below comment.","commit_id":"0e7378225b94adb32d6b27234ad002fba27e8e91"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"931b00887700a79aa0a3b7b93b52cf5c8367ab8d","unresolved":false,"context_lines":[{"line_number":897,"context_line":"        time \u003d datetime.datetime.utcnow()"},{"line_number":898,"context_line":"        with freezegun.freeze_time(time) as frozen_datetime:"},{"line_number":899,"context_line":"            new_password \u003d uuid.uuid4().hex"},{"line_number":900,"context_line":"            self.config_fixture.config(group\u003d\u0027security_compliance\u0027,"},{"line_number":901,"context_line":"                                       minimum_password_age\u003d1)"},{"line_number":902,"context_line":"            min_pass_age_opt \u003d options.MIN_PASSWORD_AGE_OPT.option_name"},{"line_number":903,"context_line":"            self.user_ref[\u0027options\u0027][min_pass_age_opt] \u003d 0"},{"line_number":904,"context_line":"            PROVIDERS.identity_api.update_user(self.user_ref[\u0027id\u0027],"}],"source_content_type":"text/x-python","patch_set":5,"id":"bf659307_048662ba","line":901,"range":{"start_line":900,"start_character":12,"end_line":901,"end_character":62},"updated":"2018-04-11 20:54:12.000000000","message":"Same comment here as above.","commit_id":"0e7378225b94adb32d6b27234ad002fba27e8e91"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"781a675a4afd9e6c776fa1a3d3cc8ee191565018","unresolved":false,"context_lines":[{"line_number":897,"context_line":"        time \u003d datetime.datetime.utcnow()"},{"line_number":898,"context_line":"        with freezegun.freeze_time(time) as frozen_datetime:"},{"line_number":899,"context_line":"            new_password \u003d uuid.uuid4().hex"},{"line_number":900,"context_line":"            self.config_fixture.config(group\u003d\u0027security_compliance\u0027,"},{"line_number":901,"context_line":"                                       minimum_password_age\u003d1)"},{"line_number":902,"context_line":"            min_pass_age_opt \u003d options.MIN_PASSWORD_AGE_OPT.option_name"},{"line_number":903,"context_line":"            self.user_ref[\u0027options\u0027][min_pass_age_opt] \u003d 0"},{"line_number":904,"context_line":"            PROVIDERS.identity_api.update_user(self.user_ref[\u0027id\u0027],"}],"source_content_type":"text/x-python","patch_set":5,"id":"bf659307_f37e7268","line":901,"range":{"start_line":900,"start_character":12,"end_line":901,"end_character":62},"in_reply_to":"bf659307_048662ba","updated":"2018-04-12 19:43:09.000000000","message":"This one is testing that the override should not be allowed to be less than the security_compliance.\n\nThere is a racy-thing here we need to fix. If you change the password in the same second, it is not considered less than ... it\u0027s a bug in i think our password change logic.\n\nSee def test_changing_password_with_min_password_age(self):\n\nThis is broken in general, but we are consistent in how we\u0027re broken.\n\nI\u0027ll work on a followup that will fix this.","commit_id":"0e7378225b94adb32d6b27234ad002fba27e8e91"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"931b00887700a79aa0a3b7b93b52cf5c8367ab8d","unresolved":false,"context_lines":[{"line_number":934,"context_line":"            # able to change password after create user"},{"line_number":935,"context_line":"            self.change_password(password\u003dnew_password,"},{"line_number":936,"context_line":"                                 original_password\u003dself.user_ref[\u0027password\u0027],"},{"line_number":937,"context_line":"                                 expected_status\u003dhttp_client.NO_CONTENT)"},{"line_number":938,"context_line":"            # 2nd change password should fail due to minimum password age and"},{"line_number":939,"context_line":"            # make sure we wait one second to avoid race conditions with Fernet"},{"line_number":940,"context_line":"            frozen_datetime.tick(delta\u003ddatetime.timedelta(seconds\u003d1))"}],"source_content_type":"text/x-python","patch_set":5,"id":"bf659307_c48b8abd","line":937,"updated":"2018-04-11 20:54:12.000000000","message":"Same comment as above.","commit_id":"0e7378225b94adb32d6b27234ad002fba27e8e91"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"781a675a4afd9e6c776fa1a3d3cc8ee191565018","unresolved":false,"context_lines":[{"line_number":934,"context_line":"            # able to change password after create user"},{"line_number":935,"context_line":"            self.change_password(password\u003dnew_password,"},{"line_number":936,"context_line":"                                 original_password\u003dself.user_ref[\u0027password\u0027],"},{"line_number":937,"context_line":"                                 expected_status\u003dhttp_client.NO_CONTENT)"},{"line_number":938,"context_line":"            # 2nd change password should fail due to minimum password age and"},{"line_number":939,"context_line":"            # make sure we wait one second to avoid race conditions with Fernet"},{"line_number":940,"context_line":"            frozen_datetime.tick(delta\u003ddatetime.timedelta(seconds\u003d1))"}],"source_content_type":"text/x-python","patch_set":5,"id":"bf659307_b3947a8c","line":937,"in_reply_to":"bf659307_c48b8abd","updated":"2018-04-12 19:43:09.000000000","message":"See above.","commit_id":"0e7378225b94adb32d6b27234ad002fba27e8e91"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"4bd8599e9e8cc70b732b9e6fcbd8ceffd7eb82da","unresolved":false,"context_lines":[{"line_number":829,"context_line":"                                               self.user_ref)"},{"line_number":830,"context_line":""},{"line_number":831,"context_line":"            # able to change password after create user"},{"line_number":832,"context_line":"            self.change_password(password\u003dnew_password,"},{"line_number":833,"context_line":"                                 original_password\u003dself.user_ref[\u0027password\u0027],"},{"line_number":834,"context_line":"                                 expected_status\u003dhttp_client.NO_CONTENT)"},{"line_number":835,"context_line":"            # 2nd change password should fail due to minimum password age and"},{"line_number":836,"context_line":"            # make sure we wait one second to avoid race conditions with Fernet"},{"line_number":837,"context_line":"            frozen_datetime.tick(delta\u003ddatetime.timedelta(seconds\u003d1))"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf659307_d738f3d3","line":834,"range":{"start_line":832,"start_character":0,"end_line":834,"end_character":72},"updated":"2018-04-13 00:54:02.000000000","message":"AHA! Ok, so min_password_age only ever applies to non-admin set passwords. I will need to rework the logic a little for the -1 case.","commit_id":"e751811c19d33ec6d50ee432cffee6dd7e106d0f"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"6a569607de563ce9fb5182ed6e2dcdbd6cd648e0","unresolved":false,"context_lines":[{"line_number":462,"context_line":"    def test_admin_password_reset_with_password_lock(self):"},{"line_number":463,"context_line":"        # enable minimum_password_age via override, this should have no effect"},{"line_number":464,"context_line":"        # on admin password reset"},{"line_number":465,"context_line":"        self.config_fixture.config(group\u003d\u0027security_compliance\u0027,"},{"line_number":466,"context_line":"                                   minimum_password_age\u003d0)"},{"line_number":467,"context_line":"        # create user"},{"line_number":468,"context_line":"        user_ref \u003d unit.create_user(PROVIDERS.identity_api,"},{"line_number":469,"context_line":"                                    domain_id\u003dself.domain[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":8,"id":"bf659307_6cb5877d","line":466,"range":{"start_line":465,"start_character":0,"end_line":466,"end_character":58},"updated":"2018-04-13 19:08:07.000000000","message":"Is this left over from the previous patchset?","commit_id":"551eaa13bf08e8559657c9655e6bbc32ed741972"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"b47160214303ce51b04492daf48b8249c53f5cff","unresolved":false,"context_lines":[{"line_number":462,"context_line":"    def test_admin_password_reset_with_password_lock(self):"},{"line_number":463,"context_line":"        # enable minimum_password_age via override, this should have no effect"},{"line_number":464,"context_line":"        # on admin password reset"},{"line_number":465,"context_line":"        self.config_fixture.config(group\u003d\u0027security_compliance\u0027,"},{"line_number":466,"context_line":"                                   minimum_password_age\u003d0)"},{"line_number":467,"context_line":"        # create user"},{"line_number":468,"context_line":"        user_ref \u003d unit.create_user(PROVIDERS.identity_api,"},{"line_number":469,"context_line":"                                    domain_id\u003dself.domain[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":8,"id":"bf659307_cf0925dd","line":466,"range":{"start_line":465,"start_character":0,"end_line":466,"end_character":58},"in_reply_to":"bf659307_6cb5877d","updated":"2018-04-13 19:28:57.000000000","message":"Maybe.","commit_id":"551eaa13bf08e8559657c9655e6bbc32ed741972"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"6a569607de563ce9fb5182ed6e2dcdbd6cd648e0","unresolved":false,"context_lines":[{"line_number":480,"context_line":"        new_password_auth \u003d self.build_authentication_request("},{"line_number":481,"context_line":"            user_id\u003duser_ref[\u0027id\u0027],"},{"line_number":482,"context_line":"            password\u003dnew_password)"},{"line_number":483,"context_line":"        self.v3_create_token(new_password_auth)"},{"line_number":484,"context_line":""},{"line_number":485,"context_line":"    def test_update_user_domain_id(self):"},{"line_number":486,"context_line":"        \"\"\"Call ``PATCH /users/{user_id}`` with domain_id."}],"source_content_type":"text/x-python","patch_set":8,"id":"bf659307_8c6d7b04","line":483,"updated":"2018-04-13 19:08:07.000000000","message":"Very nice","commit_id":"551eaa13bf08e8559657c9655e6bbc32ed741972"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"6a569607de563ce9fb5182ed6e2dcdbd6cd648e0","unresolved":false,"context_lines":[{"line_number":792,"context_line":"                                 original_password\u003dnew_password,"},{"line_number":793,"context_line":"                                 expected_status\u003dhttp_client.NO_CONTENT)"},{"line_number":794,"context_line":""},{"line_number":795,"context_line":"    def test_changing_password_with_password_lock(self):"},{"line_number":796,"context_line":"        # enable minimum_password_age override to \"forever\" and attempt to"},{"line_number":797,"context_line":"        # change password"},{"line_number":798,"context_line":"        time \u003d datetime.datetime.utcnow()"}],"source_content_type":"text/x-python","patch_set":8,"id":"bf659307_0ca40b4a","line":795,"range":{"start_line":795,"start_character":8,"end_line":795,"end_character":49},"updated":"2018-04-13 19:08:07.000000000","message":"We should have a test to make sure we can remove the option from the user.","commit_id":"551eaa13bf08e8559657c9655e6bbc32ed741972"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"b47160214303ce51b04492daf48b8249c53f5cff","unresolved":false,"context_lines":[{"line_number":792,"context_line":"                                 original_password\u003dnew_password,"},{"line_number":793,"context_line":"                                 expected_status\u003dhttp_client.NO_CONTENT)"},{"line_number":794,"context_line":""},{"line_number":795,"context_line":"    def test_changing_password_with_password_lock(self):"},{"line_number":796,"context_line":"        # enable minimum_password_age override to \"forever\" and attempt to"},{"line_number":797,"context_line":"        # change password"},{"line_number":798,"context_line":"        time \u003d datetime.datetime.utcnow()"}],"source_content_type":"text/x-python","patch_set":8,"id":"bf659307_8f0fadde","line":795,"range":{"start_line":795,"start_character":8,"end_line":795,"end_character":49},"in_reply_to":"bf659307_0ca40b4a","updated":"2018-04-13 19:28:57.000000000","message":"That should be the base resource-options tests. If that doesn\u0027t exist, it\u0027s a separate bug/issue.","commit_id":"551eaa13bf08e8559657c9655e6bbc32ed741972"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"50672a29b80b64fe4cab083290cc7f868740a495","unresolved":false,"context_lines":[{"line_number":465,"context_line":"                                    domain_id\u003dself.domain[\u0027id\u0027])"},{"line_number":466,"context_line":"        lock_pw_opt \u003d options.LOCK_PASSWORD_OPT.option_name"},{"line_number":467,"context_line":"        user_ref[\u0027options\u0027][lock_pw_opt] \u003d True"},{"line_number":468,"context_line":"        PROVIDERS.identity_api.update_user(user_ref[\u0027id\u0027], user_ref)"},{"line_number":469,"context_line":""},{"line_number":470,"context_line":"        # administrative password reset"},{"line_number":471,"context_line":"        new_password \u003d uuid.uuid4().hex"}],"source_content_type":"text/x-python","patch_set":11,"id":"9f6a8fd7_f7e361a3","line":468,"updated":"2018-04-16 20:59:59.000000000","message":"nit: \n\nhttp://paste.openstack.org/show/719325/\n\nJust to keep all the requests in the tests going through the API instead of calling into the backends directly.","commit_id":"5864145b71e707b5e61b48235d93411c4fb91279"}],"releasenotes/notes/bug-1755874-9951f77c6d18431c.yaml":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4fec932bae1d4145dba54f8002c3c5a5dcc6b5aa","unresolved":false,"context_lines":[{"line_number":7,"context_line":"    if the override is greater than the global option setting.\r"},{"line_number":8,"context_line":"\r"},{"line_number":9,"context_line":"    If either of these values are set to ``-1`` the user may not change their\r"},{"line_number":10,"context_line":"    password; if the global settin is used, it cannot be overridden by the\r"},{"line_number":11,"context_line":"    user resource-option."}],"source_content_type":"text/x-yaml","patch_set":4,"id":"bf659307_52aa1f85","line":10,"range":{"start_line":10,"start_character":28,"end_line":10,"end_character":34},"updated":"2018-04-09 17:56:59.000000000","message":"setting*","commit_id":"e21d907045efa800effdc2ee124eaf824ee2b1bd"}]}
