)]}'
{"keystoneclient/common/cms.py":[{"author":{"_account_id":7473,"name":"Grant Murphy","email":"grantcmurphy@gmail.com","username":"gm"},"change_message_id":"a42229e19ebd6a95f289f87ac8514fdc31c9d31a","unresolved":false,"context_lines":[{"line_number":263,"context_line":"    if token_id is None:"},{"line_number":264,"context_line":"        return None"},{"line_number":265,"context_line":"    if is_ans1_token(token_id):"},{"line_number":266,"context_line":"        if mode \u003d\u003d \u0027sha256\u0027:"},{"line_number":267,"context_line":"            fn \u003d hashlib.sha256"},{"line_number":268,"context_line":"        else:"},{"line_number":269,"context_line":"            fn \u003d hashlib.md5"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F%2Fa4E%3D","line":266,"updated":"2014-03-18 00:35:46.000000000","message":"h \u003d hashlib.new(mode) \n\nwhere mode \u003d \u0027md5\u0027, \u0027sha256\u0027 you will get the same behaviour.","commit_id":"3b51450f88b8e4ed6b90ad6bd4cebc415d7fb7c1"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e5f60018a7e173e876746dbf627d100a84577dd4","unresolved":false,"context_lines":[{"line_number":263,"context_line":"    if token_id is None:"},{"line_number":264,"context_line":"        return None"},{"line_number":265,"context_line":"    if is_ans1_token(token_id):"},{"line_number":266,"context_line":"        if mode \u003d\u003d \u0027sha256\u0027:"},{"line_number":267,"context_line":"            fn \u003d hashlib.sha256"},{"line_number":268,"context_line":"        else:"},{"line_number":269,"context_line":"            fn \u003d hashlib.md5"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F%2FIl8%3D","line":266,"in_reply_to":"AAAAWH%2F%2Fa4E%3D","updated":"2014-03-20 01:38:13.000000000","message":"that is awesome.","commit_id":"3b51450f88b8e4ed6b90ad6bd4cebc415d7fb7c1"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"0b8f1ceb3f7751c88ba6732ad8be65acbbc9f18c","unresolved":false,"context_lines":[{"line_number":270,"context_line":"    if token_id is None:"},{"line_number":271,"context_line":"        return None"},{"line_number":272,"context_line":"    if is_ans1_token(token_id):"},{"line_number":273,"context_line":"        hasher \u003d hashlib.new(mode)"},{"line_number":274,"context_line":"        if isinstance(token_id, six.text_type):"},{"line_number":275,"context_line":"            token_id \u003d token_id.encode(\u0027utf-8\u0027)"},{"line_number":276,"context_line":"        hasher.update(token_id)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWn%2F%2F%2B2w%3D","line":273,"updated":"2014-04-08 05:26:23.000000000","message":"can this just use keystoneclient.utils.hash_signed_token rather than do this twice?","commit_id":"a3db0516c136767e493e1125e3980f057165a585"}],"keystoneclient/middleware/auth_token.py":[{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"0b8f1ceb3f7751c88ba6732ad8be65acbbc9f18c","unresolved":false,"context_lines":[{"line_number":318,"context_line":"               \" hashlib.new as the algorithm. Expected values are \u0027md5\u0027 or\""},{"line_number":319,"context_line":"               \" \u0027sha256\u0027.\""},{"line_number":320,"context_line":"               \" WARNING: This value needs to match the setting of the\""},{"line_number":321,"context_line":"               \" Keystone server, otherwise revoked tokens will not work.\"),"},{"line_number":322,"context_line":"]"},{"line_number":323,"context_line":""},{"line_number":324,"context_line":"CONF \u003d cfg.CONF"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWn%2F%2F%2Byc%3D","line":321,"updated":"2014-04-08 05:26:23.000000000","message":"would be nice to say what the hash algorithm is used for.\n\nThe hash algorithm to used when storing tokens and checking against revocation lists.","commit_id":"a3db0516c136767e493e1125e3980f057165a585"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"329aba9cd98c50afc6057ee7a3be8d6f013cd97c","unresolved":false,"context_lines":[{"line_number":318,"context_line":"               \" hashlib.new as the algorithm. Expected values are \u0027md5\u0027 or\""},{"line_number":319,"context_line":"               \" \u0027sha256\u0027.\""},{"line_number":320,"context_line":"               \" WARNING: This value needs to match the setting of the\""},{"line_number":321,"context_line":"               \" Keystone server, otherwise revoked tokens will not work.\"),"},{"line_number":322,"context_line":"]"},{"line_number":323,"context_line":""},{"line_number":324,"context_line":"CONF \u003d cfg.CONF"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWn%2F%2F6Gk%3D","line":321,"in_reply_to":"AAAAWn%2F%2F%2Byc%3D","updated":"2014-04-08 15:27:36.000000000","message":"could also say that sha256 is recommended","commit_id":"a3db0516c136767e493e1125e3980f057165a585"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"19af40ec97a21fcdea19622bdb84d4e829f0a7d2","unresolved":false,"context_lines":[{"line_number":318,"context_line":"               \" hashlib.new as the algorithm. Expected values are \u0027md5\u0027 or\""},{"line_number":319,"context_line":"               \" \u0027sha256\u0027.\""},{"line_number":320,"context_line":"               \" WARNING: This value needs to match the setting of the\""},{"line_number":321,"context_line":"               \" Keystone server, otherwise revoked tokens will not work.\"),"},{"line_number":322,"context_line":"]"},{"line_number":323,"context_line":""},{"line_number":324,"context_line":"CONF \u003d cfg.CONF"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWn%2F%2F5fY%3D","line":321,"in_reply_to":"AAAAWn%2F%2F6Gk%3D","updated":"2014-04-08 16:40:26.000000000","message":"Having a configurable hash algorithm on the client-side will break rolling upgrade. Hash algorithm should be embedded into token (meta) data.","commit_id":"a3db0516c136767e493e1125e3980f057165a585"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"070a376deb49eb59b026e85c8820435ad1c083ab","unresolved":false,"context_lines":[{"line_number":844,"context_line":""},{"line_number":845,"context_line":"        try:"},{"line_number":846,"context_line":"            if cms.is_ans1_token(user_token):"},{"line_number":847,"context_line":"                token_id \u003d cms.cms_hash_token(user_token, mode\u003d\u0027sha256\u0027)"},{"line_number":848,"context_line":"                cached \u003d self._cache_get(token_id)"},{"line_number":849,"context_line":"                if cached:"},{"line_number":850,"context_line":"                    return cached"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAW3%2F%2F%2BhA%3D","line":847,"updated":"2014-04-09 05:50:22.000000000","message":"Ouch! May want to consider doing this in a for loop or something. For example,\n\nfor mode in (\u0027md5\u0027, \u0027sha1\u0027, \u0027sha256\u0027, \u0027sha384\u0027, \u0027sha512\u0027):\n    token_id \u003d cms.cms_hash_token(user_token, mode\u003dmode)\n    cached \u003d self._cache_get(token_id)\n    if cached:\n        return cached\n\n\nBut then again, using PKI token in conjunction with cache seem redundant. PKI token is designed for offline validation. Depending on the type of cache backend, I bet validating PKI token signature may even be faster than fetching the token data from cache. Wish we have some performance number on that.","commit_id":"99f9effcb51c3a398db0e0631a80ee91b620a4d5"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"5c85dc6b926d064fe351f4505e1e36e85423ada1","unresolved":false,"context_lines":[{"line_number":844,"context_line":""},{"line_number":845,"context_line":"        try:"},{"line_number":846,"context_line":"            if cms.is_ans1_token(user_token):"},{"line_number":847,"context_line":"                token_id \u003d cms.cms_hash_token(user_token, mode\u003d\u0027sha256\u0027)"},{"line_number":848,"context_line":"                cached \u003d self._cache_get(token_id)"},{"line_number":849,"context_line":"                if cached:"},{"line_number":850,"context_line":"                    return cached"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAW3%2F%2F7GU%3D","line":847,"in_reply_to":"AAAAW3%2F%2F%2BhA%3D","updated":"2014-04-09 13:20:54.000000000","message":"gyee - What do you think about adding a follow-on patch that allows configuring the hash algorithm, and if that\u0027s set then auth_token will only use that algorithm and not check both.","commit_id":"99f9effcb51c3a398db0e0631a80ee91b620a4d5"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"24961b8ca34476dbd1177ca3e9dc48aa02fc4366","unresolved":false,"context_lines":[{"line_number":844,"context_line":""},{"line_number":845,"context_line":"        try:"},{"line_number":846,"context_line":"            if cms.is_ans1_token(user_token):"},{"line_number":847,"context_line":"                token_id \u003d cms.cms_hash_token(user_token, mode\u003d\u0027sha256\u0027)"},{"line_number":848,"context_line":"                cached \u003d self._cache_get(token_id)"},{"line_number":849,"context_line":"                if cached:"},{"line_number":850,"context_line":"                    return cached"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAW3%2F%2F3iI%3D","line":847,"in_reply_to":"AAAAW3%2F%2F4R8%3D","updated":"2014-04-09 20:00:09.000000000","message":"Dolph suggested a configurable list. What do you think?","commit_id":"99f9effcb51c3a398db0e0631a80ee91b620a4d5"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"608538fc9897995900c07617e700554d0e45df31","unresolved":false,"context_lines":[{"line_number":844,"context_line":""},{"line_number":845,"context_line":"        try:"},{"line_number":846,"context_line":"            if cms.is_ans1_token(user_token):"},{"line_number":847,"context_line":"                token_id \u003d cms.cms_hash_token(user_token, mode\u003d\u0027sha256\u0027)"},{"line_number":848,"context_line":"                cached \u003d self._cache_get(token_id)"},{"line_number":849,"context_line":"                if cached:"},{"line_number":850,"context_line":"                    return cached"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAW3%2F%2F4R8%3D","line":847,"in_reply_to":"AAAAW3%2F%2F7GU%3D","updated":"2014-04-09 18:11:05.000000000","message":"Brant, I didn\u0027t realize doing online token validate for PKI tokens is not even possible. For cache lookup, making the hash algorithm configurable, with sha256 being the default, seem reasonable. No need for a follow-on patch.","commit_id":"99f9effcb51c3a398db0e0631a80ee91b620a4d5"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"070a376deb49eb59b026e85c8820435ad1c083ab","unresolved":false,"context_lines":[{"line_number":1202,"context_line":"        revoked_ids \u003d (x[\u0027id\u0027] for x in revoked_tokens)"},{"line_number":1203,"context_line":"        if isinstance(signed_text, six.text_type):"},{"line_number":1204,"context_line":"            signed_text \u003d signed_text.encode(\u0027utf-8\u0027)"},{"line_number":1205,"context_line":"        token_id_sha256 \u003d utils.hash_signed_token(signed_text, mode\u003d\u0027sha256\u0027)"},{"line_number":1206,"context_line":"        token_id_md5 \u003d utils.hash_signed_token(signed_text, mode\u003d\u0027md5\u0027)"},{"line_number":1207,"context_line":"        for revoked_id in revoked_ids:"},{"line_number":1208,"context_line":"            if revoked_id in (token_id_sha256, token_id_md5):"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAW3%2F%2F%2Bgo%3D","line":1205,"updated":"2014-04-09 05:50:22.000000000","message":"why do we need to hardcode the mode? I thought the algorithm is part of the revocation event.","commit_id":"99f9effcb51c3a398db0e0631a80ee91b620a4d5"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"5c85dc6b926d064fe351f4505e1e36e85423ada1","unresolved":false,"context_lines":[{"line_number":1202,"context_line":"        revoked_ids \u003d (x[\u0027id\u0027] for x in revoked_tokens)"},{"line_number":1203,"context_line":"        if isinstance(signed_text, six.text_type):"},{"line_number":1204,"context_line":"            signed_text \u003d signed_text.encode(\u0027utf-8\u0027)"},{"line_number":1205,"context_line":"        token_id_sha256 \u003d utils.hash_signed_token(signed_text, mode\u003d\u0027sha256\u0027)"},{"line_number":1206,"context_line":"        token_id_md5 \u003d utils.hash_signed_token(signed_text, mode\u003d\u0027md5\u0027)"},{"line_number":1207,"context_line":"        for revoked_id in revoked_ids:"},{"line_number":1208,"context_line":"            if revoked_id in (token_id_sha256, token_id_md5):"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAW3%2F%2F7FE%3D","line":1205,"in_reply_to":"AAAAW3%2F%2F%2Bgo%3D","updated":"2014-04-09 13:20:54.000000000","message":"gyee - I was trying to work without changing the revocation list, but I can add that back in.","commit_id":"99f9effcb51c3a398db0e0631a80ee91b620a4d5"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"24961b8ca34476dbd1177ca3e9dc48aa02fc4366","unresolved":false,"context_lines":[{"line_number":1202,"context_line":"        revoked_ids \u003d (x[\u0027id\u0027] for x in revoked_tokens)"},{"line_number":1203,"context_line":"        if isinstance(signed_text, six.text_type):"},{"line_number":1204,"context_line":"            signed_text \u003d signed_text.encode(\u0027utf-8\u0027)"},{"line_number":1205,"context_line":"        token_id_sha256 \u003d utils.hash_signed_token(signed_text, mode\u003d\u0027sha256\u0027)"},{"line_number":1206,"context_line":"        token_id_md5 \u003d utils.hash_signed_token(signed_text, mode\u003d\u0027md5\u0027)"},{"line_number":1207,"context_line":"        for revoked_id in revoked_ids:"},{"line_number":1208,"context_line":"            if revoked_id in (token_id_sha256, token_id_md5):"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAW3%2F%2F3iM%3D","line":1205,"in_reply_to":"AAAAW3%2F%2F7FE%3D","updated":"2014-04-09 20:00:09.000000000","message":"gyee - I\u0027d rather do this with no changes to the revocation list, so we\u0027ll have a list of hash algorithms to check.","commit_id":"99f9effcb51c3a398db0e0631a80ee91b620a4d5"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"3186a1ea310415fb17fe511b95972f821cdcf7b2","unresolved":false,"context_lines":[{"line_number":322,"context_line":"                \u0027 values only while migrating from a less secure algorithm to\u0027"},{"line_number":323,"context_line":"                \u0027 a more secure one. Once all the old tokens are expired this\u0027"},{"line_number":324,"context_line":"                \u0027 option should be set to a single value for better\u0027"},{"line_number":325,"context_line":"                \u0027 performance.\u0027)"},{"line_number":326,"context_line":"]"},{"line_number":327,"context_line":""},{"line_number":328,"context_line":"CONF \u003d cfg.CONF"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAW3%2F%2F2%2BE%3D","line":325,"updated":"2014-04-09 21:50:44.000000000","message":"Here\u0027s a shining example of there\u0027s no single \"right\" default, and thus make this debate more interesting. :)\n\nhttp://www.mail-archive.com/openstack-dev@lists.openstack.org/msg21406.html\n\nThese values are different depending on upgrade or newly install. For upgrade, its a two step process. For newly install, it should contain a single value.","commit_id":"6f0d61b0fc4a8671cf12bb516514c9f209cf1180"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"51f21581489e5f2ab750092e55995f7dc085ed7a","unresolved":false,"context_lines":[{"line_number":322,"context_line":"                \u0027 values only while migrating from a less secure algorithm to\u0027"},{"line_number":323,"context_line":"                \u0027 a more secure one. Once all the old tokens are expired this\u0027"},{"line_number":324,"context_line":"                \u0027 option should be set to a single value for better\u0027"},{"line_number":325,"context_line":"                \u0027 performance.\u0027)"},{"line_number":326,"context_line":"]"},{"line_number":327,"context_line":""},{"line_number":328,"context_line":"CONF \u003d cfg.CONF"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAW3%2F%2F2ws%3D","line":325,"in_reply_to":"AAAAW3%2F%2F2%2BE%3D","updated":"2014-04-09 22:28:53.000000000","message":"why do we set the default value to a list if it will only be multiple values whilst migrating? We should default just to md5 and let people  move to a list when they try to migrate.","commit_id":"6f0d61b0fc4a8671cf12bb516514c9f209cf1180"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"8532a42a360b307af3cdc98814946a6cc7627856","unresolved":false,"context_lines":[{"line_number":322,"context_line":"                \u0027 values only while migrating from a less secure algorithm to\u0027"},{"line_number":323,"context_line":"                \u0027 a more secure one. Once all the old tokens are expired this\u0027"},{"line_number":324,"context_line":"                \u0027 option should be set to a single value for better\u0027"},{"line_number":325,"context_line":"                \u0027 performance.\u0027)"},{"line_number":326,"context_line":"]"},{"line_number":327,"context_line":""},{"line_number":328,"context_line":"CONF \u003d cfg.CONF"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAW3%2F%2F2qc%3D","line":325,"in_reply_to":"AAAAW3%2F%2F2ws%3D","updated":"2014-04-09 22:58:25.000000000","message":"Done","commit_id":"6f0d61b0fc4a8671cf12bb516514c9f209cf1180"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"51f21581489e5f2ab750092e55995f7dc085ed7a","unresolved":false,"context_lines":[{"line_number":1215,"context_line":"        if isinstance(signed_text, six.text_type):"},{"line_number":1216,"context_line":"            signed_text \u003d signed_text.encode(\u0027utf-8\u0027)"},{"line_number":1217,"context_line":""},{"line_number":1218,"context_line":"        def check_token_with_hash(hash_algorithm):"},{"line_number":1219,"context_line":"            token_id \u003d utils.hash_signed_token(signed_text,"},{"line_number":1220,"context_line":"                                               mode\u003dhash_algorithm)"},{"line_number":1221,"context_line":"            revoked_ids \u003d (x[\u0027id\u0027] for x in revoked_tokens)"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAW3%2F%2F2wI%3D","line":1218,"updated":"2014-04-09 22:28:53.000000000","message":"nit: see no reason for this to be a function (or at least a nested function) the responses are exactly the same","commit_id":"6f0d61b0fc4a8671cf12bb516514c9f209cf1180"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"8532a42a360b307af3cdc98814946a6cc7627856","unresolved":false,"context_lines":[{"line_number":1215,"context_line":"        if isinstance(signed_text, six.text_type):"},{"line_number":1216,"context_line":"            signed_text \u003d signed_text.encode(\u0027utf-8\u0027)"},{"line_number":1217,"context_line":""},{"line_number":1218,"context_line":"        def check_token_with_hash(hash_algorithm):"},{"line_number":1219,"context_line":"            token_id \u003d utils.hash_signed_token(signed_text,"},{"line_number":1220,"context_line":"                                               mode\u003dhash_algorithm)"},{"line_number":1221,"context_line":"            revoked_ids \u003d (x[\u0027id\u0027] for x in revoked_tokens)"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAW3%2F%2F2kE%3D","line":1218,"in_reply_to":"AAAAW3%2F%2F2wI%3D","updated":"2014-04-09 22:58:25.000000000","message":"Done","commit_id":"6f0d61b0fc4a8671cf12bb516514c9f209cf1180"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"197595de5c12cab436df7074984f9c3df227cae1","unresolved":false,"context_lines":[{"line_number":1225,"context_line":"                    return True"},{"line_number":1226,"context_line":"            return False"},{"line_number":1227,"context_line":""},{"line_number":1228,"context_line":"        for hash_algorithm in self._conf_get(\u0027hash_algorithms\u0027):"},{"line_number":1229,"context_line":"            if check_token_with_hash(hash_algorithm):"},{"line_number":1230,"context_line":"                return True"},{"line_number":1231,"context_line":"        return False"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAW3%2F%2F2r0%3D","line":1228,"updated":"2014-04-09 22:32:30.000000000","message":"is there not an easier way of quitting out of this early? \n\nIf we get a md5 revocation list here we should be able to tell instantly that my sha256 token hash is not going to match any elements of this list and just return.\n\nIs it still worth embedding the hash algorithm in the token revocation list response?","commit_id":"6f0d61b0fc4a8671cf12bb516514c9f209cf1180"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"8532a42a360b307af3cdc98814946a6cc7627856","unresolved":false,"context_lines":[{"line_number":1225,"context_line":"                    return True"},{"line_number":1226,"context_line":"            return False"},{"line_number":1227,"context_line":""},{"line_number":1228,"context_line":"        for hash_algorithm in self._conf_get(\u0027hash_algorithms\u0027):"},{"line_number":1229,"context_line":"            if check_token_with_hash(hash_algorithm):"},{"line_number":1230,"context_line":"                return True"},{"line_number":1231,"context_line":"        return False"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAW3%2F%2F2jw%3D","line":1228,"in_reply_to":"AAAAW3%2F%2F2r0%3D","updated":"2014-04-09 22:58:25.000000000","message":"I\u0027m not planning to embed the hash algorithm in the revocation list response. It\u0027s not necessary since we\u0027re able to check for both.\n\nDuring the transition period, there may be tokens hashed with the old algorithm and tokens hash with the new algorithm.","commit_id":"6f0d61b0fc4a8671cf12bb516514c9f209cf1180"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"e02f03b1df4960b3562c2cca806a7e5677c6e0e0","unresolved":false,"context_lines":[{"line_number":1217,"context_line":"        for hash_algorithm in self._conf_get(\u0027hash_algorithms\u0027):"},{"line_number":1218,"context_line":"            token_id \u003d utils.hash_signed_token(signed_text,"},{"line_number":1219,"context_line":"                                               mode\u003dhash_algorithm)"},{"line_number":1220,"context_line":"            revoked_ids \u003d (x[\u0027id\u0027] for x in revoked_tokens)"},{"line_number":1221,"context_line":"            for revoked_id in revoked_ids:"},{"line_number":1222,"context_line":"                if token_id \u003d\u003d revoked_id:"},{"line_number":1223,"context_line":"                    self.LOG.debug(\u0027Token is marked as having been revoked\u0027)"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAW3%2F%2FyNU%3D","line":1220,"updated":"2014-04-10 14:07:21.000000000","message":"do this work (L1220) outside the for loop!","commit_id":"316b3eeb2e629f36e24ace5c1e5e362dd0c4cad6"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"6cea90aba70d2282229ec3db01cae9371da8d338","unresolved":false,"context_lines":[{"line_number":1217,"context_line":"        for hash_algorithm in self._conf_get(\u0027hash_algorithms\u0027):"},{"line_number":1218,"context_line":"            token_id \u003d utils.hash_signed_token(signed_text,"},{"line_number":1219,"context_line":"                                               mode\u003dhash_algorithm)"},{"line_number":1220,"context_line":"            revoked_ids \u003d (x[\u0027id\u0027] for x in revoked_tokens)"},{"line_number":1221,"context_line":"            for revoked_id in revoked_ids:"},{"line_number":1222,"context_line":"                if token_id \u003d\u003d revoked_id:"},{"line_number":1223,"context_line":"                    self.LOG.debug(\u0027Token is marked as having been revoked\u0027)"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAW3%2F%2Fotw%3D","line":1220,"in_reply_to":"AAAAW3%2F%2FyNU%3D","updated":"2014-04-11 14:34:29.000000000","message":"Done","commit_id":"316b3eeb2e629f36e24ace5c1e5e362dd0c4cad6"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"80dabe625acef06d953029c158383b6f17a148af","unresolved":false,"context_lines":[{"line_number":315,"context_line":"    cfg.ListOpt(\u0027hash_algorithms\u0027, default\u003d[\u0027md5\u0027],"},{"line_number":316,"context_line":"                help\u003d\u0027Hash algorithms to use for hashing PKI tokens. This may\u0027"},{"line_number":317,"context_line":"                \u0027 be a single algorithm or multiple. The algorithms are those\u0027"},{"line_number":318,"context_line":"                \u0027 supported by Python standard hashlib.new(). The hashes will\u0027"},{"line_number":319,"context_line":"                \u0027 be tried in the order given, so put the preferred one first\u0027"},{"line_number":320,"context_line":"                \u0027 for performance. The result of the first hash will be stored\u0027"},{"line_number":321,"context_line":"                \u0027 in the cache. This will typically be set to multiple values\u0027"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAXH%2F%2Fb7s%3D","line":318,"updated":"2014-04-21 20:06:07.000000000","message":"I stumbled across this earlier: \n\nhttps://docs.python.org/2/library/new.html#module-new\n\nwhich we might have issues with when moving completely to python 3.3 and also from https://docs.python.org/2/library/hashlib.html\n\n\"The named constructors are much faster than new() and should be preferred.\"\n\nNot saying that this has to be implemented in this patch but maybe we can add a note, or discuss moving away from hashlib.new(algorithm)? \n\nhttps://github.com/openstack/python-keystoneclient/blob/master/keystoneclient/utils.py#L145\n\nI *think* we could get away with keeping the calls to util.hash_signed_token the same, we would just need to have some detection in there for the algorithm.","commit_id":"04852e6ce32ec90ef5d7dd1864af394580bd33b2"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b541a3b9982398be36be269b7fce055f30700c7c","unresolved":false,"context_lines":[{"line_number":315,"context_line":"    cfg.ListOpt(\u0027hash_algorithms\u0027, default\u003d[\u0027md5\u0027],"},{"line_number":316,"context_line":"                help\u003d\u0027Hash algorithms to use for hashing PKI tokens. This may\u0027"},{"line_number":317,"context_line":"                \u0027 be a single algorithm or multiple. The algorithms are those\u0027"},{"line_number":318,"context_line":"                \u0027 supported by Python standard hashlib.new(). The hashes will\u0027"},{"line_number":319,"context_line":"                \u0027 be tried in the order given, so put the preferred one first\u0027"},{"line_number":320,"context_line":"                \u0027 for performance. The result of the first hash will be stored\u0027"},{"line_number":321,"context_line":"                \u0027 in the cache. This will typically be set to multiple values\u0027"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAXH%2F%2Fb40%3D","line":318,"in_reply_to":"AAAAXH%2F%2Fb7s%3D","updated":"2014-04-21 20:14:40.000000000","message":"Lance - It was suggested in patch set 4 that new() should be used.","commit_id":"04852e6ce32ec90ef5d7dd1864af394580bd33b2"},{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"af2f14737c6602ea98bfe5d56ff1c9507c542253","unresolved":false,"context_lines":[{"line_number":1212,"context_line":"        if isinstance(signed_text, six.text_type):"},{"line_number":1213,"context_line":"            signed_text \u003d signed_text.encode(\u0027utf-8\u0027)"},{"line_number":1214,"context_line":""},{"line_number":1215,"context_line":"        for hash_algorithm in self._conf_get(\u0027hash_algorithms\u0027):"},{"line_number":1216,"context_line":"            token_id \u003d utils.hash_signed_token(signed_text,"},{"line_number":1217,"context_line":"                                               mode\u003dhash_algorithm)"},{"line_number":1218,"context_line":"            for revoked_id in revoked_ids:"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAXH%2F%2Fin8%3D","line":1215,"updated":"2014-04-19 20:52:22.000000000","message":"So you try all the hash algorithms in the list.  That is very cool!","commit_id":"04852e6ce32ec90ef5d7dd1864af394580bd33b2"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"557b2053b0ecf95c62728438d89ab7205839aa93","unresolved":false,"context_lines":[{"line_number":1212,"context_line":"        if isinstance(signed_text, six.text_type):"},{"line_number":1213,"context_line":"            signed_text \u003d signed_text.encode(\u0027utf-8\u0027)"},{"line_number":1214,"context_line":""},{"line_number":1215,"context_line":"        for hash_algorithm in self._conf_get(\u0027hash_algorithms\u0027):"},{"line_number":1216,"context_line":"            token_id \u003d utils.hash_signed_token(signed_text,"},{"line_number":1217,"context_line":"                                               mode\u003dhash_algorithm)"},{"line_number":1218,"context_line":"            for revoked_id in revoked_ids:"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAXH%2F%2Fg0I%3D","line":1215,"in_reply_to":"AAAAXH%2F%2Fin8%3D","updated":"2014-04-21 00:45:08.000000000","message":"It was Dolph\u0027s idea.","commit_id":"04852e6ce32ec90ef5d7dd1864af394580bd33b2"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"b1db9cb734972f24ac2e4215e27d1e37a7397ac4","unresolved":false,"context_lines":[{"line_number":321,"context_line":"                \u0027 in the cache. This will typically be set to multiple values\u0027"},{"line_number":322,"context_line":"                \u0027 only while migrating from a less secure algorithm to a more\u0027"},{"line_number":323,"context_line":"                \u0027 secure one. Once all the old tokens are expired this option\u0027"},{"line_number":324,"context_line":"                \u0027 should be set to a single value for better performance.\u0027),"},{"line_number":325,"context_line":"]"},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"CONF \u003d cfg.CONF"}],"source_content_type":"text/x-python","patch_set":24,"id":"9ad9bd40_4c8fc3cc","line":324,"updated":"2014-05-02 14:13:35.000000000","message":"fantastic help text","commit_id":"20f75c47f0dcea2bcb2593c5120cf324663a8f86"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"b1db9cb734972f24ac2e4215e27d1e37a7397ac4","unresolved":false,"context_lines":[{"line_number":853,"context_line":"        \"\"\""},{"line_number":854,"context_line":"        token_id \u003d None"},{"line_number":855,"context_line":""},{"line_number":856,"context_line":"        try:"},{"line_number":857,"context_line":"            if cms.is_asn1_token(user_token):"},{"line_number":858,"context_line":"                for hash_algorithm in self._conf_get(\u0027hash_algorithms\u0027):"},{"line_number":859,"context_line":"                    token_hash \u003d cms.cms_hash_token(user_token,"}],"source_content_type":"text/x-python","patch_set":24,"id":"9ad9bd40_2cab5f1e","line":856,"updated":"2014-05-02 14:13:35.000000000","message":"this try block is exploding","commit_id":"20f75c47f0dcea2bcb2593c5120cf324663a8f86"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"b1db9cb734972f24ac2e4215e27d1e37a7397ac4","unresolved":false,"context_lines":[{"line_number":875,"context_line":"                verified \u003d self.verify_signed_token(user_token)"},{"line_number":876,"context_line":"                data \u003d jsonutils.loads(verified)"},{"line_number":877,"context_line":"            else:"},{"line_number":878,"context_line":"                token_id \u003d user_token"},{"line_number":879,"context_line":"                cached \u003d self._cache_get(token_id)"},{"line_number":880,"context_line":"                if cached:"},{"line_number":881,"context_line":"                    # A token stored in Memcached might have been revoked"}],"source_content_type":"text/x-python","patch_set":24,"id":"9ad9bd40_0c73fbe7","line":878,"updated":"2014-05-02 14:13:35.000000000","message":"reading code like this makes me feel like i\u0027m playing a shell game with a con artist","commit_id":"20f75c47f0dcea2bcb2593c5120cf324663a8f86"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"b1db9cb734972f24ac2e4215e27d1e37a7397ac4","unresolved":false,"context_lines":[{"line_number":881,"context_line":"                    # A token stored in Memcached might have been revoked"},{"line_number":882,"context_line":"                    # regardless of initial mechanism used to validate it,"},{"line_number":883,"context_line":"                    # and needs to be checked."},{"line_number":884,"context_line":"                    if self._is_token_id_in_revoked_list(token_id):"},{"line_number":885,"context_line":"                        self.LOG.debug("},{"line_number":886,"context_line":"                            \u0027UUID token is marked as having been revoked\u0027)"},{"line_number":887,"context_line":"                        raise InvalidUserToken(\u0027Token authorization failed\u0027)"}],"source_content_type":"text/x-python","patch_set":24,"id":"9ad9bd40_0c213bb4","line":884,"updated":"2014-05-02 14:13:35.000000000","message":"if it\u0027s not a PKI token it won\u0027t be in the revocation list","commit_id":"20f75c47f0dcea2bcb2593c5120cf324663a8f86"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"e09daea146dd8b749d3d3f399f1a455ab79556ef","unresolved":false,"context_lines":[{"line_number":882,"context_line":"                    for token_hash in token_ids:"},{"line_number":883,"context_line":"                        is_revoked \u003d self._is_token_id_in_revoked_list("},{"line_number":884,"context_line":"                            token_hash)"},{"line_number":885,"context_line":"                        if is_revoked:"},{"line_number":886,"context_line":"                            self.LOG.debug("},{"line_number":887,"context_line":"                                \u0027Token is marked as having been revoked\u0027)"},{"line_number":888,"context_line":"                            raise InvalidUserToken("}],"source_content_type":"text/x-python","patch_set":29,"id":"9ad9bd40_8315b54a","line":885,"updated":"2014-05-06 22:45:56.000000000","message":"(NIT): you could collapse lines 883, 884, and 885 into a single if-check\n\n                        if self._is_token_id_in_revoked_list(token_hash):","commit_id":"4310ecc4d97eeb4bdb0c90b818e12982d20c3a7c"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"d3d2b96f029ee18b83339e9f9b9723b55967dd92","unresolved":false,"context_lines":[{"line_number":882,"context_line":"                    for token_hash in token_ids:"},{"line_number":883,"context_line":"                        is_revoked \u003d self._is_token_id_in_revoked_list("},{"line_number":884,"context_line":"                            token_hash)"},{"line_number":885,"context_line":"                        if is_revoked:"},{"line_number":886,"context_line":"                            self.LOG.debug("},{"line_number":887,"context_line":"                                \u0027Token is marked as having been revoked\u0027)"},{"line_number":888,"context_line":"                            raise InvalidUserToken("}],"source_content_type":"text/x-python","patch_set":29,"id":"9ad9bd40_b9f6668d","line":885,"in_reply_to":"9ad9bd40_8315b54a","updated":"2014-05-07 00:55:11.000000000","message":"Done","commit_id":"4310ecc4d97eeb4bdb0c90b818e12982d20c3a7c"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"e09daea146dd8b749d3d3f399f1a455ab79556ef","unresolved":false,"context_lines":[{"line_number":1260,"context_line":""},{"line_number":1261,"context_line":"        for hash_algorithm in self._conf_get(\u0027hash_algorithms\u0027):"},{"line_number":1262,"context_line":"            token_id \u003d utils.hash_signed_token(signed_text,"},{"line_number":1263,"context_line":"                                               mode\u003dhash_algorithm)"},{"line_number":1264,"context_line":""},{"line_number":1265,"context_line":"            if self._is_token_id_in_revoked_list(token_id):"},{"line_number":1266,"context_line":"                self.LOG.debug(\u0027Token is marked as having been revoked\u0027)"}],"source_content_type":"text/x-python","patch_set":29,"id":"9ad9bd40_deb6b03d","line":1263,"updated":"2014-05-06 22:45:56.000000000","message":"We\u0027ve already calculated the hashes at this point on line 873, do we need to recalculate here? Could we instead pass in the hashes to is_signed_token_revoked instead of the \"signed_text\"?","commit_id":"4310ecc4d97eeb4bdb0c90b818e12982d20c3a7c"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"d3d2b96f029ee18b83339e9f9b9723b55967dd92","unresolved":false,"context_lines":[{"line_number":1260,"context_line":""},{"line_number":1261,"context_line":"        for hash_algorithm in self._conf_get(\u0027hash_algorithms\u0027):"},{"line_number":1262,"context_line":"            token_id \u003d utils.hash_signed_token(signed_text,"},{"line_number":1263,"context_line":"                                               mode\u003dhash_algorithm)"},{"line_number":1264,"context_line":""},{"line_number":1265,"context_line":"            if self._is_token_id_in_revoked_list(token_id):"},{"line_number":1266,"context_line":"                self.LOG.debug(\u0027Token is marked as having been revoked\u0027)"}],"source_content_type":"text/x-python","patch_set":29,"id":"9ad9bd40_5db46534","line":1263,"in_reply_to":"9ad9bd40_deb6b03d","updated":"2014-05-07 00:55:11.000000000","message":"Done","commit_id":"4310ecc4d97eeb4bdb0c90b818e12982d20c3a7c"}],"keystoneclient/tests/test_auth_token_middleware.py":[{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"af2f14737c6602ea98bfe5d56ff1c9507c542253","unresolved":false,"context_lines":[{"line_number":556,"context_line":"        self.assertEqual(self.response_status, 401)"},{"line_number":557,"context_line":""},{"line_number":558,"context_line":"    def test_revoked_token_receives_401_md5_secondary(self):"},{"line_number":559,"context_line":"        # When the hash_algorithms has \u0027md5\u0027 as the secondary hash and the"},{"line_number":560,"context_line":"        # revocation list contains the md5 hash for a token, that token is"},{"line_number":561,"context_line":"        # considered revoked so returns 401."},{"line_number":562,"context_line":"        self.conf[\u0027hash_algorithms\u0027] \u003d [\u0027sha256\u0027, \u0027md5\u0027]"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAXH%2F%2Fio4%3D","line":559,"updated":"2014-04-19 20:52:22.000000000","message":"Nice comment. Very helpful!","commit_id":"04852e6ce32ec90ef5d7dd1864af394580bd33b2"},{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"af2f14737c6602ea98bfe5d56ff1c9507c542253","unresolved":false,"context_lines":[{"line_number":624,"context_line":"        self.middleware.token_revocation_list \u003d ("},{"line_number":625,"context_line":"            self.get_revocation_list_json(mode\u003d\u0027sha256\u0027))"},{"line_number":626,"context_line":"        self.middleware.verify_signed_token("},{"line_number":627,"context_line":"            self.token_dict[\u0027signed_token_scoped\u0027])"},{"line_number":628,"context_line":""},{"line_number":629,"context_line":"    def test_verify_signing_dir_create_while_missing(self):"},{"line_number":630,"context_line":"        tmp_name \u003d uuid.uuid4().hex"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAXH%2F%2FioU%3D","line":627,"updated":"2014-04-19 20:52:22.000000000","message":"How come this test did not need something like a self.assertTrue or equivalent at the end?","commit_id":"04852e6ce32ec90ef5d7dd1864af394580bd33b2"},{"author":{"_account_id":6460,"name":"Brad Topol","email":"btopol@us.ibm.com","username":"btopol"},"change_message_id":"b352417b11b9cf09db53c586bc247c601a26f964","unresolved":false,"context_lines":[{"line_number":624,"context_line":"        self.middleware.token_revocation_list \u003d ("},{"line_number":625,"context_line":"            self.get_revocation_list_json(mode\u003d\u0027sha256\u0027))"},{"line_number":626,"context_line":"        self.middleware.verify_signed_token("},{"line_number":627,"context_line":"            self.token_dict[\u0027signed_token_scoped\u0027])"},{"line_number":628,"context_line":""},{"line_number":629,"context_line":"    def test_verify_signing_dir_create_while_missing(self):"},{"line_number":630,"context_line":"        tmp_name \u003d uuid.uuid4().hex"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAXH%2F%2FcyQ%3D","line":627,"in_reply_to":"AAAAXH%2F%2Fg0U%3D","updated":"2014-04-21 17:22:56.000000000","message":"K, Thanks!","commit_id":"04852e6ce32ec90ef5d7dd1864af394580bd33b2"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"557b2053b0ecf95c62728438d89ab7205839aa93","unresolved":false,"context_lines":[{"line_number":624,"context_line":"        self.middleware.token_revocation_list \u003d ("},{"line_number":625,"context_line":"            self.get_revocation_list_json(mode\u003d\u0027sha256\u0027))"},{"line_number":626,"context_line":"        self.middleware.verify_signed_token("},{"line_number":627,"context_line":"            self.token_dict[\u0027signed_token_scoped\u0027])"},{"line_number":628,"context_line":""},{"line_number":629,"context_line":"    def test_verify_signing_dir_create_while_missing(self):"},{"line_number":630,"context_line":"        tmp_name \u003d uuid.uuid4().hex"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAAXH%2F%2Fg0U%3D","line":627,"in_reply_to":"AAAAXH%2F%2FioU%3D","updated":"2014-04-21 00:45:08.000000000","message":"Brad - There are several tests that show that verify_signed_token raises if the token is invalid. If there was an assertion here then it would be that verify_signed_token didn\u0027t raise, but that\u0027s already handled by the test harness -- if verify_signed_token did raise in this case then the test would fail.","commit_id":"04852e6ce32ec90ef5d7dd1864af394580bd33b2"}],"keystoneclient/tests/test_utils.py":[{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"0b8f1ceb3f7751c88ba6732ad8be65acbbc9f18c","unresolved":false,"context_lines":[{"line_number":221,"context_line":"        if six.PY3:"},{"line_number":222,"context_line":"            token \u003d token.encode(\u0027utf-8\u0027)"},{"line_number":223,"context_line":"        token_id \u003d utils.hash_signed_token(token, mode\u003d\u0027md5\u0027)"},{"line_number":224,"context_line":"        self.assertThat(utils.hash_signed_token(token),"},{"line_number":225,"context_line":"                        matchers.Equals(token_id))"},{"line_number":226,"context_line":"        # md5 hash is 32 chars."},{"line_number":227,"context_line":"        self.assertThat(token_id, matchers.HasLength(32))"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWn%2F%2F%2Bzg%3D","line":224,"updated":"2014-04-08 05:26:23.000000000","message":"why not just assertEqual like everything else?","commit_id":"a3db0516c136767e493e1125e3980f057165a585"}],"keystoneclient/utils.py":[{"author":{"_account_id":7473,"name":"Grant Murphy","email":"grantcmurphy@gmail.com","username":"gm"},"change_message_id":"a42229e19ebd6a95f289f87ac8514fdc31c9d31a","unresolved":false,"context_lines":[{"line_number":135,"context_line":"    return getattr(f, \u0027unauthenticated\u0027, False)"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"def hash_signed_token(signed_text, mode\u003d\u0027md5\u0027):"},{"line_number":139,"context_line":"    if mode \u003d\u003d \u0027sha256\u0027:"},{"line_number":140,"context_line":"        fn \u003d hashlib.sha256"},{"line_number":141,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F%2Fa5M%3D","line":138,"updated":"2014-03-18 00:35:46.000000000","message":"Could you just use h \u003d hashlib.new(mode) here?","commit_id":"3b51450f88b8e4ed6b90ad6bd4cebc415d7fb7c1"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e5f60018a7e173e876746dbf627d100a84577dd4","unresolved":false,"context_lines":[{"line_number":135,"context_line":"    return getattr(f, \u0027unauthenticated\u0027, False)"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"def hash_signed_token(signed_text, mode\u003d\u0027md5\u0027):"},{"line_number":139,"context_line":"    if mode \u003d\u003d \u0027sha256\u0027:"},{"line_number":140,"context_line":"        fn \u003d hashlib.sha256"},{"line_number":141,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F%2FIkM%3D","line":138,"in_reply_to":"AAAAWH%2F%2Fa5M%3D","updated":"2014-03-20 01:38:13.000000000","message":"Done","commit_id":"3b51450f88b8e4ed6b90ad6bd4cebc415d7fb7c1"}]}
