)]}'
{"refstack/api/controllers/results.py":[{"author":{"_account_id":10234,"name":"Andrey Pavlov","email":"andrey.mp@gmail.com","username":"andrey-mp"},"change_message_id":"bfa20939d1e6407d03270291a3a554faf7143f87","unresolved":false,"context_lines":[{"line_number":46,"context_line":"        if (api_utils.check_user_is_foundation_admin() or"},{"line_number":47,"context_line":"           api_utils.check_owner(test_id)):"},{"line_number":48,"context_line":"                return test_info[\u0027meta\u0027]"},{"line_number":49,"context_line":"        else:"},{"line_number":50,"context_line":"            return {k: v for k, v in six.iteritems(test_info[\u0027meta\u0027])"},{"line_number":51,"context_line":"                    if k in self.rw_access_keys}"},{"line_number":52,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"bacf61ea_89ec392b","line":49,"range":{"start_line":49,"start_character":8,"end_line":49,"end_character":12},"updated":"2016-08-01 12:06:21.000000000","message":"\u0027else\u0027 is not needed here - just return filtered data.\n(first block always returns from function.)","commit_id":"17f3bdd3d2bc8633ea53f0fcad480bbf8ff0d358"},{"author":{"_account_id":9626,"name":"Paul Van Eck","email":"pvaneck@us.ibm.com","username":"pvaneck"},"change_message_id":"5fb82be9e6ffd31a4271c00b1bf8471f3711123d","unresolved":false,"context_lines":[{"line_number":46,"context_line":"        if (api_utils.check_user_is_foundation_admin() or"},{"line_number":47,"context_line":"           api_utils.check_owner(test_id)):"},{"line_number":48,"context_line":"                return test_info[\u0027meta\u0027]"},{"line_number":49,"context_line":"        else:"},{"line_number":50,"context_line":"            return {k: v for k, v in six.iteritems(test_info[\u0027meta\u0027])"},{"line_number":51,"context_line":"                    if k in self.rw_access_keys}"},{"line_number":52,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"bacf61ea_a34e5535","line":49,"range":{"start_line":49,"start_character":8,"end_line":49,"end_character":12},"in_reply_to":"bacf61ea_89ec392b","updated":"2016-08-06 23:01:49.000000000","message":"Done","commit_id":"17f3bdd3d2bc8633ea53f0fcad480bbf8ff0d358"},{"author":{"_account_id":10234,"name":"Andrey Pavlov","email":"andrey.mp@gmail.com","username":"andrey-mp"},"change_message_id":"bfa20939d1e6407d03270291a3a554faf7143f87","unresolved":false,"context_lines":[{"line_number":53,"context_line":"    @pecan.expose(\u0027json\u0027)"},{"line_number":54,"context_line":"    def get_one(self, test_id, key):"},{"line_number":55,"context_line":"        \"\"\"Get value for key from test run metadata.\"\"\""},{"line_number":56,"context_line":"        if (api_utils.check_user_is_foundation_admin() or"},{"line_number":57,"context_line":"           api_utils.check_owner(test_id) or key in self.rw_access_keys):"},{"line_number":58,"context_line":"                return db.get_test_meta_key(test_id, key)"},{"line_number":59,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"bacf61ea_2971cd44","line":56,"range":{"start_line":56,"start_character":8,"end_line":56,"end_character":10},"updated":"2016-08-01 12:06:21.000000000","message":"if this condition fails - what happens? maybe code should raise exception?","commit_id":"17f3bdd3d2bc8633ea53f0fcad480bbf8ff0d358"},{"author":{"_account_id":9626,"name":"Paul Van Eck","email":"pvaneck@us.ibm.com","username":"pvaneck"},"change_message_id":"5fb82be9e6ffd31a4271c00b1bf8471f3711123d","unresolved":false,"context_lines":[{"line_number":53,"context_line":"    @pecan.expose(\u0027json\u0027)"},{"line_number":54,"context_line":"    def get_one(self, test_id, key):"},{"line_number":55,"context_line":"        \"\"\"Get value for key from test run metadata.\"\"\""},{"line_number":56,"context_line":"        if (api_utils.check_user_is_foundation_admin() or"},{"line_number":57,"context_line":"           api_utils.check_owner(test_id) or key in self.rw_access_keys):"},{"line_number":58,"context_line":"                return db.get_test_meta_key(test_id, key)"},{"line_number":59,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"bacf61ea_435679ce","line":56,"range":{"start_line":56,"start_character":8,"end_line":56,"end_character":10},"in_reply_to":"bacf61ea_2971cd44","updated":"2016-08-06 23:01:49.000000000","message":"Yea, I\u0027ll have it return an HTTP Forbidden.","commit_id":"17f3bdd3d2bc8633ea53f0fcad480bbf8ff0d358"},{"author":{"_account_id":10234,"name":"Andrey Pavlov","email":"andrey.mp@gmail.com","username":"andrey-mp"},"change_message_id":"bfa20939d1e6407d03270291a3a554faf7143f87","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    def post(self, test_id, key):"},{"line_number":63,"context_line":"        \"\"\"Save value for key in test run metadata.\"\"\""},{"line_number":64,"context_line":"        if key not in self.rw_access_keys:"},{"line_number":65,"context_line":"                pecan.abort(403)"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"        db.save_test_meta_item(test_id, key, pecan.request.body)"},{"line_number":68,"context_line":"        pecan.response.status \u003d 201"}],"source_content_type":"text/x-python","patch_set":1,"id":"bacf61ea_c940f109","line":65,"range":{"start_line":65,"start_character":0,"end_line":65,"end_character":16},"updated":"2016-08-01 12:06:21.000000000","message":"indent is big.","commit_id":"17f3bdd3d2bc8633ea53f0fcad480bbf8ff0d358"},{"author":{"_account_id":9626,"name":"Paul Van Eck","email":"pvaneck@us.ibm.com","username":"pvaneck"},"change_message_id":"5fb82be9e6ffd31a4271c00b1bf8471f3711123d","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    def post(self, test_id, key):"},{"line_number":63,"context_line":"        \"\"\"Save value for key in test run metadata.\"\"\""},{"line_number":64,"context_line":"        if key not in self.rw_access_keys:"},{"line_number":65,"context_line":"                pecan.abort(403)"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"        db.save_test_meta_item(test_id, key, pecan.request.body)"},{"line_number":68,"context_line":"        pecan.response.status \u003d 201"}],"source_content_type":"text/x-python","patch_set":1,"id":"bacf61ea_036001a4","line":65,"range":{"start_line":65,"start_character":0,"end_line":65,"end_character":16},"in_reply_to":"bacf61ea_c940f109","updated":"2016-08-06 23:01:49.000000000","message":"Done","commit_id":"17f3bdd3d2bc8633ea53f0fcad480bbf8ff0d358"},{"author":{"_account_id":9377,"name":"Sergey Slipushenko","email":"slipushenko@gmail.com","username":"sslypushenko"},"change_message_id":"cddcb30af90e5c77a6e4b33b80d9a3c9a4063a7d","unresolved":false,"context_lines":[{"line_number":53,"context_line":"    @pecan.expose(\u0027json\u0027)"},{"line_number":54,"context_line":"    def get_one(self, test_id, key):"},{"line_number":55,"context_line":"        \"\"\"Get value for key from test run metadata.\"\"\""},{"line_number":56,"context_line":"        if (api_utils.check_user_is_foundation_admin() or"},{"line_number":57,"context_line":"           api_utils.check_owner(test_id) or key in self.rw_access_keys):"},{"line_number":58,"context_line":"                return db.get_test_meta_key(test_id, key)"},{"line_number":59,"context_line":"        pecan.abort(403)"},{"line_number":60,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9ad45d7e_a82f25a0","line":57,"range":{"start_line":56,"start_character":12,"end_line":57,"end_character":41},"updated":"2016-08-08 15:05:32.000000000","message":"It looks pretty familiar to api_utils.check_permissions(level\u003dconst.ROLE_OWNER)\nIf it is not enough, check_permissions can be updated","commit_id":"30f92d27a2ee23ad364f73fa62ab6af1de4d9811"},{"author":{"_account_id":9626,"name":"Paul Van Eck","email":"pvaneck@us.ibm.com","username":"pvaneck"},"change_message_id":"8fb2356832e275184969f84ba07d5ec8c998517a","unresolved":false,"context_lines":[{"line_number":53,"context_line":"    @pecan.expose(\u0027json\u0027)"},{"line_number":54,"context_line":"    def get_one(self, test_id, key):"},{"line_number":55,"context_line":"        \"\"\"Get value for key from test run metadata.\"\"\""},{"line_number":56,"context_line":"        if (api_utils.check_user_is_foundation_admin() or"},{"line_number":57,"context_line":"           api_utils.check_owner(test_id) or key in self.rw_access_keys):"},{"line_number":58,"context_line":"                return db.get_test_meta_key(test_id, key)"},{"line_number":59,"context_line":"        pecan.abort(403)"},{"line_number":60,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9ad45d7e_cdca146e","line":57,"range":{"start_line":56,"start_character":12,"end_line":57,"end_character":41},"in_reply_to":"9ad45d7e_a82f25a0","updated":"2016-08-10 00:26:55.000000000","message":"Admittedly, there is some overlap here as both roles (USER and OWNER) should be able to access it, but the USER role should only be able to access keys in the rw_access_keys list. So, I don\u0027t want to add the check_permissions(level\u003dconst.ROLE_OWNER) decorator, as that would block normal users.\n\nThis endpoint doesn\u0027t seem to be hit much, if at all, so I don\u0027t particularly mind the overlap, but one thing I could do is just remove the check_permissions(level\u003dconst.ROLE_USER) decorator from these GET endpoints, and then do a get_user_role from here.\n\ni.e.\n\nrole \u003d api_utils.get_user_role(test_id)\nif role in (const.ROLE_FOUNDATION, const.ROLE_OWNER):\n    return db.get_test_meta_key(test_id, key)\nelif role in (const.ROLE_USER) and key in self.rw_access_keys:\n    return db.get_test_meta_key(test_id, key)\npecan.abort(403)\n\nSo we don\u0027t have functions like check_owner being called multiple times (once in decorator, once in function). If you think this would be preferable, I can update.","commit_id":"30f92d27a2ee23ad364f73fa62ab6af1de4d9811"},{"author":{"_account_id":9377,"name":"Sergey Slipushenko","email":"slipushenko@gmail.com","username":"sslypushenko"},"change_message_id":"cddcb30af90e5c77a6e4b33b80d9a3c9a4063a7d","unresolved":false,"context_lines":[{"line_number":61,"context_line":"    @api_utils.check_permissions(level\u003dconst.ROLE_OWNER)"},{"line_number":62,"context_line":"    @pecan.expose(\u0027json\u0027)"},{"line_number":63,"context_line":"    def post(self, test_id, key):"},{"line_number":64,"context_line":"        \"\"\"Save value for key in test run metadata.\"\"\""},{"line_number":65,"context_line":"        if key not in self.rw_access_keys:"},{"line_number":66,"context_line":"            pecan.abort(403)"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"        db.save_test_meta_item(test_id, key, pecan.request.body)"}],"source_content_type":"text/x-python","patch_set":2,"id":"9ad45d7e_289fb504","line":65,"range":{"start_line":64,"start_character":8,"end_line":65,"end_character":42},"updated":"2016-08-08 15:05:32.000000000","message":"Looks like code duplication. This specific check should be triggered for edit actions of MetadataController. So it can be implemented as decorator for MetadataController class.","commit_id":"30f92d27a2ee23ad364f73fa62ab6af1de4d9811"},{"author":{"_account_id":9626,"name":"Paul Van Eck","email":"pvaneck@us.ibm.com","username":"pvaneck"},"change_message_id":"8fb2356832e275184969f84ba07d5ec8c998517a","unresolved":false,"context_lines":[{"line_number":61,"context_line":"    @api_utils.check_permissions(level\u003dconst.ROLE_OWNER)"},{"line_number":62,"context_line":"    @pecan.expose(\u0027json\u0027)"},{"line_number":63,"context_line":"    def post(self, test_id, key):"},{"line_number":64,"context_line":"        \"\"\"Save value for key in test run metadata.\"\"\""},{"line_number":65,"context_line":"        if key not in self.rw_access_keys:"},{"line_number":66,"context_line":"            pecan.abort(403)"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"        db.save_test_meta_item(test_id, key, pecan.request.body)"}],"source_content_type":"text/x-python","patch_set":2,"id":"9ad45d7e_0a5ff20e","line":65,"range":{"start_line":64,"start_character":8,"end_line":65,"end_character":42},"in_reply_to":"9ad45d7e_289fb504","updated":"2016-08-10 00:26:55.000000000","message":"Created an in-class decorator for this.","commit_id":"30f92d27a2ee23ad364f73fa62ab6af1de4d9811"},{"author":{"_account_id":9377,"name":"Sergey Slipushenko","email":"slipushenko@gmail.com","username":"sslypushenko"},"change_message_id":"501ce923d1bfb94be22428dc2dc6a4476603f6cf","unresolved":false,"context_lines":[{"line_number":65,"context_line":"    @pecan.expose(\u0027json\u0027)"},{"line_number":66,"context_line":"    def get_one(self, test_id, key):"},{"line_number":67,"context_line":"        \"\"\"Get value for key from test run metadata.\"\"\""},{"line_number":68,"context_line":"        if (api_utils.check_user_is_foundation_admin() or"},{"line_number":69,"context_line":"           api_utils.check_owner(test_id) or key in self.rw_access_keys):"},{"line_number":70,"context_line":"                return db.get_test_meta_key(test_id, key)"},{"line_number":71,"context_line":"        pecan.abort(403)"},{"line_number":72,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9ad45d7e_2204f1c4","line":69,"range":{"start_line":68,"start_character":11,"end_line":69,"end_character":72},"updated":"2016-08-12 15:10:09.000000000","message":"I don\u0027t have fancy solution for now, just please move this check into separate function","commit_id":"d6845df1cd32b95faf7bfe1d8c77510586a58568"},{"author":{"_account_id":9626,"name":"Paul Van Eck","email":"pvaneck@us.ibm.com","username":"pvaneck"},"change_message_id":"a740323838fe0940a32d4d1fa4eaaa93487a48ec","unresolved":false,"context_lines":[{"line_number":53,"context_line":"    def get(self, test_id):"},{"line_number":54,"context_line":"        \"\"\"Get test run metadata.\"\"\""},{"line_number":55,"context_line":"        test_info \u003d db.get_test(test_id)"},{"line_number":56,"context_line":"        role \u003d api_utils.get_user_role(test_id)"},{"line_number":57,"context_line":"        if role in (const.ROLE_FOUNDATION, const.ROLE_OWNER):"},{"line_number":58,"context_line":"            return test_info[\u0027meta\u0027]"},{"line_number":59,"context_line":"        elif role in (const.ROLE_USER):"},{"line_number":60,"context_line":"            return {k: v for k, v in six.iteritems(test_info[\u0027meta\u0027])"},{"line_number":61,"context_line":"                    if k in self.rw_access_keys}"},{"line_number":62,"context_line":"        pecan.abort(403)"}],"source_content_type":"text/x-python","patch_set":5,"id":"7ac969e8_77318fec","line":59,"range":{"start_line":56,"start_character":8,"end_line":59,"end_character":39},"updated":"2016-08-13 07:28:20.000000000","message":"I think this way handles the different returns for different roles more aptly and clearly.","commit_id":"90d4ec5199d9519b8d66bf9a9d90bacf74d603e6"}]}
