)]}'
{"keystone/auth/__init__.py":[{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"8c2adb11f436de1ca6611a8f5444a629af459375","unresolved":false,"context_lines":[{"line_number":15,"context_line":"# NOTE(notmorgan): Be careful in adjusting whitespace here, flake8 checks"},{"line_number":16,"context_line":"# get cranky."},{"line_number":17,"context_line":"from keystone.auth import core  # noqa"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"from keystone.auth import controllers  # noqa"}],"source_content_type":"text/x-python","patch_set":11,"id":"3a461143_ad18441f","line":18,"updated":"2017-01-31 04:53:41.000000000","message":"no need for a blank line here","commit_id":"383c054e48b4ebae9911cfcd6a5162293775bcb0"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"ff252b09953f6cd865af35e430ecf8a3c82ebde2","unresolved":false,"context_lines":[{"line_number":15,"context_line":"# NOTE(notmorgan): Be careful in adjusting whitespace here, flake8 checks"},{"line_number":16,"context_line":"# get cranky."},{"line_number":17,"context_line":"from keystone.auth import core  # noqa"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"from keystone.auth import controllers  # noqa"}],"source_content_type":"text/x-python","patch_set":11,"id":"3a461143_688ba31f","line":18,"in_reply_to":"3a461143_ad18441f","updated":"2017-01-31 05:04:16.000000000","message":"Yep, or it complains and i really want to ensure core is imported first.","commit_id":"383c054e48b4ebae9911cfcd6a5162293775bcb0"}],"keystone/auth/controllers.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"1688b4a0cda9c3c681529acd456b6ef62651f03f","unresolved":false,"context_lines":[{"line_number":134,"context_line":"            # impossible to accidently lock-out a subset of users with a"},{"line_number":135,"context_line":"            # bad keystone.conf"},{"line_number":136,"context_line":"            r_set \u003d r.intersection(self.auth_methods)"},{"line_number":137,"context_line":"            if auth_methods.issuperset(set(r_set)):"},{"line_number":138,"context_line":"                # Rule Matches no need to continue, return here."},{"line_number":139,"context_line":"                LOG.debug(\u0027User %(user_id)s auth methods %(methods)r \u0027"},{"line_number":140,"context_line":"                          \u0027matched MFA rule %(rule)r. Loaded \u0027"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a3905b3_dd01fbb0","line":137,"range":{"start_line":137,"start_character":39,"end_line":137,"end_character":49},"updated":"2017-01-21 03:25:30.000000000","message":"This should already be a set and does not need to be cast *again* into a set.","commit_id":"2e7f98fb3f2b91ec074f08decb0b630fc2e3fbff"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"a7ff76eb1080f61638276cb2d5d16c6923d19bf0","unresolved":false,"context_lines":[{"line_number":89,"context_line":"    return AUTH_METHODS[method_name]"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"@dependency.requires(\u0027identity_api\u0027)"},{"line_number":93,"context_line":"class UserMFARulesValidator(object):"},{"line_number":94,"context_line":"    \"\"\"Helper object that can validate the MFA Rules.\"\"\""},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a3905b3_85afbf7b","line":93,"range":{"start_line":92,"start_character":0,"end_line":93,"end_character":36},"updated":"2017-01-24 05:31:07.000000000","message":"maybe put this in another module?","commit_id":"dc322f4b81d5c3761c19b2e9581c2e1770f5b51a"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"a7ff76eb1080f61638276cb2d5d16c6923d19bf0","unresolved":false,"context_lines":[{"line_number":120,"context_line":""},{"line_number":121,"context_line":"        if not rules or not user_ref.mfa.enabled:"},{"line_number":122,"context_line":"            # return quickly if the rules are disabled for the user or not set"},{"line_number":123,"context_line":"            LOG.debug(\u0027User MFA Rules not processed for %(user_id)s. \u0027"},{"line_number":124,"context_line":"                      \u0027Rule list: %(rules)r (Enabled: %(enabled)s).\u0027,"},{"line_number":125,"context_line":"                      {\u0027user_id\u0027: user_id,"},{"line_number":126,"context_line":"                       \u0027rules\u0027: user_ref[\u0027mfa_rules\u0027],"},{"line_number":127,"context_line":"                       \u0027enabled\u0027: user_ref[\u0027mfa_rules_enabled\u0027]})"},{"line_number":128,"context_line":"            return True"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"        for r in rules:"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a3905b3_05dbcf1b","line":127,"range":{"start_line":123,"start_character":0,"end_line":127,"end_character":65},"updated":"2017-01-24 05:31:07.000000000","message":"this is too very chatty, \"User MFA Rules\" shows up 570 times in http://logs.openstack.org/48/423548/5/check/gate-tempest-dsvm-neutron-full-ubuntu-xenial/3a6f046/logs/apache/keystone.txt.gz","commit_id":"dc322f4b81d5c3761c19b2e9581c2e1770f5b51a"},{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"6a8f9c4207f0b99674ba764780e15b9890776a65","unresolved":false,"context_lines":[{"line_number":120,"context_line":""},{"line_number":121,"context_line":"        if not rules or not user_ref.mfa.enabled:"},{"line_number":122,"context_line":"            # return quickly if the rules are disabled for the user or not set"},{"line_number":123,"context_line":"            LOG.debug(\u0027User MFA Rules not processed for %(user_id)s. \u0027"},{"line_number":124,"context_line":"                      \u0027Rule list: %(rules)r (Enabled: %(enabled)s).\u0027,"},{"line_number":125,"context_line":"                      {\u0027user_id\u0027: user_id,"},{"line_number":126,"context_line":"                       \u0027rules\u0027: user_ref[\u0027mfa_rules\u0027],"},{"line_number":127,"context_line":"                       \u0027enabled\u0027: user_ref[\u0027mfa_rules_enabled\u0027]})"},{"line_number":128,"context_line":"            return True"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"        for r in rules:"}],"source_content_type":"text/x-python","patch_set":5,"id":"3a461143_1b8947cb","line":127,"range":{"start_line":123,"start_character":0,"end_line":127,"end_character":65},"in_reply_to":"5a3905b3_05dbcf1b","updated":"2017-01-25 14:52:53.000000000","message":"On one hand, i think that keystone is not logging enough and debug log might be handy.\n\nOn the other, this is useless here. It won\u0027t help in production and in debugging it will just show what we can easily lookup.","commit_id":"dc322f4b81d5c3761c19b2e9581c2e1770f5b51a"},{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"6a8f9c4207f0b99674ba764780e15b9890776a65","unresolved":false,"context_lines":[{"line_number":165,"context_line":"        :raises: ValueError"},{"line_number":166,"context_line":"        \"\"\""},{"line_number":167,"context_line":"        rule_set \u003d set()"},{"line_number":168,"context_line":"        if not isinstance(rules, list):"},{"line_number":169,"context_line":"            raise ValueError(_(\u0027rules list must be a list of lists, got \u0027"},{"line_number":170,"context_line":"                               \u0027%(type)s\u0027) %"},{"line_number":171,"context_line":"                             {\u0027type\u0027: type(rules)})"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"        if not rules:"},{"line_number":174,"context_line":"            # No rules exist."}],"source_content_type":"text/x-python","patch_set":5,"id":"3a461143_5bdbcf1b","line":171,"range":{"start_line":168,"start_character":0,"end_line":171,"end_character":51},"updated":"2017-01-25 14:52:53.000000000","message":"i think this is not necessary. It\u0027s python after all.","commit_id":"dc322f4b81d5c3761c19b2e9581c2e1770f5b51a"},{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"6a8f9c4207f0b99674ba764780e15b9890776a65","unresolved":false,"context_lines":[{"line_number":175,"context_line":"            return rule_set"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"        for r_list in rules:"},{"line_number":178,"context_line":"            if not isinstance(r_list, list):"},{"line_number":179,"context_line":"                LOG.info(_LI(\u0027Ignoring Rule %(rule)r; rule must be a list of \u0027"},{"line_number":180,"context_line":"                             \u0027strings.\u0027),"},{"line_number":181,"context_line":"                         {\u0027type\u0027: type(r_list)})"},{"line_number":182,"context_line":"                continue"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"            if r_list:"}],"source_content_type":"text/x-python","patch_set":5,"id":"3a461143_db6c1f0b","line":181,"range":{"start_line":178,"start_character":0,"end_line":181,"end_character":48},"updated":"2017-01-25 14:52:53.000000000","message":"same here.\n\nThese checks should happen on rule list creation, not when it is used.","commit_id":"dc322f4b81d5c3761c19b2e9581c2e1770f5b51a"},{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"6a8f9c4207f0b99674ba764780e15b9890776a65","unresolved":false,"context_lines":[{"line_number":184,"context_line":"            if r_list:"},{"line_number":185,"context_line":"                # No empty rules are allowed."},{"line_number":186,"context_line":"                for item in r_list:"},{"line_number":187,"context_line":"                    if not isinstance(item, six.string_types):"},{"line_number":188,"context_line":"                        # Rules may only contain strings for method names"},{"line_number":189,"context_line":"                        # Reject a rule with non-string values"},{"line_number":190,"context_line":"                        LOG.info(_LI(\u0027Ignoring Rule %(rule)r; rule contains \u0027"}],"source_content_type":"text/x-python","patch_set":5,"id":"3a461143_3b5b6356","line":187,"range":{"start_line":187,"start_character":0,"end_line":187,"end_character":62},"updated":"2017-01-25 14:52:53.000000000","message":"same here","commit_id":"dc322f4b81d5c3761c19b2e9581c2e1770f5b51a"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"8c2adb11f436de1ca6611a8f5444a629af459375","unresolved":false,"context_lines":[{"line_number":408,"context_line":"            # NOTE(notmorgan): only methods that actually run and succeed will"},{"line_number":409,"context_line":"            # be in the auth_context[\u0027method_names\u0027] list. Do not blindly take"},{"line_number":410,"context_line":"            # the values from auth_info, look at the authoritative values. Make"},{"line_number":411,"context_line":"            # sure the set is unique."},{"line_number":412,"context_line":"            method_names_set \u003d set(auth_context.get(\u0027method_names\u0027, []))"},{"line_number":413,"context_line":"            method_names \u003d list(method_names_set)"},{"line_number":414,"context_line":""},{"line_number":415,"context_line":"            # Do MFA Rule Validation for the user"},{"line_number":416,"context_line":"            if not self._mfa_rules_validator.check_auth_methods_against_rules("}],"source_content_type":"text/x-python","patch_set":11,"id":"3a461143_081f7f08","line":413,"range":{"start_line":411,"start_character":12,"end_line":413,"end_character":49},"updated":"2017-01-31 04:53:41.000000000","message":"unnecessary refactor","commit_id":"383c054e48b4ebae9911cfcd6a5162293775bcb0"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"ff252b09953f6cd865af35e430ecf8a3c82ebde2","unresolved":false,"context_lines":[{"line_number":408,"context_line":"            # NOTE(notmorgan): only methods that actually run and succeed will"},{"line_number":409,"context_line":"            # be in the auth_context[\u0027method_names\u0027] list. Do not blindly take"},{"line_number":410,"context_line":"            # the values from auth_info, look at the authoritative values. Make"},{"line_number":411,"context_line":"            # sure the set is unique."},{"line_number":412,"context_line":"            method_names_set \u003d set(auth_context.get(\u0027method_names\u0027, []))"},{"line_number":413,"context_line":"            method_names \u003d list(method_names_set)"},{"line_number":414,"context_line":""},{"line_number":415,"context_line":"            # Do MFA Rule Validation for the user"},{"line_number":416,"context_line":"            if not self._mfa_rules_validator.check_auth_methods_against_rules("}],"source_content_type":"text/x-python","patch_set":11,"id":"3a461143_e87f9312","line":413,"range":{"start_line":411,"start_character":12,"end_line":413,"end_character":49},"in_reply_to":"3a461143_081f7f08","updated":"2017-01-31 05:04:16.000000000","message":"This was part of debugging a larger issue, it could be reverted.","commit_id":"383c054e48b4ebae9911cfcd6a5162293775bcb0"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"8c2adb11f436de1ca6611a8f5444a629af459375","unresolved":false,"context_lines":[{"line_number":414,"context_line":""},{"line_number":415,"context_line":"            # Do MFA Rule Validation for the user"},{"line_number":416,"context_line":"            if not self._mfa_rules_validator.check_auth_methods_against_rules("},{"line_number":417,"context_line":"                    auth_context[\u0027user_id\u0027], method_names_set):"},{"line_number":418,"context_line":"                raise exception.InsufficientAuthMethods("},{"line_number":419,"context_line":"                    user_id\u003dauth_context[\u0027user_id\u0027],"},{"line_number":420,"context_line":"                    methods\u003d\u0027[%s]\u0027 % \u0027,\u0027.join(auth_info.get_method_names()))"}],"source_content_type":"text/x-python","patch_set":11,"id":"3a461143_68d64329","line":417,"range":{"start_line":417,"start_character":45,"end_line":417,"end_character":61},"updated":"2017-01-31 04:53:41.000000000","message":"why pass in the set and not the list (once it\u0027s been made unique)?","commit_id":"383c054e48b4ebae9911cfcd6a5162293775bcb0"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"ff252b09953f6cd865af35e430ecf8a3c82ebde2","unresolved":false,"context_lines":[{"line_number":414,"context_line":""},{"line_number":415,"context_line":"            # Do MFA Rule Validation for the user"},{"line_number":416,"context_line":"            if not self._mfa_rules_validator.check_auth_methods_against_rules("},{"line_number":417,"context_line":"                    auth_context[\u0027user_id\u0027], method_names_set):"},{"line_number":418,"context_line":"                raise exception.InsufficientAuthMethods("},{"line_number":419,"context_line":"                    user_id\u003dauth_context[\u0027user_id\u0027],"},{"line_number":420,"context_line":"                    methods\u003d\u0027[%s]\u0027 % \u0027,\u0027.join(auth_info.get_method_names()))"}],"source_content_type":"text/x-python","patch_set":11,"id":"3a461143_88952f34","line":417,"range":{"start_line":417,"start_character":45,"end_line":417,"end_character":61},"in_reply_to":"3a461143_68d64329","updated":"2017-01-31 05:04:16.000000000","message":"The validator actually expects a set so it doesn\u0027t have to do casting (or it did at one point, it may not now).","commit_id":"383c054e48b4ebae9911cfcd6a5162293775bcb0"}],"keystone/auth/core.py":[{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"8c2adb11f436de1ca6611a8f5444a629af459375","unresolved":false,"context_lines":[{"line_number":99,"context_line":"        \"\"\""},{"line_number":100,"context_line":"        user_ref \u003d self.identity_api.get_user(user_id)"},{"line_number":101,"context_line":"        mfa_rules \u003d user_ref[\u0027options\u0027].get(ro.MFA_RULES_OPT.option_name, [])"},{"line_number":102,"context_line":"        mfa_rules_enabled \u003d user_ref[\u0027options\u0027].get("},{"line_number":103,"context_line":"            ro.MFA_ENABLED_OPT.option_name, True)"},{"line_number":104,"context_line":"        rules \u003d self._parse_rule_structure(mfa_rules, user_ref[\u0027id\u0027])"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        if not rules or not mfa_rules_enabled:"}],"source_content_type":"text/x-python","patch_set":11,"id":"3a461143_48ec27f3","line":103,"range":{"start_line":102,"start_character":8,"end_line":103,"end_character":49},"updated":"2017-01-31 04:53:41.000000000","message":"slight optimization: check if mfa_rules_enabled first, then return True if disabled.\n\nthis will eliminate the rules fetch, and the parsing of rule structure","commit_id":"383c054e48b4ebae9911cfcd6a5162293775bcb0"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"ff252b09953f6cd865af35e430ecf8a3c82ebde2","unresolved":false,"context_lines":[{"line_number":99,"context_line":"        \"\"\""},{"line_number":100,"context_line":"        user_ref \u003d self.identity_api.get_user(user_id)"},{"line_number":101,"context_line":"        mfa_rules \u003d user_ref[\u0027options\u0027].get(ro.MFA_RULES_OPT.option_name, [])"},{"line_number":102,"context_line":"        mfa_rules_enabled \u003d user_ref[\u0027options\u0027].get("},{"line_number":103,"context_line":"            ro.MFA_ENABLED_OPT.option_name, True)"},{"line_number":104,"context_line":"        rules \u003d self._parse_rule_structure(mfa_rules, user_ref[\u0027id\u0027])"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        if not rules or not mfa_rules_enabled:"}],"source_content_type":"text/x-python","patch_set":11,"id":"3a461143_e8a6b3ac","line":103,"range":{"start_line":102,"start_character":8,"end_line":103,"end_character":49},"in_reply_to":"3a461143_48ec27f3","updated":"2017-01-31 05:04:16.000000000","message":"At this point it is a dict lookup (near to free), it isn\u0027t actually fetching from the backend, we\u0027ve already done that. the parse bit below could be skipped.","commit_id":"383c054e48b4ebae9911cfcd6a5162293775bcb0"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"8c2adb11f436de1ca6611a8f5444a629af459375","unresolved":false,"context_lines":[{"line_number":118,"context_line":"            # disable an auth method, and a rule will still pass making it"},{"line_number":119,"context_line":"            # impossible to accidently lock-out a subset of users with a"},{"line_number":120,"context_line":"            # bad keystone.conf"},{"line_number":121,"context_line":"            r_set \u003d set(r).intersection(self._auth_methods)"},{"line_number":122,"context_line":"            if set(auth_methods).issuperset(r_set):"},{"line_number":123,"context_line":"                # Rule Matches no need to continue, return here."},{"line_number":124,"context_line":"                LOG.debug(\u0027Auth methods for user `%(user_id)s`, `%(methods)s` \u0027"}],"source_content_type":"text/x-python","patch_set":11,"id":"3a461143_88c0cf51","line":121,"range":{"start_line":121,"start_character":12,"end_line":121,"end_character":59},"updated":"2017-01-31 04:53:41.000000000","message":"ah okay, i get why you passed in the set now","commit_id":"383c054e48b4ebae9911cfcd6a5162293775bcb0"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"ff252b09953f6cd865af35e430ecf8a3c82ebde2","unresolved":false,"context_lines":[{"line_number":118,"context_line":"            # disable an auth method, and a rule will still pass making it"},{"line_number":119,"context_line":"            # impossible to accidently lock-out a subset of users with a"},{"line_number":120,"context_line":"            # bad keystone.conf"},{"line_number":121,"context_line":"            r_set \u003d set(r).intersection(self._auth_methods)"},{"line_number":122,"context_line":"            if set(auth_methods).issuperset(r_set):"},{"line_number":123,"context_line":"                # Rule Matches no need to continue, return here."},{"line_number":124,"context_line":"                LOG.debug(\u0027Auth methods for user `%(user_id)s`, `%(methods)s` \u0027"}],"source_content_type":"text/x-python","patch_set":11,"id":"3a461143_48a8a777","line":121,"range":{"start_line":121,"start_character":12,"end_line":121,"end_character":59},"in_reply_to":"3a461143_88c0cf51","updated":"2017-01-31 05:04:16.000000000","message":"Yep, avoids casting in here since we already had to do the set things before.","commit_id":"383c054e48b4ebae9911cfcd6a5162293775bcb0"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"e26d514d46ca3d746162fc416df17223e052e401","unresolved":false,"context_lines":[{"line_number":153,"context_line":"        \"\"\""},{"line_number":154,"context_line":"        # NOTE(notmorgan): Most of this is done at the API request validation"},{"line_number":155,"context_line":"        # and in the storage layer, it makes sense to also validate here and"},{"line_number":156,"context_line":"        # ensure the data returned from the DB is sane, This will not raise"},{"line_number":157,"context_line":"        # any exceptions, but just produce a usable set of data for rules"},{"line_number":158,"context_line":"        # processing."},{"line_number":159,"context_line":"        rule_set \u003d []"}],"source_content_type":"text/x-python","patch_set":11,"id":"3a461143_2d81b4c3","line":156,"updated":"2017-01-30 22:30:30.000000000","message":"nit: s/,/./","commit_id":"383c054e48b4ebae9911cfcd6a5162293775bcb0"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"8c2adb11f436de1ca6611a8f5444a629af459375","unresolved":false,"context_lines":[{"line_number":185,"context_line":"                                 {\u0027rule\u0027: r_list})"},{"line_number":186,"context_line":"                        _ok_rule \u003d False"},{"line_number":187,"context_line":"                        break"},{"line_number":188,"context_line":"                if _ok_rule:"},{"line_number":189,"context_line":"                    # De-dupe rule and add to the return value"},{"line_number":190,"context_line":"                    rule_string \u003d \u0027;\u0027.join(sorted(r_list))"},{"line_number":191,"context_line":"                    if rule_string not in found_rules:"},{"line_number":192,"context_line":"                        found_rules.add(rule_string)"},{"line_number":193,"context_line":"                    r_list \u003d list(set(r_list))"},{"line_number":194,"context_line":"                    rule_set.append(r_list)"},{"line_number":195,"context_line":""},{"line_number":196,"context_line":"        return rule_set"}],"source_content_type":"text/x-python","patch_set":11,"id":"3a461143_08cdbf84","line":194,"range":{"start_line":188,"start_character":16,"end_line":194,"end_character":43},"updated":"2017-01-31 04:53:41.000000000","message":"shouldn\u0027t this be in the loop? or at least the part that adds to \"found_rules\"?","commit_id":"383c054e48b4ebae9911cfcd6a5162293775bcb0"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"ff252b09953f6cd865af35e430ecf8a3c82ebde2","unresolved":false,"context_lines":[{"line_number":185,"context_line":"                                 {\u0027rule\u0027: r_list})"},{"line_number":186,"context_line":"                        _ok_rule \u003d False"},{"line_number":187,"context_line":"                        break"},{"line_number":188,"context_line":"                if _ok_rule:"},{"line_number":189,"context_line":"                    # De-dupe rule and add to the return value"},{"line_number":190,"context_line":"                    rule_string \u003d \u0027;\u0027.join(sorted(r_list))"},{"line_number":191,"context_line":"                    if rule_string not in found_rules:"},{"line_number":192,"context_line":"                        found_rules.add(rule_string)"},{"line_number":193,"context_line":"                    r_list \u003d list(set(r_list))"},{"line_number":194,"context_line":"                    rule_set.append(r_list)"},{"line_number":195,"context_line":""},{"line_number":196,"context_line":"        return rule_set"}],"source_content_type":"text/x-python","patch_set":11,"id":"3a461143_28db5b1c","line":194,"range":{"start_line":188,"start_character":16,"end_line":194,"end_character":43},"in_reply_to":"3a461143_08cdbf84","updated":"2017-01-31 05:04:16.000000000","message":"So, the for-loop simply verifies everything is a string, this adds it to a set (which must be moved from a list which is unhashable to a non-list thing). I could in theory build the ordered string bit in the loop, but this ensures we have a consistent check (sorted -\u003e joined string) of rules to parse through when doing the auth loop. \n\nThe alternative is to have potentially more rules that are duplicates in the list to check against. We could probably just drop the de-dupe stuff here, it is unlikely to matter much.","commit_id":"383c054e48b4ebae9911cfcd6a5162293775bcb0"}],"keystone/tests/unit/test_backend_ldap.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"6727aec1fed6158ef8a0a476dfed381b5879a92c","unresolved":false,"context_lines":[{"line_number":324,"context_line":""},{"line_number":325,"context_line":"        # Add in the mfa_rules and mfa_rules_enabled values for user_sna"},{"line_number":326,"context_line":"        # This whole test is going away once LDAP writes are no longer a"},{"line_number":327,"context_line":"        # part of Keystone. Until then, this is a work-around for this specific"},{"line_number":328,"context_line":"        # test."},{"line_number":329,"context_line":"        self.user_sna[\u0027mfa_rules\u0027] \u003d []"},{"line_number":330,"context_line":"        self.user_sna[\u0027mfa_rules_enabled\u0027] \u003d True"},{"line_number":331,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"5a3905b3_6a867c14","line":328,"range":{"start_line":327,"start_character":66,"end_line":328,"end_character":15},"updated":"2017-01-21 01:24:09.000000000","message":"ldap tests that deal with user updates.","commit_id":"99929b056e51d33bfac2a98097aabda022a121f2"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"467866c4d3a8181c3b1ebfe1ef72d8a6ec20cb2e","unresolved":false,"context_lines":[{"line_number":323,"context_line":"        self.load_fixtures(default_fixtures)"},{"line_number":324,"context_line":""},{"line_number":325,"context_line":"        # Add in the mfa_rules and mfa_rules_enabled values for user_sna"},{"line_number":326,"context_line":"        # This whole test is going away once LDAP writes are no longer a"},{"line_number":327,"context_line":"        # part of Keystone. Until then, this is a work-around for LDAP"},{"line_number":328,"context_line":"        # tests that deal with user_ref matching. LDAP does not store"},{"line_number":329,"context_line":"        # the mfa_rules or mfa_rules_enabled attributes directly."},{"line_number":330,"context_line":"        self.user_sna[\u0027mfa_rules\u0027] \u003d []"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a3905b3_1d1aa37d","line":327,"range":{"start_line":326,"start_character":9,"end_line":327,"end_character":38},"updated":"2017-01-21 04:32:38.000000000","message":"Until LDAP writes are not longer part of Keystone,","commit_id":"2e7f98fb3f2b91ec074f08decb0b630fc2e3fbff"}],"keystone/tests/unit/test_backend_ldap_pool.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"0c995550e15b928ee6b6158b45dbe9c6f404a096","unresolved":false,"context_lines":[{"line_number":181,"context_line":""},{"line_number":182,"context_line":"        self.user_sna.pop(\u0027password\u0027)"},{"line_number":183,"context_line":"        self.user_sna[\u0027enabled\u0027] \u003d True"},{"line_number":184,"context_line":""},{"line_number":185,"context_line":"        self.assertDictEqual(self.user_sna, user_ref)"},{"line_number":186,"context_line":""},{"line_number":187,"context_line":"        new_password \u003d \u0027new_password\u0027"}],"source_content_type":"text/x-python","patch_set":4,"id":"5a3905b3_2bd708ee","line":184,"updated":"2017-01-22 04:50:06.000000000","message":"Revert","commit_id":"680b981940814595236cf4c3ad6149fa42844253"}],"keystone/tests/unit/test_v3_auth.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"e26d514d46ca3d746162fc416df17223e052e401","unresolved":false,"context_lines":[{"line_number":137,"context_line":"                project_id\u003dself.project_id))"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    def test_MFA_rules_disabled_MFA_succeeeds(self):"},{"line_number":140,"context_line":"        # ensure that if MFA is \"disableD\" authentication succeeds, even if"},{"line_number":141,"context_line":"        # not enough auth methods are specified"},{"line_number":142,"context_line":"        rule_list \u003d [[\u0027password\u0027, \u0027totp\u0027]]"},{"line_number":143,"context_line":"        self._update_user_with_MFA_rules(rule_list\u003drule_list,"}],"source_content_type":"text/x-python","patch_set":11,"id":"3a461143_a8bcb206","line":140,"updated":"2017-01-30 22:30:30.000000000","message":"nit: s/disableD/disabled/","commit_id":"383c054e48b4ebae9911cfcd6a5162293775bcb0"}]}
