)]}'
{"swift/common/middleware/decrypter.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"105edde7d86b3a5e39653a833039ecb736478388","unresolved":false,"context_lines":[{"line_number":326,"context_line":""},{"line_number":327,"context_line":"        keys \u003d self.process_resp(req)"},{"line_number":328,"context_line":""},{"line_number":329,"context_line":"        if keys:"},{"line_number":330,"context_line":"            out_content_type \u003d get_listing_content_type(req)"},{"line_number":331,"context_line":"            if out_content_type \u003d\u003d \u0027application/json\u0027:"},{"line_number":332,"context_line":"                app_resp \u003d self.process_json_resp(keys, app_resp)"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a18252c_03a35f50","line":329,"updated":"2016-04-13 13:22:56.000000000","message":"check that this is a successful response first, otherwise do not decrypt","commit_id":"087fcfaeaf68470904997e5b34990f11c6f0ffe0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"105edde7d86b3a5e39653a833039ecb736478388","unresolved":false,"context_lines":[{"line_number":347,"context_line":""},{"line_number":348,"context_line":"    def process_json_resp(self, keys, resp_iter):"},{"line_number":349,"context_line":"        \"\"\""},{"line_number":350,"context_line":"        Parses json body listing and decrypt content-type entries. Updates"},{"line_number":351,"context_line":"        Content-Length header with new body length and return a body iter."},{"line_number":352,"context_line":"        \"\"\""},{"line_number":353,"context_line":"        with closing_if_possible(resp_iter):"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a18252c_a3ab8b1c","line":350,"updated":"2016-04-13 13:22:56.000000000","message":"delete \"content-type\"","commit_id":"087fcfaeaf68470904997e5b34990f11c6f0ffe0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"105edde7d86b3a5e39653a833039ecb736478388","unresolved":false,"context_lines":[{"line_number":364,"context_line":"            ciphertext, keys[\u0027container\u0027], None)"},{"line_number":365,"context_line":""},{"line_number":366,"context_line":"        # TODO - did we need to use the length to decide to decrypt?"},{"line_number":367,"context_line":"        # if etag and (len(etag) \u003e constraints.ETAG_LENGTH):"},{"line_number":368,"context_line":"        return obj_dict"},{"line_number":369,"context_line":""},{"line_number":370,"context_line":"    def process_xml_resp(self, keys, resp_iter):"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a18252c_5e140e43","line":367,"updated":"2016-04-13 13:22:56.000000000","message":"IDK, why did we think we might need to check length? As it is we are assuming that an etag (either encrypted or just a plain etag) never has a \u0027;\u0027 character since we use that as a delimiter for the crypto_meta. If that is safe then we don\u0027t need a check on length.","commit_id":"087fcfaeaf68470904997e5b34990f11c6f0ffe0"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"f2d4a62fba63c67ab95101ea52ff488c08f007c5","unresolved":false,"context_lines":[{"line_number":364,"context_line":"            ciphertext, keys[\u0027container\u0027], None)"},{"line_number":365,"context_line":""},{"line_number":366,"context_line":"        # TODO - did we need to use the length to decide to decrypt?"},{"line_number":367,"context_line":"        # if etag and (len(etag) \u003e constraints.ETAG_LENGTH):"},{"line_number":368,"context_line":"        return obj_dict"},{"line_number":369,"context_line":""},{"line_number":370,"context_line":"    def process_xml_resp(self, keys, resp_iter):"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a18252c_7951160e","line":367,"in_reply_to":"5a18252c_5e140e43","updated":"2016-04-14 17:56:21.000000000","message":"ok, i just put that because it had been on the spec at some point.  it might still be there.","commit_id":"087fcfaeaf68470904997e5b34990f11c6f0ffe0"}],"test/unit/common/middleware/test_decrypter.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b7f5c1a3822d9f0cfc25df1f53623f7ce3c989d4","unresolved":false,"context_lines":[{"line_number":674,"context_line":"        self.assertEqual(len(body), int(resp.headers[\u0027Content-Length\u0027]))"},{"line_number":675,"context_line":"        body_json \u003d json.loads(body)"},{"line_number":676,"context_line":"        self.assertEqual(2, len(body_json))"},{"line_number":677,"context_line":"        obj_dict_1[\u0027content_type\u0027] \u003d content_type_1"},{"line_number":678,"context_line":"        obj_dict_1[\u0027hash\u0027] \u003d pt_etag1"},{"line_number":679,"context_line":"        self.assertDictEqual(obj_dict_1, body_json[0])"},{"line_number":680,"context_line":"        obj_dict_2[\u0027content_type\u0027] \u003d content_type_2"}],"source_content_type":"text/x-python","patch_set":8,"id":"1a122d0e_afe38932","line":677,"updated":"2016-04-18 11:42:00.000000000","message":"unrelated to this patch but these lines that set \u0027content_type\u0027 are unnecessary","commit_id":"a794054eafa4c9ffc32a730f133d73e91fc05458"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b7f5c1a3822d9f0cfc25df1f53623f7ce3c989d4","unresolved":false,"context_lines":[{"line_number":710,"context_line":"        body_json \u003d json.loads(body)"},{"line_number":711,"context_line":"        self.assertEqual(2, len(body_json))"},{"line_number":712,"context_line":"        obj_dict_1[\u0027content_type\u0027] \u003d content_type_1"},{"line_number":713,"context_line":"        obj_dict_1[\u0027hash\u0027] \u003d pt_etag1"},{"line_number":714,"context_line":"        self.assertDictEqual(obj_dict_1, body_json[0])"},{"line_number":715,"context_line":"        obj_dict_2[\u0027content_type\u0027] \u003d content_type_2"},{"line_number":716,"context_line":"        obj_dict_2[\u0027hash\u0027] \u003d pt_etag2"}],"source_content_type":"text/x-python","patch_set":8,"id":"1a122d0e_8fcb2d53","line":713,"updated":"2016-04-18 11:42:00.000000000","message":"not necessary","commit_id":"a794054eafa4c9ffc32a730f133d73e91fc05458"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b7f5c1a3822d9f0cfc25df1f53623f7ce3c989d4","unresolved":false,"context_lines":[{"line_number":713,"context_line":"        obj_dict_1[\u0027hash\u0027] \u003d pt_etag1"},{"line_number":714,"context_line":"        self.assertDictEqual(obj_dict_1, body_json[0])"},{"line_number":715,"context_line":"        obj_dict_2[\u0027content_type\u0027] \u003d content_type_2"},{"line_number":716,"context_line":"        obj_dict_2[\u0027hash\u0027] \u003d pt_etag2"},{"line_number":717,"context_line":"        self.assertDictEqual(obj_dict_2, body_json[1])"},{"line_number":718,"context_line":""},{"line_number":719,"context_line":"    def test_cont_get_json_req_with_cipher_mismatch(self):"}],"source_content_type":"text/x-python","patch_set":8,"id":"1a122d0e_efe0e1ce","line":716,"updated":"2016-04-18 11:42:00.000000000","message":"not necessary","commit_id":"a794054eafa4c9ffc32a730f133d73e91fc05458"}],"test/unit/common/middleware/test_encrypter.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"105edde7d86b3a5e39653a833039ecb736478388","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        actual \u003d json.loads(urllib.unquote_plus("},{"line_number":73,"context_line":"            req_hdrs[\u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027]))"},{"line_number":74,"context_line":"        self.assertEqual(Crypto({}).get_cipher(), actual[\u0027cipher\u0027])"},{"line_number":75,"context_line":"        self.assertEqual(fake_iv(), base64.b64decode(actual[\u0027iv\u0027]))"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"        # content-type is not encrypted"},{"line_number":78,"context_line":"        ctype \u003d req_hdrs[\u0027Content-Type\u0027]"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a18252c_0559acfe","line":75,"updated":"2016-04-13 13:22:56.000000000","message":"repeated lines 62-65","commit_id":"087fcfaeaf68470904997e5b34990f11c6f0ffe0"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"f2d4a62fba63c67ab95101ea52ff488c08f007c5","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        actual \u003d json.loads(urllib.unquote_plus("},{"line_number":73,"context_line":"            req_hdrs[\u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027]))"},{"line_number":74,"context_line":"        self.assertEqual(Crypto({}).get_cipher(), actual[\u0027cipher\u0027])"},{"line_number":75,"context_line":"        self.assertEqual(fake_iv(), base64.b64decode(actual[\u0027iv\u0027]))"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"        # content-type is not encrypted"},{"line_number":78,"context_line":"        ctype \u003d req_hdrs[\u0027Content-Type\u0027]"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a18252c_5809afdc","line":75,"in_reply_to":"5a18252c_0559acfe","updated":"2016-04-14 17:56:21.000000000","message":"these lines were here to assert the cipher and iv from the new \"actual\" value that was the container key encrypted etag.  but i suppose just using a different key would not execute a different path to test.","commit_id":"087fcfaeaf68470904997e5b34990f11c6f0ffe0"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"6e434d37c4626f976c1dbf4596f2232bd80e922c","unresolved":false,"context_lines":[{"line_number":81,"context_line":"        cont_key \u003d fetch_crypto_keys()[\u0027container\u0027]"},{"line_number":82,"context_line":"        actual \u003d base64.b64decode("},{"line_number":83,"context_line":"            req_hdrs[\u0027X-Backend-Container-Update-Override-Etag\u0027])"},{"line_number":84,"context_line":"        self.assertEqual(encrypt(plaintext_etag, cont_key, fake_iv()), actual)"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"        # content-type is not encrypted"},{"line_number":87,"context_line":"        self.assertEqual(\u0027text/plain\u0027, req_hdrs[\u0027Content-Type\u0027])"}],"source_content_type":"text/x-python","patch_set":5,"id":"5a18252c_cc2dbda9","line":84,"updated":"2016-04-14 18:58:29.000000000","message":"oops - \"fake_iv()\" didn\u0027t get changed here (thus the unit test error).  Will fix in the next patch.","commit_id":"b90219f4870576ba86cf3904c260d096074ef3a8"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"017e21d328875cb52a8201d2da120547dd4cd261","unresolved":false,"context_lines":[{"line_number":76,"context_line":"        self.assertEqual(Crypto().get_cipher(), actual[\u0027cipher\u0027])"},{"line_number":77,"context_line":"        self.assertEqual(etag_iv, base64.b64decode(actual[\u0027iv\u0027]))"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        # verify plaintext etag for container update"},{"line_number":80,"context_line":"        self.assertIn(\u0027X-Backend-Container-Update-Override-Etag\u0027, req_hdrs)"},{"line_number":81,"context_line":"        cont_key \u003d fetch_crypto_keys()[\u0027container\u0027]"},{"line_number":82,"context_line":"        actual \u003d base64.b64decode("}],"source_content_type":"text/x-python","patch_set":6,"id":"5a18252c_607bcd28","line":79,"updated":"2016-04-14 22:17:27.000000000","message":"comment should not say plaintext.  its encrypted now.","commit_id":"4295e3e67693c61a5453b017c6a886bcd9c01561"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"017e21d328875cb52a8201d2da120547dd4cd261","unresolved":false,"context_lines":[{"line_number":81,"context_line":"        cont_key \u003d fetch_crypto_keys()[\u0027container\u0027]"},{"line_number":82,"context_line":"        actual \u003d base64.b64decode("},{"line_number":83,"context_line":"            req_hdrs[\u0027X-Backend-Container-Update-Override-Etag\u0027])"},{"line_number":84,"context_line":"        self.assertEqual(encrypt(plaintext_etag, cont_key, FAKE_IV), actual)"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"        # content-type is not encrypted"},{"line_number":87,"context_line":"        self.assertEqual(\u0027text/plain\u0027, req_hdrs[\u0027Content-Type\u0027])"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a18252c_859a736c","line":84,"updated":"2016-04-14 22:17:27.000000000","message":"There is no assertion that the crypto-meta is appended to the value.  It seems that the decode method will only process up to the \";\" so it only grabs the value itself (otherwise, this assertion should fail).  I have started working on fixing this.","commit_id":"4295e3e67693c61a5453b017c6a886bcd9c01561"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b7f5c1a3822d9f0cfc25df1f53623f7ce3c989d4","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        # verify encrypted etag for container update"},{"line_number":85,"context_line":"        self.assertIn(\u0027X-Backend-Container-Update-Override-Etag\u0027, req_hdrs)"},{"line_number":86,"context_line":"        cont_key \u003d fetch_crypto_keys()[\u0027container\u0027]"},{"line_number":87,"context_line":"        actual \u003d base64.b64decode("},{"line_number":88,"context_line":"            req_hdrs[\u0027X-Backend-Container-Update-Override-Etag\u0027])"},{"line_number":89,"context_line":"        self.assertEqual(encrypt(plaintext_etag, cont_key, FAKE_IV), actual)"},{"line_number":90,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"1a122d0e_24020070","line":87,"updated":"2016-04-18 11:42:00.000000000","message":"interesting that the b64decode stops at \u0027;\u0027 - I\u0027d prefer to split the header value before verifying the value though.","commit_id":"a794054eafa4c9ffc32a730f133d73e91fc05458"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b7f5c1a3822d9f0cfc25df1f53623f7ce3c989d4","unresolved":false,"context_lines":[{"line_number":88,"context_line":"            req_hdrs[\u0027X-Backend-Container-Update-Override-Etag\u0027])"},{"line_number":89,"context_line":"        self.assertEqual(encrypt(plaintext_etag, cont_key, FAKE_IV), actual)"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"        # extract crypto_meta from end of etag for container update"},{"line_number":92,"context_line":"        parts \u003d req_hdrs["},{"line_number":93,"context_line":"            \u0027X-Backend-Container-Update-Override-Etag\u0027].rsplit(\u0027;\u0027, 1)"},{"line_number":94,"context_line":"        param \u003d None"}],"source_content_type":"text/x-python","patch_set":8,"id":"1a122d0e_042c2401","line":91,"updated":"2016-04-18 11:42:00.000000000","message":"good catch to check the meta","commit_id":"a794054eafa4c9ffc32a730f133d73e91fc05458"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b7f5c1a3822d9f0cfc25df1f53623f7ce3c989d4","unresolved":false,"context_lines":[{"line_number":92,"context_line":"        parts \u003d req_hdrs["},{"line_number":93,"context_line":"            \u0027X-Backend-Container-Update-Override-Etag\u0027].rsplit(\u0027;\u0027, 1)"},{"line_number":94,"context_line":"        param \u003d None"},{"line_number":95,"context_line":"        if len(parts) \u003d\u003d 2:"},{"line_number":96,"context_line":"            value, param \u003d parts"},{"line_number":97,"context_line":"            if param.strip().startswith(\u0027meta\u003d\u0027):"},{"line_number":98,"context_line":"                param \u003d param.strip()[5:]"}],"source_content_type":"text/x-python","patch_set":8,"id":"1a122d0e_4159eefd","line":95,"updated":"2016-04-18 11:42:00.000000000","message":"makes this an assertion","commit_id":"a794054eafa4c9ffc32a730f133d73e91fc05458"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b7f5c1a3822d9f0cfc25df1f53623f7ce3c989d4","unresolved":false,"context_lines":[{"line_number":94,"context_line":"        param \u003d None"},{"line_number":95,"context_line":"        if len(parts) \u003d\u003d 2:"},{"line_number":96,"context_line":"            value, param \u003d parts"},{"line_number":97,"context_line":"            if param.strip().startswith(\u0027meta\u003d\u0027):"},{"line_number":98,"context_line":"                param \u003d param.strip()[5:]"},{"line_number":99,"context_line":"        actual \u003d json.loads(urllib.unquote_plus(param))"},{"line_number":100,"context_line":"        self.assertEqual(Crypto().get_cipher(), actual[\u0027cipher\u0027])"}],"source_content_type":"text/x-python","patch_set":8,"id":"1a122d0e_81fae6bb","line":97,"updated":"2016-04-18 11:42:00.000000000","message":"make this an assertion","commit_id":"a794054eafa4c9ffc32a730f133d73e91fc05458"}],"test/unit/proxy/controllers/test_obj.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"105edde7d86b3a5e39653a833039ecb736478388","unresolved":false,"context_lines":[{"line_number":107,"context_line":"        \u0027versions\u0027: None,"},{"line_number":108,"context_line":"    }"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    cont_etag \u003d \u002720242af0cd21dd7195a10483eb7472c9\u0027"},{"line_number":111,"context_line":"    crypto_etag \u003d \u002720242af0cd21dd7195a10483eb7472c9\u0027"},{"line_number":112,"context_line":"    etag_crypto_meta \u003d \\"},{"line_number":113,"context_line":"        \u0027{\"cipher\": \"AES_CTR_256\", \"iv\": \"sD+PSw/DfqYwpsVGSo0GEw\u003d\u003d\"}\u0027"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a18252c_652b4095","line":110,"updated":"2016-04-13 13:22:56.000000000","message":"We should probably make this a different value so we really do verify that the given value is propagated to the override header, and not the Etag getting copied into the override header.","commit_id":"087fcfaeaf68470904997e5b34990f11c6f0ffe0"}]}
