)]}'
{"keystone/common/config.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4116051f40af57584d3f4604d9afca9191080c73","unresolved":false,"context_lines":[{"line_number":1050,"context_line":"        cfg.IntOpt(\u0027password_expires_ignore_list\u0027,"},{"line_number":1051,"context_line":"                   default\u003dNone,"},{"line_number":1052,"context_line":"                   help\u003d\u0027Comma separated list of user IDs to be ignored \u0027"},{"line_number":1053,"context_line":"                        \u0027when checking if a password is expired.\u0027),"},{"line_number":1054,"context_line":"        cfg.IntOpt(\u0027unique_last_password_count\u0027,"},{"line_number":1055,"context_line":"                   default\u003d0,"},{"line_number":1056,"context_line":"                   help\u003d\u0027Number of latest password iterations for which the \u0027"}],"source_content_type":"text/x-python","patch_set":44,"id":"9abb7d3a_d45149da","line":1053,"updated":"2016-06-02 18:36:16.000000000","message":"Do we have a reason to not explicitly call out that this is designed for service users?","commit_id":"7468ad524d1824b6155598f114731d325c8057fe"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"b9b6e379ac26d647719ad3483be4edab2c25add7","unresolved":false,"context_lines":[{"line_number":1050,"context_line":"        cfg.IntOpt(\u0027password_expires_ignore_list\u0027,"},{"line_number":1051,"context_line":"                   default\u003dNone,"},{"line_number":1052,"context_line":"                   help\u003d\u0027Comma separated list of user IDs to be ignored \u0027"},{"line_number":1053,"context_line":"                        \u0027when checking if a password is expired.\u0027),"},{"line_number":1054,"context_line":"        cfg.IntOpt(\u0027unique_last_password_count\u0027,"},{"line_number":1055,"context_line":"                   default\u003d0,"},{"line_number":1056,"context_line":"                   help\u003d\u0027Number of latest password iterations for which the \u0027"}],"source_content_type":"text/x-python","patch_set":44,"id":"9abb7d3a_14f2b16f","line":1053,"in_reply_to":"9abb7d3a_d45149da","updated":"2016-06-02 18:38:58.000000000","message":"I think it could be used for some admins as well, but I\u0027m open to suggestions.","commit_id":"7468ad524d1824b6155598f114731d325c8057fe"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"81921c0fbf8940c1447041bc5091efca579cf2f2","unresolved":false,"context_lines":[{"line_number":1050,"context_line":"        cfg.IntOpt(\u0027password_expires_ignore_list\u0027,"},{"line_number":1051,"context_line":"                   default\u003dNone,"},{"line_number":1052,"context_line":"                   help\u003d\u0027Comma separated list of user IDs to be ignored \u0027"},{"line_number":1053,"context_line":"                        \u0027when checking if a password is expired.\u0027),"},{"line_number":1054,"context_line":"        cfg.IntOpt(\u0027unique_last_password_count\u0027,"},{"line_number":1055,"context_line":"                   default\u003d0,"},{"line_number":1056,"context_line":"                   help\u003d\u0027Number of latest password iterations for which the \u0027"}],"source_content_type":"text/x-python","patch_set":45,"id":"9abb7d3a_f4fbad45","line":1053,"updated":"2016-06-02 18:39:03.000000000","message":"Do we have a reason to not explicitly call out that this is designed for service users?\n\nAlso - if a deployment has a set of service users that are exempt from PCI rules, is the deployment still PCI compliant?","commit_id":"f2594d571b5e7d7dbe08aef5dbe07c0112adc352"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"3043c220d60a65e283d45c0137b5cce06a6b0776","unresolved":false,"context_lines":[{"line_number":1050,"context_line":"        cfg.IntOpt(\u0027password_expires_ignore_list\u0027,"},{"line_number":1051,"context_line":"                   default\u003dNone,"},{"line_number":1052,"context_line":"                   help\u003d\u0027Comma separated list of user IDs to be ignored \u0027"},{"line_number":1053,"context_line":"                        \u0027when checking if a password is expired.\u0027),"},{"line_number":1054,"context_line":"        cfg.IntOpt(\u0027unique_last_password_count\u0027,"},{"line_number":1055,"context_line":"                   default\u003d0,"},{"line_number":1056,"context_line":"                   help\u003d\u0027Number of latest password iterations for which the \u0027"}],"source_content_type":"text/x-python","patch_set":45,"id":"9abb7d3a_b7ae47e5","line":1053,"in_reply_to":"9abb7d3a_374c1776","updated":"2016-06-02 18:44:55.000000000","message":"As far as I know, there isn\u0027t a hard requirement on x509 certs.","commit_id":"f2594d571b5e7d7dbe08aef5dbe07c0112adc352"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"32ce362ef91028a89c6d671795acb37199255146","unresolved":false,"context_lines":[{"line_number":1050,"context_line":"        cfg.IntOpt(\u0027password_expires_ignore_list\u0027,"},{"line_number":1051,"context_line":"                   default\u003dNone,"},{"line_number":1052,"context_line":"                   help\u003d\u0027Comma separated list of user IDs to be ignored \u0027"},{"line_number":1053,"context_line":"                        \u0027when checking if a password is expired.\u0027),"},{"line_number":1054,"context_line":"        cfg.IntOpt(\u0027unique_last_password_count\u0027,"},{"line_number":1055,"context_line":"                   default\u003d0,"},{"line_number":1056,"context_line":"                   help\u003d\u0027Number of latest password iterations for which the \u0027"}],"source_content_type":"text/x-python","patch_set":45,"id":"9abb7d3a_b7e64714","line":1053,"in_reply_to":"9abb7d3a_374c1776","updated":"2016-06-02 18:52:30.000000000","message":"Implement PCI differently as in not rely on what we\u0027re introducing into Keystone for PCI requirements?\n\nI guess the thing I\u0027m thinking about is does it make sense to provide PCI with an ignore_list of the ignore_list violates PCI in some way. Does that make sense? Of course, I don\u0027t claim to be a PCI expert here, just something I thought of.","commit_id":"f2594d571b5e7d7dbe08aef5dbe07c0112adc352"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"be08d445bf8946a6eafa3f3d14119a284de6cbb3","unresolved":false,"context_lines":[{"line_number":1050,"context_line":"        cfg.IntOpt(\u0027password_expires_ignore_list\u0027,"},{"line_number":1051,"context_line":"                   default\u003dNone,"},{"line_number":1052,"context_line":"                   help\u003d\u0027Comma separated list of user IDs to be ignored \u0027"},{"line_number":1053,"context_line":"                        \u0027when checking if a password is expired.\u0027),"},{"line_number":1054,"context_line":"        cfg.IntOpt(\u0027unique_last_password_count\u0027,"},{"line_number":1055,"context_line":"                   default\u003d0,"},{"line_number":1056,"context_line":"                   help\u003d\u0027Number of latest password iterations for which the \u0027"}],"source_content_type":"text/x-python","patch_set":45,"id":"9abb7d3a_976ea394","line":1053,"in_reply_to":"9abb7d3a_57cefbb4","updated":"2016-06-02 18:50:11.000000000","message":"The other thing to consider is that even though we are adding this for PCI, an operator could be using it for meeting HIPAA standards.  Or, to simply meet their specific security requirements.","commit_id":"f2594d571b5e7d7dbe08aef5dbe07c0112adc352"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"3ee7c7257bc6c0e88a70f38897540608e9d2fb6a","unresolved":false,"context_lines":[{"line_number":1050,"context_line":"        cfg.IntOpt(\u0027password_expires_ignore_list\u0027,"},{"line_number":1051,"context_line":"                   default\u003dNone,"},{"line_number":1052,"context_line":"                   help\u003d\u0027Comma separated list of user IDs to be ignored \u0027"},{"line_number":1053,"context_line":"                        \u0027when checking if a password is expired.\u0027),"},{"line_number":1054,"context_line":"        cfg.IntOpt(\u0027unique_last_password_count\u0027,"},{"line_number":1055,"context_line":"                   default\u003d0,"},{"line_number":1056,"context_line":"                   help\u003d\u0027Number of latest password iterations for which the \u0027"}],"source_content_type":"text/x-python","patch_set":45,"id":"9abb7d3a_57cefbb4","line":1053,"in_reply_to":"9abb7d3a_b7ae47e5","updated":"2016-06-02 18:48:23.000000000","message":"Regarding explicitly calling out service users, I think it could be used for some admins as well. I\u0027m open to suggestions though.","commit_id":"f2594d571b5e7d7dbe08aef5dbe07c0112adc352"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"e1ac5e6ab5dc21a1ed8658306d592d51e4bf3e87","unresolved":false,"context_lines":[{"line_number":1050,"context_line":"        cfg.IntOpt(\u0027password_expires_ignore_list\u0027,"},{"line_number":1051,"context_line":"                   default\u003dNone,"},{"line_number":1052,"context_line":"                   help\u003d\u0027Comma separated list of user IDs to be ignored \u0027"},{"line_number":1053,"context_line":"                        \u0027when checking if a password is expired.\u0027),"},{"line_number":1054,"context_line":"        cfg.IntOpt(\u0027unique_last_password_count\u0027,"},{"line_number":1055,"context_line":"                   default\u003d0,"},{"line_number":1056,"context_line":"                   help\u003d\u0027Number of latest password iterations for which the \u0027"}],"source_content_type":"text/x-python","patch_set":45,"id":"9abb7d3a_57eb9bb0","line":1053,"in_reply_to":"9abb7d3a_b7e64714","updated":"2016-06-02 19:00:15.000000000","message":"As much as I\u0027d like to say, that if you have these config settings, you\u0027re PCI compliant, I don\u0027t think we can. It would be based on our interpretation of the standards. And it would be very difficult for us to maintain that as the standards change over time. Ultimately, I think we want to provide operators security features to configure and let them decide whether or not they are PCI compliant.","commit_id":"f2594d571b5e7d7dbe08aef5dbe07c0112adc352"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"e1103c52c6a23464bdab6fc283964dbe0f5860c3","unresolved":false,"context_lines":[{"line_number":1050,"context_line":"        cfg.IntOpt(\u0027password_expires_ignore_list\u0027,"},{"line_number":1051,"context_line":"                   default\u003dNone,"},{"line_number":1052,"context_line":"                   help\u003d\u0027Comma separated list of user IDs to be ignored \u0027"},{"line_number":1053,"context_line":"                        \u0027when checking if a password is expired.\u0027),"},{"line_number":1054,"context_line":"        cfg.IntOpt(\u0027unique_last_password_count\u0027,"},{"line_number":1055,"context_line":"                   default\u003d0,"},{"line_number":1056,"context_line":"                   help\u003d\u0027Number of latest password iterations for which the \u0027"}],"source_content_type":"text/x-python","patch_set":45,"id":"9abb7d3a_34625517","line":1053,"in_reply_to":"9abb7d3a_f4fbad45","updated":"2016-06-02 18:41:02.000000000","message":"Or - does PCI need to have a hard requirement on using x509 certificates for service users, eliminating the password problem all together?","commit_id":"f2594d571b5e7d7dbe08aef5dbe07c0112adc352"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"da38571cc1831e88950782e67d796375a47eb989","unresolved":false,"context_lines":[{"line_number":1050,"context_line":"        cfg.IntOpt(\u0027password_expires_ignore_list\u0027,"},{"line_number":1051,"context_line":"                   default\u003dNone,"},{"line_number":1052,"context_line":"                   help\u003d\u0027Comma separated list of user IDs to be ignored \u0027"},{"line_number":1053,"context_line":"                        \u0027when checking if a password is expired.\u0027),"},{"line_number":1054,"context_line":"        cfg.IntOpt(\u0027unique_last_password_count\u0027,"},{"line_number":1055,"context_line":"                   default\u003d0,"},{"line_number":1056,"context_line":"                   help\u003d\u0027Number of latest password iterations for which the \u0027"}],"source_content_type":"text/x-python","patch_set":45,"id":"9abb7d3a_374c1776","line":1053,"in_reply_to":"9abb7d3a_f4fbad45","updated":"2016-06-02 18:43:25.000000000","message":"Probably not. However, I expect that operators will implement PCI differently; thus, have different config settings. Often, it\u0027s a matter of how you interpret the standards. Plus, PCI standards will change over time.","commit_id":"f2594d571b5e7d7dbe08aef5dbe07c0112adc352"}],"keystone/exception.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4e6d70a3a8ce16f6c79c9db00ccebf7e762e1dfa","unresolved":false,"context_lines":[{"line_number":213,"context_line":""},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"class PasswordExpired(Unauthorized):"},{"line_number":216,"context_line":"    message_format \u003d _(\"The user\u0027s password is expired\")"},{"line_number":217,"context_line":""},{"line_number":218,"context_line":""},{"line_number":219,"context_line":"class AuthMethodNotSupported(AuthPluginException):"}],"source_content_type":"text/x-python","patch_set":37,"id":"9abb7d3a_125a01f2","line":216,"updated":"2016-06-01 20:40:18.000000000","message":"Adding the user\u0027s ID to this message will make it a bit more descriptive for administrators.","commit_id":"629a502125e01bcf27661e6a9c32b84685d3c947"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"e622db5b6983c12ed0e259ed3b552b04cf81064c","unresolved":false,"context_lines":[{"line_number":213,"context_line":""},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"class PasswordExpired(Unauthorized):"},{"line_number":216,"context_line":"    message_format \u003d _(\"The user\u0027s password is expired\")"},{"line_number":217,"context_line":""},{"line_number":218,"context_line":""},{"line_number":219,"context_line":"class AuthMethodNotSupported(AuthPluginException):"}],"source_content_type":"text/x-python","patch_set":37,"id":"9abb7d3a_eb52e811","line":216,"in_reply_to":"9abb7d3a_125a01f2","updated":"2016-06-01 21:14:45.000000000","message":"I think I tried that, but got an error because Unauthorized filters out some attributes for security (I think).  I\u0027ll re-look at this.","commit_id":"629a502125e01bcf27661e6a9c32b84685d3c947"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4116051f40af57584d3f4604d9afca9191080c73","unresolved":false,"context_lines":[{"line_number":200,"context_line":""},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"class PasswordExpired(Unauthorized):"},{"line_number":203,"context_line":"    message_format \u003d _(\"The password is expired for user: %(user_id)s\")"},{"line_number":204,"context_line":""},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"class AuthPluginException(Unauthorized):"}],"source_content_type":"text/x-python","patch_set":44,"id":"9abb7d3a_f46bad83","line":203,"updated":"2016-06-02 18:36:16.000000000","message":"++ sweet","commit_id":"7468ad524d1824b6155598f114731d325c8057fe"}],"keystone/identity/backends/sql.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"f455eb16ed9c70c799cf53e997e0123597e2247c","unresolved":false,"context_lines":[{"line_number":12,"context_line":"# License for the specific language governing permissions and limitations"},{"line_number":13,"context_line":"# under the License."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import datetime"},{"line_number":16,"context_line":"import sqlalchemy"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from oslo_config import cfg"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_43047d7d","line":15,"updated":"2016-06-06 12:34:36.000000000","message":"Hacking rules: http://docs.openstack.org/developer/hacking/#import-order-template","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"d1a062107b0fbb0de76340a505c06d69194198c5","unresolved":false,"context_lines":[{"line_number":12,"context_line":"# License for the specific language governing permissions and limitations"},{"line_number":13,"context_line":"# under the License."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import datetime"},{"line_number":16,"context_line":"import sqlalchemy"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from oslo_config import cfg"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_af9edf53","line":15,"in_reply_to":"7aa08908_43047d7d","updated":"2016-06-06 15:12:02.000000000","message":"Done","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"f455eb16ed9c70c799cf53e997e0123597e2247c","unresolved":false,"context_lines":[{"line_number":15,"context_line":"import datetime"},{"line_number":16,"context_line":"import sqlalchemy"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from oslo_config import cfg"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from keystone.common import driver_hints"},{"line_number":21,"context_line":"from keystone.common import sql"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_83fe6569","line":18,"updated":"2016-06-06 12:34:36.000000000","message":"Same here","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"d1a062107b0fbb0de76340a505c06d69194198c5","unresolved":false,"context_lines":[{"line_number":15,"context_line":"import datetime"},{"line_number":16,"context_line":"import sqlalchemy"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from oslo_config import cfg"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from keystone.common import driver_hints"},{"line_number":21,"context_line":"from keystone.common import sql"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_0fa453a4","line":18,"in_reply_to":"7aa08908_83fe6569","updated":"2016-06-06 15:12:02.000000000","message":"Done","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"f455eb16ed9c70c799cf53e997e0123597e2247c","unresolved":false,"context_lines":[{"line_number":233,"context_line":"            session.delete(ref)"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":""},{"line_number":236,"context_line":"class Authenticator(object):"},{"line_number":237,"context_line":"    def authenticate(self, user_id, password):"},{"line_number":238,"context_line":"        with sql.session_for_read() as session:"},{"line_number":239,"context_line":"            user_ref \u003d None"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_a323a104","line":236,"updated":"2016-06-06 12:34:36.000000000","message":"Why is there a new class when there is no state of its own?","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"984aeeda4f66a5bde084fc81d458f45a228c6d0b","unresolved":false,"context_lines":[{"line_number":233,"context_line":"            session.delete(ref)"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":""},{"line_number":236,"context_line":"class Authenticator(object):"},{"line_number":237,"context_line":"    def authenticate(self, user_id, password):"},{"line_number":238,"context_line":"        with sql.session_for_read() as session:"},{"line_number":239,"context_line":"            user_ref \u003d None"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_c05a1583","line":236,"in_reply_to":"7aa08908_a323a104","updated":"2016-06-06 15:17:37.000000000","message":"No state of it\u0027s own?  Not following.","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"c7ddb1d71f9238b5d485d1501df13e88aaaa5551","unresolved":false,"context_lines":[{"line_number":233,"context_line":"            session.delete(ref)"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":""},{"line_number":236,"context_line":"class Authenticator(object):"},{"line_number":237,"context_line":"    def authenticate(self, user_id, password):"},{"line_number":238,"context_line":"        with sql.session_for_read() as session:"},{"line_number":239,"context_line":"            user_ref \u003d None"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_2e921ca0","line":236,"in_reply_to":"7aa08908_c05a1583","updated":"2016-06-09 13:04:57.000000000","message":"This class has no state. No self.X variables. That\u0027s typically a code smell.","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"f455eb16ed9c70c799cf53e997e0123597e2247c","unresolved":false,"context_lines":[{"line_number":249,"context_line":"                raise exception.PasswordExpired(user_id\u003duser_id)"},{"line_number":250,"context_line":"            return base.filter_user(user_ref.to_dict())"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"    def _password_matches(self, password, hashed_password):"},{"line_number":253,"context_line":"        \"\"\"Check the specified password against the data store."},{"line_number":254,"context_line":""},{"line_number":255,"context_line":"        For more info, please see the follow up suggestion at"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_de48465e","line":252,"updated":"2016-06-06 12:34:36.000000000","message":"The renames and refactoring should be in their own patch.","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"984aeeda4f66a5bde084fc81d458f45a228c6d0b","unresolved":false,"context_lines":[{"line_number":249,"context_line":"                raise exception.PasswordExpired(user_id\u003duser_id)"},{"line_number":250,"context_line":"            return base.filter_user(user_ref.to_dict())"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"    def _password_matches(self, password, hashed_password):"},{"line_number":253,"context_line":"        \"\"\"Check the specified password against the data store."},{"line_number":254,"context_line":""},{"line_number":255,"context_line":"        For more info, please see the follow up suggestion at"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_a0d6e9c2","line":252,"in_reply_to":"7aa08908_de48465e","updated":"2016-06-06 15:17:37.000000000","message":"I think minimal refactoring while adding new features should be acceptable.","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"f455eb16ed9c70c799cf53e997e0123597e2247c","unresolved":false,"context_lines":[{"line_number":258,"context_line":"        \"\"\""},{"line_number":259,"context_line":"        return utils.check_password(password, hashed_password)"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"    def _get_user(self, session, user_id):"},{"line_number":262,"context_line":"        user_ref \u003d session.query(model.User).get(user_id)"},{"line_number":263,"context_line":"        if not user_ref:"},{"line_number":264,"context_line":"            raise exception.UserNotFound(user_id\u003duser_id)"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_fe90a297","line":261,"updated":"2016-06-06 12:34:36.000000000","message":"Needing a copy of this is a code smell that usually indicates the classes should be merged.","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"c7ddb1d71f9238b5d485d1501df13e88aaaa5551","unresolved":false,"context_lines":[{"line_number":258,"context_line":"        \"\"\""},{"line_number":259,"context_line":"        return utils.check_password(password, hashed_password)"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"    def _get_user(self, session, user_id):"},{"line_number":262,"context_line":"        user_ref \u003d session.query(model.User).get(user_id)"},{"line_number":263,"context_line":"        if not user_ref:"},{"line_number":264,"context_line":"            raise exception.UserNotFound(user_id\u003duser_id)"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_0e5760cb","line":261,"in_reply_to":"7aa08908_601d2173","updated":"2016-06-09 13:04:57.000000000","message":"If all you ever do is create a new instance with no state and call a single method then this really is the wrong abstraction. I don\u0027t see this a an SRP thing at all.","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"984aeeda4f66a5bde084fc81d458f45a228c6d0b","unresolved":false,"context_lines":[{"line_number":258,"context_line":"        \"\"\""},{"line_number":259,"context_line":"        return utils.check_password(password, hashed_password)"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"    def _get_user(self, session, user_id):"},{"line_number":262,"context_line":"        user_ref \u003d session.query(model.User).get(user_id)"},{"line_number":263,"context_line":"        if not user_ref:"},{"line_number":264,"context_line":"            raise exception.UserNotFound(user_id\u003duser_id)"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_601d2173","line":261,"in_reply_to":"7aa08908_fe90a297","updated":"2016-06-06 15:17:37.000000000","message":"I don\u0027t like the copy, but disagree that the class should be merged.  The new class makes the code more modular and supports single responsibility principle.","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"}],"keystone/identity/backends/sql_security.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4e6d70a3a8ce16f6c79c9db00ccebf7e762e1dfa","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    def _password_matches(self, password, hashed_password):"},{"line_number":47,"context_line":"        \"\"\"Check the specified password against the data store."},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"        Note that we\u0027ll pass in the entire user_ref in case the subclass"},{"line_number":50,"context_line":"        needs things like user_ref.get(\u0027name\u0027)"},{"line_number":51,"context_line":"        For further justification, please see the follow up suggestion at"},{"line_number":52,"context_line":"        https://blueprints.launchpad.net/keystone/+spec/sql-identiy-pam"}],"source_content_type":"text/x-python","patch_set":37,"id":"9abb7d3a_b2f17597","line":49,"updated":"2016-06-01 20:40:18.000000000","message":"Where do we pass in the entire user_ref? Doesn\u0027t this method only deal with the password value for the authentication request and the hashed value from the backend?","commit_id":"629a502125e01bcf27661e6a9c32b84685d3c947"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"e622db5b6983c12ed0e259ed3b552b04cf81064c","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    def _password_matches(self, password, hashed_password):"},{"line_number":47,"context_line":"        \"\"\"Check the specified password against the data store."},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"        Note that we\u0027ll pass in the entire user_ref in case the subclass"},{"line_number":50,"context_line":"        needs things like user_ref.get(\u0027name\u0027)"},{"line_number":51,"context_line":"        For further justification, please see the follow up suggestion at"},{"line_number":52,"context_line":"        https://blueprints.launchpad.net/keystone/+spec/sql-identiy-pam"}],"source_content_type":"text/x-python","patch_set":37,"id":"9abb7d3a_eb794894","line":49,"in_reply_to":"9abb7d3a_b2f17597","updated":"2016-06-01 21:14:45.000000000","message":"Oops, changed this but didn\u0027t update the comments","commit_id":"629a502125e01bcf27661e6a9c32b84685d3c947"}],"keystone/tests/unit/identity/backends/test_sql.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"f455eb16ed9c70c799cf53e997e0123597e2247c","unresolved":false,"context_lines":[{"line_number":56,"context_line":"        return user_ref"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def test_authenticate_with_expired_password(self):"},{"line_number":59,"context_line":"        CONF.security_compliance.password_expires_days \u003d 90"},{"line_number":60,"context_line":"        password \u003d uuid.uuid4().hex"},{"line_number":61,"context_line":"        user_dict \u003d self._get_test_user_dict(password)"},{"line_number":62,"context_line":"        # set password created_at so that the password will expire"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_fe5542c6","line":59,"updated":"2016-06-06 12:34:36.000000000","message":"Use the config fixture so that the values are properly set to their defaults after the test executes. You should already have it setup, just check self.config_fixture.","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"fbb338d530df465a1194f99fb9d941a4f8a320a9","unresolved":false,"context_lines":[{"line_number":56,"context_line":"        return user_ref"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def test_authenticate_with_expired_password(self):"},{"line_number":59,"context_line":"        CONF.security_compliance.password_expires_days \u003d 90"},{"line_number":60,"context_line":"        password \u003d uuid.uuid4().hex"},{"line_number":61,"context_line":"        user_dict \u003d self._get_test_user_dict(password)"},{"line_number":62,"context_line":"        # set password created_at so that the password will expire"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_d45da67a","line":59,"in_reply_to":"7aa08908_c0997570","updated":"2016-06-06 21:49:40.000000000","message":"Wired the tests up differently so that I could utilize self.config_fixtures","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"fbb338d530df465a1194f99fb9d941a4f8a320a9","unresolved":false,"context_lines":[{"line_number":56,"context_line":"        return user_ref"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def test_authenticate_with_expired_password(self):"},{"line_number":59,"context_line":"        CONF.security_compliance.password_expires_days \u003d 90"},{"line_number":60,"context_line":"        password \u003d uuid.uuid4().hex"},{"line_number":61,"context_line":"        user_dict \u003d self._get_test_user_dict(password)"},{"line_number":62,"context_line":"        # set password created_at so that the password will expire"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_34550a50","line":59,"in_reply_to":"7aa08908_fe5542c6","updated":"2016-06-06 21:49:40.000000000","message":"Done","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"d1a062107b0fbb0de76340a505c06d69194198c5","unresolved":false,"context_lines":[{"line_number":56,"context_line":"        return user_ref"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def test_authenticate_with_expired_password(self):"},{"line_number":59,"context_line":"        CONF.security_compliance.password_expires_days \u003d 90"},{"line_number":60,"context_line":"        password \u003d uuid.uuid4().hex"},{"line_number":61,"context_line":"        user_dict \u003d self._get_test_user_dict(password)"},{"line_number":62,"context_line":"        # set password created_at so that the password will expire"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_c0997570","line":59,"in_reply_to":"7aa08908_fe5542c6","updated":"2016-06-06 15:12:02.000000000","message":"Hmm... when I add self.config_fixture, I get:AttributeError: \u0027TestIdentityDriver\u0027 object has no attribute \u0027config_fixture\u0027\n\nHowever, I tested it and the config values are properly getting set back to the default value for each test.","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"f455eb16ed9c70c799cf53e997e0123597e2247c","unresolved":false,"context_lines":[{"line_number":71,"context_line":"                          password)"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    def test_authenticate_with_non_expired_password(self):"},{"line_number":74,"context_line":"        CONF.security_compliance.password_expires_days \u003d 90"},{"line_number":75,"context_line":"        password \u003d uuid.uuid4().hex"},{"line_number":76,"context_line":"        user_dict \u003d self._get_test_user_dict(password)"},{"line_number":77,"context_line":"        # set password created_at so that the password will not expire"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_deaa0670","line":74,"updated":"2016-06-06 12:34:36.000000000","message":"Same here","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"fbb338d530df465a1194f99fb9d941a4f8a320a9","unresolved":false,"context_lines":[{"line_number":71,"context_line":"                          password)"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    def test_authenticate_with_non_expired_password(self):"},{"line_number":74,"context_line":"        CONF.security_compliance.password_expires_days \u003d 90"},{"line_number":75,"context_line":"        password \u003d uuid.uuid4().hex"},{"line_number":76,"context_line":"        user_dict \u003d self._get_test_user_dict(password)"},{"line_number":77,"context_line":"        # set password created_at so that the password will not expire"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_1450ce5d","line":74,"in_reply_to":"7aa08908_deaa0670","updated":"2016-06-06 21:49:40.000000000","message":"Done","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"f455eb16ed9c70c799cf53e997e0123597e2247c","unresolved":false,"context_lines":[{"line_number":85,"context_line":"        self.assertEqual(user[\u0027id\u0027], actual_user[\u0027id\u0027])"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    def test_authenticate_with_expired_password_for_ignore_user(self):"},{"line_number":88,"context_line":"        CONF.security_compliance.password_expires_days \u003d 90"},{"line_number":89,"context_line":"        password \u003d uuid.uuid4().hex"},{"line_number":90,"context_line":"        user_dict \u003d self._get_test_user_dict(password)"},{"line_number":91,"context_line":"        # set password created_at so that the password will expire"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_fec42241","line":88,"updated":"2016-06-06 12:34:36.000000000","message":"Same here","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"fbb338d530df465a1194f99fb9d941a4f8a320a9","unresolved":false,"context_lines":[{"line_number":85,"context_line":"        self.assertEqual(user[\u0027id\u0027], actual_user[\u0027id\u0027])"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    def test_authenticate_with_expired_password_for_ignore_user(self):"},{"line_number":88,"context_line":"        CONF.security_compliance.password_expires_days \u003d 90"},{"line_number":89,"context_line":"        password \u003d uuid.uuid4().hex"},{"line_number":90,"context_line":"        user_dict \u003d self._get_test_user_dict(password)"},{"line_number":91,"context_line":"        # set password created_at so that the password will expire"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_744f92bd","line":88,"in_reply_to":"7aa08908_fec42241","updated":"2016-06-06 21:49:40.000000000","message":"Done","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"f455eb16ed9c70c799cf53e997e0123597e2247c","unresolved":false,"context_lines":[{"line_number":99,"context_line":"                          user[\u0027id\u0027],"},{"line_number":100,"context_line":"                          password)"},{"line_number":101,"context_line":"        # add user to ignore list and confirm password is no longer expired"},{"line_number":102,"context_line":"        CONF.security_compliance.password_expires_ignore_list \u003d user[\u0027id\u0027]"},{"line_number":103,"context_line":"        ret_user \u003d sql_backend.Authenticator().authenticate(user[\u0027id\u0027],"},{"line_number":104,"context_line":"                                                            password)"},{"line_number":105,"context_line":"        self.assertEqual(user[\u0027id\u0027], ret_user[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_3edd0a15","line":102,"updated":"2016-06-06 12:34:36.000000000","message":"Same here","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"fbb338d530df465a1194f99fb9d941a4f8a320a9","unresolved":false,"context_lines":[{"line_number":99,"context_line":"                          user[\u0027id\u0027],"},{"line_number":100,"context_line":"                          password)"},{"line_number":101,"context_line":"        # add user to ignore list and confirm password is no longer expired"},{"line_number":102,"context_line":"        CONF.security_compliance.password_expires_ignore_list \u003d user[\u0027id\u0027]"},{"line_number":103,"context_line":"        ret_user \u003d sql_backend.Authenticator().authenticate(user[\u0027id\u0027],"},{"line_number":104,"context_line":"                                                            password)"},{"line_number":105,"context_line":"        self.assertEqual(user[\u0027id\u0027], ret_user[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_544a56ad","line":102,"in_reply_to":"7aa08908_3edd0a15","updated":"2016-06-06 21:49:40.000000000","message":"Done","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"}],"keystone/token/providers/common.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"f455eb16ed9c70c799cf53e997e0123597e2247c","unresolved":false,"context_lines":[{"line_number":364,"context_line":"            \u0027id\u0027: user_ref[\u0027id\u0027],"},{"line_number":365,"context_line":"            \u0027name\u0027: user_ref[\u0027name\u0027],"},{"line_number":366,"context_line":"            \u0027domain\u0027: self._get_filtered_domain(user_ref[\u0027domain_id\u0027])}"},{"line_number":367,"context_line":"        if user_ref[\u0027password_expires_at\u0027]:"},{"line_number":368,"context_line":"            filtered_user[\u0027password_expires_at\u0027] \u003d ("},{"line_number":369,"context_line":"                user_ref[\u0027password_expires_at\u0027])"},{"line_number":370,"context_line":"        token_data[\u0027user\u0027] \u003d filtered_user"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_1e092e96","line":367,"updated":"2016-06-06 12:34:36.000000000","message":"What\u0027s the case where this won\u0027t be in the user_ref?","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"d1a062107b0fbb0de76340a505c06d69194198c5","unresolved":false,"context_lines":[{"line_number":364,"context_line":"            \u0027id\u0027: user_ref[\u0027id\u0027],"},{"line_number":365,"context_line":"            \u0027name\u0027: user_ref[\u0027name\u0027],"},{"line_number":366,"context_line":"            \u0027domain\u0027: self._get_filtered_domain(user_ref[\u0027domain_id\u0027])}"},{"line_number":367,"context_line":"        if user_ref[\u0027password_expires_at\u0027]:"},{"line_number":368,"context_line":"            filtered_user[\u0027password_expires_at\u0027] \u003d ("},{"line_number":369,"context_line":"                user_ref[\u0027password_expires_at\u0027])"},{"line_number":370,"context_line":"        token_data[\u0027user\u0027] \u003d filtered_user"}],"source_content_type":"text/x-python","patch_set":46,"id":"7aa08908_ba5c5f26","line":367,"in_reply_to":"7aa08908_1e092e96","updated":"2016-06-06 15:12:02.000000000","message":"If the identity driver is something other than sql, this attribute won\u0027t be there.","commit_id":"1d8f5d3df2be939d6fb375219ff59ec9da3336a9"}]}
