)]}'
{"etc/proxy-server.conf-sample":[{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"5e20504398ea613bac9ecff0e6820d2c30d0668b","unresolved":false,"context_lines":[{"line_number":78,"context_line":""},{"line_number":79,"context_line":"[pipeline:main]"},{"line_number":80,"context_line":"pipeline \u003d catch_errors gatekeeper healthcheck proxy-logging cache container_sync bulk tempurl ratelimit tempauth container-quotas account-quotas slo dlo proxy-logging proxy-server"},{"line_number":81,"context_line":"# You can enable encryption by adding decrypter trivialkeymaster encrypter between dlo and proxy-logging"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"[app:proxy-server]"},{"line_number":84,"context_line":"use \u003d egg:swift#proxy"}],"source_content_type":"application/octet-stream","patch_set":5,"id":"3a50d1a3_bfb828c9","line":81,"updated":"2015-07-29 05:57:16.000000000","message":"I don\u0027t think you need this comment here (you go over it below).","commit_id":"496b08e39658260a089cda3ebf6a6dc080938f6d"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"7675fb3549f8fa28d3105e529e3645a9c37de1f8","unresolved":false,"context_lines":[{"line_number":78,"context_line":""},{"line_number":79,"context_line":"[pipeline:main]"},{"line_number":80,"context_line":"pipeline \u003d catch_errors gatekeeper healthcheck proxy-logging cache container_sync bulk tempurl ratelimit tempauth container-quotas account-quotas slo dlo proxy-logging proxy-server"},{"line_number":81,"context_line":"# You can enable encryption by adding decrypter trivialkeymaster encrypter between dlo and proxy-logging"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"[app:proxy-server]"},{"line_number":84,"context_line":"use \u003d egg:swift#proxy"}],"source_content_type":"application/octet-stream","patch_set":5,"id":"3a50d1a3_80ebdd11","line":81,"in_reply_to":"3a50d1a3_bfb828c9","updated":"2015-08-01 22:07:20.000000000","message":"done.","commit_id":"496b08e39658260a089cda3ebf6a6dc080938f6d"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"1e864596fc5653a23b44ecda578caa0fc7253452","unresolved":false,"context_lines":[{"line_number":714,"context_line":"# in the container configuration file, which will be eventually"},{"line_number":715,"context_line":"# deprecated. See documentation for more details."},{"line_number":716,"context_line":"# allow_versioned_writes \u003d false"},{"line_number":717,"context_line":""},{"line_number":718,"context_line":"# Note: The ordering of the 3 dependant pieces of crypto middleware below"},{"line_number":719,"context_line":"# should be as follows in the proxy-server pipeline:"},{"line_number":720,"context_line":"# ... decrypter trivial_keymaster encrypter ..."}],"source_content_type":"application/octet-stream","patch_set":13,"id":"9a1a9d01_0f88d021","line":717,"updated":"2015-09-24 19:31:51.000000000","message":"Well I think this looks good now : - )","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"75ae70efdb88aae9798ab9cce7099fea10cb7fe4","unresolved":false,"context_lines":[{"line_number":715,"context_line":"# deprecated. See documentation for more details."},{"line_number":716,"context_line":"# allow_versioned_writes \u003d false"},{"line_number":717,"context_line":""},{"line_number":718,"context_line":"# Note: The ordering of the 3 dependant pieces of crypto middleware below"},{"line_number":719,"context_line":"# should be as follows in the proxy-server pipeline:"},{"line_number":720,"context_line":"# ... decrypter trivial_keymaster encrypter ..."},{"line_number":721,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":13,"id":"9a1a9d01_699387fb","line":718,"updated":"2015-09-24 19:27:53.000000000","message":"nit s/dependant/dependent/","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":715,"context_line":"# deprecated. See documentation for more details."},{"line_number":716,"context_line":"# allow_versioned_writes \u003d false"},{"line_number":717,"context_line":""},{"line_number":718,"context_line":"# Note: The ordering of the 3 dependant pieces of crypto middleware below"},{"line_number":719,"context_line":"# should be as follows in the proxy-server pipeline:"},{"line_number":720,"context_line":"# ... decrypter trivial_keymaster encrypter ..."},{"line_number":721,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":13,"id":"9a1a9d01_c796af3e","line":718,"in_reply_to":"9a1a9d01_699387fb","updated":"2015-09-29 13:39:21.000000000","message":"will change","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":715,"context_line":"# deprecated. See documentation for more details."},{"line_number":716,"context_line":"# allow_versioned_writes \u003d false"},{"line_number":717,"context_line":""},{"line_number":718,"context_line":"# Note: The ordering of the 3 dependant pieces of crypto middleware below"},{"line_number":719,"context_line":"# should be as follows in the proxy-server pipeline:"},{"line_number":720,"context_line":"# ... decrypter trivial_keymaster encrypter ..."},{"line_number":721,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":13,"id":"9a1a9d01_12d2875c","line":718,"in_reply_to":"9a1a9d01_c796af3e","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5869c613d2e7facdee98c473341fcfe40757b943","unresolved":false,"context_lines":[{"line_number":724,"context_line":"[filter:decrypter]"},{"line_number":725,"context_line":"use \u003d egg:swift#decrypter"},{"line_number":726,"context_line":""},{"line_number":727,"context_line":"# Note: Put trivial_keymaster between decrypter and proxy-logging in the"},{"line_number":728,"context_line":"# pipeline."},{"line_number":729,"context_line":"# This option is part of enabling encryption for testing purposes."},{"line_number":730,"context_line":"[filter:trivial_keymaster]"}],"source_content_type":"application/octet-stream","patch_set":13,"id":"9a1a9d01_21077219","line":727,"updated":"2015-09-29 01:11:06.000000000","message":"proxy-logging is typically included twice in a pipeline, once at the beginning and once at the end. It may not be a good reference point. Ditto for encrypter\u0027s comment.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":724,"context_line":"[filter:decrypter]"},{"line_number":725,"context_line":"use \u003d egg:swift#decrypter"},{"line_number":726,"context_line":""},{"line_number":727,"context_line":"# Note: Put trivial_keymaster between decrypter and proxy-logging in the"},{"line_number":728,"context_line":"# pipeline."},{"line_number":729,"context_line":"# This option is part of enabling encryption for testing purposes."},{"line_number":730,"context_line":"[filter:trivial_keymaster]"}],"source_content_type":"application/octet-stream","patch_set":13,"id":"9a1a9d01_a7b85bc9","line":727,"in_reply_to":"9a1a9d01_21077219","updated":"2015-09-29 13:39:21.000000000","message":"will make mention","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":724,"context_line":"[filter:decrypter]"},{"line_number":725,"context_line":"use \u003d egg:swift#decrypter"},{"line_number":726,"context_line":""},{"line_number":727,"context_line":"# Note: Put trivial_keymaster between decrypter and proxy-logging in the"},{"line_number":728,"context_line":"# pipeline."},{"line_number":729,"context_line":"# This option is part of enabling encryption for testing purposes."},{"line_number":730,"context_line":"[filter:trivial_keymaster]"}],"source_content_type":"application/octet-stream","patch_set":13,"id":"9a1a9d01_32d78b4c","line":727,"in_reply_to":"9a1a9d01_a7b85bc9","updated":"2015-09-30 15:37:19.000000000","message":"I improved the details of the top comment, and removed the \u0027sub-comments\u0027 over each crypto middleware.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"}],"swift/common/crypto_utils.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e2fed5c89a890ebc4646d8d7f4f2a9bd43f72f19","unresolved":false,"context_lines":[{"line_number":16,"context_line":"from swift.common.swob import HTTPInternalServerError"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"class CryptoUtils(object):"},{"line_number":20,"context_line":"    \"\"\""},{"line_number":21,"context_line":"    Used by crypto middleware"},{"line_number":22,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_4dd78523","line":19,"updated":"2015-08-04 17:11:37.000000000","message":"My observation is that stuff like this is usually implemented as module functions in swift rather than static methods.","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3b95d640ad057703b574028089ff89ed5be946db","unresolved":false,"context_lines":[{"line_number":16,"context_line":"from swift.common.swob import HTTPInternalServerError"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"class CryptoUtils(object):"},{"line_number":20,"context_line":"    \"\"\""},{"line_number":21,"context_line":"    Used by crypto middleware"},{"line_number":22,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_669e0456","line":19,"in_reply_to":"1a4dcd0f_4dd78523","updated":"2015-08-17 19:07:32.000000000","message":"the get_keys method is used by both the encrypter and decrypter.  This was a way that they could share that code.  I expect there may be other things that could move to this utils class by the time we are done with encryption.  If at the end, we still only have this one method, I agree that we should remove the class.","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e2fed5c89a890ebc4646d8d7f4f2a9bd43f72f19","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        return keys"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    @staticmethod"},{"line_number":36,"context_line":"    def get_crypto_meta(iv, cipher):"},{"line_number":37,"context_line":"        return {\u0027iv\u0027: iv, \u0027cipher\u0027: cipher}"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_2def9988","line":36,"updated":"2015-08-04 17:11:37.000000000","message":"only used in encrypter so define there?","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3b95d640ad057703b574028089ff89ed5be946db","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        return keys"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    @staticmethod"},{"line_number":36,"context_line":"    def get_crypto_meta(iv, cipher):"},{"line_number":37,"context_line":"        return {\u0027iv\u0027: iv, \u0027cipher\u0027: cipher}"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_26a8fc76","line":36,"in_reply_to":"1a4dcd0f_2def9988","updated":"2015-08-17 19:07:32.000000000","message":"removed from utils.","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"62a2f1c55ef6300f735f28e40bfa095976c3aadb","unresolved":false,"context_lines":[{"line_number":26,"context_line":"        try:"},{"line_number":27,"context_line":"            fetch_crypto_keys \u003d env[\u0027swift.crypto.fetch_crypto_keys\u0027]"},{"line_number":28,"context_line":"            keys \u003d fetch_crypto_keys()"},{"line_number":29,"context_line":"        except Exception as err:"},{"line_number":30,"context_line":"            # TODO - change this case to use KeyMasterException when it exists"},{"line_number":31,"context_line":"            raise HTTPInternalServerError(\"Fetch keys had exception %s\" %"},{"line_number":32,"context_line":"                                          err.message)"}],"source_content_type":"text/x-python","patch_set":17,"id":"5a2ca52d_abe27d2d","line":29,"updated":"2015-10-15 20:10:12.000000000","message":"separate the exception handling for the KeyError and other exceptions from the callback.\n\nLog errors.","commit_id":"3fcfef319fbcae875af6fd29798e16a9317efb07"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"5387cc8318b3553c893cd4839ba16b510f931ec9","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from swift.common.wsgi import WSGIContext"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"class CryptoWSGIContext(WSGIContext):"},{"line_number":22,"context_line":"    \"\"\""},{"line_number":23,"context_line":"    Base class for contexts used by crypto middlewares."},{"line_number":24,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":18,"id":"3a29b11f_301b8a74","line":21,"updated":"2015-10-20 01:08:25.000000000","message":"Alistair - great idea to have this class be a base context and include the logging here.  Thanks!","commit_id":"f3231ff407bd731b054a42e2070be5768103fd18"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"5387cc8318b3553c893cd4839ba16b510f931ec9","unresolved":false,"context_lines":[{"line_number":40,"context_line":"        try:"},{"line_number":41,"context_line":"            return fetch_crypto_keys()"},{"line_number":42,"context_line":"        except Exception as err:  # noqa"},{"line_number":43,"context_line":"            # TODO - change this case to use KeyMasterException when it exists"},{"line_number":44,"context_line":"            self.logger.exception(_("},{"line_number":45,"context_line":"                \u0027ERROR get_keys(): from swift.crypto.fetch_crypto_keys: %s\u0027)"},{"line_number":46,"context_line":"                % err)"}],"source_content_type":"text/x-python","patch_set":18,"id":"3a29b11f_6d004f35","line":43,"updated":"2015-10-20 01:08:25.000000000","message":"I added this comment a long time ago.  It seems like it is time to make a decision on the KeyMasterException.  That doesn\u0027t need to hold up this merging, but its one of the little things we can talk about when we design more of the keymaster.","commit_id":"f3231ff407bd731b054a42e2070be5768103fd18"}],"swift/common/exceptions.py":[{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"5387cc8318b3553c893cd4839ba16b510f931ec9","unresolved":false,"context_lines":[{"line_number":215,"context_line":"    pass"},{"line_number":216,"context_line":""},{"line_number":217,"context_line":""},{"line_number":218,"context_line":"class StopDecryption(SwiftException):"},{"line_number":219,"context_line":"    pass"},{"line_number":220,"context_line":""},{"line_number":221,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"3a29b11f_9057fe01","line":218,"updated":"2015-10-20 01:08:25.000000000","message":"Makes more sense, thanks!","commit_id":"f3231ff407bd731b054a42e2070be5768103fd18"}],"swift/common/middleware/decrypter.py":[{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"5e20504398ea613bac9ecff0e6820d2c30d0668b","unresolved":false,"context_lines":[{"line_number":144,"context_line":"        self.body_crypto_ctxt \u003d self.decrypter.crypto.create_decryption_ctxt("},{"line_number":145,"context_line":"            keys[\u0027object\u0027], body_iv, offset)"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"        # This is setup to do more header modifications in a later version"},{"line_number":148,"context_line":"        mod_hdr_keys \u003d []"},{"line_number":149,"context_line":"        mod_hdr_pairs \u003d []"},{"line_number":150,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3a50d1a3_5628ea85","line":147,"updated":"2015-07-29 05:57:16.000000000","message":"Can we just use a python dictionary and add like normal, later you can use dict.keys() to return a list of the keys.  Using this list we can create a new list from the response headers but exclude any of these keys ?","commit_id":"496b08e39658260a089cda3ebf6a6dc080938f6d"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"7675fb3549f8fa28d3105e529e3645a9c37de1f8","unresolved":false,"context_lines":[{"line_number":144,"context_line":"        self.body_crypto_ctxt \u003d self.decrypter.crypto.create_decryption_ctxt("},{"line_number":145,"context_line":"            keys[\u0027object\u0027], body_iv, offset)"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"        # This is setup to do more header modifications in a later version"},{"line_number":148,"context_line":"        mod_hdr_keys \u003d []"},{"line_number":149,"context_line":"        mod_hdr_pairs \u003d []"},{"line_number":150,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3a50d1a3_a04859cd","line":147,"in_reply_to":"3a50d1a3_5628ea85","updated":"2015-08-01 22:07:20.000000000","message":"I changed this to compile the list of keys from the header \"pairs\".","commit_id":"496b08e39658260a089cda3ebf6a6dc080938f6d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e2fed5c89a890ebc4646d8d7f4f2a9bd43f72f19","unresolved":false,"context_lines":[{"line_number":29,"context_line":"    def __init__(self, decrypter):"},{"line_number":30,"context_line":"        super(DecrypterObjContext, self).__init__(decrypter.app)"},{"line_number":31,"context_line":"        self.decrypter \u003d decrypter"},{"line_number":32,"context_line":"        self.logger \u003d decrypter.logger"},{"line_number":33,"context_line":"        self.body_crypto_ctxt \u003d None"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    def handle_get(self, req, start_response):"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_70649148","line":32,"updated":"2015-08-04 17:11:37.000000000","message":"nit: pass logger as arg perhaps?","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3b95d640ad057703b574028089ff89ed5be946db","unresolved":false,"context_lines":[{"line_number":29,"context_line":"    def __init__(self, decrypter):"},{"line_number":30,"context_line":"        super(DecrypterObjContext, self).__init__(decrypter.app)"},{"line_number":31,"context_line":"        self.decrypter \u003d decrypter"},{"line_number":32,"context_line":"        self.logger \u003d decrypter.logger"},{"line_number":33,"context_line":"        self.body_crypto_ctxt \u003d None"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    def handle_get(self, req, start_response):"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_86e6b0e6","line":32,"in_reply_to":"1a4dcd0f_70649148","updated":"2015-08-17 19:07:32.000000000","message":"now passing logger too in order to facilitate using FakeLogger.  (note that decrypter is still needed for the __init__ part)","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e2fed5c89a890ebc4646d8d7f4f2a9bd43f72f19","unresolved":false,"context_lines":[{"line_number":152,"context_line":"            etag \u003d self._response_header_value(\u0027X-Object-Sysmeta-Crypto-Etag\u0027)"},{"line_number":153,"context_line":"            mod_hdr_pairs.append((hkey, etag))"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"        except StopEncryption:"},{"line_number":156,"context_line":"            # X-Object-Sysmeta-Crypto-Etag is not always present"},{"line_number":157,"context_line":"            pass"},{"line_number":158,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_0b6e4001","line":155,"updated":"2015-08-04 17:11:37.000000000","message":"StopEncryption is not raised in this try scope\n\nshoudl this be wrapping the call to get_sysmeta_crypto_meta ??","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3b95d640ad057703b574028089ff89ed5be946db","unresolved":false,"context_lines":[{"line_number":152,"context_line":"            etag \u003d self._response_header_value(\u0027X-Object-Sysmeta-Crypto-Etag\u0027)"},{"line_number":153,"context_line":"            mod_hdr_pairs.append((hkey, etag))"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"        except StopEncryption:"},{"line_number":156,"context_line":"            # X-Object-Sysmeta-Crypto-Etag is not always present"},{"line_number":157,"context_line":"            pass"},{"line_number":158,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_463f4825","line":155,"in_reply_to":"1a4dcd0f_0b6e4001","updated":"2015-08-17 19:07:32.000000000","message":"removed.  (the get_sysmeta_crypto_meta is added in this block in a later review that has user-meta encrypted)","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5869c613d2e7facdee98c473341fcfe40757b943","unresolved":false,"context_lines":[{"line_number":14,"context_line":"# limitations under the License."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"import base64"},{"line_number":17,"context_line":"import ast"},{"line_number":18,"context_line":"from swift.common.utils import get_logger, config_true_value, \\"},{"line_number":19,"context_line":"    parse_content_range"},{"line_number":20,"context_line":"from swift.common.http import is_success"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_cfeeeab3","line":17,"updated":"2015-09-29 01:11:06.000000000","message":"Well this feels like a giant red flag. Won\u0027t this cause issues once we support python3? In particular, migrating a cluster from py2 to py3 seems like a terrifying prospect. I\u0027ve got an idea; I think it makes more sense to explain it in encrypter.py, though.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":14,"context_line":"# limitations under the License."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"import base64"},{"line_number":17,"context_line":"import ast"},{"line_number":18,"context_line":"from swift.common.utils import get_logger, config_true_value, \\"},{"line_number":19,"context_line":"    parse_content_range"},{"line_number":20,"context_line":"from swift.common.http import is_success"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_4d7b667b","line":17,"in_reply_to":"9a1a9d01_cfeeeab3","updated":"2015-09-30 15:37:19.000000000","message":"Hamdi will be uploading a patch to address this part","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"1e864596fc5653a23b44ecda578caa0fc7253452","unresolved":false,"context_lines":[{"line_number":48,"context_line":"            return app_resp"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"        # Only proceed processing if an error has not occurred"},{"line_number":51,"context_line":"        if self._response_status:"},{"line_number":52,"context_line":"            resp_int \u003d int(self._response_status[:3])"},{"line_number":53,"context_line":"            if not is_success(resp_int):"},{"line_number":54,"context_line":"                start_response(self._response_status, mod_resp_headers,"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_45c4693f","line":51,"updated":"2015-09-24 19:31:51.000000000","message":"hmm, should we not check this before we call process_resp_headers ?  What\u0027s the point if we already ran into an error ?  I think I may know the answer (i.e. as to why, i.e. that we should fix the headers regardless) but if that\u0027s the case I think we need to add a comment that makes that aspect very clear (i.e. why we always process the resp headers even in error scenarios).","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":48,"context_line":"            return app_resp"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"        # Only proceed processing if an error has not occurred"},{"line_number":51,"context_line":"        if self._response_status:"},{"line_number":52,"context_line":"            resp_int \u003d int(self._response_status[:3])"},{"line_number":53,"context_line":"            if not is_success(resp_int):"},{"line_number":54,"context_line":"                start_response(self._response_status, mod_resp_headers,"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_cc2d7496","line":51,"in_reply_to":"9a1a9d01_45c4693f","updated":"2015-09-29 13:39:21.000000000","message":"this probably could be moved to just after the app_resp.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":48,"context_line":"            return app_resp"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"        # Only proceed processing if an error has not occurred"},{"line_number":51,"context_line":"        if self._response_status:"},{"line_number":52,"context_line":"            resp_int \u003d int(self._response_status[:3])"},{"line_number":53,"context_line":"            if not is_success(resp_int):"},{"line_number":54,"context_line":"                start_response(self._response_status, mod_resp_headers,"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_1ecdbbb6","line":51,"in_reply_to":"9a1a9d01_cc2d7496","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"70e0be720a38c6787cbbb3ecba7a6db8f5e095a1","unresolved":false,"context_lines":[{"line_number":75,"context_line":"                    chunk \u003d iterator.next()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"            except StopIteration:"},{"line_number":78,"context_line":"                pass"},{"line_number":79,"context_line":"            finally:"},{"line_number":80,"context_line":"                close_method \u003d getattr(iterable, \u0027close\u0027, None)"},{"line_number":81,"context_line":"                if callable(close_method):"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_707228af","line":78,"updated":"2015-09-28 15:21:06.000000000","message":"We can remove the except part and just have try and finally I suppose","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":75,"context_line":"                    chunk \u003d iterator.next()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"            except StopIteration:"},{"line_number":78,"context_line":"                pass"},{"line_number":79,"context_line":"            finally:"},{"line_number":80,"context_line":"                close_method \u003d getattr(iterable, \u0027close\u0027, None)"},{"line_number":81,"context_line":"                if callable(close_method):"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_2dae32e6","line":78,"in_reply_to":"9a1a9d01_0c684c86","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"5a0add9c9cd040269745666d6a07803a55e1b126","unresolved":false,"context_lines":[{"line_number":75,"context_line":"                    chunk \u003d iterator.next()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"            except StopIteration:"},{"line_number":78,"context_line":"                pass"},{"line_number":79,"context_line":"            finally:"},{"line_number":80,"context_line":"                close_method \u003d getattr(iterable, \u0027close\u0027, None)"},{"line_number":81,"context_line":"                if callable(close_method):"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_5345ae6d","line":78,"in_reply_to":"9a1a9d01_10288ce1","updated":"2015-09-28 15:53:46.000000000","message":"the above try block will never hit \"StopIteration\" from what I see.\n\nAnd no python expert either, but yes a try and finally can exist w/o except. I do know that :)","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"ac3e554b98fefa4d7f5bf0ace1131f2592bac6ce","unresolved":false,"context_lines":[{"line_number":75,"context_line":"                    chunk \u003d iterator.next()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"            except StopIteration:"},{"line_number":78,"context_line":"                pass"},{"line_number":79,"context_line":"            finally:"},{"line_number":80,"context_line":"                close_method \u003d getattr(iterable, \u0027close\u0027, None)"},{"line_number":81,"context_line":"                if callable(close_method):"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_76ba2070","line":78,"in_reply_to":"9a1a9d01_5345ae6d","updated":"2015-09-28 16:07:56.000000000","message":"Ah if no \u0027stopiteration\u0027 can be hit, go for it : ), not sure that\u0027s the case though.\n\nOh no no, I wasn\u0027t saying \u0027try and finally without an exception cannot exist, rather, if \u0027stop iteration\u0027 can indeed be thrown, and we want to catch it, it makes sense that the code has the \u0027except StopIteration: pass\u0027 logic.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"079549c303e0fc6c0d8cd88acc49a258960fe397","unresolved":false,"context_lines":[{"line_number":75,"context_line":"                    chunk \u003d iterator.next()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"            except StopIteration:"},{"line_number":78,"context_line":"                pass"},{"line_number":79,"context_line":"            finally:"},{"line_number":80,"context_line":"                close_method \u003d getattr(iterable, \u0027close\u0027, None)"},{"line_number":81,"context_line":"                if callable(close_method):"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_10288ce1","line":78,"in_reply_to":"9a1a9d01_707228af","updated":"2015-09-28 15:29:17.000000000","message":"hmm, no python expert here but I don\u0027t think so : )  The problem is in that case we\u0027d end up throwing StopIteration (passing it up), this way above we catch it so it doesn\u0027t get thrown further .. I think .. : )","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":75,"context_line":"                    chunk \u003d iterator.next()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"            except StopIteration:"},{"line_number":78,"context_line":"                pass"},{"line_number":79,"context_line":"            finally:"},{"line_number":80,"context_line":"                close_method \u003d getattr(iterable, \u0027close\u0027, None)"},{"line_number":81,"context_line":"                if callable(close_method):"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_0c684c86","line":78,"in_reply_to":"9a1a9d01_7661bb38","updated":"2015-09-29 13:39:21.000000000","message":"We could give this a try.  I had just looked for what another class was doing for streaming the response.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5869c613d2e7facdee98c473341fcfe40757b943","unresolved":false,"context_lines":[{"line_number":75,"context_line":"                    chunk \u003d iterator.next()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"            except StopIteration:"},{"line_number":78,"context_line":"                pass"},{"line_number":79,"context_line":"            finally:"},{"line_number":80,"context_line":"                close_method \u003d getattr(iterable, \u0027close\u0027, None)"},{"line_number":81,"context_line":"                if callable(close_method):"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_7661bb38","line":78,"in_reply_to":"9a1a9d01_76ba2070","updated":"2015-09-29 01:11:06.000000000","message":"Are we sure StopIteration will never get raised? I guess it\u0027d be OK to let it bubble up (the generator is going to raise it shortly anyway), but all of this just makes me wonder why we\u0027re managing the iterator ourselves.\n\nAlso, what if app_resp has an empty string mid-stream? Is it intentional that we only process up to the first empty string?\n\nAnd are we ever using bytes_processed?\n\nHow about doing something like this:\n\n    from swift.common.utils import closing_if_possible\n    ...\n    def iter_response(iterable, crypto_ctxt):\n        with closing_if_possible(iterable):\n            for chunk in iterable:\n                yield crypto_ctxt.update(chunk)","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"1e864596fc5653a23b44ecda578caa0fc7253452","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        except StopEncryption:"},{"line_number":96,"context_line":"            # continue to call start_response and return"},{"line_number":97,"context_line":"            pass"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"        # Only proceed processing if an error has not occurred"},{"line_number":100,"context_line":"        if self._response_status:"},{"line_number":101,"context_line":"            resp_int \u003d int(self._response_status[:3])"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_0512f1b4","line":98,"updated":"2015-09-24 19:31:51.000000000","message":"Similar comment to above, need to explain why we process resp_headers first.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5869c613d2e7facdee98c473341fcfe40757b943","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        except StopEncryption:"},{"line_number":96,"context_line":"            # continue to call start_response and return"},{"line_number":97,"context_line":"            pass"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"        # Only proceed processing if an error has not occurred"},{"line_number":100,"context_line":"        if self._response_status:"},{"line_number":101,"context_line":"            resp_int \u003d int(self._response_status[:3])"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_6c61ec38","line":98,"in_reply_to":"9a1a9d01_0512f1b4","updated":"2015-09-29 01:11:06.000000000","message":"Do we even need to check self._response_status here? Either way, it looks like we do\n\n    start_response(self._response_status,\n                   resp_headers,\n                   self._response_exc_info)\n    return app_resp\n\n...and we just rely on process_resp_headers raising StopEncryption above to ensure resp_headers has the headers we want.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        except StopEncryption:"},{"line_number":96,"context_line":"            # continue to call start_response and return"},{"line_number":97,"context_line":"            pass"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"        # Only proceed processing if an error has not occurred"},{"line_number":100,"context_line":"        if self._response_status:"},{"line_number":101,"context_line":"            resp_int \u003d int(self._response_status[:3])"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_5ef57354","line":98,"in_reply_to":"9a1a9d01_4cce4483","updated":"2015-09-30 15:37:19.000000000","message":"I moved the check like Hamdi suggested.  I looked at later reviews, and there is not something more done here.  But, the reason for the \u0027pass\u0027 is so that the decrypter will not throw an exception for the cases where the object is not encrypted (That is what StopEncryption means most of the time - it says the method detected that encryption activities should stop).","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        except StopEncryption:"},{"line_number":96,"context_line":"            # continue to call start_response and return"},{"line_number":97,"context_line":"            pass"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"        # Only proceed processing if an error has not occurred"},{"line_number":100,"context_line":"        if self._response_status:"},{"line_number":101,"context_line":"            resp_int \u003d int(self._response_status[:3])"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_4cce4483","line":98,"in_reply_to":"9a1a9d01_6c61ec38","updated":"2015-09-29 13:39:21.000000000","message":"I believe that there is more done afterward in later reviews.  We could change for just this version, but then add the check back for the other reviews.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"1e864596fc5653a23b44ecda578caa0fc7253452","unresolved":false,"context_lines":[{"line_number":113,"context_line":""},{"line_number":114,"context_line":"        # Check for the override now that keymaster has run"},{"line_number":115,"context_line":"        if config_true_value(req.environ.get(\u0027swift.crypto.override\u0027)):"},{"line_number":116,"context_line":"            self.logger.debug(\u0027No decryption is necessary because of override\u0027)"},{"line_number":117,"context_line":"            raise StopEncryption(\"swift.crypto.override override is set\")"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"        # Get \u0027X-Object-Sysmeta-Crypto-Meta\u0027"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_0a82fe52","line":116,"updated":"2015-09-24 19:31:51.000000000","message":"NIT - I think I\u0027d delete this comment, not a big deal for the trivial keymaster but for anything else (where there is policy / account based crypto) we\u0027d be logging this often and it\u0027s not of much value ?  Maybe for debug it doesn\u0027t matter.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":113,"context_line":""},{"line_number":114,"context_line":"        # Check for the override now that keymaster has run"},{"line_number":115,"context_line":"        if config_true_value(req.environ.get(\u0027swift.crypto.override\u0027)):"},{"line_number":116,"context_line":"            self.logger.debug(\u0027No decryption is necessary because of override\u0027)"},{"line_number":117,"context_line":"            raise StopEncryption(\"swift.crypto.override override is set\")"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"        # Get \u0027X-Object-Sysmeta-Crypto-Meta\u0027"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_2c98b077","line":116,"in_reply_to":"9a1a9d01_0a82fe52","updated":"2015-09-29 13:39:21.000000000","message":"I could change the comment or move it.  The purpose was to explain why we can\u0027t make this check upfront in the __call__ method like we can for the encrypter.  It is because the keymaster won\u0027t run before the decrypter on the \"way in\".  So it has to wait until it is intercepting a response on the \"way out\".","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":113,"context_line":""},{"line_number":114,"context_line":"        # Check for the override now that keymaster has run"},{"line_number":115,"context_line":"        if config_true_value(req.environ.get(\u0027swift.crypto.override\u0027)):"},{"line_number":116,"context_line":"            self.logger.debug(\u0027No decryption is necessary because of override\u0027)"},{"line_number":117,"context_line":"            raise StopEncryption(\"swift.crypto.override override is set\")"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"        # Get \u0027X-Object-Sysmeta-Crypto-Meta\u0027"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_b424ebc4","line":116,"in_reply_to":"9a1a9d01_2c98b077","updated":"2015-09-30 15:37:19.000000000","message":"Actually, I just decided to remove the comment as suggested.  The log is at debug level, so I thought it would be good to keep in.  Especially in the beginning when the override flag might get set mistakenly.  Maybe when things are more stable, we won\u0027t need this debug line.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"1e864596fc5653a23b44ecda578caa0fc7253452","unresolved":false,"context_lines":[{"line_number":127,"context_line":"        body_iv \u003d body_crypto_meta.get(\u0027iv\u0027)"},{"line_number":128,"context_line":"        body_cipher \u003d body_crypto_meta.get(\u0027cipher\u0027)"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"        if body_cipher !\u003d self.crypto.get_cipher():"},{"line_number":131,"context_line":"            raise EncryptionException("},{"line_number":132,"context_line":"                \"Encrypted with cipher %s, but can only decrypt with cipher %s\""},{"line_number":133,"context_line":"                % (body_cipher, self.crypto.get_cipher()))"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_6abb7a0f","line":130,"updated":"2015-09-24 19:31:51.000000000","message":"Really minor but if we ever support multiple cipher algo\u0027s (e.g. CTR / ECB) we don\u0027t really have a need for this as the crypto engine will support all, I guess we can make this check it matches one of the crypto engine\u0027s supported methods .. yea that makes sense.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"1e864596fc5653a23b44ecda578caa0fc7253452","unresolved":false,"context_lines":[{"line_number":143,"context_line":""},{"line_number":144,"context_line":"        self.body_crypto_ctxt \u003d self.crypto.create_decryption_ctxt("},{"line_number":145,"context_line":"            keys[\u0027object\u0027], body_iv, offset)"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"        # This is setup to do more header modifications in a later version"},{"line_number":148,"context_line":"        mod_hdr_pairs \u003d []"},{"line_number":149,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_25793594","line":146,"updated":"2015-09-24 19:31:51.000000000","message":"Let\u0027s add a comment describing what we are doing below, namely:  We want to strip out certain headers from the _response_headers and replace them with the correct version e.g. the etag.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":143,"context_line":""},{"line_number":144,"context_line":"        self.body_crypto_ctxt \u003d self.crypto.create_decryption_ctxt("},{"line_number":145,"context_line":"            keys[\u0027object\u0027], body_iv, offset)"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"        # This is setup to do more header modifications in a later version"},{"line_number":148,"context_line":"        mod_hdr_pairs \u003d []"},{"line_number":149,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_b7394dd9","line":146,"in_reply_to":"9a1a9d01_25793594","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"1e864596fc5653a23b44ecda578caa0fc7253452","unresolved":false,"context_lines":[{"line_number":144,"context_line":"        self.body_crypto_ctxt \u003d self.crypto.create_decryption_ctxt("},{"line_number":145,"context_line":"            keys[\u0027object\u0027], body_iv, offset)"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"        # This is setup to do more header modifications in a later version"},{"line_number":148,"context_line":"        mod_hdr_pairs \u003d []"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"        hkey \u003d \u0027Etag\u0027"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_8ace0e82","line":147,"updated":"2015-09-24 19:31:51.000000000","message":"Delete this comment we are indeed using it in this version.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":144,"context_line":"        self.body_crypto_ctxt \u003d self.crypto.create_decryption_ctxt("},{"line_number":145,"context_line":"            keys[\u0027object\u0027], body_iv, offset)"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"        # This is setup to do more header modifications in a later version"},{"line_number":148,"context_line":"        mod_hdr_pairs \u003d []"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"        hkey \u003d \u0027Etag\u0027"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_573231f3","line":147,"in_reply_to":"9a1a9d01_8ace0e82","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"1e864596fc5653a23b44ecda578caa0fc7253452","unresolved":false,"context_lines":[{"line_number":148,"context_line":"        mod_hdr_pairs \u003d []"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"        hkey \u003d \u0027Etag\u0027"},{"line_number":151,"context_line":"        etag \u003d self._response_header_value(\u0027X-Object-Sysmeta-Crypto-Etag\u0027)"},{"line_number":152,"context_line":"        mod_hdr_pairs.append((hkey, etag))"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"        mod_hdr_keys \u003d []"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_eae1caff","line":151,"updated":"2015-09-24 19:31:51.000000000","message":"NIT - maybe use etagKey and etagVal here for clarity.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":148,"context_line":"        mod_hdr_pairs \u003d []"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"        hkey \u003d \u0027Etag\u0027"},{"line_number":151,"context_line":"        etag \u003d self._response_header_value(\u0027X-Object-Sysmeta-Crypto-Etag\u0027)"},{"line_number":152,"context_line":"        mod_hdr_pairs.append((hkey, etag))"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"        mod_hdr_keys \u003d []"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_2c051045","line":151,"in_reply_to":"9a1a9d01_eae1caff","updated":"2015-09-29 13:39:21.000000000","message":"later when more items are added, I find it easier to keep with using hkey for header keys in general.  but i will take a look.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"1e864596fc5653a23b44ecda578caa0fc7253452","unresolved":false,"context_lines":[{"line_number":151,"context_line":"        etag \u003d self._response_header_value(\u0027X-Object-Sysmeta-Crypto-Etag\u0027)"},{"line_number":152,"context_line":"        mod_hdr_pairs.append((hkey, etag))"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"        mod_hdr_keys \u003d []"},{"line_number":155,"context_line":"        for h, v in mod_hdr_pairs:"},{"line_number":156,"context_line":"            mod_hdr_keys.append(h.lower())"},{"line_number":157,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_6a905aed","line":154,"updated":"2015-09-24 19:31:51.000000000","message":"Can we just use a list comprehension here directly (as is done below), like this:\n\nmod_hdr_keys \u003d [ (h.lower()) for h,v in mod_hdr_pair]","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":151,"context_line":"        etag \u003d self._response_header_value(\u0027X-Object-Sysmeta-Crypto-Etag\u0027)"},{"line_number":152,"context_line":"        mod_hdr_pairs.append((hkey, etag))"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"        mod_hdr_keys \u003d []"},{"line_number":155,"context_line":"        for h, v in mod_hdr_pairs:"},{"line_number":156,"context_line":"            mod_hdr_keys.append(h.lower())"},{"line_number":157,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_772f3588","line":154,"in_reply_to":"9a1a9d01_0c8feccc","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":151,"context_line":"        etag \u003d self._response_header_value(\u0027X-Object-Sysmeta-Crypto-Etag\u0027)"},{"line_number":152,"context_line":"        mod_hdr_pairs.append((hkey, etag))"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"        mod_hdr_keys \u003d []"},{"line_number":155,"context_line":"        for h, v in mod_hdr_pairs:"},{"line_number":156,"context_line":"            mod_hdr_keys.append(h.lower())"},{"line_number":157,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_0c8feccc","line":154,"in_reply_to":"9a1a9d01_6a905aed","updated":"2015-09-29 13:39:21.000000000","message":"ok, will do","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"1e864596fc5653a23b44ecda578caa0fc7253452","unresolved":false,"context_lines":[{"line_number":188,"context_line":""},{"line_number":189,"context_line":"class Decrypter(object):"},{"line_number":190,"context_line":"    \"\"\""},{"line_number":191,"context_line":"    Decryption middleware using AES in CTR mode with 256-bit keys"},{"line_number":192,"context_line":"    \"\"\""},{"line_number":193,"context_line":"    def __init__(self, app, conf):"},{"line_number":194,"context_line":"        self.app \u003d app"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_2f4fd493","line":191,"updated":"2015-09-24 19:31:51.000000000","message":"NIT - We shouldn\u0027t mention the crypto mode here in a comment because, who knows, that can change, and it\u0027s completely transparent to the decrypter in any case.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":188,"context_line":""},{"line_number":189,"context_line":"class Decrypter(object):"},{"line_number":190,"context_line":"    \"\"\""},{"line_number":191,"context_line":"    Decryption middleware using AES in CTR mode with 256-bit keys"},{"line_number":192,"context_line":"    \"\"\""},{"line_number":193,"context_line":"    def __init__(self, app, conf):"},{"line_number":194,"context_line":"        self.app \u003d app"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_eca87822","line":191,"in_reply_to":"9a1a9d01_2f4fd493","updated":"2015-09-29 13:39:21.000000000","message":"agreed","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":188,"context_line":""},{"line_number":189,"context_line":"class Decrypter(object):"},{"line_number":190,"context_line":"    \"\"\""},{"line_number":191,"context_line":"    Decryption middleware using AES in CTR mode with 256-bit keys"},{"line_number":192,"context_line":"    \"\"\""},{"line_number":193,"context_line":"    def __init__(self, app, conf):"},{"line_number":194,"context_line":"        self.app \u003d app"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_b7406d35","line":191,"in_reply_to":"9a1a9d01_eca87822","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"1e864596fc5653a23b44ecda578caa0fc7253452","unresolved":false,"context_lines":[{"line_number":201,"context_line":"        req \u003d Request(env)"},{"line_number":202,"context_line":"        try:"},{"line_number":203,"context_line":"            path_ver, path_acc, path_cont, path_obj \u003d \\"},{"line_number":204,"context_line":"                req.split_path(1, 4, True)"},{"line_number":205,"context_line":"        except ValueError:"},{"line_number":206,"context_line":"            return self.app(env, start_response)"},{"line_number":207,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_cf11785f","line":204,"updated":"2015-09-24 19:31:51.000000000","message":"Could we just look for 2,4 paths (i.e. given we don\u0027t care about the path_ver or account), actually in this patch set we would just look for 4, as all we care about is obj level crypto here.  We can let the exception handle the rest.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":201,"context_line":"        req \u003d Request(env)"},{"line_number":202,"context_line":"        try:"},{"line_number":203,"context_line":"            path_ver, path_acc, path_cont, path_obj \u003d \\"},{"line_number":204,"context_line":"                req.split_path(1, 4, True)"},{"line_number":205,"context_line":"        except ValueError:"},{"line_number":206,"context_line":"            return self.app(env, start_response)"},{"line_number":207,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_4da86220","line":204,"in_reply_to":"9a1a9d01_4c5e4445","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":201,"context_line":"        req \u003d Request(env)"},{"line_number":202,"context_line":"        try:"},{"line_number":203,"context_line":"            path_ver, path_acc, path_cont, path_obj \u003d \\"},{"line_number":204,"context_line":"                req.split_path(1, 4, True)"},{"line_number":205,"context_line":"        except ValueError:"},{"line_number":206,"context_line":"            return self.app(env, start_response)"},{"line_number":207,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_4c5e4445","line":204,"in_reply_to":"9a1a9d01_cf11785f","updated":"2015-09-29 13:39:21.000000000","message":"ok, will do","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"1e864596fc5653a23b44ecda578caa0fc7253452","unresolved":false,"context_lines":[{"line_number":206,"context_line":"            return self.app(env, start_response)"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"        try:"},{"line_number":209,"context_line":"            if path_acc and path_cont and path_obj:"},{"line_number":210,"context_line":"                obj_context \u003d DecrypterObjContext(self, self.logger)"},{"line_number":211,"context_line":"                if req.method \u003d\u003d \"GET\":"},{"line_number":212,"context_line":"                    return obj_context.handle_get(req, start_response)"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_aa3e72b6","line":209,"updated":"2015-09-24 19:31:51.000000000","message":"We can take an approach similar to the trivial_keymaster instead now ?  That is have DecrypterObjContext implement a GET and HEAD function directly and then just refer to that here ?\ni.e. https://github.com/openstack/swift/blob/feature/crypto/swift/common/middleware/trivial_keymaster.py#L94","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":206,"context_line":"            return self.app(env, start_response)"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"        try:"},{"line_number":209,"context_line":"            if path_acc and path_cont and path_obj:"},{"line_number":210,"context_line":"                obj_context \u003d DecrypterObjContext(self, self.logger)"},{"line_number":211,"context_line":"                if req.method \u003d\u003d \"GET\":"},{"line_number":212,"context_line":"                    return obj_context.handle_get(req, start_response)"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_cc1fb46a","line":209,"in_reply_to":"9a1a9d01_aa3e72b6","updated":"2015-09-29 13:39:21.000000000","message":"yes, will do.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":206,"context_line":"            return self.app(env, start_response)"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"        try:"},{"line_number":209,"context_line":"            if path_acc and path_cont and path_obj:"},{"line_number":210,"context_line":"                obj_context \u003d DecrypterObjContext(self, self.logger)"},{"line_number":211,"context_line":"                if req.method \u003d\u003d \"GET\":"},{"line_number":212,"context_line":"                    return obj_context.handle_get(req, start_response)"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_6da52645","line":209,"in_reply_to":"9a1a9d01_cc1fb46a","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"62a2f1c55ef6300f735f28e40bfa095976c3aadb","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        except EncryptionException as err:"},{"line_number":49,"context_line":"            self.logger.error(\u0027Could not process headers for obj get: %s\u0027 %"},{"line_number":50,"context_line":"                              str(err))"},{"line_number":51,"context_line":"            return HTTPInternalServerError(body\u003dstr(err),"},{"line_number":52,"context_line":"                                           content_type\u003d\u0027text/plain\u0027)"},{"line_number":53,"context_line":"        except StopEncryption:"},{"line_number":54,"context_line":"            start_response(self._response_status, self._response_headers,"}],"source_content_type":"text/x-python","patch_set":17,"id":"5a2ca52d_7862f03f","line":51,"updated":"2015-10-15 20:10:12.000000000","message":"should be raise not return","commit_id":"3fcfef319fbcae875af6fd29798e16a9317efb07"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"62a2f1c55ef6300f735f28e40bfa095976c3aadb","unresolved":false,"context_lines":[{"line_number":70,"context_line":""},{"line_number":71,"context_line":"        return iter_response(app_resp, self.body_crypto_ctxt)"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    def HEAD(self, req, start_response):"},{"line_number":74,"context_line":"        app_resp \u003d self._app_call(req.environ)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"        # Only proceed processing if an error has not occurred"}],"source_content_type":"text/x-python","patch_set":17,"id":"5a2ca52d_8e89ca77","line":73,"updated":"2015-10-15 20:10:12.000000000","message":"code here that can be shared with the GET path","commit_id":"3fcfef319fbcae875af6fd29798e16a9317efb07"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"62a2f1c55ef6300f735f28e40bfa095976c3aadb","unresolved":false,"context_lines":[{"line_number":99,"context_line":"    def process_resp_headers(self, req):"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"        if config_true_value(req.environ.get(\u0027swift.crypto.override\u0027)):"},{"line_number":102,"context_line":"            self.logger.debug(\u0027No decryption is necessary because of override\u0027)"},{"line_number":103,"context_line":"            raise StopEncryption(\"swift.crypto.override override is set\")"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"        # Get \u0027X-Object-Sysmeta-Crypto-Meta\u0027"}],"source_content_type":"text/x-python","patch_set":17,"id":"5a2ca52d_d4dd1ae1","line":102,"updated":"2015-10-15 20:10:12.000000000","message":"no equivalent debug log in encrypter","commit_id":"3fcfef319fbcae875af6fd29798e16a9317efb07"}],"swift/common/middleware/encrypter.py":[{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"5e20504398ea613bac9ecff0e6820d2c30d0668b","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    # TODO - remove the use of fake_footers when the real solution is there"},{"line_number":34,"context_line":"    def footers_callback(self, footers):"},{"line_number":35,"context_line":"        for footer in self.footers_to_add:"},{"line_number":36,"context_line":"            footers.update("},{"line_number":37,"context_line":"                {footer: self.footers_to_add[footer]})"},{"line_number":38,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3a50d1a3_9083d902","line":35,"updated":"2015-07-29 05:57:16.000000000","message":"May be clearer to replace \u0027footer\u0027 with \u0027key\u0027 here.","commit_id":"496b08e39658260a089cda3ebf6a6dc080938f6d"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"7675fb3549f8fa28d3105e529e3645a9c37de1f8","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    # TODO - remove the use of fake_footers when the real solution is there"},{"line_number":34,"context_line":"    def footers_callback(self, footers):"},{"line_number":35,"context_line":"        for footer in self.footers_to_add:"},{"line_number":36,"context_line":"            footers.update("},{"line_number":37,"context_line":"                {footer: self.footers_to_add[footer]})"},{"line_number":38,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3a50d1a3_20c9a9ac","line":35,"in_reply_to":"3a50d1a3_9083d902","updated":"2015-08-01 22:07:20.000000000","message":"done","commit_id":"496b08e39658260a089cda3ebf6a6dc080938f6d"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"5e20504398ea613bac9ecff0e6820d2c30d0668b","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        # over the value with the plaintext version"},{"line_number":72,"context_line":"        mod_resp_headers \u003d self._response_headers"},{"line_number":73,"context_line":"        if self._response_header_value(\u0027etag\u0027) and \\"},{"line_number":74,"context_line":"                (\u0027swift.crypto.etag\u0027 in req.environ):"},{"line_number":75,"context_line":"            mod_resp_headers \u003d ["},{"line_number":76,"context_line":"                (h, v) for h, v in self._response_headers"},{"line_number":77,"context_line":"                if h.lower() !\u003d \u0027etag\u0027]"}],"source_content_type":"text/x-python","patch_set":5,"id":"3a50d1a3_90e8b9b4","line":74,"updated":"2015-07-29 05:57:16.000000000","message":"Generic comment;  I\u0027ve seen this repeated in various pieces of middleware (i.e. removing a key/value pair as to replace it with a new value), wonder if its worthwhile to create a generic wrapper that can be used to do this going forward.","commit_id":"496b08e39658260a089cda3ebf6a6dc080938f6d"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"7675fb3549f8fa28d3105e529e3645a9c37de1f8","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        # over the value with the plaintext version"},{"line_number":72,"context_line":"        mod_resp_headers \u003d self._response_headers"},{"line_number":73,"context_line":"        if self._response_header_value(\u0027etag\u0027) and \\"},{"line_number":74,"context_line":"                (\u0027swift.crypto.etag\u0027 in req.environ):"},{"line_number":75,"context_line":"            mod_resp_headers \u003d ["},{"line_number":76,"context_line":"                (h, v) for h, v in self._response_headers"},{"line_number":77,"context_line":"                if h.lower() !\u003d \u0027etag\u0027]"}],"source_content_type":"text/x-python","patch_set":5,"id":"3a50d1a3_20dc4945","line":74,"in_reply_to":"3a50d1a3_90e8b9b4","updated":"2015-08-01 22:07:20.000000000","message":"sounds good.  I will put it on my \"todo\" list :-)","commit_id":"496b08e39658260a089cda3ebf6a6dc080938f6d"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"5e20504398ea613bac9ecff0e6820d2c30d0668b","unresolved":false,"context_lines":[{"line_number":128,"context_line":"    return Crypto(conf)"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"class EncInputProxy(object):"},{"line_number":132,"context_line":"    \"\"\""},{"line_number":133,"context_line":"    File-like object"},{"line_number":134,"context_line":"    to be swapped in for wsgi.input."}],"source_content_type":"text/x-python","patch_set":5,"id":"3a50d1a3_70a3ad00","line":131,"updated":"2015-07-29 05:57:16.000000000","message":"I don\u0027t find this name is very clear; Maybe, EncrObjWrapper or maybe to leave it generic EncrInputWrapper ?","commit_id":"496b08e39658260a089cda3ebf6a6dc080938f6d"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"7675fb3549f8fa28d3105e529e3645a9c37de1f8","unresolved":false,"context_lines":[{"line_number":128,"context_line":"    return Crypto(conf)"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"class EncInputProxy(object):"},{"line_number":132,"context_line":"    \"\"\""},{"line_number":133,"context_line":"    File-like object"},{"line_number":134,"context_line":"    to be swapped in for wsgi.input."}],"source_content_type":"text/x-python","patch_set":5,"id":"3a50d1a3_40df153a","line":131,"in_reply_to":"3a50d1a3_70a3ad00","updated":"2015-08-01 22:07:20.000000000","message":"changed","commit_id":"496b08e39658260a089cda3ebf6a6dc080938f6d"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"5e20504398ea613bac9ecff0e6820d2c30d0668b","unresolved":false,"context_lines":[{"line_number":171,"context_line":"                if self.plaintext_etag !\u003d self.client_etag:"},{"line_number":172,"context_line":"                    raise HTTPUnprocessableEntity(request\u003dRequest(self.env))"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"                self.footers_to_add[\u0027Etag\u0027] \u003d self.ciphertext_etag.hexdigest()"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"            # This crypto-etag will be encrypted in a later version"},{"line_number":177,"context_line":"            self.footers_to_add[\u0027X-Object-Sysmeta-Crypto-Etag\u0027] \u003d \\"}],"source_content_type":"text/x-python","patch_set":5,"id":"3a50d1a3_5070f171","line":174,"updated":"2015-07-29 05:57:16.000000000","message":"Should we not always add the cipher txt etag as a footer later regardless if the client supplies an etag ?","commit_id":"496b08e39658260a089cda3ebf6a6dc080938f6d"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"7675fb3549f8fa28d3105e529e3645a9c37de1f8","unresolved":false,"context_lines":[{"line_number":171,"context_line":"                if self.plaintext_etag !\u003d self.client_etag:"},{"line_number":172,"context_line":"                    raise HTTPUnprocessableEntity(request\u003dRequest(self.env))"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"                self.footers_to_add[\u0027Etag\u0027] \u003d self.ciphertext_etag.hexdigest()"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"            # This crypto-etag will be encrypted in a later version"},{"line_number":177,"context_line":"            self.footers_to_add[\u0027X-Object-Sysmeta-Crypto-Etag\u0027] \u003d \\"}],"source_content_type":"text/x-python","patch_set":5,"id":"3a50d1a3_a0acd98c","line":174,"in_reply_to":"3a50d1a3_5070f171","updated":"2015-08-01 22:07:20.000000000","message":"The client doesn\u0027t always supply the Etag.  The purpose of the footer is to be able to override the \"client-supplied\" plaintext Etag associated to the request with the ciphertext etag so they will match.  It would change the response behavior if we added the client Etag to the request when it wasn\u0027t in the original request.  The object server will calculate the ciphertext etag itself when the client request does not include this header.\n\nacoles: please chime in and correct me if I am wrong :-)\n\nNote that there is a backend etag and a Crypto etag that gets set also.","commit_id":"496b08e39658260a089cda3ebf6a6dc080938f6d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e2fed5c89a890ebc4646d8d7f4f2a9bd43f72f19","unresolved":false,"context_lines":[{"line_number":13,"context_line":"# See the License for the specific language governing permissions and"},{"line_number":14,"context_line":"# limitations under the License."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"from swift.common.utils import get_logger, config_true_value"},{"line_number":17,"context_line":"from swift.common.swob import Request, HTTPException, HTTPUnprocessableEntity"},{"line_number":18,"context_line":"from swift.common.middleware.crypto import Crypto"},{"line_number":19,"context_line":"from swift.common.wsgi import WSGIContext"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_751b231c","line":16,"updated":"2015-08-04 17:11:37.000000000","message":"nit: one day someone (pep8 maybe) is going to moan that the swift imports should come after the builtin lib imports","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3b95d640ad057703b574028089ff89ed5be946db","unresolved":false,"context_lines":[{"line_number":13,"context_line":"# See the License for the specific language governing permissions and"},{"line_number":14,"context_line":"# limitations under the License."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"from swift.common.utils import get_logger, config_true_value"},{"line_number":17,"context_line":"from swift.common.swob import Request, HTTPException, HTTPUnprocessableEntity"},{"line_number":18,"context_line":"from swift.common.middleware.crypto import Crypto"},{"line_number":19,"context_line":"from swift.common.wsgi import WSGIContext"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_a65c0c7e","line":16,"in_reply_to":"1a4dcd0f_751b231c","updated":"2015-08-17 19:07:32.000000000","message":"done in encrypter/decrypter and there unit tests.   will get keymaster and crypto in the next patches on those reviews.","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e2fed5c89a890ebc4646d8d7f4f2a9bd43f72f19","unresolved":false,"context_lines":[{"line_number":26,"context_line":"    def __init__(self, encrypter):"},{"line_number":27,"context_line":"        super(EncrypterObjContext, self).__init__(encrypter.app)"},{"line_number":28,"context_line":"        self.encrypter \u003d encrypter"},{"line_number":29,"context_line":"        self.logger \u003d encrypter.logger"},{"line_number":30,"context_line":"        self.footers_to_add \u003d {}"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    # TODO - remove the use of fake_footers when the real solution is there"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_ed0c5196","line":29,"updated":"2015-08-04 17:11:37.000000000","message":"nit: maybe pass logger as an arg  to __init__ (that could prove useful for setting a FakeLogger during testing)","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3b95d640ad057703b574028089ff89ed5be946db","unresolved":false,"context_lines":[{"line_number":26,"context_line":"    def __init__(self, encrypter):"},{"line_number":27,"context_line":"        super(EncrypterObjContext, self).__init__(encrypter.app)"},{"line_number":28,"context_line":"        self.encrypter \u003d encrypter"},{"line_number":29,"context_line":"        self.logger \u003d encrypter.logger"},{"line_number":30,"context_line":"        self.footers_to_add \u003d {}"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    # TODO - remove the use of fake_footers when the real solution is there"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_667284e5","line":29,"in_reply_to":"1a4dcd0f_ed0c5196","updated":"2015-08-17 19:07:32.000000000","message":"now passing logger too in order to facilitate using FakeLogger. (note that encrypter is still needed for the __init__ part)","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e2fed5c89a890ebc4646d8d7f4f2a9bd43f72f19","unresolved":false,"context_lines":[{"line_number":29,"context_line":"        self.logger \u003d encrypter.logger"},{"line_number":30,"context_line":"        self.footers_to_add \u003d {}"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    # TODO - remove the use of fake_footers when the real solution is there"},{"line_number":33,"context_line":"    def footers_callback(self, footers):"},{"line_number":34,"context_line":"        for key in self.footers_to_add:"},{"line_number":35,"context_line":"            footers.update("}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_76a9f67a","line":32,"updated":"2015-08-04 17:11:37.000000000","message":"Just a passing comment - it may well be that a call back is still required - it will just get called by the object controller rather than FF middleware.","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3b95d640ad057703b574028089ff89ed5be946db","unresolved":false,"context_lines":[{"line_number":29,"context_line":"        self.logger \u003d encrypter.logger"},{"line_number":30,"context_line":"        self.footers_to_add \u003d {}"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    # TODO - remove the use of fake_footers when the real solution is there"},{"line_number":33,"context_line":"    def footers_callback(self, footers):"},{"line_number":34,"context_line":"        for key in self.footers_to_add:"},{"line_number":35,"context_line":"            footers.update("}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_c6491890","line":32,"in_reply_to":"1a4dcd0f_76a9f67a","updated":"2015-08-17 19:07:32.000000000","message":"removed comment.  my real footers support does still use a callback :-)","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e2fed5c89a890ebc4646d8d7f4f2a9bd43f72f19","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        # over the value with the plaintext version"},{"line_number":72,"context_line":"        mod_resp_headers \u003d self._response_headers"},{"line_number":73,"context_line":"        if self._response_header_value(\u0027etag\u0027) and \\"},{"line_number":74,"context_line":"                (\u0027swift.crypto.etag\u0027 in req.environ):"},{"line_number":75,"context_line":"            mod_resp_headers \u003d ["},{"line_number":76,"context_line":"                (h, v) for h, v in self._response_headers"},{"line_number":77,"context_line":"                if h.lower() !\u003d \u0027etag\u0027]"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_d5d9d784","line":74,"updated":"2015-08-04 17:11:37.000000000","message":"Can swift.crypto.etag ever not be in req.environ?\n\nSee comment line 167 - should we call something like a new enc_input_proxy.close() method after self._app_call(req.environ)???","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3b95d640ad057703b574028089ff89ed5be946db","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        # over the value with the plaintext version"},{"line_number":72,"context_line":"        mod_resp_headers \u003d self._response_headers"},{"line_number":73,"context_line":"        if self._response_header_value(\u0027etag\u0027) and \\"},{"line_number":74,"context_line":"                (\u0027swift.crypto.etag\u0027 in req.environ):"},{"line_number":75,"context_line":"            mod_resp_headers \u003d ["},{"line_number":76,"context_line":"                (h, v) for h, v in self._response_headers"},{"line_number":77,"context_line":"                if h.lower() !\u003d \u0027etag\u0027]"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_863a30e6","line":74,"in_reply_to":"1a4dcd0f_d5d9d784","updated":"2015-08-17 19:07:32.000000000","message":"removed check for etag","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e2fed5c89a890ebc4646d8d7f4f2a9bd43f72f19","unresolved":false,"context_lines":[{"line_number":92,"context_line":"        self.conf \u003d conf"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    def __call__(self, env, start_response):"},{"line_number":95,"context_line":"        self.crypto \u003d get_crypto(self.conf)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        req \u003d Request(env)"},{"line_number":98,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_67ab821e","line":95,"updated":"2015-08-04 17:11:37.000000000","message":"could this just be:\n\n  self.crypto \u003d Crypto(self.conf)","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3b95d640ad057703b574028089ff89ed5be946db","unresolved":false,"context_lines":[{"line_number":92,"context_line":"        self.conf \u003d conf"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    def __call__(self, env, start_response):"},{"line_number":95,"context_line":"        self.crypto \u003d get_crypto(self.conf)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        req \u003d Request(env)"},{"line_number":98,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_c617d852","line":95,"in_reply_to":"1a4dcd0f_67ab821e","updated":"2015-08-17 19:07:32.000000000","message":"this was done for the unit test that was using a mocked class.  Mahaitc loaded a patch to change unit tests.  We can remove this as part of that patch.  Will put a comment there.","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e2fed5c89a890ebc4646d8d7f4f2a9bd43f72f19","unresolved":false,"context_lines":[{"line_number":103,"context_line":""},{"line_number":104,"context_line":"        try:"},{"line_number":105,"context_line":"            # If override is set in env, then just pass along"},{"line_number":106,"context_line":"            # If not PUT or POST, then just pass along"},{"line_number":107,"context_line":"            if config_true_value(env.get(\u0027swift.crypto.override\u0027)) or \\"},{"line_number":108,"context_line":"                    (req.method !\u003d \u0027PUT\u0027 and req.method !\u003d \u0027POST\u0027):"},{"line_number":109,"context_line":"                return self.app(env, start_response)"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_1990e342","line":106,"updated":"2015-08-04 17:11:37.000000000","message":"lets do this right at the start of the __call__ method. I don\u0027t *think* it needs to be in the try/except because app(env, response) shouldn\u0027t raise HTTPException (maybe check that with a wsgi guru!)","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3b95d640ad057703b574028089ff89ed5be946db","unresolved":false,"context_lines":[{"line_number":103,"context_line":""},{"line_number":104,"context_line":"        try:"},{"line_number":105,"context_line":"            # If override is set in env, then just pass along"},{"line_number":106,"context_line":"            # If not PUT or POST, then just pass along"},{"line_number":107,"context_line":"            if config_true_value(env.get(\u0027swift.crypto.override\u0027)) or \\"},{"line_number":108,"context_line":"                    (req.method !\u003d \u0027PUT\u0027 and req.method !\u003d \u0027POST\u0027):"},{"line_number":109,"context_line":"                return self.app(env, start_response)"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_d19a30c5","line":106,"in_reply_to":"1a4dcd0f_1990e342","updated":"2015-08-17 19:07:32.000000000","message":"moved to the start","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e2fed5c89a890ebc4646d8d7f4f2a9bd43f72f19","unresolved":false,"context_lines":[{"line_number":111,"context_line":"            if path_acc:"},{"line_number":112,"context_line":"                if path_cont and path_obj:"},{"line_number":113,"context_line":"                    # Object"},{"line_number":114,"context_line":"                    obj_context \u003d EncrypterObjContext(self)"},{"line_number":115,"context_line":"                    if req.method \u003d\u003d \"PUT\":"},{"line_number":116,"context_line":"                        return obj_context.handle_put(req, start_response)"},{"line_number":117,"context_line":"                    # else POST - will be in later version"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_22832858","line":114,"updated":"2015-08-04 17:11:37.000000000","message":"move obj_context constructor to after the if.\n\ni\u0027m guessing we may eventually end up with \n\n  if req.method in (\u0027PUT\u0027, \u0027POST\u0027):\n      EncrypterObjContext(self).handle_put(req, start_response)","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3b95d640ad057703b574028089ff89ed5be946db","unresolved":false,"context_lines":[{"line_number":111,"context_line":"            if path_acc:"},{"line_number":112,"context_line":"                if path_cont and path_obj:"},{"line_number":113,"context_line":"                    # Object"},{"line_number":114,"context_line":"                    obj_context \u003d EncrypterObjContext(self)"},{"line_number":115,"context_line":"                    if req.method \u003d\u003d \"PUT\":"},{"line_number":116,"context_line":"                        return obj_context.handle_put(req, start_response)"},{"line_number":117,"context_line":"                    # else POST - will be in later version"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_311594e4","line":114,"in_reply_to":"1a4dcd0f_22832858","updated":"2015-08-17 19:07:32.000000000","message":"which if?  The handle_put is only called for a PUT.  I think that it is best to perfect this method in the end of the crypto chain where each different request handling is represented.  Is that ok?","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e2fed5c89a890ebc4646d8d7f4f2a9bd43f72f19","unresolved":false,"context_lines":[{"line_number":124,"context_line":"        return self.app(env, start_response)"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"def get_crypto(conf):"},{"line_number":128,"context_line":"    return Crypto(conf)"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_67fdc239","line":127,"updated":"2015-08-04 17:11:37.000000000","message":"why the module level function - its only called once from inside Encrypter class?","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3b95d640ad057703b574028089ff89ed5be946db","unresolved":false,"context_lines":[{"line_number":124,"context_line":"        return self.app(env, start_response)"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"def get_crypto(conf):"},{"line_number":128,"context_line":"    return Crypto(conf)"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_31a83477","line":127,"in_reply_to":"1a4dcd0f_67fdc239","updated":"2015-08-17 19:07:32.000000000","message":"this will be removed with mahatic\u0027s change","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e2fed5c89a890ebc4646d8d7f4f2a9bd43f72f19","unresolved":false,"context_lines":[{"line_number":128,"context_line":"    return Crypto(conf)"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"class EncInputWrapper(object):"},{"line_number":132,"context_line":"    \"\"\""},{"line_number":133,"context_line":"    File-like object"},{"line_number":134,"context_line":"    to be swapped in for wsgi.input."}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_22d1e857","line":131,"updated":"2015-08-04 17:11:37.000000000","message":"very nit-picky:\n\ncould this class go to top of module so that as I work up the file I find classes in order they get used?","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3b95d640ad057703b574028089ff89ed5be946db","unresolved":false,"context_lines":[{"line_number":128,"context_line":"    return Crypto(conf)"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"class EncInputWrapper(object):"},{"line_number":132,"context_line":"    \"\"\""},{"line_number":133,"context_line":"    File-like object"},{"line_number":134,"context_line":"    to be swapped in for wsgi.input."}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_91afc87c","line":131,"in_reply_to":"1a4dcd0f_22d1e857","updated":"2015-08-17 19:07:32.000000000","message":"done","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e2fed5c89a890ebc4646d8d7f4f2a9bd43f72f19","unresolved":false,"context_lines":[{"line_number":133,"context_line":"    File-like object"},{"line_number":134,"context_line":"    to be swapped in for wsgi.input."},{"line_number":135,"context_line":"    \"\"\""},{"line_number":136,"context_line":"    def __init__(self, wsgi_input, crypto, keys, env, client_etag,"},{"line_number":137,"context_line":"                 crypto_meta, footers_to_add, logger):"},{"line_number":138,"context_line":"        self.wsgi_input \u003d wsgi_input"},{"line_number":139,"context_line":"        self.crypto \u003d crypto"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_d547971b","line":136,"updated":"2015-08-04 17:11:37.000000000","message":"nit: we have wsgi_input in the env so no need to pass explicitly?","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3b95d640ad057703b574028089ff89ed5be946db","unresolved":false,"context_lines":[{"line_number":133,"context_line":"    File-like object"},{"line_number":134,"context_line":"    to be swapped in for wsgi.input."},{"line_number":135,"context_line":"    \"\"\""},{"line_number":136,"context_line":"    def __init__(self, wsgi_input, crypto, keys, env, client_etag,"},{"line_number":137,"context_line":"                 crypto_meta, footers_to_add, logger):"},{"line_number":138,"context_line":"        self.wsgi_input \u003d wsgi_input"},{"line_number":139,"context_line":"        self.crypto \u003d crypto"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_71cc7c61","line":136,"in_reply_to":"1a4dcd0f_d547971b","updated":"2015-08-17 19:07:32.000000000","message":"removed the arg.","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e2fed5c89a890ebc4646d8d7f4f2a9bd43f72f19","unresolved":false,"context_lines":[{"line_number":164,"context_line":"            ciphertext \u003d self.crypto_ctxt.update(chunk)"},{"line_number":165,"context_line":"            self.ciphertext_etag.update(ciphertext)"},{"line_number":166,"context_line":"            return ciphertext"},{"line_number":167,"context_line":"        else:"},{"line_number":168,"context_line":"            self.plaintext_etag \u003d self.plaintext_etag.hexdigest()"},{"line_number":169,"context_line":"            # If client supplied etag,then validate while we have plaintext"},{"line_number":170,"context_line":"            if self.client_etag:"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_552aa77f","line":167,"updated":"2015-08-04 17:11:37.000000000","message":"hmmm, idk, is it possible that the caller of read() methods does not make the final call so we never reach the else condition?\n\nIf so, and we then get a call to footers_callback, should footers_callback call some kind of cleanup/close method in this class so that all the etags are calculated and set in footer_to_add?","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3b95d640ad057703b574028089ff89ed5be946db","unresolved":false,"context_lines":[{"line_number":164,"context_line":"            ciphertext \u003d self.crypto_ctxt.update(chunk)"},{"line_number":165,"context_line":"            self.ciphertext_etag.update(ciphertext)"},{"line_number":166,"context_line":"            return ciphertext"},{"line_number":167,"context_line":"        else:"},{"line_number":168,"context_line":"            self.plaintext_etag \u003d self.plaintext_etag.hexdigest()"},{"line_number":169,"context_line":"            # If client supplied etag,then validate while we have plaintext"},{"line_number":170,"context_line":"            if self.client_etag:"}],"source_content_type":"text/x-python","patch_set":6,"id":"fa1b9901_2f87c810","line":167,"in_reply_to":"1a4dcd0f_552aa77f","updated":"2015-08-17 19:07:32.000000000","message":"Can we add this with the review that includes the real footers support?  that way, we will know when the callback is invoked and exactly what it will do \"for real\".  I will add this to the trello card for real footers.","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e2fed5c89a890ebc4646d8d7f4f2a9bd43f72f19","unresolved":false,"context_lines":[{"line_number":178,"context_line":"                self.plaintext_etag"},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"            # This line will not be processed"},{"line_number":181,"context_line":"            # until the real support for footers is in place"},{"line_number":182,"context_line":"            self.footers_to_add[\u0027X-Backend-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":183,"context_line":"                self.plaintext_etag"},{"line_number":184,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_12ec358e","line":181,"updated":"2015-08-04 17:11:37.000000000","message":"comment confuses me - looks like the line is executed, which is ok imho\n\nor does comment mean the header will have no effect on object server yet?","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3b95d640ad057703b574028089ff89ed5be946db","unresolved":false,"context_lines":[{"line_number":178,"context_line":"                self.plaintext_etag"},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"            # This line will not be processed"},{"line_number":181,"context_line":"            # until the real support for footers is in place"},{"line_number":182,"context_line":"            self.footers_to_add[\u0027X-Backend-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":183,"context_line":"                self.plaintext_etag"},{"line_number":184,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_91fd8870","line":181,"in_reply_to":"1a4dcd0f_12ec358e","updated":"2015-08-17 19:07:32.000000000","message":"you are correct.  I removed the comment.","commit_id":"c7b1d4ad67f4e950afedbade34d31509350e50b1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5869c613d2e7facdee98c473341fcfe40757b943","unresolved":false,"context_lines":[{"line_number":106,"context_line":"        # set the crypto-meta associated to the obj body"},{"line_number":107,"context_line":"        # b64encode because of the iv/nonce"},{"line_number":108,"context_line":"        req.headers[\u0027X-Object-Sysmeta-Crypto-Meta\u0027] \u003d \\"},{"line_number":109,"context_line":"            base64.b64encode(str(body_crypto_meta))"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"        client_etag \u003d None"},{"line_number":112,"context_line":"        if \u0027etag\u0027 in req.headers:"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_6f647e21","line":109,"updated":"2015-09-29 01:11:06.000000000","message":"This feels like a surefire way to shoot ourselves in the foot later. Won\u0027t this hamper our ability to migrate clusters to Python3? Suddenly we\u0027ll find ourselves with Unicode codepoints instead of bytes for our IV.\n\nThe json module feels like a more natural fit than str\u0027ing a dict. We already use if to store arbitrary semi-structured data like SLO manifests or account ACLs. I get that we can\u0027t just use use it directly (we\u0027ll hit UnicodeDecodeErrors when trying to serialize the IV), but we\u0027re already using base64. So why not have something like\n\n    req.headers[\u0027X-Object-Sysmeta-Crypto-Meta\u0027] \u003d json.dumps({\n        key: (base64.b64encode(value) if key \u003d\u003d \u0027iv\u0027 else value)\n        for key, value in body_crypto_meta.items()})\n\nor just have the iv base64ed in general, and only decode when we need the actual bytes?","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":106,"context_line":"        # set the crypto-meta associated to the obj body"},{"line_number":107,"context_line":"        # b64encode because of the iv/nonce"},{"line_number":108,"context_line":"        req.headers[\u0027X-Object-Sysmeta-Crypto-Meta\u0027] \u003d \\"},{"line_number":109,"context_line":"            base64.b64encode(str(body_crypto_meta))"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"        client_etag \u003d None"},{"line_number":112,"context_line":"        if \u0027etag\u0027 in req.headers:"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_adefa21c","line":109,"in_reply_to":"9a1a9d01_27444b48","updated":"2015-09-30 15:37:19.000000000","message":"Hamdi will be uploading a patch to address this part","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":106,"context_line":"        # set the crypto-meta associated to the obj body"},{"line_number":107,"context_line":"        # b64encode because of the iv/nonce"},{"line_number":108,"context_line":"        req.headers[\u0027X-Object-Sysmeta-Crypto-Meta\u0027] \u003d \\"},{"line_number":109,"context_line":"            base64.b64encode(str(body_crypto_meta))"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"        client_etag \u003d None"},{"line_number":112,"context_line":"        if \u0027etag\u0027 in req.headers:"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_27444b48","line":109,"in_reply_to":"9a1a9d01_6f647e21","updated":"2015-09-29 13:39:21.000000000","message":"ok, I will look into this.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5869c613d2e7facdee98c473341fcfe40757b943","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        req.headers[\u0027X-Object-Sysmeta-Crypto-Meta\u0027] \u003d \\"},{"line_number":109,"context_line":"            base64.b64encode(str(body_crypto_meta))"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"        client_etag \u003d None"},{"line_number":112,"context_line":"        if \u0027etag\u0027 in req.headers:"},{"line_number":113,"context_line":"            # save-off in order to validate client etag when possible"},{"line_number":114,"context_line":"            client_etag \u003d req.headers[\u0027etag\u0027]"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_f6d05ef8","line":111,"updated":"2015-09-29 01:11:06.000000000","message":"How about\n\n    client_etag \u003d req.headers.pop(\u0027etag\u0027, None)","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        req.headers[\u0027X-Object-Sysmeta-Crypto-Meta\u0027] \u003d \\"},{"line_number":109,"context_line":"            base64.b64encode(str(body_crypto_meta))"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"        client_etag \u003d None"},{"line_number":112,"context_line":"        if \u0027etag\u0027 in req.headers:"},{"line_number":113,"context_line":"            # save-off in order to validate client etag when possible"},{"line_number":114,"context_line":"            client_etag \u003d req.headers[\u0027etag\u0027]"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_f2111305","line":111,"in_reply_to":"9a1a9d01_276bebb8","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        req.headers[\u0027X-Object-Sysmeta-Crypto-Meta\u0027] \u003d \\"},{"line_number":109,"context_line":"            base64.b64encode(str(body_crypto_meta))"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"        client_etag \u003d None"},{"line_number":112,"context_line":"        if \u0027etag\u0027 in req.headers:"},{"line_number":113,"context_line":"            # save-off in order to validate client etag when possible"},{"line_number":114,"context_line":"            client_etag \u003d req.headers[\u0027etag\u0027]"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_276bebb8","line":111,"in_reply_to":"9a1a9d01_f6d05ef8","updated":"2015-09-29 13:39:21.000000000","message":"will do","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"1e864596fc5653a23b44ecda578caa0fc7253452","unresolved":false,"context_lines":[{"line_number":148,"context_line":""},{"line_number":149,"context_line":"class Encrypter(object):"},{"line_number":150,"context_line":"    \"\"\""},{"line_number":151,"context_line":"    Encryption middleware using AES in CTR mode with 256-bit keys"},{"line_number":152,"context_line":"    \"\"\""},{"line_number":153,"context_line":"    def __init__(self, app, conf):"},{"line_number":154,"context_line":"        self.app \u003d app"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_45aa291b","line":151,"updated":"2015-09-24 19:31:51.000000000","message":"Don\u0027t refer to crypto algo as that can change and is transparent to the encrypter.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":148,"context_line":""},{"line_number":149,"context_line":"class Encrypter(object):"},{"line_number":150,"context_line":"    \"\"\""},{"line_number":151,"context_line":"    Encryption middleware using AES in CTR mode with 256-bit keys"},{"line_number":152,"context_line":"    \"\"\""},{"line_number":153,"context_line":"    def __init__(self, app, conf):"},{"line_number":154,"context_line":"        self.app \u003d app"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_a79dbbbd","line":151,"in_reply_to":"9a1a9d01_45aa291b","updated":"2015-09-29 13:39:21.000000000","message":"agreed.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":148,"context_line":""},{"line_number":149,"context_line":"class Encrypter(object):"},{"line_number":150,"context_line":"    \"\"\""},{"line_number":151,"context_line":"    Encryption middleware using AES in CTR mode with 256-bit keys"},{"line_number":152,"context_line":"    \"\"\""},{"line_number":153,"context_line":"    def __init__(self, app, conf):"},{"line_number":154,"context_line":"        self.app \u003d app"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_32330bad","line":151,"in_reply_to":"9a1a9d01_a79dbbbd","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"1e864596fc5653a23b44ecda578caa0fc7253452","unresolved":false,"context_lines":[{"line_number":176,"context_line":"                if path_cont and path_obj:"},{"line_number":177,"context_line":"                    # Object"},{"line_number":178,"context_line":"                    obj_context \u003d EncrypterObjContext(self, self.logger)"},{"line_number":179,"context_line":"                    if req.method \u003d\u003d \"PUT\":"},{"line_number":180,"context_line":"                        return obj_context.handle_put(req, start_response)"},{"line_number":181,"context_line":"                    # else POST - will be in later version"},{"line_number":182,"context_line":"                # else Account or Container - will be in later version"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_a55b0554","line":179,"updated":"2015-09-24 19:31:51.000000000","message":"Similar comment to decrypter i.e. we could just implement a PUT directly in EncrypterObjContext (as was done in the trivial_keymaster)","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":176,"context_line":"                if path_cont and path_obj:"},{"line_number":177,"context_line":"                    # Object"},{"line_number":178,"context_line":"                    obj_context \u003d EncrypterObjContext(self, self.logger)"},{"line_number":179,"context_line":"                    if req.method \u003d\u003d \"PUT\":"},{"line_number":180,"context_line":"                        return obj_context.handle_put(req, start_response)"},{"line_number":181,"context_line":"                    # else POST - will be in later version"},{"line_number":182,"context_line":"                # else Account or Container - will be in later version"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_72ec23f3","line":179,"in_reply_to":"9a1a9d01_87a8b7dc","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":176,"context_line":"                if path_cont and path_obj:"},{"line_number":177,"context_line":"                    # Object"},{"line_number":178,"context_line":"                    obj_context \u003d EncrypterObjContext(self, self.logger)"},{"line_number":179,"context_line":"                    if req.method \u003d\u003d \"PUT\":"},{"line_number":180,"context_line":"                        return obj_context.handle_put(req, start_response)"},{"line_number":181,"context_line":"                    # else POST - will be in later version"},{"line_number":182,"context_line":"                # else Account or Container - will be in later version"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_87a8b7dc","line":179,"in_reply_to":"9a1a9d01_a55b0554","updated":"2015-09-29 13:39:21.000000000","message":"agreed.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2813600e8fe532ad6deaad414c8afe9b80da59c5","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        req.headers[\u0027X-Object-Sysmeta-Crypto-Meta\u0027] \u003d \\"},{"line_number":109,"context_line":"            base64.b64encode(str(body_crypto_meta))"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"        client_etag \u003d None"},{"line_number":112,"context_line":"        if \u0027etag\u0027 in req.headers:"},{"line_number":113,"context_line":"            # save-off in order to validate client etag when possible"},{"line_number":114,"context_line":"            client_etag \u003d req.headers[\u0027etag\u0027]"}],"source_content_type":"text/x-python","patch_set":14,"id":"9a1a9d01_3331480c","line":111,"updated":"2015-10-02 22:09:26.000000000","message":"I\u0027d actually meant that in place of\n\n    client_etag \u003d None\n    if \u0027etag\u0027 in req.headers:\n        # save-off in order to validate client etag when possible\n        client_etag \u003d req.headers[\u0027etag\u0027]\n\n        # remove client etag that will not match encrypted data\n        self.logger.info(\"client supplied ETAG is being removed.\")\n        req.headers[\u0027etag\u0027] \u003d None\n\nwe could have\n\n    # save-off in order to validate client etag when possible\n    # but remove it so proxy/obj servers won\u0027t do that validation\n    client_etag \u003d req.headers.pop(\u0027etag\u0027, None)\n    if client_etag:\n        self.logger.info(\"client supplied ETAG is being removed.\")\n\nwhich would be functionally equivalent. Later, once we feel like all of this is settled and well-understood (so maybe we don\u0027t need quite as much logging), we could even drop the if block entirely.","commit_id":"1543128878e96b857bb812a6102bebc13986a5f8"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"159987afb53832c0a329c90c64728523476f53ec","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        req.headers[\u0027X-Object-Sysmeta-Crypto-Meta\u0027] \u003d \\"},{"line_number":109,"context_line":"            base64.b64encode(str(body_crypto_meta))"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"        client_etag \u003d None"},{"line_number":112,"context_line":"        if \u0027etag\u0027 in req.headers:"},{"line_number":113,"context_line":"            # save-off in order to validate client etag when possible"},{"line_number":114,"context_line":"            client_etag \u003d req.headers[\u0027etag\u0027]"}],"source_content_type":"text/x-python","patch_set":14,"id":"9a1a9d01_941b501c","line":111,"in_reply_to":"9a1a9d01_3331480c","updated":"2015-10-03 03:44:06.000000000","message":"I like this, cleaner.  Agreed about logging eventually as well (at the very least debug only).","commit_id":"1543128878e96b857bb812a6102bebc13986a5f8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"62a2f1c55ef6300f735f28e40bfa095976c3aadb","unresolved":false,"context_lines":[{"line_number":81,"context_line":""},{"line_number":82,"context_line":"            # Set the plaintext etag in the request env so that it can"},{"line_number":83,"context_line":"            # be set in the response headers before returned to the client"},{"line_number":84,"context_line":"            self.env[\u0027swift.crypto.etag\u0027] \u003d self.plaintext_etag"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"            return chunk"},{"line_number":87,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"5a2ca52d_b915f7e5","line":84,"updated":"2015-10-15 20:10:12.000000000","message":"don\u0027t need to put into req.env, the EncrypterObjContext has a ref to self so just get self.plaintext_etag","commit_id":"3fcfef319fbcae875af6fd29798e16a9317efb07"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"faba4e8a4b11b6fe521c040a47e80bbe71aad5de","unresolved":false,"context_lines":[{"line_number":81,"context_line":""},{"line_number":82,"context_line":"            # Set the plaintext etag in the request env so that it can"},{"line_number":83,"context_line":"            # be set in the response headers before returned to the client"},{"line_number":84,"context_line":"            self.env[\u0027swift.crypto.etag\u0027] \u003d self.plaintext_etag"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"            return chunk"},{"line_number":87,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"3a29b11f_9981694d","line":84,"in_reply_to":"5a2ca52d_b915f7e5","updated":"2015-10-20 01:06:51.000000000","message":"of course.  I guess I wasn\u0027t thinking about the fact that the same object instance was used on the return trip of the request, for some reason.  Just focused on putting things in the env or request, I guess ;-)","commit_id":"3fcfef319fbcae875af6fd29798e16a9317efb07"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"1bdf2d3442382debe6938827a8bd826ccb5dd657","unresolved":false,"context_lines":[{"line_number":67,"context_line":"        # TODO: This crypto-etag will be encrypted in a later version"},{"line_number":68,"context_line":"        self.footers_to_add[\u0027X-Object-Sysmeta-Crypto-Etag\u0027] \u003d \\"},{"line_number":69,"context_line":"            self.plaintext_etag"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"        # TODO: This etag will be encrypted in a later version"},{"line_number":72,"context_line":"        self.footers_to_add[\u0027X-Backend-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":73,"context_line":"            self.plaintext_etag"}],"source_content_type":"text/x-python","patch_set":18,"id":"3a29b11f_15f3e70b","line":70,"updated":"2015-10-19 18:54:27.000000000","message":"I maybe late to ask this, but: Is the plan to encrypt self.ciphertext_etag and then validate later? And hence implement end-end validation?","commit_id":"f3231ff407bd731b054a42e2070be5768103fd18"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b8bd09a0df85c55f169c18f636a6f85a246d2b14","unresolved":false,"context_lines":[{"line_number":67,"context_line":"        # TODO: This crypto-etag will be encrypted in a later version"},{"line_number":68,"context_line":"        self.footers_to_add[\u0027X-Object-Sysmeta-Crypto-Etag\u0027] \u003d \\"},{"line_number":69,"context_line":"            self.plaintext_etag"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"        # TODO: This etag will be encrypted in a later version"},{"line_number":72,"context_line":"        self.footers_to_add[\u0027X-Backend-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":73,"context_line":"            self.plaintext_etag"}],"source_content_type":"text/x-python","patch_set":18,"id":"3a29b11f_000047a9","line":70,"in_reply_to":"3a29b11f_15f3e70b","updated":"2015-10-20 14:42:34.000000000","message":"No. We need the ciphertext_etag to pass unencrypted to the object server - it is the etag of the actual bytes that are stored and therefore must match what the object server will calculate for bytes written to disk (and later what the auditor will check).","commit_id":"f3231ff407bd731b054a42e2070be5768103fd18"}],"test/unit/common/middleware/crypto_helpers.py":[{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"5387cc8318b3553c893cd4839ba16b510f931ec9","unresolved":false,"context_lines":[{"line_number":14,"context_line":"# limitations under the License."},{"line_number":15,"context_line":"import hashlib"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"def fetch_crypto_keys():"},{"line_number":19,"context_line":"    # Notice that these are not long enough for the real encryption."},{"line_number":20,"context_line":"    return {\u0027account\u0027: \u0027account_key\u0027,"}],"source_content_type":"text/x-python","patch_set":18,"id":"3a29b11f_7999ed6d","line":17,"updated":"2015-10-20 01:08:25.000000000","message":"thanks for creating this!  I knew the tests would change a lot, and wanted to wait until later to see what could be shared.  This was a good time to start that.","commit_id":"f3231ff407bd731b054a42e2070be5768103fd18"}],"test/unit/common/middleware/test_decrypter.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5869c613d2e7facdee98c473341fcfe40757b943","unresolved":false,"context_lines":[{"line_number":55,"context_line":"        caught_exc \u003d None"},{"line_number":56,"context_line":"        try:"},{"line_number":57,"context_line":"            for chunk in body_iter:"},{"line_number":58,"context_line":"                body +\u003d chunk"},{"line_number":59,"context_line":"        except Exception as exc:"},{"line_number":60,"context_line":"            if self.expect_exception:"},{"line_number":61,"context_line":"                caught_exc \u003d exc"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_a1494262","line":58,"updated":"2015-09-29 01:11:06.000000000","message":"How about this?\n\n    body \u003d \u0027\u0027.join(body_iter)","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":55,"context_line":"        caught_exc \u003d None"},{"line_number":56,"context_line":"        try:"},{"line_number":57,"context_line":"            for chunk in body_iter:"},{"line_number":58,"context_line":"                body +\u003d chunk"},{"line_number":59,"context_line":"        except Exception as exc:"},{"line_number":60,"context_line":"            if self.expect_exception:"},{"line_number":61,"context_line":"                caught_exc \u003d exc"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_e7b73338","line":58,"in_reply_to":"9a1a9d01_a1494262","updated":"2015-09-29 13:39:21.000000000","message":"will do","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":55,"context_line":"        caught_exc \u003d None"},{"line_number":56,"context_line":"        try:"},{"line_number":57,"context_line":"            for chunk in body_iter:"},{"line_number":58,"context_line":"                body +\u003d chunk"},{"line_number":59,"context_line":"        except Exception as exc:"},{"line_number":60,"context_line":"            if self.expect_exception:"},{"line_number":61,"context_line":"                caught_exc \u003d exc"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_b27b9b27","line":58,"in_reply_to":"9a1a9d01_e7b73338","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5869c613d2e7facdee98c473341fcfe40757b943","unresolved":false,"context_lines":[{"line_number":243,"context_line":"            \u0027Object\u0027, [fake_app_body], \u0027200 OK\u0027, True, False), {})"},{"line_number":244,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":245,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":246,"context_line":"        self.assertEquals(\u0027\u0027.join(body), \u0027\u0027.join(fake_app_body))"},{"line_number":247,"context_line":"        self.assertTrue(status \u003d\u003d \u0027200 OK\u0027)"},{"line_number":248,"context_line":"        self.assertTrue(resp_hdr_val(\u0027Etag\u0027, headers) \u003d\u003d md5hex(fake_app_body))"},{"line_number":249,"context_line":"        # TODO - somehow assert that encrypt/decrypt happened"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_0196ee92","line":246,"updated":"2015-09-29 01:11:06.000000000","message":"Isn\u0027t FakeApp already joining body? And fake_app_body is *definitely* already joined.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":243,"context_line":"            \u0027Object\u0027, [fake_app_body], \u0027200 OK\u0027, True, False), {})"},{"line_number":244,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":245,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":246,"context_line":"        self.assertEquals(\u0027\u0027.join(body), \u0027\u0027.join(fake_app_body))"},{"line_number":247,"context_line":"        self.assertTrue(status \u003d\u003d \u0027200 OK\u0027)"},{"line_number":248,"context_line":"        self.assertTrue(resp_hdr_val(\u0027Etag\u0027, headers) \u003d\u003d md5hex(fake_app_body))"},{"line_number":249,"context_line":"        # TODO - somehow assert that encrypt/decrypt happened"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_078ca77d","line":246,"in_reply_to":"9a1a9d01_0196ee92","updated":"2015-09-29 13:39:21.000000000","message":"will change","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":243,"context_line":"            \u0027Object\u0027, [fake_app_body], \u0027200 OK\u0027, True, False), {})"},{"line_number":244,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":245,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":246,"context_line":"        self.assertEquals(\u0027\u0027.join(body), \u0027\u0027.join(fake_app_body))"},{"line_number":247,"context_line":"        self.assertTrue(status \u003d\u003d \u0027200 OK\u0027)"},{"line_number":248,"context_line":"        self.assertTrue(resp_hdr_val(\u0027Etag\u0027, headers) \u003d\u003d md5hex(fake_app_body))"},{"line_number":249,"context_line":"        # TODO - somehow assert that encrypt/decrypt happened"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_cdb31299","line":246,"in_reply_to":"9a1a9d01_078ca77d","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5869c613d2e7facdee98c473341fcfe40757b943","unresolved":false,"context_lines":[{"line_number":257,"context_line":"        dec_app \u003d decrypter.Decrypter(FakeAppThatSetsKeys("},{"line_number":258,"context_line":"            \u0027Object\u0027, [fake_app_body], \u0027200 OK\u0027, True, False), {})"},{"line_number":259,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":260,"context_line":"        try:"},{"line_number":261,"context_line":"            # an exception will be thrown from crypto.contxt.update()"},{"line_number":262,"context_line":"            status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":263,"context_line":"        except HTTPException as e:"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_c1e2362f","line":260,"updated":"2015-09-29 01:11:06.000000000","message":"We don\u0027t actually verify that HTTPException is raised. We could just add a self.fail() after the app call, but how about this instead?\n\n    with self.assertRaises(HTTPException) as catcher:\n        fake_app(req.environ, start_response)\n    self.assertEqual(catcher.exception.body, FakeContextThrows.get_error_msg())","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":257,"context_line":"        dec_app \u003d decrypter.Decrypter(FakeAppThatSetsKeys("},{"line_number":258,"context_line":"            \u0027Object\u0027, [fake_app_body], \u0027200 OK\u0027, True, False), {})"},{"line_number":259,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":260,"context_line":"        try:"},{"line_number":261,"context_line":"            # an exception will be thrown from crypto.contxt.update()"},{"line_number":262,"context_line":"            status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":263,"context_line":"        except HTTPException as e:"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_f2b273e4","line":260,"in_reply_to":"9a1a9d01_67c803a9","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":257,"context_line":"        dec_app \u003d decrypter.Decrypter(FakeAppThatSetsKeys("},{"line_number":258,"context_line":"            \u0027Object\u0027, [fake_app_body], \u0027200 OK\u0027, True, False), {})"},{"line_number":259,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":260,"context_line":"        try:"},{"line_number":261,"context_line":"            # an exception will be thrown from crypto.contxt.update()"},{"line_number":262,"context_line":"            status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":263,"context_line":"        except HTTPException as e:"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_67c803a9","line":260,"in_reply_to":"9a1a9d01_c1e2362f","updated":"2015-09-29 13:39:21.000000000","message":"will do","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5869c613d2e7facdee98c473341fcfe40757b943","unresolved":false,"context_lines":[{"line_number":270,"context_line":"            \u0027Object\u0027, [fake_app_body], \u0027200 OK\u0027, True, False), {})"},{"line_number":271,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":272,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":273,"context_line":"        self.assertTrue(status \u003d\u003d \u0027200 OK\u0027)"},{"line_number":274,"context_line":"        self.assertTrue(resp_hdr_val(\u0027Etag\u0027, headers) \u003d\u003d md5hex(fake_app_body))"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"    def test_multiseg_get_obj(self, fake_get_crpyto):"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_21dbf250","line":273,"updated":"2015-09-29 01:11:06.000000000","message":"self.assertEqual, please. Then if/when the test breaks, we won\u0027t have to dig to find out what the status was instead. Ditto below, although it\u0027s less useful for ETags.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":270,"context_line":"            \u0027Object\u0027, [fake_app_body], \u0027200 OK\u0027, True, False), {})"},{"line_number":271,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":272,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":273,"context_line":"        self.assertTrue(status \u003d\u003d \u0027200 OK\u0027)"},{"line_number":274,"context_line":"        self.assertTrue(resp_hdr_val(\u0027Etag\u0027, headers) \u003d\u003d md5hex(fake_app_body))"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"    def test_multiseg_get_obj(self, fake_get_crpyto):"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_e753b3e0","line":273,"in_reply_to":"9a1a9d01_21dbf250","updated":"2015-09-29 13:39:21.000000000","message":"will do","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":270,"context_line":"            \u0027Object\u0027, [fake_app_body], \u0027200 OK\u0027, True, False), {})"},{"line_number":271,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":272,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":273,"context_line":"        self.assertTrue(status \u003d\u003d \u0027200 OK\u0027)"},{"line_number":274,"context_line":"        self.assertTrue(resp_hdr_val(\u0027Etag\u0027, headers) \u003d\u003d md5hex(fake_app_body))"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"    def test_multiseg_get_obj(self, fake_get_crpyto):"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_52479fbb","line":273,"in_reply_to":"9a1a9d01_e753b3e0","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5869c613d2e7facdee98c473341fcfe40757b943","unresolved":false,"context_lines":[{"line_number":280,"context_line":"            {})"},{"line_number":281,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":282,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":283,"context_line":"        resp_body \u003d \u0027\u0027.join(body)"},{"line_number":284,"context_line":""},{"line_number":285,"context_line":"        self.assertEquals(resp_body, \u0027somechunksof data\u0027)"},{"line_number":286,"context_line":"        self.assertTrue(status \u003d\u003d \u0027200 OK\u0027)"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_e1d09a21","line":283,"updated":"2015-09-29 01:11:06.000000000","message":"Again, isn\u0027t FakeApp doing this for us?","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":280,"context_line":"            {})"},{"line_number":281,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":282,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":283,"context_line":"        resp_body \u003d \u0027\u0027.join(body)"},{"line_number":284,"context_line":""},{"line_number":285,"context_line":"        self.assertEquals(resp_body, \u0027somechunksof data\u0027)"},{"line_number":286,"context_line":"        self.assertTrue(status \u003d\u003d \u0027200 OK\u0027)"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_724423b6","line":283,"in_reply_to":"9a1a9d01_27752b63","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":280,"context_line":"            {})"},{"line_number":281,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":282,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":283,"context_line":"        resp_body \u003d \u0027\u0027.join(body)"},{"line_number":284,"context_line":""},{"line_number":285,"context_line":"        self.assertEquals(resp_body, \u0027somechunksof data\u0027)"},{"line_number":286,"context_line":"        self.assertTrue(status \u003d\u003d \u0027200 OK\u0027)"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_27752b63","line":283,"in_reply_to":"9a1a9d01_e1d09a21","updated":"2015-09-29 13:39:21.000000000","message":"will change","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5869c613d2e7facdee98c473341fcfe40757b943","unresolved":false,"context_lines":[{"line_number":301,"context_line":"            {})"},{"line_number":302,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":303,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":304,"context_line":"        resp_body \u003d \u0027\u0027.join(body)"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"        self.assertEquals(resp_body, \u00273456789a\u0027)"},{"line_number":307,"context_line":"        self.assertTrue(status \u003d\u003d \u0027200 OK\u0027)"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_a1c62266","line":304,"updated":"2015-09-29 01:11:06.000000000","message":"Again, isn\u0027t FakeApp doing this for us?","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":301,"context_line":"            {})"},{"line_number":302,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":303,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":304,"context_line":"        resp_body \u003d \u0027\u0027.join(body)"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"        self.assertEquals(resp_body, \u00273456789a\u0027)"},{"line_number":307,"context_line":"        self.assertTrue(status \u003d\u003d \u0027200 OK\u0027)"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_d2096f85","line":304,"in_reply_to":"9a1a9d01_87299739","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":301,"context_line":"            {})"},{"line_number":302,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":303,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":304,"context_line":"        resp_body \u003d \u0027\u0027.join(body)"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"        self.assertEquals(resp_body, \u00273456789a\u0027)"},{"line_number":307,"context_line":"        self.assertTrue(status \u003d\u003d \u0027200 OK\u0027)"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_87299739","line":304,"in_reply_to":"9a1a9d01_a1c62266","updated":"2015-09-29 13:39:21.000000000","message":"will change","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5869c613d2e7facdee98c473341fcfe40757b943","unresolved":false,"context_lines":[{"line_number":344,"context_line":"            \u0027Object\u0027, [fake_app_body], \u0027200 OK\u0027, False, True), {})"},{"line_number":345,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":346,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":347,"context_line":"        resp_body \u003d \u0027\u0027.join(body)"},{"line_number":348,"context_line":"        # assert that the body contents remain the same"},{"line_number":349,"context_line":"        self.assertEquals(resp_body, \u0027\u0027.join(fake_app_body))"},{"line_number":350,"context_line":"        # TODO - maybe assert that there is no crypto-meta?"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_21a9b290","line":347,"updated":"2015-09-29 01:11:06.000000000","message":"Again, isn\u0027t FakeApp doing this for us?","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":344,"context_line":"            \u0027Object\u0027, [fake_app_body], \u0027200 OK\u0027, False, True), {})"},{"line_number":345,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":346,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":347,"context_line":"        resp_body \u003d \u0027\u0027.join(body)"},{"line_number":348,"context_line":"        # assert that the body contents remain the same"},{"line_number":349,"context_line":"        self.assertEquals(resp_body, \u0027\u0027.join(fake_app_body))"},{"line_number":350,"context_line":"        # TODO - maybe assert that there is no crypto-meta?"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_e7189320","line":347,"in_reply_to":"9a1a9d01_21a9b290","updated":"2015-09-29 13:39:21.000000000","message":"will change","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":344,"context_line":"            \u0027Object\u0027, [fake_app_body], \u0027200 OK\u0027, False, True), {})"},{"line_number":345,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":346,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":347,"context_line":"        resp_body \u003d \u0027\u0027.join(body)"},{"line_number":348,"context_line":"        # assert that the body contents remain the same"},{"line_number":349,"context_line":"        self.assertEquals(resp_body, \u0027\u0027.join(fake_app_body))"},{"line_number":350,"context_line":"        # TODO - maybe assert that there is no crypto-meta?"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_f20ef38a","line":347,"in_reply_to":"9a1a9d01_e7189320","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"75ae70efdb88aae9798ab9cce7099fea10cb7fe4","unresolved":false,"context_lines":[{"line_number":346,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":347,"context_line":"        resp_body \u003d \u0027\u0027.join(body)"},{"line_number":348,"context_line":"        # assert that the body contents remain the same"},{"line_number":349,"context_line":"        self.assertEquals(resp_body, \u0027\u0027.join(fake_app_body))"},{"line_number":350,"context_line":"        # TODO - maybe assert that there is no crypto-meta?"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def test_filter(self, fake_get_crpyto):"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_2c9b5dcb","line":349,"updated":"2015-09-24 19:27:53.000000000","message":"assertEquals is deprecated and the deprecation-police have been clearing it out on master so may as well do same throughout this patch - use self.assertEqual","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":346,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":347,"context_line":"        resp_body \u003d \u0027\u0027.join(body)"},{"line_number":348,"context_line":"        # assert that the body contents remain the same"},{"line_number":349,"context_line":"        self.assertEquals(resp_body, \u0027\u0027.join(fake_app_body))"},{"line_number":350,"context_line":"        # TODO - maybe assert that there is no crypto-meta?"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def test_filter(self, fake_get_crpyto):"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_a7d5bb1c","line":349,"in_reply_to":"9a1a9d01_2c9b5dcb","updated":"2015-09-29 13:39:21.000000000","message":"will do","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":346,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":347,"context_line":"        resp_body \u003d \u0027\u0027.join(body)"},{"line_number":348,"context_line":"        # assert that the body contents remain the same"},{"line_number":349,"context_line":"        self.assertEquals(resp_body, \u0027\u0027.join(fake_app_body))"},{"line_number":350,"context_line":"        # TODO - maybe assert that there is no crypto-meta?"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def test_filter(self, fake_get_crpyto):"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_9228d7e3","line":349,"in_reply_to":"9a1a9d01_a7d5bb1c","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"75ae70efdb88aae9798ab9cce7099fea10cb7fe4","unresolved":false,"context_lines":[{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def test_filter(self, fake_get_crpyto):"},{"line_number":353,"context_line":"        factory \u003d decrypter.filter_factory({})"},{"line_number":354,"context_line":"        self.assertTrue(callable(factory))"},{"line_number":355,"context_line":""},{"line_number":356,"context_line":"    def test_app_exception(self, fake_get_crpyto):"},{"line_number":357,"context_line":"        app \u003d decrypter.Decrypter("}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_ccac21f0","line":354,"updated":"2015-09-24 19:27:53.000000000","message":"yes. assert_ is also deprecated.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def test_filter(self, fake_get_crpyto):"},{"line_number":353,"context_line":"        factory \u003d decrypter.filter_factory({})"},{"line_number":354,"context_line":"        self.assertTrue(callable(factory))"},{"line_number":355,"context_line":""},{"line_number":356,"context_line":"    def test_app_exception(self, fake_get_crpyto):"},{"line_number":357,"context_line":"        app \u003d decrypter.Decrypter("}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_edadb69b","line":354,"in_reply_to":"9a1a9d01_67db2350","updated":"2015-09-30 15:37:19.000000000","message":"Actually, I didn\u0027t see where assert_ was used.  Did I miss something?","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def test_filter(self, fake_get_crpyto):"},{"line_number":353,"context_line":"        factory \u003d decrypter.filter_factory({})"},{"line_number":354,"context_line":"        self.assertTrue(callable(factory))"},{"line_number":355,"context_line":""},{"line_number":356,"context_line":"    def test_app_exception(self, fake_get_crpyto):"},{"line_number":357,"context_line":"        app \u003d decrypter.Decrypter("}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_67db2350","line":354,"in_reply_to":"9a1a9d01_ccac21f0","updated":"2015-09-29 13:39:21.000000000","message":"will change","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5869c613d2e7facdee98c473341fcfe40757b943","unresolved":false,"context_lines":[{"line_number":357,"context_line":"        app \u003d decrypter.Decrypter("},{"line_number":358,"context_line":"            FakeAppThatExcepts(), {})"},{"line_number":359,"context_line":"        req \u003d Request.blank(\u0027/\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027})"},{"line_number":360,"context_line":"        self.assertRaises(Exception, app, req.environ, start_response)"},{"line_number":361,"context_line":""},{"line_number":362,"context_line":""},{"line_number":363,"context_line":"def fake_decrypt(chunk):"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_e1a5faa1","line":360,"updated":"2015-09-29 01:11:06.000000000","message":"Let\u0027s use the context-manager form, and also assert that the raised exception has the expected message.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"cb03789742ff7e1c0360f5f0f3eda91a5cbaf75b","unresolved":false,"context_lines":[{"line_number":357,"context_line":"        app \u003d decrypter.Decrypter("},{"line_number":358,"context_line":"            FakeAppThatExcepts(), {})"},{"line_number":359,"context_line":"        req \u003d Request.blank(\u0027/\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027})"},{"line_number":360,"context_line":"        self.assertRaises(Exception, app, req.environ, start_response)"},{"line_number":361,"context_line":""},{"line_number":362,"context_line":""},{"line_number":363,"context_line":"def fake_decrypt(chunk):"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_0dbcaada","line":360,"in_reply_to":"9a1a9d01_67a9e38f","updated":"2015-09-30 15:37:19.000000000","message":"Done","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"ee72e6224dc5578e83db000d3aa54ae9f59507e4","unresolved":false,"context_lines":[{"line_number":357,"context_line":"        app \u003d decrypter.Decrypter("},{"line_number":358,"context_line":"            FakeAppThatExcepts(), {})"},{"line_number":359,"context_line":"        req \u003d Request.blank(\u0027/\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027})"},{"line_number":360,"context_line":"        self.assertRaises(Exception, app, req.environ, start_response)"},{"line_number":361,"context_line":""},{"line_number":362,"context_line":""},{"line_number":363,"context_line":"def fake_decrypt(chunk):"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a1a9d01_67a9e38f","line":360,"in_reply_to":"9a1a9d01_e1a5faa1","updated":"2015-09-29 13:39:21.000000000","message":"ok.","commit_id":"e13de967be4ae78591eb1136712e746cde677eb9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"62a2f1c55ef6300f735f28e40bfa095976c3aadb","unresolved":false,"context_lines":[{"line_number":29,"context_line":"    return hashlib.md5(s).hexdigest()"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"class FakeApp(object):"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    def __init__(self, app, req, body\u003dNone, expect_exception\u003dFalse):"},{"line_number":35,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"5a2ca52d_38a01390","line":32,"updated":"2015-10-15 20:10:12.000000000","message":"not necessary - use Request.get_response()","commit_id":"3fcfef319fbcae875af6fd29798e16a9317efb07"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"62a2f1c55ef6300f735f28e40bfa095976c3aadb","unresolved":false,"context_lines":[{"line_number":253,"context_line":"        self.assertEqual(body, fake_app_body)"},{"line_number":254,"context_line":"        self.assertTrue(status \u003d\u003d \u0027200 OK\u0027)"},{"line_number":255,"context_line":"        self.assertTrue(resp_hdr_val(\u0027Etag\u0027, headers) \u003d\u003d md5hex(fake_app_body))"},{"line_number":256,"context_line":"        # TODO - somehow assert that encrypt/decrypt happened"},{"line_number":257,"context_line":""},{"line_number":258,"context_line":"    def test_get_req_hdr_decrypt_throws(self, fake_get_crpyto):"},{"line_number":259,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027})"}],"source_content_type":"text/x-python","patch_set":17,"id":"5a2ca52d_d8f31f9d","line":256,"updated":"2015-10-15 20:10:12.000000000","message":"the test has done that, but its hidden in the FakeAppThatSetsKeys. Makes me wonder if that could all be a bit more explicit in the test.","commit_id":"3fcfef319fbcae875af6fd29798e16a9317efb07"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"62a2f1c55ef6300f735f28e40bfa095976c3aadb","unresolved":false,"context_lines":[{"line_number":271,"context_line":""},{"line_number":272,"context_line":"    def test_basic_head_req(self, fake_get_crpyto):"},{"line_number":273,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027HEAD\u0027})"},{"line_number":274,"context_line":"        fake_app_body \u003d \u0027FAKE APP\u0027"},{"line_number":275,"context_line":"        dec_app \u003d decrypter.Decrypter(FakeAppThatSetsKeys("},{"line_number":276,"context_line":"            \u0027Object\u0027, [fake_app_body], \u0027200 OK\u0027, True, False), {})"},{"line_number":277,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"}],"source_content_type":"text/x-python","patch_set":17,"id":"5a2ca52d_f8c05b2c","line":274,"updated":"2015-10-15 20:10:12.000000000","message":"HEAD response has no body","commit_id":"3fcfef319fbcae875af6fd29798e16a9317efb07"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"62a2f1c55ef6300f735f28e40bfa095976c3aadb","unresolved":false,"context_lines":[{"line_number":328,"context_line":"        # TODO - ADD BACK WHEN no longer using FakeFooters"},{"line_number":329,"context_line":"        # if not caught_exc:"},{"line_number":330,"context_line":"        #     self.fail(\u0027Expected HTTPUnprocessableEntity to be raised.\u0027)"},{"line_number":331,"context_line":"        # self.assertEqual(\u0027422 Unprocessable Entity\u0027, caught_exc.status)"},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"    def test_missing_keys(self, fake_get_crpyto):"},{"line_number":334,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027})"}],"source_content_type":"text/x-python","patch_set":17,"id":"5a2ca52d_585b8f87","line":331,"updated":"2015-10-15 20:10:12.000000000","message":"hmm, on a GET I am not sure we would expect a 422. Maybe 503?","commit_id":"3fcfef319fbcae875af6fd29798e16a9317efb07"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"faba4e8a4b11b6fe521c040a47e80bbe71aad5de","unresolved":false,"context_lines":[{"line_number":328,"context_line":"        # TODO - ADD BACK WHEN no longer using FakeFooters"},{"line_number":329,"context_line":"        # if not caught_exc:"},{"line_number":330,"context_line":"        #     self.fail(\u0027Expected HTTPUnprocessableEntity to be raised.\u0027)"},{"line_number":331,"context_line":"        # self.assertEqual(\u0027422 Unprocessable Entity\u0027, caught_exc.status)"},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"    def test_missing_keys(self, fake_get_crpyto):"},{"line_number":334,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027})"}],"source_content_type":"text/x-python","patch_set":17,"id":"3a29b11f_d7147345","line":331,"in_reply_to":"5a2ca52d_585b8f87","updated":"2015-10-20 01:06:51.000000000","message":"I am confused about this test case in general.  There used to be a check against the etag on a GET within the decrypter, but it was mentioned in a review that swift doesn\u0027t do this internally.  that part is left to the client to compare what is retrieved.  So, should this test go away?  Or am I wrong?","commit_id":"3fcfef319fbcae875af6fd29798e16a9317efb07"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"62a2f1c55ef6300f735f28e40bfa095976c3aadb","unresolved":false,"context_lines":[{"line_number":334,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027})"},{"line_number":335,"context_line":"        # Do not provide keys, and do not set override flag"},{"line_number":336,"context_line":"        dec_app \u003d decrypter.Decrypter(FakeAppThatSetsKeys("},{"line_number":337,"context_line":"            \u0027Object\u0027, [\u0027FAKE APP\u0027], \u0027200 OK\u0027, False, False), {})"},{"line_number":338,"context_line":"        fake_app \u003d FakeApp(dec_app, req)"},{"line_number":339,"context_line":"        status, headers, body \u003d fake_app(req.environ, start_response)"},{"line_number":340,"context_line":"        self.assertTrue(status \u003d\u003d \u0027500 Internal Error\u0027)"}],"source_content_type":"text/x-python","patch_set":17,"id":"5a2ca52d_5884efd2","line":337,"updated":"2015-10-15 20:10:12.000000000","message":"Again, the test is delegating to FakeAppThatSetsKeys, in this case to not include keys. I\u0027d prefer it to be more explicit in the test.","commit_id":"3fcfef319fbcae875af6fd29798e16a9317efb07"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"5387cc8318b3553c893cd4839ba16b510f931ec9","unresolved":false,"context_lines":[{"line_number":65,"context_line":"@mock.patch(\u0027swift.common.middleware.decrypter.Crypto\u0027, FakeCrypto)"},{"line_number":66,"context_line":"class TestDecrypter(unittest.TestCase):"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    def test_basic_get_req(self):"},{"line_number":69,"context_line":"        env \u003d {\u0027REQUEST_METHOD\u0027: \u0027GET\u0027,"},{"line_number":70,"context_line":"               \u0027swift.crypto.fetch_crypto_keys\u0027: fetch_crypto_keys}"},{"line_number":71,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o\u0027, environ\u003denv)"}],"source_content_type":"text/x-python","patch_set":18,"id":"3a29b11f_777d5fe6","line":68,"updated":"2015-10-20 01:08:25.000000000","message":"using FakeSwift is much better.  Thanks for rolling this in :-)\nI had used test_proxy_logging as an example, which didnt use FakeSwift.","commit_id":"f3231ff407bd731b054a42e2070be5768103fd18"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"5387cc8318b3553c893cd4839ba16b510f931ec9","unresolved":false,"context_lines":[{"line_number":153,"context_line":"        self.assertEqual(resp.body, \u00273456789a\u0027)"},{"line_number":154,"context_line":"        self.assertEqual(resp.status, \u0027200 OK\u0027)"},{"line_number":155,"context_line":"        # TODO - how do we validate the range body if etag is for whole? Is"},{"line_number":156,"context_line":"        # the test actually faking the correct Etag in response?"},{"line_number":157,"context_line":"        self.assertEqual(resp.headers[\u0027Etag\u0027], md5hex(body))"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    def test_etag_no_match_on_get(self):"}],"source_content_type":"text/x-python","patch_set":18,"id":"3a29b11f_dc21fab5","line":156,"updated":"2015-10-20 01:08:25.000000000","message":"good point.  I wrote that bit so long ago, that I dont remember if I had checked what happens in a regular range GET.  I assume that I did, but ... we should check.","commit_id":"f3231ff407bd731b054a42e2070be5768103fd18"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"5387cc8318b3553c893cd4839ba16b510f931ec9","unresolved":false,"context_lines":[{"line_number":157,"context_line":"        self.assertEqual(resp.headers[\u0027Etag\u0027], md5hex(body))"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    def test_etag_no_match_on_get(self):"},{"line_number":160,"context_line":"        self.skipTest(\u0027Etag verification not yet implemented\u0027)"},{"line_number":161,"context_line":"        env \u003d {\u0027REQUEST_METHOD\u0027: \u0027GET\u0027,"},{"line_number":162,"context_line":"               \u0027swift.crypto.fetch_crypto_keys\u0027: fetch_crypto_keys}"},{"line_number":163,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o\u0027, environ\u003denv)"}],"source_content_type":"text/x-python","patch_set":18,"id":"3a29b11f_fc12b661","line":160,"updated":"2015-10-20 01:08:25.000000000","message":"Nice, thanks.","commit_id":"f3231ff407bd731b054a42e2070be5768103fd18"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"1bdf2d3442382debe6938827a8bd826ccb5dd657","unresolved":false,"context_lines":[{"line_number":213,"context_line":"            resp.body, \u0027swift.crypto.fetch_crypto_keys had exception: Testing\u0027)"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"    def test_cipher_mismatch(self):"},{"line_number":216,"context_line":"        # Cipher does nto match"},{"line_number":217,"context_line":"        env \u003d {\u0027REQUEST_METHOD\u0027: \u0027GET\u0027,"},{"line_number":218,"context_line":"               \u0027swift.crypto.fetch_crypto_keys\u0027: fetch_crypto_keys}"},{"line_number":219,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o\u0027, environ\u003denv)"}],"source_content_type":"text/x-python","patch_set":18,"id":"3a29b11f_052de7a6","line":216,"updated":"2015-10-19 18:54:27.000000000","message":"nit: s/nto/not","commit_id":"f3231ff407bd731b054a42e2070be5768103fd18"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b8bd09a0df85c55f169c18f636a6f85a246d2b14","unresolved":false,"context_lines":[{"line_number":213,"context_line":"            resp.body, \u0027swift.crypto.fetch_crypto_keys had exception: Testing\u0027)"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"    def test_cipher_mismatch(self):"},{"line_number":216,"context_line":"        # Cipher does nto match"},{"line_number":217,"context_line":"        env \u003d {\u0027REQUEST_METHOD\u0027: \u0027GET\u0027,"},{"line_number":218,"context_line":"               \u0027swift.crypto.fetch_crypto_keys\u0027: fetch_crypto_keys}"},{"line_number":219,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o\u0027, environ\u003denv)"}],"source_content_type":"text/x-python","patch_set":18,"id":"3a29b11f_c0a56fb5","line":216,"in_reply_to":"3a29b11f_052de7a6","updated":"2015-10-20 14:42:34.000000000","message":"argh! :)","commit_id":"f3231ff407bd731b054a42e2070be5768103fd18"}]}
