)]}'
{"swift/common/crypto_utils.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e1b4281ce87eb4ea03e1cdc73a34e07a5882afd5","unresolved":false,"context_lines":[{"line_number":66,"context_line":"    Utility function to parse headers for BYOK and crypto override headers"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    :param req: request object"},{"line_number":69,"context_line":"    :param keys: empty dictionary"},{"line_number":70,"context_line":"    :return: True if override headers or BYOK headers are present"},{"line_number":71,"context_line":"    :raises: HTTPBadRequest if one of the keys in BYOK headers is missing"},{"line_number":72,"context_line":"    :raises: ValueError if BYOK key length is less than 32"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a122d0e_c543c66a","line":69,"updated":"2016-04-20 14:53:53.000000000","message":"Ideally I would prefer not to have a function updating a dict param. Since this is only used in the encrypter it could be a class method and then be able to reference self.keys","commit_id":"66d07b0509fed6c1aa81c1abe8b68c54c07b4088"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e1b4281ce87eb4ea03e1cdc73a34e07a5882afd5","unresolved":false,"context_lines":[{"line_number":69,"context_line":"    :param keys: empty dictionary"},{"line_number":70,"context_line":"    :return: True if override headers or BYOK headers are present"},{"line_number":71,"context_line":"    :raises: HTTPBadRequest if one of the keys in BYOK headers is missing"},{"line_number":72,"context_line":"    :raises: ValueError if BYOK key length is less than 32"},{"line_number":73,"context_line":"    \"\"\""},{"line_number":74,"context_line":"    if req.headers.get(\u0027X-Crypto-Override\u0027, \u0027False\u0027) \u003d\u003d \u0027True\u0027:"},{"line_number":75,"context_line":"            req.environ[\u0027swift.crypto.override\u0027] \u003d True"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a122d0e_65cd9230","line":72,"updated":"2016-04-20 14:53:53.000000000","message":"should raise BadRequest for wrong length too","commit_id":"66d07b0509fed6c1aa81c1abe8b68c54c07b4088"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e1b4281ce87eb4ea03e1cdc73a34e07a5882afd5","unresolved":false,"context_lines":[{"line_number":86,"context_line":"            keys[\u0027container\u0027] \u003d cont_key"},{"line_number":87,"context_line":"            return True"},{"line_number":88,"context_line":"        except KeyError:"},{"line_number":89,"context_line":"            raise HTTPBadRequest(\"Object or container key is missing\")"},{"line_number":90,"context_line":"    return False"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a122d0e_8598ae1d","line":89,"updated":"2016-04-20 14:53:53.000000000","message":"It would be nice if we validated each header in turn and were then specific in the BadRequest message as to which was bad.","commit_id":"66d07b0509fed6c1aa81c1abe8b68c54c07b4088"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"08d89cee3923e21a95d138b2946575be169872a1","unresolved":false,"context_lines":[{"line_number":80,"context_line":"                key \u003d base64.b64decode(req.headers[header_name])"},{"line_number":81,"context_line":"            except KeyError:"},{"line_number":82,"context_line":"                raise HTTPBadRequest(\"%s is missing\" % header_name)"},{"line_number":83,"context_line":"            if len(key) !\u003d 32:"},{"line_number":84,"context_line":"                raise HTTPBadRequest(\"%s length should be 32\" % header_name)"},{"line_number":85,"context_line":"            return key"},{"line_number":86,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"1a122d0e_92f1cd98","line":83,"updated":"2016-04-21 16:24:34.000000000","message":"call crypto.check_key(key instead)","commit_id":"2711ffe681d023c27d346b6f66e70945c78805c6"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"908915d817df62e4a43d7904ff1a4759589fd946","unresolved":false,"context_lines":[{"line_number":80,"context_line":"                key \u003d base64.b64decode(req.headers[header_name])"},{"line_number":81,"context_line":"            except KeyError:"},{"line_number":82,"context_line":"                raise HTTPBadRequest(\"%s is missing\" % header_name)"},{"line_number":83,"context_line":"            if len(key) !\u003d 32:"},{"line_number":84,"context_line":"                raise HTTPBadRequest(\"%s length should be 32\" % header_name)"},{"line_number":85,"context_line":"            return key"},{"line_number":86,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"1a122d0e_0ecf51b4","line":83,"in_reply_to":"1a122d0e_92f1cd98","updated":"2016-04-21 16:54:33.000000000","message":"on second thought, that is a private method _check_key and it raises a different error.  nevermind, i suppose.","commit_id":"2711ffe681d023c27d346b6f66e70945c78805c6"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"a50ec06de0e10337c50d966e7f935c868eed7711","unresolved":false,"context_lines":[{"line_number":84,"context_line":"                raise HTTPBadRequest(\"%s is an invalid format\" % header_name)"},{"line_number":85,"context_line":"            if len(key) !\u003d 32:"},{"line_number":86,"context_line":"                raise HTTPBadRequest(\"%s length should be 32\" % header_name)"},{"line_number":87,"context_line":"            return key"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"        keys[\u0027object\u0027] \u003d _validate_key(\u0027X-Crypto-Object-Key\u0027)"},{"line_number":90,"context_line":"        keys[\u0027container\u0027] \u003d _validate_key(\u0027X-Crypto-Container-Key\u0027)"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a122d0e_0c1d87bd","line":87,"updated":"2016-04-22 05:18:18.000000000","message":"nice work!","commit_id":"37fd84cb900a229642111e957421b72291e4b8bb"}],"swift/common/middleware/keymaster.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5dab42c1ac9402b3d57394770e042bedf31209b0","unresolved":false,"context_lines":[{"line_number":69,"context_line":"                    self.obj_path)"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"    def _handle_post_or_put(self, req, start_response):"},{"line_number":72,"context_line":"        if (\u0027X-Crypto-Object-Key\u0027 or \u0027X-Crypto-Container-Key\u0027) in req.headers:"},{"line_number":73,"context_line":"            try:"},{"line_number":74,"context_line":"                self.keys[\u0027object\u0027] \u003d req.headers[\u0027X-Crypto-Object-Key\u0027]"},{"line_number":75,"context_line":"                self.keys[\u0027container\u0027] \u003d req.headers[\u0027X-Crypto-Container-Key\u0027]"}],"source_content_type":"text/x-python","patch_set":1,"id":"1a122d0e_e098abc2","line":72,"updated":"2016-04-19 14:39:02.000000000","message":"This reduces to\n\n  if \u0027X-Crypto-Object-Key\u0027 in req.headers\n\nThe \u0027or\u0027 is applied to the two strings before the \u0027in\u0027 is evaluated.","commit_id":"19605cff05ef633b031eb11a6a8dc6d195aae31a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5dab42c1ac9402b3d57394770e042bedf31209b0","unresolved":false,"context_lines":[{"line_number":73,"context_line":"            try:"},{"line_number":74,"context_line":"                self.keys[\u0027object\u0027] \u003d req.headers[\u0027X-Crypto-Object-Key\u0027]"},{"line_number":75,"context_line":"                self.keys[\u0027container\u0027] \u003d req.headers[\u0027X-Crypto-Container-Key\u0027]"},{"line_number":76,"context_line":"            except ValueError:"},{"line_number":77,"context_line":"                raise HTTPBadRequest(\"Object or container key is missing\")"},{"line_number":78,"context_line":"        req.environ[CRYPTO_KEY_CALLBACK] \u003d self.fetch_crypto_keys"},{"line_number":79,"context_line":"        resp \u003d self._app_call(req.environ)"}],"source_content_type":"text/x-python","patch_set":1,"id":"1a122d0e_40d7df4a","line":76,"updated":"2016-04-19 14:39:02.000000000","message":"needs to be KeyError to catch if one of the keys is missing.\n\nAlso we should check that the key is a 256bit string.","commit_id":"19605cff05ef633b031eb11a6a8dc6d195aae31a"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"4110b1af43b93d9dd609959cf22755875ecf5a3c","unresolved":false,"context_lines":[{"line_number":76,"context_line":"                       self._response_exc_info)"},{"line_number":77,"context_line":"        return resp"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    def PUT(self, req, start_response):"},{"line_number":80,"context_line":"        if self.obj_path:"},{"line_number":81,"context_line":"            # TODO: re-examine need for this special handling once COPY has"},{"line_number":82,"context_line":"            # been moved to middleware."}],"source_content_type":"text/x-python","patch_set":4,"id":"1a122d0e_6cc6249b","line":79,"updated":"2016-04-20 11:04:55.000000000","message":"By moving override header check into a helper method, \"if self.obj_path\" is now executed irrespective of override header presence, as the check is now done in handle_post_or_put. Is this ok or should we have the check back in here?","commit_id":"66d07b0509fed6c1aa81c1abe8b68c54c07b4088"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e1b4281ce87eb4ea03e1cdc73a34e07a5882afd5","unresolved":false,"context_lines":[{"line_number":76,"context_line":"                       self._response_exc_info)"},{"line_number":77,"context_line":"        return resp"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    def PUT(self, req, start_response):"},{"line_number":80,"context_line":"        if self.obj_path:"},{"line_number":81,"context_line":"            # TODO: re-examine need for this special handling once COPY has"},{"line_number":82,"context_line":"            # been moved to middleware."}],"source_content_type":"text/x-python","patch_set":4,"id":"1a122d0e_60a100f8","line":79,"in_reply_to":"1a122d0e_6cc6249b","updated":"2016-04-20 14:53:53.000000000","message":"We don\u0027t really want to write the crypto id sysmeta if crypto has in fact been overriden - that could be very confusing - so yes we need the check back here.\n\nActually, we can put the check much earlier - in the keymaster __call__ method, and do parse_headers there too.","commit_id":"66d07b0509fed6c1aa81c1abe8b68c54c07b4088"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"a50ec06de0e10337c50d966e7f935c868eed7711","unresolved":false,"context_lines":[{"line_number":207,"context_line":"                # get keys for the error response when in fact there are no"},{"line_number":208,"context_line":"                # keys, and actually nothing to decrypt. It would be better if"},{"line_number":209,"context_line":"                # the decrypter just never attempted to get keys unless there"},{"line_number":210,"context_line":"                # was crypo meta indicating something needs decrypting."},{"line_number":211,"context_line":"                req.environ[\u0027swift.crypto.override\u0027] \u003d True"},{"line_number":212,"context_line":"                return err_resp(env, start_response)"},{"line_number":213,"context_line":"            km_context \u003d KeyMasterContext(self, header_keys, *parts[1:])"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a122d0e_6c035b77","line":210,"updated":"2016-04-22 05:18:18.000000000","message":"Decrypter first checks for override in req. environ [1], do you suggest that we do a check for crypto-meta before that?\n\nhttps://github.com/openstack/swift/blob/feature/crypto/swift/common/middleware/decrypter.py#L143","commit_id":"37fd84cb900a229642111e957421b72291e4b8bb"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"f17c7a15bea5c48b08cf9e6fb5ea23e2273b6f5b","unresolved":false,"context_lines":[{"line_number":207,"context_line":"                # get keys for the error response when in fact there are no"},{"line_number":208,"context_line":"                # keys, and actually nothing to decrypt. It would be better if"},{"line_number":209,"context_line":"                # the decrypter just never attempted to get keys unless there"},{"line_number":210,"context_line":"                # was crypo meta indicating something needs decrypting."},{"line_number":211,"context_line":"                req.environ[\u0027swift.crypto.override\u0027] \u003d True"},{"line_number":212,"context_line":"                return err_resp(env, start_response)"},{"line_number":213,"context_line":"            km_context \u003d KeyMasterContext(self, header_keys, *parts[1:])"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a122d0e_b9f80ec6","line":210,"in_reply_to":"1a122d0e_1978228f","updated":"2016-04-22 08:20:39.000000000","message":"+1, thanks for explaining.","commit_id":"37fd84cb900a229642111e957421b72291e4b8bb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"61bf997f55c7833994288f2515fa1dce50a40063","unresolved":false,"context_lines":[{"line_number":207,"context_line":"                # get keys for the error response when in fact there are no"},{"line_number":208,"context_line":"                # keys, and actually nothing to decrypt. It would be better if"},{"line_number":209,"context_line":"                # the decrypter just never attempted to get keys unless there"},{"line_number":210,"context_line":"                # was crypo meta indicating something needs decrypting."},{"line_number":211,"context_line":"                req.environ[\u0027swift.crypto.override\u0027] \u003d True"},{"line_number":212,"context_line":"                return err_resp(env, start_response)"},{"line_number":213,"context_line":"            km_context \u003d KeyMasterContext(self, header_keys, *parts[1:])"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a122d0e_1978228f","line":210,"in_reply_to":"1a122d0e_6c035b77","updated":"2016-04-22 08:12:33.000000000","message":"I added the TODO because i think we need to give some thought o whether using crypto.override in te way I have done here is the best way to deal with these situations. I also added a trello card.\n\nThis works, but other middlewares, or the proxy app, that raise exceptions or return error responses without the keymaster having installed a callback, may not set crypto.override like we are here, and then the decrypter will do the wrong thing.\n\nSo this change here does not solve the bigger problem.","commit_id":"37fd84cb900a229642111e957421b72291e4b8bb"}],"test/unit/common/middleware/test_keymaster.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"55b824b5a6992c38501a5814e0ff0331a01e16db","unresolved":false,"context_lines":[{"line_number":177,"context_line":""},{"line_number":178,"context_line":"    def test_object_with_byok(self):"},{"line_number":179,"context_line":"        # assert keys are client sent keys in byok support"},{"line_number":180,"context_line":"        # on PUT and GET"},{"line_number":181,"context_line":"        path \u003d \u0027/v1/a/c/o\u0027"},{"line_number":182,"context_line":"        obj_key \u003d \u0027This is an object key 1234567890\u0027"},{"line_number":183,"context_line":"        cont_key \u003d \u0027This is a container key 12345678\u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a122d0e_3b06521d","line":180,"updated":"2016-04-19 14:49:38.000000000","message":"also POST and HEAD?","commit_id":"521dcd9f4035212ed2df1c1779ac291a85640002"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e1b4281ce87eb4ea03e1cdc73a34e07a5882afd5","unresolved":false,"context_lines":[{"line_number":223,"context_line":""},{"line_number":224,"context_line":"    def test_object_with_override_header(self):"},{"line_number":225,"context_line":"        path \u003d \u0027/v1/a/c/o\u0027"},{"line_number":226,"context_line":"        for method in \u0027PUT\u0027:"},{"line_number":227,"context_line":"            self.swift.register(method, path, swob.HTTPOk, \u0027\u0027)"},{"line_number":228,"context_line":"            app \u003d keymaster.KeyMaster(self.swift,"},{"line_number":229,"context_line":"                                      {\u0027encryption_root_secret\u0027: \u0027secret\u0027})"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a122d0e_f4a15195","line":226,"updated":"2016-04-20 14:53:53.000000000","message":"this iterates over \u0027P\u0027 \u0027U\u0027 \u0027T\u0027 - need to wrap \u0027PUT\u0027 in a tuple or list","commit_id":"66d07b0509fed6c1aa81c1abe8b68c54c07b4088"}]}
