)]}'
{"swift/common/middleware/decrypter.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6c9ab0eca6b346030940395ec272142aef0dd1f5","unresolved":false,"context_lines":[{"line_number":203,"context_line":""},{"line_number":204,"context_line":"        # Pop off container etag override, so copies work correctly"},{"line_number":205,"context_line":"        mod_hdr_pairs.append("},{"line_number":206,"context_line":"            (\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027, \u0027\u0027))"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"        # Decrypt all user metadata"},{"line_number":209,"context_line":"        mod_hdr_pairs.extend(self.decrypt_user_metadata(keys))"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_9d25320c","line":206,"updated":"2016-05-24 10:43:05.000000000","message":"Yes! But we should probably do this once either in the proxy obj controller (i.e. never let these override values leak out in a response) or in copy middleware (i.e. have an exclusion list for sysmeta  that is copied) because the same problem could occur with EC overrides when copying from EC to non-EC policy. (I realise this is a problem I have created by making the override values persistent :/)","commit_id":"3bdff4a47115862b1f5daef626b038eadbbaaf78"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f09a50fc2fbc51b7040a1cf5266bb95436575a1d","unresolved":false,"context_lines":[{"line_number":203,"context_line":""},{"line_number":204,"context_line":"        # Pop off container etag override, so copies work correctly"},{"line_number":205,"context_line":"        mod_hdr_pairs.append("},{"line_number":206,"context_line":"            (\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027, \u0027\u0027))"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"        # Decrypt all user metadata"},{"line_number":209,"context_line":"        mod_hdr_pairs.extend(self.decrypt_user_metadata(keys))"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_a32354bc","line":206,"in_reply_to":"bab6814e_9d25320c","updated":"2016-05-25 22:05:21.000000000","message":"I\u0027ll keep thinking on this. I\u0027m still not sure whether we want to pop it off or just return it to the decrypted value.\n\nMaybe we should just decrypt it and defer on deciding whether (and if so, where) to drop it until later?","commit_id":"3bdff4a47115862b1f5daef626b038eadbbaaf78"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6c9ab0eca6b346030940395ec272142aef0dd1f5","unresolved":false,"context_lines":[{"line_number":210,"context_line":""},{"line_number":211,"context_line":"        mod_hdr_names \u003d {h.lower() for h, v in mod_hdr_pairs}"},{"line_number":212,"context_line":"        mod_resp_headers \u003d [(h, v) for h, v in self._response_headers"},{"line_number":213,"context_line":"                            if h.lower() not in mod_hdr_names]"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"        mod_resp_headers.extend((h, v) for h, v in mod_hdr_pairs if v)"},{"line_number":216,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_5d590a8e","line":213,"updated":"2016-05-24 10:43:05.000000000","message":"So I\u0027m curious - what\u0027s wrong with map and filter?","commit_id":"3bdff4a47115862b1f5daef626b038eadbbaaf78"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f09a50fc2fbc51b7040a1cf5266bb95436575a1d","unresolved":false,"context_lines":[{"line_number":210,"context_line":""},{"line_number":211,"context_line":"        mod_hdr_names \u003d {h.lower() for h, v in mod_hdr_pairs}"},{"line_number":212,"context_line":"        mod_resp_headers \u003d [(h, v) for h, v in self._response_headers"},{"line_number":213,"context_line":"                            if h.lower() not in mod_hdr_names]"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"        mod_resp_headers.extend((h, v) for h, v in mod_hdr_pairs if v)"},{"line_number":216,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_23500432","line":213,"in_reply_to":"bab6814e_5d590a8e","updated":"2016-05-25 22:05:21.000000000","message":"Personal preference, and some vague memory of slight performance benefits in certain situations (typically when much of the work is done in off C-land, as I\u0027d expect most string operations to be).\n\nI could put it back if you like, but I\u0027m going to insist on extend().","commit_id":"3bdff4a47115862b1f5daef626b038eadbbaaf78"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"23f489cac100f241bb40d9fdefc84e6912c4d047","unresolved":false,"context_lines":[{"line_number":202,"context_line":"            mod_hdr_pairs.append((\u0027Etag\u0027, decrypted_etag))"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":"        etag_header \u003d \u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027"},{"line_number":205,"context_line":"        encrypted_etag \u003d self._response_header_value(etag_header)"},{"line_number":206,"context_line":"        if encrypted_etag:"},{"line_number":207,"context_line":"            decrypted_etag \u003d self.decrypt_value_with_meta("},{"line_number":208,"context_line":"                encrypted_etag, keys[\u0027container\u0027])"}],"source_content_type":"text/x-python","patch_set":4,"id":"bab6814e_91a10897","line":205,"updated":"2016-05-26 16:11:17.000000000","message":"nit: it may not be encrypted, if object was PUT unencrypted","commit_id":"ea22b3fdbcc4af2de7e4508ee57b88ec42c5f53c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"23f489cac100f241bb40d9fdefc84e6912c4d047","unresolved":false,"context_lines":[{"line_number":204,"context_line":"        etag_header \u003d \u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027"},{"line_number":205,"context_line":"        encrypted_etag \u003d self._response_header_value(etag_header)"},{"line_number":206,"context_line":"        if encrypted_etag:"},{"line_number":207,"context_line":"            decrypted_etag \u003d self.decrypt_value_with_meta("},{"line_number":208,"context_line":"                encrypted_etag, keys[\u0027container\u0027])"},{"line_number":209,"context_line":"            mod_hdr_pairs.append((etag_header, decrypted_etag))"},{"line_number":210,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"bab6814e_1c41c163","line":207,"updated":"2016-05-26 16:11:17.000000000","message":"need to catch any exceptions and generate a 500 response, perhaps by refactoring decrypt_header to suit this case too.","commit_id":"ea22b3fdbcc4af2de7e4508ee57b88ec42c5f53c"}],"swift/common/middleware/encrypter.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6c9ab0eca6b346030940395ec272142aef0dd1f5","unresolved":false,"context_lines":[{"line_number":86,"context_line":"        # body has been sent"},{"line_number":87,"context_line":"        inner_callback \u003d req.environ.get(\u0027swift.callback.update_footers\u0027)"},{"line_number":88,"context_line":"        container_listing_etag_header \u003d req.headers.get("},{"line_number":89,"context_line":"            \u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027)"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"        def footers_callback(footers):"},{"line_number":92,"context_line":"            plaintext_etag \u003d None"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_1d178255","line":89,"updated":"2016-05-24 10:43:05.000000000","message":"off-topic - we could initialise client_etag as well here, rather than it being an instance variable.","commit_id":"3bdff4a47115862b1f5daef626b038eadbbaaf78"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f09a50fc2fbc51b7040a1cf5266bb95436575a1d","unresolved":false,"context_lines":[{"line_number":86,"context_line":"        # body has been sent"},{"line_number":87,"context_line":"        inner_callback \u003d req.environ.get(\u0027swift.callback.update_footers\u0027)"},{"line_number":88,"context_line":"        container_listing_etag_header \u003d req.headers.get("},{"line_number":89,"context_line":"            \u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027)"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"        def footers_callback(footers):"},{"line_number":92,"context_line":"            plaintext_etag \u003d None"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_c62666cd","line":89,"in_reply_to":"bab6814e_1d178255","updated":"2016-05-25 22:05:21.000000000","message":"Done","commit_id":"3bdff4a47115862b1f5daef626b038eadbbaaf78"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6c9ab0eca6b346030940395ec272142aef0dd1f5","unresolved":false,"context_lines":[{"line_number":120,"context_line":"                # listings, look for:"},{"line_number":121,"context_line":"                #   * override in the footer, otherwise"},{"line_number":122,"context_line":"                #   * override in the header, and finally"},{"line_number":123,"context_line":"                #   * MD5 of the plaintext received"},{"line_number":124,"context_line":"                container_listing_etag \u003d footers.get("},{"line_number":125,"context_line":"                    \u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027,"},{"line_number":126,"context_line":"                    container_listing_etag_header or plaintext_etag)"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_93a24199","line":123,"updated":"2016-05-24 10:43:05.000000000","message":"We only get here if there was a non-empty body. Might there be some future middleware that wants to override the listing etag of an empty object? (I can\u0027t think of any current middleware that does it)\n\nNot suggesting we code for it now - it\u0027s not a must-have to land on master, but I\u0027ll make a note on trello.\n\nhttps://trello.com/c/VspxUvHm/106-encrypt-listing-override-etag-from-other-middlewares-even-when-body-is-empty","commit_id":"3bdff4a47115862b1f5daef626b038eadbbaaf78"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f09a50fc2fbc51b7040a1cf5266bb95436575a1d","unresolved":false,"context_lines":[{"line_number":120,"context_line":"                # listings, look for:"},{"line_number":121,"context_line":"                #   * override in the footer, otherwise"},{"line_number":122,"context_line":"                #   * override in the header, and finally"},{"line_number":123,"context_line":"                #   * MD5 of the plaintext received"},{"line_number":124,"context_line":"                container_listing_etag \u003d footers.get("},{"line_number":125,"context_line":"                    \u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027,"},{"line_number":126,"context_line":"                    container_listing_etag_header or plaintext_etag)"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_462716b6","line":123,"in_reply_to":"bab6814e_93a24199","updated":"2016-05-25 22:05:21.000000000","message":"Since self.crypto and self.keys are always available, I think this is just a matter of taking this out of the if? Lets try it.","commit_id":"3bdff4a47115862b1f5daef626b038eadbbaaf78"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6c9ab0eca6b346030940395ec272142aef0dd1f5","unresolved":false,"context_lines":[{"line_number":135,"context_line":"                    val"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"                # If client (or other middleware) supplied etag, then validate"},{"line_number":138,"context_line":"                # against plaintext etag"},{"line_number":139,"context_line":"                self.client_etag \u003d footers.get(\u0027Etag\u0027) or self.client_etag"},{"line_number":140,"context_line":"                if (self.client_etag is not None and"},{"line_number":141,"context_line":"                        plaintext_etag !\u003d self.client_etag):"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_58b3d80a","line":138,"updated":"2016-05-24 10:43:05.000000000","message":"nit: if we did this check first (i.e. at line 119) then we\u0027d save some wasted encryption cycles if the etags don\u0027t match","commit_id":"3bdff4a47115862b1f5daef626b038eadbbaaf78"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f09a50fc2fbc51b7040a1cf5266bb95436575a1d","unresolved":false,"context_lines":[{"line_number":135,"context_line":"                    val"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"                # If client (or other middleware) supplied etag, then validate"},{"line_number":138,"context_line":"                # against plaintext etag"},{"line_number":139,"context_line":"                self.client_etag \u003d footers.get(\u0027Etag\u0027) or self.client_etag"},{"line_number":140,"context_line":"                if (self.client_etag is not None and"},{"line_number":141,"context_line":"                        plaintext_etag !\u003d self.client_etag):"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_690b0d25","line":138,"in_reply_to":"bab6814e_58b3d80a","updated":"2016-05-25 22:05:21.000000000","message":"Done","commit_id":"3bdff4a47115862b1f5daef626b038eadbbaaf78"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"23f489cac100f241bb40d9fdefc84e6912c4d047","unresolved":false,"context_lines":[{"line_number":90,"context_line":""},{"line_number":91,"context_line":"        def footers_callback(footers):"},{"line_number":92,"context_line":"            plaintext_etag \u003d None"},{"line_number":93,"context_line":"            if self.body_crypto_ctxt:"},{"line_number":94,"context_line":"                plaintext_etag \u003d self.plaintext_md5.hexdigest()"},{"line_number":95,"context_line":"                # Encrypt the plaintext etag using the object key and persist"},{"line_number":96,"context_line":"                # as sysmeta along with the crypto parameters that were used."}],"source_content_type":"text/x-python","patch_set":4,"id":"bab6814e_1eb1b847","line":93,"updated":"2016-05-26 16:11:17.000000000","message":"this if clause can be merged with the later one. Now that we set the X-Object-Sysmeta-Container-Update-Override-Etag later, we don\u0027t need this clause to happen before the call to inner_callback - there is nothing we set here that we would want to allow a leftside middleware to modify.","commit_id":"ea22b3fdbcc4af2de7e4508ee57b88ec42c5f53c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"23f489cac100f241bb40d9fdefc84e6912c4d047","unresolved":false,"context_lines":[{"line_number":131,"context_line":"            #   * override in the footer, otherwise"},{"line_number":132,"context_line":"            #   * override in the header, and finally"},{"line_number":133,"context_line":"            #   * MD5 of the plaintext received"},{"line_number":134,"context_line":"            # This may be None if no override was set and no data was read"},{"line_number":135,"context_line":"            container_listing_etag \u003d footers.get("},{"line_number":136,"context_line":"                \u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027,"},{"line_number":137,"context_line":"                container_listing_etag_header or plaintext_etag)"}],"source_content_type":"text/x-python","patch_set":4,"id":"bab6814e_c3b8fb77","line":134,"updated":"2016-05-26 16:11:17.000000000","message":"Right. So if no override and no object body we still do not encrypt the etag. +1","commit_id":"ea22b3fdbcc4af2de7e4508ee57b88ec42c5f53c"}],"test/unit/common/middleware/test_decrypter.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f09a50fc2fbc51b7040a1cf5266bb95436575a1d","unresolved":false,"context_lines":[{"line_number":75,"context_line":"                base64.b64encode(encrypt(\u0027encrypt me\u0027, object_key, FAKE_IV)),"},{"line_number":76,"context_line":"            \u0027x-object-transient-sysmeta-crypto-meta-test\u0027:"},{"line_number":77,"context_line":"                get_crypto_meta_header(),"},{"line_number":78,"context_line":"            \u0027x-object-sysmeta-container-override-etag\u0027: \u0027drop me\u0027,"},{"line_number":79,"context_line":"            \u0027x-object-sysmeta-test\u0027: \u0027do not encrypt me\u0027}"},{"line_number":80,"context_line":"        self.app.register("},{"line_number":81,"context_line":"            \u0027GET\u0027, \u0027/v1/a/c/o\u0027, HTTPOk, body\u003denc_body, headers\u003dhdrs)"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_cf55d950","line":78,"range":{"start_line":78,"start_character":30,"end_line":78,"end_character":48},"updated":"2016-05-25 22:05:21.000000000","message":"Whoops! :(","commit_id":"3bdff4a47115862b1f5daef626b038eadbbaaf78"}],"test/unit/common/middleware/test_encrypter.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6c9ab0eca6b346030940395ec272142aef0dd1f5","unresolved":false,"context_lines":[{"line_number":208,"context_line":"        self.assertEqual(2, len(parts))"},{"line_number":209,"context_line":"        cont_key \u003d fetch_crypto_keys()[\u0027container\u0027]"},{"line_number":210,"context_line":"        actual \u003d base64.b64decode(parts[0])"},{"line_number":211,"context_line":"        self.assertEqual(encrypt(\u0027final etag\u0027, cont_key, FAKE_IV), actual)"},{"line_number":212,"context_line":""},{"line_number":213,"context_line":"        # extract crypto_meta from end of etag for container update"},{"line_number":214,"context_line":"        param \u003d parts[1].strip()"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_6e50965f","line":211,"updated":"2016-05-24 10:43:05.000000000","message":"hmm, we should be using a derived iv for the override etag i.e. \"etag_iv\". Added another task to trello.","commit_id":"3bdff4a47115862b1f5daef626b038eadbbaaf78"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6c9ab0eca6b346030940395ec272142aef0dd1f5","unresolved":false,"context_lines":[{"line_number":226,"context_line":"        self.assertEqual(expected_wrapped_key, base64.b64decode(actual[\u0027key\u0027]))"},{"line_number":227,"context_line":""},{"line_number":228,"context_line":"    def test_PUT_with_etag_override_in_headers(self):"},{"line_number":229,"context_line":"        # verify handling of another middleware\u0027s footer callback"},{"line_number":230,"context_line":"        plaintext \u003d \u0027FAKE APP\u0027"},{"line_number":231,"context_line":"        plaintext_etag \u003d md5hex(plaintext)"},{"line_number":232,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_ce80a28e","line":229,"updated":"2016-05-24 10:43:05.000000000","message":"comment doesn\u0027t apply","commit_id":"3bdff4a47115862b1f5daef626b038eadbbaaf78"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f09a50fc2fbc51b7040a1cf5266bb95436575a1d","unresolved":false,"context_lines":[{"line_number":226,"context_line":"        self.assertEqual(expected_wrapped_key, base64.b64decode(actual[\u0027key\u0027]))"},{"line_number":227,"context_line":""},{"line_number":228,"context_line":"    def test_PUT_with_etag_override_in_headers(self):"},{"line_number":229,"context_line":"        # verify handling of another middleware\u0027s footer callback"},{"line_number":230,"context_line":"        plaintext \u003d \u0027FAKE APP\u0027"},{"line_number":231,"context_line":"        plaintext_etag \u003d md5hex(plaintext)"},{"line_number":232,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_c9de796c","line":229,"in_reply_to":"bab6814e_ce80a28e","updated":"2016-05-25 22:05:21.000000000","message":"Done","commit_id":"3bdff4a47115862b1f5daef626b038eadbbaaf78"}]}
