)]}'
{"swift/common/middleware/decrypter.py":[{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"4ce4350e3facc6c8bfb8358522651146e584e4bc","unresolved":false,"context_lines":[{"line_number":301,"context_line":"                # else, plaintext: nothing to change"},{"line_number":302,"context_line":""},{"line_number":303,"context_line":"                if not chunk:"},{"line_number":304,"context_line":"                    # TODO - determine the right error code to return"},{"line_number":305,"context_line":"                    self.logger.error(\"Could not construct container listing.\")"},{"line_number":306,"context_line":"                    raise HTTPInternalServerError(\"Couldn\u0027t construct listing\")"},{"line_number":307,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"da85f559_cba3969d","line":304,"updated":"2015-11-08 20:52:09.000000000","message":"Isn\u0027t 500 appropriate here ?  Just wondering what other error codes may be better in this context ?","commit_id":"a3ef567ace8661de3f054f0fc8058c62c1e08776"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"590cbdafc3e131c3f8549c65f391e040d5f5b35e","unresolved":false,"context_lines":[{"line_number":301,"context_line":"                # else, plaintext: nothing to change"},{"line_number":302,"context_line":""},{"line_number":303,"context_line":"                if not chunk:"},{"line_number":304,"context_line":"                    # TODO - determine the right error code to return"},{"line_number":305,"context_line":"                    self.logger.error(\"Could not construct container listing.\")"},{"line_number":306,"context_line":"                    raise HTTPInternalServerError(\"Couldn\u0027t construct listing\")"},{"line_number":307,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"ba8a016a_057d20e7","line":304,"in_reply_to":"da85f559_cba3969d","updated":"2015-11-20 16:37:15.000000000","message":"I\u0027m going to remove this check and wait for Janie to shout if she thinks it should be there. I\u0027m not sure what error case its catching.","commit_id":"a3ef567ace8661de3f054f0fc8058c62c1e08776"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"4ce4350e3facc6c8bfb8358522651146e584e4bc","unresolved":false,"context_lines":[{"line_number":316,"context_line":"            close_method \u003d getattr(body_iter, \u0027close\u0027, None)"},{"line_number":317,"context_line":"            if callable(close_method):"},{"line_number":318,"context_line":"                close_method()"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"        mod_resp_headers \u003d ["},{"line_number":321,"context_line":"            (h, v) for h, v in self._response_headers"},{"line_number":322,"context_line":"            if h.lower() !\u003d \u0027content-length\u0027]"}],"source_content_type":"text/x-python","patch_set":13,"id":"da85f559_8bc4ae40","line":319,"updated":"2015-11-08 20:52:09.000000000","message":"As an alternative can _response_headers[\"content-length\"] just be modified in place ? Or is it immutable.","commit_id":"a3ef567ace8661de3f054f0fc8058c62c1e08776"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"590cbdafc3e131c3f8549c65f391e040d5f5b35e","unresolved":false,"context_lines":[{"line_number":316,"context_line":"            close_method \u003d getattr(body_iter, \u0027close\u0027, None)"},{"line_number":317,"context_line":"            if callable(close_method):"},{"line_number":318,"context_line":"                close_method()"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"        mod_resp_headers \u003d ["},{"line_number":321,"context_line":"            (h, v) for h, v in self._response_headers"},{"line_number":322,"context_line":"            if h.lower() !\u003d \u0027content-length\u0027]"}],"source_content_type":"text/x-python","patch_set":13,"id":"ba8a016a_852110b7","line":319,"in_reply_to":"da85f559_8bc4ae40","updated":"2015-11-20 16:37:15.000000000","message":"the h,v pair tuple would be immutable","commit_id":"a3ef567ace8661de3f054f0fc8058c62c1e08776"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"4ce4350e3facc6c8bfb8358522651146e584e4bc","unresolved":false,"context_lines":[{"line_number":360,"context_line":"        # TODO - decode/decrypt etag when not using FakeFooters"},{"line_number":361,"context_line":"        # if etag and (len(etag) \u003e constraints.ETAG_LENGTH):"},{"line_number":362,"context_line":"        return obj_dict"},{"line_number":363,"context_line":""},{"line_number":364,"context_line":"    def process_xml_resp(self, keys, chunk):"},{"line_number":365,"context_line":"        tree \u003d minidom.parseString(chunk)"},{"line_number":366,"context_line":"        cont \u003d []"}],"source_content_type":"text/x-python","patch_set":13,"id":"da85f559_2b87c210","line":363,"updated":"2015-11-08 20:52:09.000000000","message":"So part (not all mind you) of this logic seems very similar to container/server.py.  I\u0027ll point the specific block I\u0027m referring too below.","commit_id":"a3ef567ace8661de3f054f0fc8058c62c1e08776"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"590cbdafc3e131c3f8549c65f391e040d5f5b35e","unresolved":false,"context_lines":[{"line_number":360,"context_line":"        # TODO - decode/decrypt etag when not using FakeFooters"},{"line_number":361,"context_line":"        # if etag and (len(etag) \u003e constraints.ETAG_LENGTH):"},{"line_number":362,"context_line":"        return obj_dict"},{"line_number":363,"context_line":""},{"line_number":364,"context_line":"    def process_xml_resp(self, keys, chunk):"},{"line_number":365,"context_line":"        tree \u003d minidom.parseString(chunk)"},{"line_number":366,"context_line":"        cont \u003d []"}],"source_content_type":"text/x-python","patch_set":13,"id":"ba8a016a_172a337f","line":363,"in_reply_to":"da85f559_2b87c210","updated":"2015-11-20 16:37:15.000000000","message":"I think this method can be simplified by parsing the xml and modifying content-type elements in place.","commit_id":"a3ef567ace8661de3f054f0fc8058c62c1e08776"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"4ce4350e3facc6c8bfb8358522651146e584e4bc","unresolved":false,"context_lines":[{"line_number":382,"context_line":""},{"line_number":383,"context_line":"            cont.append(objects)"},{"line_number":384,"context_line":"            cont_name \u003d obj.attributes.getNamedItem(\"name\").value"},{"line_number":385,"context_line":"        doc \u003d Element(\u0027container\u0027, name\u003dcont_name)"},{"line_number":386,"context_line":"        for obj_hash in cont:"},{"line_number":387,"context_line":"            if child_nodes:"},{"line_number":388,"context_line":"                for index in range(0, child_nodes.length):"}],"source_content_type":"text/x-python","patch_set":13,"id":"da85f559_ab73b24c","line":385,"updated":"2015-11-08 20:52:09.000000000","message":"This section is what I was referring to above, I wonder if there\u0027s any way we can combine some of this logic;  I can take a look at this in another patch set though.  I\u0027d need to understand this all better to be able to do that, so in the meantime feel free to let me know if this is just a silly idea either way ; )","commit_id":"a3ef567ace8661de3f054f0fc8058c62c1e08776"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"4ce4350e3facc6c8bfb8358522651146e584e4bc","unresolved":false,"context_lines":[{"line_number":417,"context_line":"            \u0027\u003c?xml version\u003d\"1.0\" encoding\u003d\"UTF-8\"?\u003e\u0027, 1)"},{"line_number":418,"context_line":""},{"line_number":419,"context_line":""},{"line_number":420,"context_line":"class Decrypter(object):"},{"line_number":421,"context_line":""},{"line_number":422,"context_line":"    def __init__(self, app, conf):"},{"line_number":423,"context_line":"        self.app \u003d app"}],"source_content_type":"text/x-python","patch_set":13,"id":"da85f559_6bd5ca41","line":420,"updated":"2015-11-08 20:52:09.000000000","message":"NIT - Consider adding a DOC string to indicate this class atm handles object and container only (i.e. not account level).","commit_id":"a3ef567ace8661de3f054f0fc8058c62c1e08776"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"4ce4350e3facc6c8bfb8358522651146e584e4bc","unresolved":false,"context_lines":[{"line_number":443,"context_line":""},{"line_number":444,"context_line":"        if parts[2] and hasattr(DecrypterContContext, req.method):"},{"line_number":445,"context_line":"            # handle only those request methods that may require keys"},{"line_number":446,"context_line":"            km_context \u003d DecrypterContContext(self, self.logger)"},{"line_number":447,"context_line":"            try:"},{"line_number":448,"context_line":"                return getattr(km_context, req.method)(req, start_response)"},{"line_number":449,"context_line":"            except HTTPException as err_resp:"}],"source_content_type":"text/x-python","patch_set":13,"id":"da85f559_ebda1a78","line":446,"updated":"2015-11-08 20:52:09.000000000","message":"Was debating if there was a way to combine the object / container blocks as the try/except blocks are identical but everything I come up with ends up being more code overall and uglier nested IF statements : )  Looks great !","commit_id":"a3ef567ace8661de3f054f0fc8058c62c1e08776"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"590cbdafc3e131c3f8549c65f391e040d5f5b35e","unresolved":false,"context_lines":[{"line_number":443,"context_line":""},{"line_number":444,"context_line":"        if parts[2] and hasattr(DecrypterContContext, req.method):"},{"line_number":445,"context_line":"            # handle only those request methods that may require keys"},{"line_number":446,"context_line":"            km_context \u003d DecrypterContContext(self, self.logger)"},{"line_number":447,"context_line":"            try:"},{"line_number":448,"context_line":"                return getattr(km_context, req.method)(req, start_response)"},{"line_number":449,"context_line":"            except HTTPException as err_resp:"}],"source_content_type":"text/x-python","patch_set":13,"id":"ba8a016a_2df12a96","line":446,"in_reply_to":"da85f559_ebda1a78","updated":"2015-11-20 16:37:15.000000000","message":"good spot , it think i see a way to simplify.","commit_id":"a3ef567ace8661de3f054f0fc8058c62c1e08776"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"743ba07e1af40b81289322232354677fdaf3fbd9","unresolved":false,"context_lines":[{"line_number":300,"context_line":""},{"line_number":301,"context_line":"        out_content_type \u003d get_listing_content_type(req)"},{"line_number":302,"context_line":""},{"line_number":303,"context_line":"        # Pre-process the response body since the content-length will change"},{"line_number":304,"context_line":"        body_iter \u003d iter(app_resp)"},{"line_number":305,"context_line":"        new_body \u003d []"},{"line_number":306,"context_line":"        new_total_len \u003d 0"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba8a016a_f20be429","line":303,"updated":"2015-11-21 06:38:51.000000000","message":"remove comment if we end up removing the second set of streaming.","commit_id":"07643f35b708b91ad83de5c898b0bd0e4c2cdd96"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bbdfd73b831cdb062a196e265f90c4c11782a82f","unresolved":false,"context_lines":[{"line_number":300,"context_line":""},{"line_number":301,"context_line":"        out_content_type \u003d get_listing_content_type(req)"},{"line_number":302,"context_line":""},{"line_number":303,"context_line":"        # Pre-process the response body since the content-length will change"},{"line_number":304,"context_line":"        body_iter \u003d iter(app_resp)"},{"line_number":305,"context_line":"        new_body \u003d []"},{"line_number":306,"context_line":"        new_total_len \u003d 0"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba8a016a_48ca1c1c","line":303,"in_reply_to":"ba8a016a_f20be429","updated":"2015-11-23 11:36:46.000000000","message":"Done","commit_id":"07643f35b708b91ad83de5c898b0bd0e4c2cdd96"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"743ba07e1af40b81289322232354677fdaf3fbd9","unresolved":false,"context_lines":[{"line_number":307,"context_line":"        try:"},{"line_number":308,"context_line":"            chunk \u003d body_iter.next()"},{"line_number":309,"context_line":"            # TODO: don\u0027t we need to read the whole body before processing"},{"line_number":310,"context_line":"            # json or xml?"},{"line_number":311,"context_line":"            while chunk:"},{"line_number":312,"context_line":"                if out_content_type \u003d\u003d \u0027application/json\u0027:"},{"line_number":313,"context_line":"                    chunk \u003d self.process_json_resp(keys, chunk)"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba8a016a_92861864","line":310,"updated":"2015-11-21 06:38:51.000000000","message":"seems like we would.  I still dont know if the second set of streaming here is necessary (see that below).\n\nAlso, if this is incorrect, then maybe there should be a test somewhere with a container listing that is longer than a chunk size - and it should be failing in this case.  i will look into this.","commit_id":"07643f35b708b91ad83de5c898b0bd0e4c2cdd96"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"735bd983f69cfb4b32428d749bb2a259386fd512","unresolved":false,"context_lines":[{"line_number":307,"context_line":"        try:"},{"line_number":308,"context_line":"            chunk \u003d body_iter.next()"},{"line_number":309,"context_line":"            # TODO: don\u0027t we need to read the whole body before processing"},{"line_number":310,"context_line":"            # json or xml?"},{"line_number":311,"context_line":"            while chunk:"},{"line_number":312,"context_line":"                if out_content_type \u003d\u003d \u0027application/json\u0027:"},{"line_number":313,"context_line":"                    chunk \u003d self.process_json_resp(keys, chunk)"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba8a016a_d071a645","line":310,"in_reply_to":"ba8a016a_087094db","updated":"2015-11-24 01:42:03.000000000","message":"ok, sounds good.  thx!","commit_id":"07643f35b708b91ad83de5c898b0bd0e4c2cdd96"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bbdfd73b831cdb062a196e265f90c4c11782a82f","unresolved":false,"context_lines":[{"line_number":307,"context_line":"        try:"},{"line_number":308,"context_line":"            chunk \u003d body_iter.next()"},{"line_number":309,"context_line":"            # TODO: don\u0027t we need to read the whole body before processing"},{"line_number":310,"context_line":"            # json or xml?"},{"line_number":311,"context_line":"            while chunk:"},{"line_number":312,"context_line":"                if out_content_type \u003d\u003d \u0027application/json\u0027:"},{"line_number":313,"context_line":"                    chunk \u003d self.process_json_resp(keys, chunk)"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba8a016a_087094db","line":310,"in_reply_to":"ba8a016a_643724e4","updated":"2015-11-23 11:36:46.000000000","message":"I don\u0027t think we need to handle the body in chunks. Based on how the container server assembles the body in one chunk (with max listing length of 10000) and how SLO and DLO read entire manifest or listing bodies before processing, I think we\u0027re ok to read entire body here before processing.","commit_id":"07643f35b708b91ad83de5c898b0bd0e4c2cdd96"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3e75bd5d41f325f3f31302b0ae525df20c3aa5f1","unresolved":false,"context_lines":[{"line_number":307,"context_line":"        try:"},{"line_number":308,"context_line":"            chunk \u003d body_iter.next()"},{"line_number":309,"context_line":"            # TODO: don\u0027t we need to read the whole body before processing"},{"line_number":310,"context_line":"            # json or xml?"},{"line_number":311,"context_line":"            while chunk:"},{"line_number":312,"context_line":"                if out_content_type \u003d\u003d \u0027application/json\u0027:"},{"line_number":313,"context_line":"                    chunk \u003d self.process_json_resp(keys, chunk)"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba8a016a_643724e4","line":310,"in_reply_to":"ba8a016a_8408082a","updated":"2015-11-21 20:04:38.000000000","message":"Ok, so ... maybe there is a way to still stream and use a json parser: https://pypi.python.org/pypi/ijson\n\nis an incremental json parser.\n\nI added a trello card for this work (includes writing a test):\nhttps://trello.com/c/3ZN6JEqC/67-use-ijson-for-decrypt-container-listing\n\nso we could move this along and it will not be forgotten.","commit_id":"07643f35b708b91ad83de5c898b0bd0e4c2cdd96"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"0ce6927f9f0de37213499cae15f5dcc5fdf49169","unresolved":false,"context_lines":[{"line_number":307,"context_line":"        try:"},{"line_number":308,"context_line":"            chunk \u003d body_iter.next()"},{"line_number":309,"context_line":"            # TODO: don\u0027t we need to read the whole body before processing"},{"line_number":310,"context_line":"            # json or xml?"},{"line_number":311,"context_line":"            while chunk:"},{"line_number":312,"context_line":"                if out_content_type \u003d\u003d \u0027application/json\u0027:"},{"line_number":313,"context_line":"                    chunk \u003d self.process_json_resp(keys, chunk)"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba8a016a_e2af8b29","line":310,"in_reply_to":"ba8a016a_92861864","updated":"2015-11-21 17:27:06.000000000","message":"Once the response (app_resp) is here, we are not measuring the \"chunk size\" anywhere right? We are merely iterating through it. Am I missing something? Or by chunk size you mean, the cipher block size?","commit_id":"07643f35b708b91ad83de5c898b0bd0e4c2cdd96"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"61acc89182d8f0ea86fcd493be698219d9125ec4","unresolved":false,"context_lines":[{"line_number":307,"context_line":"        try:"},{"line_number":308,"context_line":"            chunk \u003d body_iter.next()"},{"line_number":309,"context_line":"            # TODO: don\u0027t we need to read the whole body before processing"},{"line_number":310,"context_line":"            # json or xml?"},{"line_number":311,"context_line":"            while chunk:"},{"line_number":312,"context_line":"                if out_content_type \u003d\u003d \u0027application/json\u0027:"},{"line_number":313,"context_line":"                    chunk \u003d self.process_json_resp(keys, chunk)"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba8a016a_8408082a","line":310,"in_reply_to":"ba8a016a_92861864","updated":"2015-11-21 19:23:40.000000000","message":"after some sleep, I have realized ... of course this is a problem.  I don\u0027t know why I didn\u0027t think of it when writing this.  I don\u0027t know how we fix this in a \u0027good\u0027 way.  \n\nWe have to process the entire response (no streaming) in order to process either json or xml.  There is no way to process only part of the json - unless we write a parser that doesn\u0027t require full json, but rather just looks for the items we need to decrypt.  that parser would have to ensure that enough bytes were streamed to finish any string that needs decrypting.","commit_id":"07643f35b708b91ad83de5c898b0bd0e4c2cdd96"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"61acc89182d8f0ea86fcd493be698219d9125ec4","unresolved":false,"context_lines":[{"line_number":307,"context_line":"        try:"},{"line_number":308,"context_line":"            chunk \u003d body_iter.next()"},{"line_number":309,"context_line":"            # TODO: don\u0027t we need to read the whole body before processing"},{"line_number":310,"context_line":"            # json or xml?"},{"line_number":311,"context_line":"            while chunk:"},{"line_number":312,"context_line":"                if out_content_type \u003d\u003d \u0027application/json\u0027:"},{"line_number":313,"context_line":"                    chunk \u003d self.process_json_resp(keys, chunk)"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba8a016a_a40d0c39","line":310,"in_reply_to":"ba8a016a_e2af8b29","updated":"2015-11-21 19:23:40.000000000","message":"I just mean the size of what is called a \"chunk\" in this routine.","commit_id":"07643f35b708b91ad83de5c898b0bd0e4c2cdd96"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"743ba07e1af40b81289322232354677fdaf3fbd9","unresolved":false,"context_lines":[{"line_number":335,"context_line":"        start_response(self._response_status,"},{"line_number":336,"context_line":"                       mod_resp_headers,"},{"line_number":337,"context_line":"                       self._response_exc_info)"},{"line_number":338,"context_line":""},{"line_number":339,"context_line":"        # TODO - is streaming still necessary?"},{"line_number":340,"context_line":"        def iter_response(iterable):"},{"line_number":341,"context_line":"            iterator \u003d iter(iterable)"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba8a016a_d547aa49","line":338,"updated":"2015-11-21 06:38:51.000000000","message":"i guess we could try to take this out now and see if it works.  I will give it a shot.","commit_id":"07643f35b708b91ad83de5c898b0bd0e4c2cdd96"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bbdfd73b831cdb062a196e265f90c4c11782a82f","unresolved":false,"context_lines":[{"line_number":335,"context_line":"        start_response(self._response_status,"},{"line_number":336,"context_line":"                       mod_resp_headers,"},{"line_number":337,"context_line":"                       self._response_exc_info)"},{"line_number":338,"context_line":""},{"line_number":339,"context_line":"        # TODO - is streaming still necessary?"},{"line_number":340,"context_line":"        def iter_response(iterable):"},{"line_number":341,"context_line":"            iterator \u003d iter(iterable)"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba8a016a_e8d0b0cb","line":338,"in_reply_to":"ba8a016a_d547aa49","updated":"2015-11-23 11:36:46.000000000","message":"Done","commit_id":"07643f35b708b91ad83de5c898b0bd0e4c2cdd96"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"e0ccc8e7b53bcbc2ed6fc0853f93b5906caa1d81","unresolved":false,"context_lines":[{"line_number":16,"context_line":"import base64"},{"line_number":17,"context_line":"import json"},{"line_number":18,"context_line":"import urllib"},{"line_number":19,"context_line":"try:"},{"line_number":20,"context_line":"    import xml.etree.cElementTree as ElementTree"},{"line_number":21,"context_line":"except ImportError:"},{"line_number":22,"context_line":"    import xml.etree.ElementTree as ElementTree"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a8ffd7b_e6cc7a37","line":19,"updated":"2015-11-25 06:29:04.000000000","message":"Maybe a comment explaining this?","commit_id":"3aef74554aff1daa50fb566afbdc8ea84f1e45be"},{"author":{"_account_id":17156,"name":"Hamdi Roumani","email":"roumani@ca.ibm.com","username":"hroumani"},"change_message_id":"e0ccc8e7b53bcbc2ed6fc0853f93b5906caa1d81","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        crypto_meta \u003d {str(name): (base64.b64decode(value)"},{"line_number":50,"context_line":"                                   if name \u003d\u003d \u0027iv\u0027 else str(value))"},{"line_number":51,"context_line":"                       for name, value in json.loads(value).items()}"},{"line_number":52,"context_line":"    except (ValueError, TypeError) as e:"},{"line_number":53,"context_line":"        msg \u003d \"Could not decrypt. Bad crypto_meta: %r : %s\" % (value, e)"},{"line_number":54,"context_line":"        raise HTTPInternalServerError(body\u003dmsg, content_type\u003d\u0027text/plain\u0027)"},{"line_number":55,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"9a8ffd7b_51f73ed3","line":52,"updated":"2015-11-25 06:29:04.000000000","message":"Could not decode is maybe more accurate ?","commit_id":"3aef74554aff1daa50fb566afbdc8ea84f1e45be"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f3bc9a0e16ee72fb6e784f6aa733bf6f7eea9e0c","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        crypto_meta \u003d {str(name): (base64.b64decode(value)"},{"line_number":50,"context_line":"                                   if name \u003d\u003d \u0027iv\u0027 else str(value))"},{"line_number":51,"context_line":"                       for name, value in json.loads(value).items()}"},{"line_number":52,"context_line":"    except (ValueError, TypeError) as e:"},{"line_number":53,"context_line":"        msg \u003d \"Could not decrypt. Bad crypto_meta: %r : %s\" % (value, e)"},{"line_number":54,"context_line":"        raise HTTPInternalServerError(body\u003dmsg, content_type\u003d\u0027text/plain\u0027)"},{"line_number":55,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"9a8ffd7b_10f9a780","line":52,"in_reply_to":"9a8ffd7b_51f73ed3","updated":"2015-11-25 10:20:49.000000000","message":"So...in general at some point I\u0027d like to review the content of these messages, since they get returned to clients who have no idea what we are doing internally! I\u0027m not a fan of sharing implementation details in client error messages.","commit_id":"3aef74554aff1daa50fb566afbdc8ea84f1e45be"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"30fc467c2f73f880ab7a7d236de7bfdd43eea6f6","unresolved":false,"context_lines":[{"line_number":314,"context_line":"    def process_json_resp(self, keys, resp_iter):"},{"line_number":315,"context_line":"        \"\"\""},{"line_number":316,"context_line":"        Parses json body listing and decrypt content-type entries. Updates"},{"line_number":317,"context_line":"        Content-Type header with new body length and return a body iter."},{"line_number":318,"context_line":"        \"\"\""},{"line_number":319,"context_line":"        with closing_if_possible(resp_iter):"},{"line_number":320,"context_line":"            resp_body \u003d \u0027\u0027.join(resp_iter)"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a8ffd7b_ef16c1a6","line":317,"updated":"2015-11-24 11:14:34.000000000","message":"We are updating Content-length header value I suppose","commit_id":"3aef74554aff1daa50fb566afbdc8ea84f1e45be"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f3bc9a0e16ee72fb6e784f6aa733bf6f7eea9e0c","unresolved":false,"context_lines":[{"line_number":314,"context_line":"    def process_json_resp(self, keys, resp_iter):"},{"line_number":315,"context_line":"        \"\"\""},{"line_number":316,"context_line":"        Parses json body listing and decrypt content-type entries. Updates"},{"line_number":317,"context_line":"        Content-Type header with new body length and return a body iter."},{"line_number":318,"context_line":"        \"\"\""},{"line_number":319,"context_line":"        with closing_if_possible(resp_iter):"},{"line_number":320,"context_line":"            resp_body \u003d \u0027\u0027.join(resp_iter)"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a8ffd7b_303dcb2b","line":317,"in_reply_to":"9a8ffd7b_ef16c1a6","updated":"2015-11-25 10:20:49.000000000","message":"Argh thats a bug!","commit_id":"3aef74554aff1daa50fb566afbdc8ea84f1e45be"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"30fc467c2f73f880ab7a7d236de7bfdd43eea6f6","unresolved":false,"context_lines":[{"line_number":336,"context_line":"    def process_xml_resp(self, keys, resp_iter):"},{"line_number":337,"context_line":"        \"\"\""},{"line_number":338,"context_line":"        Parses xml body listing and decrypt content-type entries. Updates"},{"line_number":339,"context_line":"        Content-Type header with new body length and return a body iter."},{"line_number":340,"context_line":"        \"\"\""},{"line_number":341,"context_line":"        with closing_if_possible(resp_iter):"},{"line_number":342,"context_line":"            resp_body \u003d \u0027\u0027.join(resp_iter)"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a8ffd7b_0f20e5f6","line":339,"updated":"2015-11-24 11:14:34.000000000","message":"We are updating Content-length header value I suppose","commit_id":"3aef74554aff1daa50fb566afbdc8ea84f1e45be"}],"test/unit/common/middleware/test_decrypter.py":[{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"7dd01a713ca4dab39ba89644bb3f70ed75730a0d","unresolved":false,"context_lines":[{"line_number":285,"context_line":"            resp_hdr_val(\u0027content-type\u0027, headers) \u003d\u003d get_content_type())"},{"line_number":286,"context_line":"        self.assertTrue(resp_hdr_val(\u0027Etag\u0027, headers) \u003d\u003d md5hex(fake_app_body))"},{"line_number":287,"context_line":"        # TODO - somehow assert that encrypt/decrypt happened"},{"line_number":288,"context_line":""},{"line_number":289,"context_line":"    def test_get_req_hdr_decrypt_throws(self, fake_get_crpyto):"},{"line_number":290,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027})"},{"line_number":291,"context_line":"        fake_app_body \u003d \u0027FAKE APP\u0027"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa1b9901_00ed0a25","line":288,"updated":"2015-08-21 16:23:12.000000000","message":"Is this test useful when we have real crypto in place? This piece can\u0027t probably be tested using real crypto, since you wouldn\u0027t know which error message to assertwith?","commit_id":"35546b1da8119b461091ad8a1aecfb510032a379"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"e10f406634742c0d57bc6e13da687b230c898c16","unresolved":false,"context_lines":[{"line_number":285,"context_line":"            resp_hdr_val(\u0027content-type\u0027, headers) \u003d\u003d get_content_type())"},{"line_number":286,"context_line":"        self.assertTrue(resp_hdr_val(\u0027Etag\u0027, headers) \u003d\u003d md5hex(fake_app_body))"},{"line_number":287,"context_line":"        # TODO - somehow assert that encrypt/decrypt happened"},{"line_number":288,"context_line":""},{"line_number":289,"context_line":"    def test_get_req_hdr_decrypt_throws(self, fake_get_crpyto):"},{"line_number":290,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027})"},{"line_number":291,"context_line":"        fake_app_body \u003d \u0027FAKE APP\u0027"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa1b9901_c1b4f183","line":288,"in_reply_to":"fa1b9901_00ed0a25","updated":"2015-08-21 18:54:35.000000000","message":"With your changes that integrate real crypto, you could change this test to test a specific error from the real crypto.  For example, you can feed the test an invalid key or an invalid iv.  You can see the expected behavior in the test_crypto class.","commit_id":"35546b1da8119b461091ad8a1aecfb510032a379"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"7dd01a713ca4dab39ba89644bb3f70ed75730a0d","unresolved":false,"context_lines":[{"line_number":429,"context_line":"        s, h, b, caught_exc \u003d fake_app(req.environ, start_response)"},{"line_number":430,"context_line":"        # TODO - ADD BACK WHEN no longer using FakeFooters"},{"line_number":431,"context_line":"        # if not caught_exc:"},{"line_number":432,"context_line":"        #     self.fail(\u0027Expected HTTPUnprocessableEntity to be raised.\u0027)"},{"line_number":433,"context_line":"        # self.assertEqual(\u0027422 Unprocessable Entity\u0027, caught_exc.status)"},{"line_number":434,"context_line":""},{"line_number":435,"context_line":"    def test_missing_keys(self, fake_get_crpyto):"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa1b9901_00098add","line":432,"updated":"2015-08-21 16:23:12.000000000","message":"Currently this test doesn\u0027t do anything. caught_exc wouldn\u0027t have a \u0027status\u0027 attribute. Could you explain why we need this in place?","commit_id":"35546b1da8119b461091ad8a1aecfb510032a379"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"e10f406634742c0d57bc6e13da687b230c898c16","unresolved":false,"context_lines":[{"line_number":429,"context_line":"        s, h, b, caught_exc \u003d fake_app(req.environ, start_response)"},{"line_number":430,"context_line":"        # TODO - ADD BACK WHEN no longer using FakeFooters"},{"line_number":431,"context_line":"        # if not caught_exc:"},{"line_number":432,"context_line":"        #     self.fail(\u0027Expected HTTPUnprocessableEntity to be raised.\u0027)"},{"line_number":433,"context_line":"        # self.assertEqual(\u0027422 Unprocessable Entity\u0027, caught_exc.status)"},{"line_number":434,"context_line":""},{"line_number":435,"context_line":"    def test_missing_keys(self, fake_get_crpyto):"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa1b9901_4461cfd2","line":432,"in_reply_to":"fa1b9901_00098add","updated":"2015-08-21 18:54:35.000000000","message":"I think this was written when there was a check in the decrypter on the etag.  But some review feedback led to that check being removed.  This test should have been removed with that.   We can remove it for now.  I am still a little concerned that the system is not asserting that the decrypted object matches the un-encrypted version given to the system by the client.  But I don\u0027t know exactly what to do for that now.","commit_id":"35546b1da8119b461091ad8a1aecfb510032a379"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"30f23092e2611e7fff41d28056384a7408d09cda","unresolved":false,"context_lines":[{"line_number":268,"context_line":"        self.assertEqual(resp.headers[\u0027Content-Type\u0027], \u0027text/plain\u0027)"},{"line_number":269,"context_line":"        self.assertEqual(resp.headers[\u0027x-object-meta-test\u0027], \u0027encrypt me\u0027)"},{"line_number":270,"context_line":"        self.assertEqual(resp.headers[\u0027x-object-sysmeta-test\u0027],"},{"line_number":271,"context_line":"                         \u0027do not encrypt me\u0027)"},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"    def test_multiseg_get_obj(self):"},{"line_number":274,"context_line":"        env \u003d {\u0027REQUEST_METHOD\u0027: \u0027GET\u0027,"}],"source_content_type":"text/x-python","patch_set":13,"id":"da85f559_32324a60","line":271,"updated":"2015-11-11 14:50:58.000000000","message":"testing encrypted metadata? But this doesn\u0027t look like we are?","commit_id":"a3ef567ace8661de3f054f0fc8058c62c1e08776"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"590cbdafc3e131c3f8549c65f391e040d5f5b35e","unresolved":false,"context_lines":[{"line_number":268,"context_line":"        self.assertEqual(resp.headers[\u0027Content-Type\u0027], \u0027text/plain\u0027)"},{"line_number":269,"context_line":"        self.assertEqual(resp.headers[\u0027x-object-meta-test\u0027], \u0027encrypt me\u0027)"},{"line_number":270,"context_line":"        self.assertEqual(resp.headers[\u0027x-object-sysmeta-test\u0027],"},{"line_number":271,"context_line":"                         \u0027do not encrypt me\u0027)"},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"    def test_multiseg_get_obj(self):"},{"line_number":274,"context_line":"        env \u003d {\u0027REQUEST_METHOD\u0027: \u0027GET\u0027,"}],"source_content_type":"text/x-python","patch_set":13,"id":"ba8a016a_8d505660","line":271,"in_reply_to":"da85f559_32324a60","updated":"2015-11-20 16:37:15.000000000","message":"the sysmeta would be set on PUT (unencrypted), the user meta on a POST","commit_id":"a3ef567ace8661de3f054f0fc8058c62c1e08776"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"bcb272a98d74c9cf41795d67cda09aec6aec6d74","unresolved":false,"context_lines":[{"line_number":506,"context_line":"        self.assertEqual(3, len(names))"},{"line_number":507,"context_line":"        self.assertIn(\u0027testfile1\u0027, names)"},{"line_number":508,"context_line":"        self.assertIn(\u0027testfile2\u0027, names)"},{"line_number":509,"context_line":"        self.assertIn(\u0027\u0027, names)"},{"line_number":510,"context_line":""},{"line_number":511,"context_line":"    def test_cont_get_json_req(self):"},{"line_number":512,"context_line":"        content_type_1 \u003d u\u0027\\uF10F\\uD20D\\uB30B\\u9409\u0027"}],"source_content_type":"text/x-python","patch_set":16,"id":"ba8a016a_30127263","line":509,"updated":"2015-11-24 01:42:23.000000000","message":"oops, was there really not a test for the simple text case?  Thanks for fixing that.","commit_id":"3aef74554aff1daa50fb566afbdc8ea84f1e45be"}]}
