)]}'
{"nova/exception.py":[{"author":{"_account_id":7634,"name":"Takashi Natsume","email":"takanattie@gmail.com","username":"natsumet"},"change_message_id":"ceb6ba0d7faf9a5305db7ede2099fc49bbcde4ed","unresolved":false,"context_lines":[{"line_number":1890,"context_line":"    msg_fmt \u003d _(\"The token \u0027%(token)s\u0027 is invalid or has expired\")"},{"line_number":1891,"context_line":""},{"line_number":1892,"context_line":""},{"line_number":1893,"context_line":"class TokenInUse(NovaException):"},{"line_number":1894,"context_line":"    msg_fmt \u003d _(\"The generated token is invalid\")"},{"line_number":1895,"context_line":""},{"line_number":1896,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"3f4b6375_aea8ffda","line":1893,"range":{"start_line":1893,"start_character":17,"end_line":1893,"end_character":30},"updated":"2017-10-30 08:48:58.000000000","message":"I wonder why it is not inherited from \u0027Invalid\u0027.\nIs there any reason for it?","commit_id":"3c20bd619e9e2d37caca91edf736734e06729ea9"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"34ad774d685ded91c2d99d808c5b3ebcb5189185","unresolved":false,"context_lines":[{"line_number":1890,"context_line":"    msg_fmt \u003d _(\"The token \u0027%(token)s\u0027 is invalid or has expired\")"},{"line_number":1891,"context_line":""},{"line_number":1892,"context_line":""},{"line_number":1893,"context_line":"class TokenInUse(NovaException):"},{"line_number":1894,"context_line":"    msg_fmt \u003d _(\"The generated token is invalid\")"},{"line_number":1895,"context_line":""},{"line_number":1896,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"df87a7cf_61525715","line":1893,"range":{"start_line":1893,"start_character":17,"end_line":1893,"end_character":30},"in_reply_to":"3f4b6375_aea8ffda","updated":"2017-12-12 19:56:09.000000000","message":"Probably just an oversight. Will inherit from Invalid.","commit_id":"3c20bd619e9e2d37caca91edf736734e06729ea9"}],"nova/objects/console_auth_token.py":[{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"fcc64497163149f384f5015f92d332f106427bc1","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        db_obj[\u0027token_hash\u0027] \u003d utils.get_sha256_str(self.token)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    def save(self, context):"},{"line_number":65,"context_line":"        pass"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    @base.remotable"},{"line_number":68,"context_line":"    def create(self):"}],"source_content_type":"text/x-python","patch_set":6,"id":"7aa08908_8aa8d8dc","line":65,"updated":"2016-06-07 18:31:43.000000000","message":"Can you remove the above method please?","commit_id":"a8f0ff682d40a223da9939a00d61f6485e07c58a"},{"author":{"_account_id":7461,"name":"Paul Murray","email":"pmurray@hpe.com","username":"ptm"},"change_message_id":"def4752519cb418b64f6a5d00a6cfac2974453a3","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        db_obj[\u0027token_hash\u0027] \u003d utils.get_sha256_str(self.token)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    def save(self, context):"},{"line_number":65,"context_line":"        pass"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    @base.remotable"},{"line_number":68,"context_line":"    def create(self):"}],"source_content_type":"text/x-python","patch_set":6,"id":"7aa08908_e0dce347","line":65,"in_reply_to":"7aa08908_8aa8d8dc","updated":"2016-06-08 14:07:19.000000000","message":"Oops, that was a place holder. Will do.","commit_id":"a8f0ff682d40a223da9939a00d61f6485e07c58a"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"fcc64497163149f384f5015f92d332f106427bc1","unresolved":false,"context_lines":[{"line_number":75,"context_line":"        db_obj \u003d db.console_auth_token_create(self._context, updates)"},{"line_number":76,"context_line":"        self._from_db_object(self._context, self, db_obj)"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    @base.remotable_classmethod"},{"line_number":79,"context_line":"    def authorize_console(cls, context, token, console_type, host, port,"},{"line_number":80,"context_line":"                          internal_access_path, instance_uuid, ttl):"},{"line_number":81,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"7aa08908_eab19c48","line":78,"updated":"2016-06-07 18:31:43.000000000","message":"How about just making this a remotable method instead of a remotable class method so that the caller can do something more like this:\n\n t \u003d objects.ConsoleAuthToken(context,\n         token\u003dtoken,\n         instance_uuid\u003dinstance.uuid,\n         console_type\u003dconsole_type,\n         host\u003dhost,\n         port\u003dport,\n         internal_access_path\u003dinternal_access_path)\n  t.authorize(ttl)\n\nand in the remotable method implementation you could do:\n\n @base.remotable\n def authorize(self, ttl)\n     self.expires \u003d timeutils.utcnow_ts() + ttl\n     self.create()\n\n     LOG.info(...)","commit_id":"a8f0ff682d40a223da9939a00d61f6485e07c58a"},{"author":{"_account_id":7461,"name":"Paul Murray","email":"pmurray@hpe.com","username":"ptm"},"change_message_id":"45e7b99eb2ad0bb59f61c9acdc09ab872f0f0303","unresolved":false,"context_lines":[{"line_number":75,"context_line":"        db_obj \u003d db.console_auth_token_create(self._context, updates)"},{"line_number":76,"context_line":"        self._from_db_object(self._context, self, db_obj)"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    @base.remotable_classmethod"},{"line_number":79,"context_line":"    def authorize_console(cls, context, token, console_type, host, port,"},{"line_number":80,"context_line":"                          internal_access_path, instance_uuid, ttl):"},{"line_number":81,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"7aa08908_8e438212","line":78,"in_reply_to":"7aa08908_9692894a","updated":"2016-06-08 16:47:51.000000000","message":"Actually, yeah it works, or course it does.\nDone","commit_id":"a8f0ff682d40a223da9939a00d61f6485e07c58a"},{"author":{"_account_id":7461,"name":"Paul Murray","email":"pmurray@hpe.com","username":"ptm"},"change_message_id":"def4752519cb418b64f6a5d00a6cfac2974453a3","unresolved":false,"context_lines":[{"line_number":75,"context_line":"        db_obj \u003d db.console_auth_token_create(self._context, updates)"},{"line_number":76,"context_line":"        self._from_db_object(self._context, self, db_obj)"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    @base.remotable_classmethod"},{"line_number":79,"context_line":"    def authorize_console(cls, context, token, console_type, host, port,"},{"line_number":80,"context_line":"                          internal_access_path, instance_uuid, ttl):"},{"line_number":81,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"7aa08908_9692894a","line":78,"in_reply_to":"7aa08908_eab19c48","updated":"2016-06-08 14:07:19.000000000","message":"I like the suggestion but I\u0027m not sure we can use a constructor quite like that with objects. I\u0027ll think it over.","commit_id":"a8f0ff682d40a223da9939a00d61f6485e07c58a"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"fcc64497163149f384f5015f92d332f106427bc1","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        return token_obj"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    @base.remotable_classmethod"},{"line_number":98,"context_line":"    def get_valid(cls, context, token, instance_uuid):"},{"line_number":99,"context_line":"        token_hash \u003d utils.get_sha256_str(token)"},{"line_number":100,"context_line":"        db_obj \u003d db.console_auth_token_get_valid("},{"line_number":101,"context_line":"            context, token_hash, instance_uuid)"}],"source_content_type":"text/x-python","patch_set":6,"id":"7aa08908_caae60e5","line":98,"updated":"2016-06-07 18:31:43.000000000","message":"A docstring would be nice for all these main methods...","commit_id":"a8f0ff682d40a223da9939a00d61f6485e07c58a"},{"author":{"_account_id":7461,"name":"Paul Murray","email":"pmurray@hpe.com","username":"ptm"},"change_message_id":"45e7b99eb2ad0bb59f61c9acdc09ab872f0f0303","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        return token_obj"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    @base.remotable_classmethod"},{"line_number":98,"context_line":"    def get_valid(cls, context, token, instance_uuid):"},{"line_number":99,"context_line":"        token_hash \u003d utils.get_sha256_str(token)"},{"line_number":100,"context_line":"        db_obj \u003d db.console_auth_token_get_valid("},{"line_number":101,"context_line":"            context, token_hash, instance_uuid)"}],"source_content_type":"text/x-python","patch_set":6,"id":"7aa08908_0e5032d3","line":98,"in_reply_to":"7aa08908_c084470c","updated":"2016-06-08 16:47:51.000000000","message":"Changed name to \"validate\" to go with \"authorize\"","commit_id":"a8f0ff682d40a223da9939a00d61f6485e07c58a"},{"author":{"_account_id":7461,"name":"Paul Murray","email":"pmurray@hpe.com","username":"ptm"},"change_message_id":"def4752519cb418b64f6a5d00a6cfac2974453a3","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        return token_obj"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    @base.remotable_classmethod"},{"line_number":98,"context_line":"    def get_valid(cls, context, token, instance_uuid):"},{"line_number":99,"context_line":"        token_hash \u003d utils.get_sha256_str(token)"},{"line_number":100,"context_line":"        db_obj \u003d db.console_auth_token_get_valid("},{"line_number":101,"context_line":"            context, token_hash, instance_uuid)"}],"source_content_type":"text/x-python","patch_set":6,"id":"7aa08908_c084470c","line":98,"in_reply_to":"7aa08908_caae60e5","updated":"2016-06-08 14:07:19.000000000","message":"Will do","commit_id":"a8f0ff682d40a223da9939a00d61f6485e07c58a"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"868cca732bbe2baac391625e99d4b9375d062f57","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":32,"context_line":"class ConsoleAuthToken(base.NovaTimestampObject, base.NovaObject,"},{"line_number":33,"context_line":"                       base.NovaObjectDictCompat):"},{"line_number":34,"context_line":"    # Version 1.0: Initial version"},{"line_number":35,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":36,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"7aa08908_1f7b0c7d","line":33,"updated":"2016-06-09 13:55:10.000000000","message":"nit: I would say need of base.NovaObjectDictCompat","commit_id":"c3c9ceb3e029e4dd9394bf858ece826fe9b72513"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"868cca732bbe2baac391625e99d4b9375d062f57","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    }"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    @staticmethod"},{"line_number":49,"context_line":"    def _from_db_object(context, obj, db_obj):"},{"line_number":50,"context_line":"        # NOTE(PaulMurray) the token is not stored in the database"},{"line_number":51,"context_line":"        # and we do not read back its hash - we don\u0027t need it"},{"line_number":52,"context_line":"        for field in set(obj.fields) - set([\u0027token\u0027]):"}],"source_content_type":"text/x-python","patch_set":8,"id":"7aa08908_bf4d989b","line":49,"updated":"2016-06-09 13:55:10.000000000","message":"No no this is too hacky. What you need here is to create a new proxy field, please refer yourself at what has been done in objects/instance_numa_topology.py, the field DictProxy..","commit_id":"c3c9ceb3e029e4dd9394bf858ece826fe9b72513"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"bd676dc14ef500d5bed8075089ccc84828302723","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    }"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    @staticmethod"},{"line_number":49,"context_line":"    def _from_db_object(context, obj, db_obj):"},{"line_number":50,"context_line":"        # NOTE(PaulMurray) the token is not stored in the database"},{"line_number":51,"context_line":"        # and we do not read back its hash - we don\u0027t need it"},{"line_number":52,"context_line":"        for field in set(obj.fields) - set([\u0027token\u0027]):"}],"source_content_type":"text/x-python","patch_set":8,"id":"7aa08908_e534aafc","line":49,"in_reply_to":"7aa08908_2524f2ad","updated":"2016-06-09 15:04:58.000000000","message":"What you want is to have \u0027token_hash\u0027 has a field which proxy token.\n\nSo the data stored in database will be token_hash and the object can still expose an attribute token.\n\nIt\u0027s clearly better than this hack where we can\u0027t see from where is coming token_hash and those both method to hack database stored and retrieve from database.","commit_id":"c3c9ceb3e029e4dd9394bf858ece826fe9b72513"},{"author":{"_account_id":7461,"name":"Paul Murray","email":"pmurray@hpe.com","username":"ptm"},"change_message_id":"542d870bfcdb746cae9e011a76d125860c2b60b3","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    }"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    @staticmethod"},{"line_number":49,"context_line":"    def _from_db_object(context, obj, db_obj):"},{"line_number":50,"context_line":"        # NOTE(PaulMurray) the token is not stored in the database"},{"line_number":51,"context_line":"        # and we do not read back its hash - we don\u0027t need it"},{"line_number":52,"context_line":"        for field in set(obj.fields) - set([\u0027token\u0027]):"}],"source_content_type":"text/x-python","patch_set":8,"id":"7aa08908_2524f2ad","line":49,"in_reply_to":"7aa08908_bf4d989b","updated":"2016-06-09 14:55:22.000000000","message":"I\u0027m not sure I understand your example. I was following the pattern in compute_node.py.\n\nI don\u0027t want to add a field - its important that what is in the object is not what is in the database.\n\nMaybe you can explain.","commit_id":"c3c9ceb3e029e4dd9394bf858ece826fe9b72513"},{"author":{"_account_id":7461,"name":"Paul Murray","email":"pmurray@hpe.com","username":"ptm"},"change_message_id":"d8fb012ccd7e4c941bb33c5bbadc87ebbf57897b","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    }"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    @staticmethod"},{"line_number":49,"context_line":"    def _from_db_object(context, obj, db_obj):"},{"line_number":50,"context_line":"        # NOTE(PaulMurray) the token is not stored in the database"},{"line_number":51,"context_line":"        # and we do not read back its hash - we don\u0027t need it"},{"line_number":52,"context_line":"        for field in set(obj.fields) - set([\u0027token\u0027]):"}],"source_content_type":"text/x-python","patch_set":8,"id":"7aa08908_cb089fdc","line":49,"in_reply_to":"7aa08908_d03a0e98","updated":"2016-06-09 15:22:16.000000000","message":"Thanks sahid. I\u0027m going to rework this object a bit and see how it all fits at the end. Just talked to dansmith on IRC - he thought it looked ok as it is. But like I said, I\u0027ll see how it looks when I have tided it up.","commit_id":"c3c9ceb3e029e4dd9394bf858ece826fe9b72513"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"e3206dfa4c5b439df94a99f8f400bebf0a084e3b","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    }"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    @staticmethod"},{"line_number":49,"context_line":"    def _from_db_object(context, obj, db_obj):"},{"line_number":50,"context_line":"        # NOTE(PaulMurray) the token is not stored in the database"},{"line_number":51,"context_line":"        # and we do not read back its hash - we don\u0027t need it"},{"line_number":52,"context_line":"        for field in set(obj.fields) - set([\u0027token\u0027]):"}],"source_content_type":"text/x-python","patch_set":8,"id":"7aa08908_d03a0e98","line":49,"in_reply_to":"7aa08908_e534aafc","updated":"2016-06-09 15:10:29.000000000","message":"You can reuse as example the ProxyDictField implemented here [1], just update the method set and get, to hash and unhash the token.\n\n  fields \u003d {\n    \u0027id\u0027: ...,\n    \u0027token_hash\u0027: StringField(nullable\u003dFalse)\n  }\n  token \u003d ProxyHashedField(\u0027token_hash\u0027)\n\nThat is much better.\n\n[1] https://github.com/openstack/oslo.versionedobjects/blob/master/oslo_versionedobjects/fields.py#L542","commit_id":"c3c9ceb3e029e4dd9394bf858ece826fe9b72513"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"868cca732bbe2baac391625e99d4b9375d062f57","unresolved":false,"context_lines":[{"line_number":55,"context_line":"        obj.obj_reset_changes()"},{"line_number":56,"context_line":"        return obj"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def _to_db_object(self, db_obj):"},{"line_number":59,"context_line":"        # NOTE(PaulMurray) the token is not stored in the database"},{"line_number":60,"context_line":"        # only a hash of the token"},{"line_number":61,"context_line":"        if \u0027token\u0027 in db_obj:"}],"source_content_type":"text/x-python","patch_set":8,"id":"7aa08908_1ffdcc6e","line":58,"updated":"2016-06-09 13:55:10.000000000","message":"s/db_obj/values (or something else)","commit_id":"c3c9ceb3e029e4dd9394bf858ece826fe9b72513"},{"author":{"_account_id":7461,"name":"Paul Murray","email":"pmurray@hpe.com","username":"ptm"},"change_message_id":"542d870bfcdb746cae9e011a76d125860c2b60b3","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        and the token is stored in the database. This funciton"},{"line_number":83,"context_line":"        can only be succeed if the token is unique and the object"},{"line_number":84,"context_line":"        has not already been stored."},{"line_number":85,"context_line":"        \"\"\""},{"line_number":86,"context_line":"        self.expires \u003d timeutils.utcnow_ts() + ttl"},{"line_number":87,"context_line":"        self._create()"},{"line_number":88,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"7aa08908_bc576325","line":85,"updated":"2016-06-09 14:55:22.000000000","message":"I\u0027m going to move creation of the token in here. There is no need for it to be elsewhere now.\n\nIn fact I will refactor the authorize and create functions.","commit_id":"c3c9ceb3e029e4dd9394bf858ece826fe9b72513"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"88c69e6f66efe5f56568f4f80f3a554335ae3d7f","unresolved":false,"context_lines":[{"line_number":116,"context_line":"        LOG.debug(\"Authorized token with expiry %(expires)s for console \""},{"line_number":117,"context_line":"                  \"connection %(console)s\","},{"line_number":118,"context_line":"                  {\u0027expires\u0027: expires,"},{"line_number":119,"context_line":"                   \u0027console\u0027: strutils.mask_password(self, \u0027***\u0027)})"},{"line_number":120,"context_line":"        return token"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"    @base.remotable_classmethod"}],"source_content_type":"text/x-python","patch_set":25,"id":"9f91af0f_f4a1d0aa","line":119,"range":{"start_line":119,"start_character":59,"end_line":119,"end_character":64},"updated":"2018-01-05 16:57:53.000000000","message":"nit: this is already the default so you don\u0027t need to specify it.","commit_id":"96685d765207a27addd3c8f3e7446fa9c4a6ffad"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"88c69e6f66efe5f56568f4f80f3a554335ae3d7f","unresolved":false,"context_lines":[{"line_number":136,"context_line":"        if db_obj is not None:"},{"line_number":137,"context_line":"            db_obj[\u0027token\u0027] \u003d token"},{"line_number":138,"context_line":"            obj \u003d cls._from_db_object(context, cls(), db_obj)"},{"line_number":139,"context_line":"            LOG.debug(\"Validated token - console connection is \""},{"line_number":140,"context_line":"                      \"%(console)s\","},{"line_number":141,"context_line":"                      {\u0027console\u0027: strutils.mask_password(obj, \u0027***\u0027)})"},{"line_number":142,"context_line":"            return obj"}],"source_content_type":"text/x-python","patch_set":25,"id":"9f91af0f_d4b5acce","line":139,"updated":"2018-01-05 16:57:53.000000000","message":"Cool, seeing this at the end of the series in the devstack patch that runs it:\n\nhttp://logs.openstack.org/12/527812/1/check/tempest-full/26f5e5f/controller/logs/screen-n-novnc-cell1.txt\n\nJan 05 01:44:25.338490 ubuntu-xenial-citycloud-sto2-0001695415 nova-novncproxy[10280]: DEBUG nova.objects.console_auth_token [None req-166854c4-3f01-4db1-890b-212b7ba78e95 None None] Validated token - console connection is ConsoleAuthToken(access_url_base\u003d\u0027http://10.0.1.151:6080/vnc_auto.html\u0027,console_type\u003d\u0027novnc\u0027,created_at\u003d2018-01-05T01:44:25Z,host\u003d\u0027127.0.0.1\u0027,id\u003d1,instance_uuid\u003d4453afe4-e6eb-4479-a073-0f99a76c71f1,internal_access_path\u003dNone,port\u003d5900,token\u003d\u0027***\u0027,updated_at\u003dNone) {{(pid\u003d6917) validate /opt/stack/nova/nova/objects/console_auth_token.py:159}}","commit_id":"96685d765207a27addd3c8f3e7446fa9c4a6ffad"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"88c69e6f66efe5f56568f4f80f3a554335ae3d7f","unresolved":false,"context_lines":[{"line_number":138,"context_line":"            obj \u003d cls._from_db_object(context, cls(), db_obj)"},{"line_number":139,"context_line":"            LOG.debug(\"Validated token - console connection is \""},{"line_number":140,"context_line":"                      \"%(console)s\","},{"line_number":141,"context_line":"                      {\u0027console\u0027: strutils.mask_password(obj, \u0027***\u0027)})"},{"line_number":142,"context_line":"            return obj"},{"line_number":143,"context_line":"        else:"},{"line_number":144,"context_line":"            LOG.debug(\"Token validation failed\")"}],"source_content_type":"text/x-python","patch_set":25,"id":"9f91af0f_b4ab4887","line":141,"range":{"start_line":141,"start_character":62,"end_line":141,"end_character":70},"updated":"2018-01-05 16:57:53.000000000","message":"same","commit_id":"96685d765207a27addd3c8f3e7446fa9c4a6ffad"}],"nova/objects/console_connection.py":[{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"71c1e1e4790d8d8fb392c9a3c2fd850348c5153d","unresolved":false,"context_lines":[{"line_number":33,"context_line":"    # Version 1.0: Initial version"},{"line_number":34,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    fields \u003d {"},{"line_number":37,"context_line":"        \u0027id\u0027: fields.IntegerField(),"},{"line_number":38,"context_line":"        \u0027console_type\u0027: fields.StringField(nullable\u003dFalse),"},{"line_number":39,"context_line":"        \u0027host\u0027: fields.StringField(nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":10,"id":"7aa08908_92940345","line":36,"updated":"2016-06-09 17:22:24.000000000","message":"You completely hide fields token_hash and expires from this object which seems to me clearly a bad idea since they are stored in the database.","commit_id":"e6f5db166f7e91ac78de79fc1c05368ec3154822"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"8548e4fd0bce4a5e8b4c587ed2e60bcbd6c7afe8","unresolved":false,"context_lines":[{"line_number":33,"context_line":"    # Version 1.0: Initial version"},{"line_number":34,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    fields \u003d {"},{"line_number":37,"context_line":"        \u0027id\u0027: fields.IntegerField(),"},{"line_number":38,"context_line":"        \u0027console_type\u0027: fields.StringField(nullable\u003dFalse),"},{"line_number":39,"context_line":"        \u0027host\u0027: fields.StringField(nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":10,"id":"7aa08908_c7592b37","line":36,"in_reply_to":"7aa08908_1b448719","updated":"2016-06-13 13:23:15.000000000","message":"Yes you made good point I did not notice that we are not going to get the token from the hashed value stored in database.\n\nEven if I still think we should to declare in a way or another those fields to avoid any confusion I don\u0027t have good solution so far so I guess It\u0027s fine.","commit_id":"e6f5db166f7e91ac78de79fc1c05368ec3154822"},{"author":{"_account_id":7461,"name":"Paul Murray","email":"pmurray@hpe.com","username":"ptm"},"change_message_id":"02066b7bbade88bad64e635dc5a1811daa7c74b2","unresolved":false,"context_lines":[{"line_number":33,"context_line":"    # Version 1.0: Initial version"},{"line_number":34,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    fields \u003d {"},{"line_number":37,"context_line":"        \u0027id\u0027: fields.IntegerField(),"},{"line_number":38,"context_line":"        \u0027console_type\u0027: fields.StringField(nullable\u003dFalse),"},{"line_number":39,"context_line":"        \u0027host\u0027: fields.StringField(nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":10,"id":"7aa08908_1b448719","line":36,"in_reply_to":"7aa08908_92940345","updated":"2016-06-10 11:16:24.000000000","message":"I think that is ok.\n\nThere is no need for object and database fields to be the same. Part of the benefit of objects is the database schema and data format is isolated from the nova code.\n\nIn the nova code we are only interested in the token. But we do not save it in the database for security reasons. The question is weather to put the token in the object just use it for lookup. Here it is just used for lookup.\n\nI know that seems odd - but this is deliberately a one way transformation. We can not get the token back from the hash (without knowing the token). Also the database lookup implements the security check - i.e. it does not return a row unless it is valid. So the token_hash and expires fields are there only to implement a check on access.","commit_id":"e6f5db166f7e91ac78de79fc1c05368ec3154822"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"42a992f36ac2a855b35a7d2fb52ec738159338ef","unresolved":false,"context_lines":[{"line_number":73,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":74,"context_line":"        updates[\u0027token_hash\u0027] \u003d token_hash"},{"line_number":75,"context_line":"        updates[\u0027expires\u0027] \u003d expires"},{"line_number":76,"context_line":"        db_obj \u003d db.console_auth_token_create(self._context, updates)"},{"line_number":77,"context_line":"        self._from_db_object(self._context, self, db_obj)"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        # TODO(PaulMurray): tokens will be redacted for logging."}],"source_content_type":"text/x-python","patch_set":10,"id":"7aa08908_f22e27f9","line":76,"updated":"2016-06-09 17:27:53.000000000","message":"Probably should handle the expected failures here right?","commit_id":"e6f5db166f7e91ac78de79fc1c05368ec3154822"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"42a992f36ac2a855b35a7d2fb52ec738159338ef","unresolved":false,"context_lines":[{"line_number":107,"context_line":"            con_obj \u003d cls()"},{"line_number":108,"context_line":"            con_obj \u003d cls._from_db_object(context, con_obj, db_obj)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        # TODO(PaulMurray): tokens will be redacted for logging."},{"line_number":111,"context_line":"        # Change when the redaction function has been introduced."},{"line_number":112,"context_line":"            LOG.info(_LI(\"Checking Token: %(token)s for %(instance)s \""},{"line_number":113,"context_line":"                         \"is valid - console connection %(console)s\"),"}],"source_content_type":"text/x-python","patch_set":10,"id":"7aa08908_121133b0","line":110,"updated":"2016-06-09 17:27:53.000000000","message":"These should be indented to match the code in this block (i.e. +4 spaces).","commit_id":"e6f5db166f7e91ac78de79fc1c05368ec3154822"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"42a992f36ac2a855b35a7d2fb52ec738159338ef","unresolved":false,"context_lines":[{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        # TODO(PaulMurray): tokens will be redacted for logging."},{"line_number":111,"context_line":"        # Change when the redaction function has been introduced."},{"line_number":112,"context_line":"            LOG.info(_LI(\"Checking Token: %(token)s for %(instance)s \""},{"line_number":113,"context_line":"                         \"is valid - console connection %(console)s\"),"},{"line_number":114,"context_line":"                     {\u0027token\u0027: token, \u0027instance\u0027: instance_uuid,"},{"line_number":115,"context_line":"                      \u0027console\u0027: con_obj.obj_to_primitive()})"}],"source_content_type":"text/x-python","patch_set":10,"id":"7aa08908_b2e13f9d","line":112,"updated":"2016-06-09 17:27:53.000000000","message":"Do we really want to log at info level every time we validate (or reject) a token? Presumably in the reject case I can generate lots of log traffic if I just start using bad tokens really fast, right? I would think logging this kind of thing at debug level would be fine.","commit_id":"e6f5db166f7e91ac78de79fc1c05368ec3154822"},{"author":{"_account_id":7461,"name":"Paul Murray","email":"pmurray@hpe.com","username":"ptm"},"change_message_id":"02066b7bbade88bad64e635dc5a1811daa7c74b2","unresolved":false,"context_lines":[{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        # TODO(PaulMurray): tokens will be redacted for logging."},{"line_number":111,"context_line":"        # Change when the redaction function has been introduced."},{"line_number":112,"context_line":"            LOG.info(_LI(\"Checking Token: %(token)s for %(instance)s \""},{"line_number":113,"context_line":"                         \"is valid - console connection %(console)s\"),"},{"line_number":114,"context_line":"                     {\u0027token\u0027: token, \u0027instance\u0027: instance_uuid,"},{"line_number":115,"context_line":"                      \u0027console\u0027: con_obj.obj_to_primitive()})"}],"source_content_type":"text/x-python","patch_set":10,"id":"7aa08908_fb2b7b31","line":112,"in_reply_to":"7aa08908_b2e13f9d","updated":"2016-06-10 11:16:24.000000000","message":"That is what we currently do with the consoleauth service. i was tempted to remove the log altogether and leave it to the code outside the object. I\u0027ll think a little more.","commit_id":"e6f5db166f7e91ac78de79fc1c05368ec3154822"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"ae78d40485a99982bd3cc45795e1412e89e2b7c9","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":33,"context_line":"class ConsoleConnection(base.NovaTimestampObject, base.NovaObject,"},{"line_number":34,"context_line":"                       base.NovaObjectDictCompat):"},{"line_number":35,"context_line":"    # Version 1.0: Initial version"},{"line_number":36,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":37,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"3aaa91ec_4443046d","line":34,"updated":"2016-06-27 16:32:45.000000000","message":"No newly defined objects should ever use DictCompat - it was purely for use when we were converting legacy code to be object based","commit_id":"6ab0f72c676bf51b01e7f8944cc2633b3e8b1ff9"},{"author":{"_account_id":7461,"name":"Paul Murray","email":"pmurray@hpe.com","username":"ptm"},"change_message_id":"8347841f5ca9a82e10ce2f99f8157e69c7fc6832","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":33,"context_line":"class ConsoleConnection(base.NovaTimestampObject, base.NovaObject,"},{"line_number":34,"context_line":"                       base.NovaObjectDictCompat):"},{"line_number":35,"context_line":"    # Version 1.0: Initial version"},{"line_number":36,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":37,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"3aaa91ec_68b36e0b","line":34,"in_reply_to":"3aaa91ec_4443046d","updated":"2016-06-27 18:31:19.000000000","message":"Done","commit_id":"6ab0f72c676bf51b01e7f8944cc2633b3e8b1ff9"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"9e95c395d0d20b43036a2b1fd30ca08c248e3147","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        and the expires time has not passed."},{"line_number":109,"context_line":"        \"\"\""},{"line_number":110,"context_line":"        token_hash \u003d utils.get_sha256_str(token)"},{"line_number":111,"context_line":"        db_obj \u003d db.console_auth_token_get_valid(context,"},{"line_number":112,"context_line":"                                                 token_hash,"},{"line_number":113,"context_line":"                                                 instance_uuid)"},{"line_number":114,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"3aaa91ec_2f5d4c79","line":111,"updated":"2016-06-24 13:30:41.000000000","message":"In the brave new world of cellsv2 this will need to be updated but it\u0027s fine for now. However what I would recommend is move the instance check out of the db method and do it here. Later once everyone is on v2 the instance_mapping table can answer if an instance exists on a project so that can be switched easily.\n\nYou\u0027ll also eventually want to look up the instance_mapping anyways to get the cell_mapping to query the right cell db. So what you could do is attempt the instance_mapping lookup, if it\u0027s None just call the db method and if you get one pull instance_mapping.cell_mapping and use that with context.target_cell when calling the db method. We\u0027re going to have to switch pretty much everything over to this in Ocata so I don\u0027t expect you to do it now.\n\nAlso, we\u0027ve been putting new db method within the objects that use them. Look at host_mapping/instance_mapping/flavors/build_request/etc.. for examples.","commit_id":"6ab0f72c676bf51b01e7f8944cc2633b3e8b1ff9"},{"author":{"_account_id":7461,"name":"Paul Murray","email":"pmurray@hpe.com","username":"ptm"},"change_message_id":"8347841f5ca9a82e10ce2f99f8157e69c7fc6832","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        and the expires time has not passed."},{"line_number":109,"context_line":"        \"\"\""},{"line_number":110,"context_line":"        token_hash \u003d utils.get_sha256_str(token)"},{"line_number":111,"context_line":"        db_obj \u003d db.console_auth_token_get_valid(context,"},{"line_number":112,"context_line":"                                                 token_hash,"},{"line_number":113,"context_line":"                                                 instance_uuid)"},{"line_number":114,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"3aaa91ec_e89e3e62","line":111,"in_reply_to":"3aaa91ec_2f5d4c79","updated":"2016-06-27 18:31:19.000000000","message":"Hi Andrew, I wasn\u0027t clear if you wanted me to address these now or later. I think you\u0027re saying it will need to be done later.","commit_id":"6ab0f72c676bf51b01e7f8944cc2633b3e8b1ff9"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"48e058c37d0ae21f0d8479ba43e4c419c6d13c80","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        and the expires time has not passed."},{"line_number":109,"context_line":"        \"\"\""},{"line_number":110,"context_line":"        token_hash \u003d utils.get_sha256_str(token)"},{"line_number":111,"context_line":"        db_obj \u003d db.console_auth_token_get_valid(context,"},{"line_number":112,"context_line":"                                                 token_hash,"},{"line_number":113,"context_line":"                                                 instance_uuid)"},{"line_number":114,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"3aaa91ec_5e40e807","line":111,"in_reply_to":"3aaa91ec_e89e3e62","updated":"2016-06-27 19:06:06.000000000","message":"Mostly I was mentioning things that will need to be done later, but some prep work could be done now. At this point it would be better to just wait.\n\nHowever, I would prefer if the db methods moved into the object. It\u0027s not worth holding this up though.","commit_id":"6ab0f72c676bf51b01e7f8944cc2633b3e8b1ff9"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"ad3e8fbbb26270c843ca330dd1956c2ab32804bb","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":33,"context_line":"class ConsoleConnection(base.NovaTimestampObject, base.NovaObject):"},{"line_number":34,"context_line":"    # Version 1.0: Initial version"},{"line_number":35,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":36,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_4b8608dc","line":33,"updated":"2016-06-29 11:51:19.000000000","message":"I think you need a ConsoleAuthToken object, that is the thing that goes in the DB. That can save/load as normal, a persistent object.\n\nThe ConsoleAuthToken object should be able to use its hash field to valid tokens, as needed. i.e. this object has the validate_token method.\n\nConsoleAuthToken also has a create method, that returns a token, and a ConsoleAuthToken object that is able to validate tokens.\n\nI think you then need a separate function, that is called generate_auth_url, that calls the above method, and constructs the required auth_url. That feels like it lives in the API layer that understands the url constructs.","commit_id":"af4a5b8306431b975dc449dedc7873bacb28cce2"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"e84434eca647e8b6c752117dae9453165cb6081e","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":33,"context_line":"class ConsoleConnection(base.NovaTimestampObject, base.NovaObject):"},{"line_number":34,"context_line":"    # Version 1.0: Initial version"},{"line_number":35,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":36,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_c573007f","line":33,"in_reply_to":"3aaa91ec_4b8608dc","updated":"2016-06-29 12:51:50.000000000","message":"Yes John that makes a lot of sense","commit_id":"af4a5b8306431b975dc449dedc7873bacb28cce2"},{"author":{"_account_id":7461,"name":"Paul Murray","email":"pmurray@hpe.com","username":"ptm"},"change_message_id":"501286beb2dba84a1a32fe6e28b629ffcae13daa","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":33,"context_line":"class ConsoleConnection(base.NovaTimestampObject, base.NovaObject):"},{"line_number":34,"context_line":"    # Version 1.0: Initial version"},{"line_number":35,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":36,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_8870e4a5","line":33,"in_reply_to":"3aaa91ec_c573007f","updated":"2016-06-29 17:21:33.000000000","message":"So that is basically going back to where I was before (earlier patch sets). Except the hash and expires are fields.\n\nI assume the validate_token method is the validate method below - i.e. the one that retrieves the object from the database. There is no need to validate the token once you have the object.\n\nThe authorize was originally a create method but jaypipes and others thought it was better to construct the object and then \"authorize\" it. Authorize already returns the token. But I did prefer it the other way.\n\nI\u0027ll knock up the changes - you might have seen I was playing with another version as well. But not sure that is helpful.","commit_id":"af4a5b8306431b975dc449dedc7873bacb28cce2"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"d2dd0103559055423c9ce5f2acaecdf5112a9572","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        \u0027internal_access_path\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":43,"context_line":"        \u0027instance_uuid\u0027: fields.UUIDField(nullable\u003dFalse),"},{"line_number":44,"context_line":"        \u0027access_url_base\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":45,"context_line":"        # NOTE(PaulMurray)The token filed is not stored in the"},{"line_number":46,"context_line":"        # database, a hash of the token is stored instead."},{"line_number":47,"context_line":"        \u0027token\u0027: fields.StringField(nullable\u003dFalse),"},{"line_number":48,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_810c5795","line":45,"updated":"2016-06-29 10:07:23.000000000","message":"s/NOTE(PaulMurray)//","commit_id":"af4a5b8306431b975dc449dedc7873bacb28cce2"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"d2dd0103559055423c9ce5f2acaecdf5112a9572","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        \u0027access_url_base\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":45,"context_line":"        # NOTE(PaulMurray)The token filed is not stored in the"},{"line_number":46,"context_line":"        # database, a hash of the token is stored instead."},{"line_number":47,"context_line":"        \u0027token\u0027: fields.StringField(nullable\u003dFalse),"},{"line_number":48,"context_line":"    }"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_4160af35","line":47,"updated":"2016-06-29 10:07:23.000000000","message":"If that field is not stored in the database no need to have it versioned you should just have it has an attribute to this object","commit_id":"af4a5b8306431b975dc449dedc7873bacb28cce2"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"ad3e8fbbb26270c843ca330dd1956c2ab32804bb","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        \u0027access_url_base\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":45,"context_line":"        # NOTE(PaulMurray)The token filed is not stored in the"},{"line_number":46,"context_line":"        # database, a hash of the token is stored instead."},{"line_number":47,"context_line":"        \u0027token\u0027: fields.StringField(nullable\u003dFalse),"},{"line_number":48,"context_line":"    }"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_ebe534a8","line":47,"in_reply_to":"3aaa91ec_35183984","updated":"2016-06-29 11:51:19.000000000","message":"hmm, so this field should be marked as secret\u003dTrue, I think?","commit_id":"af4a5b8306431b975dc449dedc7873bacb28cce2"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"34d537454d1ad8cd779350673a8353fab9115ce1","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        \u0027access_url_base\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":45,"context_line":"        # NOTE(PaulMurray)The token filed is not stored in the"},{"line_number":46,"context_line":"        # database, a hash of the token is stored instead."},{"line_number":47,"context_line":"        \u0027token\u0027: fields.StringField(nullable\u003dFalse),"},{"line_number":48,"context_line":"    }"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_35183984","line":47,"in_reply_to":"3aaa91ec_4160af35","updated":"2016-06-29 11:16:44.000000000","message":"It does feel like we should just have token_hash here.\n\nYou can still have the validate token calls to check an external token against the hash, etc.","commit_id":"af4a5b8306431b975dc449dedc7873bacb28cce2"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"d2dd0103559055423c9ce5f2acaecdf5112a9572","unresolved":false,"context_lines":[{"line_number":62,"context_line":"                self.access_url_base, self.token, self.instance_uuid)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    @staticmethod"},{"line_number":65,"context_line":"    def _from_db_object(context, obj, db_obj):"},{"line_number":66,"context_line":"        # NOTE(PaulMurray): token is not stored in the database but"},{"line_number":67,"context_line":"        # this function assumes it is in db_obj"},{"line_number":68,"context_line":"        for field in obj.fields:"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_414a6f84","line":65,"updated":"2016-06-29 10:07:23.000000000","message":"so if token is not in \u0027fields\u0027, this hack can be removed right ?","commit_id":"af4a5b8306431b975dc449dedc7873bacb28cce2"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"ad3e8fbbb26270c843ca330dd1956c2ab32804bb","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        return obj"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    @base.remotable"},{"line_number":75,"context_line":"    def authorize(self, ttl):"},{"line_number":76,"context_line":"        \"\"\"Authorise the console token and store in the database."},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        :param ttl: time to live in seconds"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_8bfd903d","line":75,"updated":"2016-06-29 11:51:19.000000000","message":"It feels like this should be a class method, that creates the object and returns it?","commit_id":"af4a5b8306431b975dc449dedc7873bacb28cce2"},{"author":{"_account_id":7461,"name":"Paul Murray","email":"pmurray@hpe.com","username":"ptm"},"change_message_id":"501286beb2dba84a1a32fe6e28b629ffcae13daa","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        return obj"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    @base.remotable"},{"line_number":75,"context_line":"    def authorize(self, ttl):"},{"line_number":76,"context_line":"        \"\"\"Authorise the console token and store in the database."},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        :param ttl: time to live in seconds"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_b1db927b","line":75,"in_reply_to":"3aaa91ec_8bfd903d","updated":"2016-06-29 17:21:33.000000000","message":"that\u0027s the way I did it originally. Others preferred it this way - they liked the idea that the object could be built up and then authorized.","commit_id":"af4a5b8306431b975dc449dedc7873bacb28cce2"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"d2dd0103559055423c9ce5f2acaecdf5112a9572","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        expires \u003d timeutils.utcnow_ts() + ttl"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":96,"context_line":"        if \u0027token\u0027 in updates:"},{"line_number":97,"context_line":"            del updates[\u0027token\u0027]"},{"line_number":98,"context_line":"        updates[\u0027token_hash\u0027] \u003d token_hash"},{"line_number":99,"context_line":"        updates[\u0027expires\u0027] \u003d expires"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_24d65127","line":96,"updated":"2016-06-29 10:07:23.000000000","message":"So this block can be removed","commit_id":"af4a5b8306431b975dc449dedc7873bacb28cce2"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"d2dd0103559055423c9ce5f2acaecdf5112a9572","unresolved":false,"context_lines":[{"line_number":103,"context_line":"            db_obj[\u0027token\u0027] \u003d token"},{"line_number":104,"context_line":"            self._from_db_object(self._context, self, db_obj)"},{"line_number":105,"context_line":"        except DBDuplicateEntry:"},{"line_number":106,"context_line":"            # NOTE(PaulMurray) we are generating the token above so this"},{"line_number":107,"context_line":"            # should almost never happen - but technically its possible"},{"line_number":108,"context_line":"            raise exception.TokenInUse()"},{"line_number":109,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_645a192c","line":106,"updated":"2016-06-29 10:07:23.000000000","message":"s/NOTE(...)//","commit_id":"af4a5b8306431b975dc449dedc7873bacb28cce2"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"ad3e8fbbb26270c843ca330dd1956c2ab32804bb","unresolved":false,"context_lines":[{"line_number":117,"context_line":"        return token"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"    @base.remotable_classmethod"},{"line_number":120,"context_line":"    def validate(cls, context, token, instance_uuid):"},{"line_number":121,"context_line":"        \"\"\"Validate the token."},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        :param context: the context"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_068b551f","line":120,"updated":"2016-06-29 11:51:19.000000000","message":"So I think you need to push validate and authorize to both be class methods that get you an object.\n\nI would call them:","commit_id":"af4a5b8306431b975dc449dedc7873bacb28cce2"},{"author":{"_account_id":7461,"name":"Paul Murray","email":"pmurray@hpe.com","username":"ptm"},"change_message_id":"501286beb2dba84a1a32fe6e28b629ffcae13daa","unresolved":false,"context_lines":[{"line_number":117,"context_line":"        return token"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"    @base.remotable_classmethod"},{"line_number":120,"context_line":"    def validate(cls, context, token, instance_uuid):"},{"line_number":121,"context_line":"        \"\"\"Validate the token."},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        :param context: the context"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_e2938059","line":120,"in_reply_to":"3aaa91ec_068b551f","updated":"2016-06-29 17:21:33.000000000","message":"yep","commit_id":"af4a5b8306431b975dc449dedc7873bacb28cce2"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"d2dd0103559055423c9ce5f2acaecdf5112a9572","unresolved":false,"context_lines":[{"line_number":136,"context_line":""},{"line_number":137,"context_line":"        if db_obj is not None:"},{"line_number":138,"context_line":"            db_obj[\u0027token\u0027] \u003d token"},{"line_number":139,"context_line":"            obj \u003d cls._from_db_object(context, cls(), db_obj)"},{"line_number":140,"context_line":"            # TODO(PaulMurray): tokens will be redacted for logging."},{"line_number":141,"context_line":"            # Change when the redaction function has been introduced."},{"line_number":142,"context_line":"            LOG.debug(\"Checking Token: %(token)s for instance %(instance)s \""}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_840f45e0","line":139,"updated":"2016-06-29 10:07:23.000000000","message":"...\n  obj \u003d cls.obj_from_primitive(db_obj)\n  obj.token \u003d token","commit_id":"af4a5b8306431b975dc449dedc7873bacb28cce2"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"ad3e8fbbb26270c843ca330dd1956c2ab32804bb","unresolved":false,"context_lines":[{"line_number":143,"context_line":"                      \"is valid - console connection is %(console)s\","},{"line_number":144,"context_line":"                      {\u0027token\u0027: token, \u0027instance\u0027: instance_uuid,"},{"line_number":145,"context_line":"                       \u0027console\u0027: obj.obj_to_primitive()})"},{"line_number":146,"context_line":"            return obj"},{"line_number":147,"context_line":"        else:"},{"line_number":148,"context_line":"            # TODO(PaulMurray): tokens will be redacted for logging."},{"line_number":149,"context_line":"            # Change when the redaction function has been introduced."}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_26881122","line":146,"updated":"2016-06-29 11:51:19.000000000","message":"This seems really odd...\n\nI think what you eant here is","commit_id":"af4a5b8306431b975dc449dedc7873bacb28cce2"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"87403f9d149b7cc65298a6119b90fdc275b95e68","unresolved":false,"context_lines":[{"line_number":48,"context_line":"    }"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    @property"},{"line_number":51,"context_line":"    def access_url(self):"},{"line_number":52,"context_line":"        \"\"\"The access url with token parameter."},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"        :returns: the access url with credential parameters"}],"source_content_type":"text/x-python","patch_set":19,"id":"df3967d1_6a0f922e","line":51,"updated":"2017-07-31 14:23:57.000000000","message":"That does not seem right, we should have a \u0027access_url_base\u0027 parameter to this function instead of have it stored.","commit_id":"9ee2167d459f369888df2994df982a23d1e5c319"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"ac1ffe7aade65d4a6d8b0f2a43ed1f9dfc215dee","unresolved":false,"context_lines":[{"line_number":48,"context_line":"    }"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    @property"},{"line_number":51,"context_line":"    def access_url(self):"},{"line_number":52,"context_line":"        \"\"\"The access url with token parameter."},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"        :returns: the access url with credential parameters"}],"source_content_type":"text/x-python","patch_set":19,"id":"5f2577a7_1603bd44","line":51,"in_reply_to":"df3967d1_6a0f922e","updated":"2017-09-08 21:21:23.000000000","message":"I think this is related to my comment on the first patch in the series, I think we need to store the access_url_base because the websocketproxies will not be (and do not currently) run on compute nodes.","commit_id":"9ee2167d459f369888df2994df982a23d1e5c319"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"b99bfedd0799bfbec8f552f92479ff0cef655427","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        \u0027internal_access_path\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":43,"context_line":"        \u0027instance_uuid\u0027: fields.UUIDField(nullable\u003dFalse),"},{"line_number":44,"context_line":"        \u0027access_url_base\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":45,"context_line":"        # NOTE(PaulMurray)The token filed is not stored in the"},{"line_number":46,"context_line":"        # database, a hash of the token is stored instead."},{"line_number":47,"context_line":"        \u0027token\u0027: fields.StringField(nullable\u003dFalse),"},{"line_number":48,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":20,"id":"ff82abbf_7cb35699","line":45,"range":{"start_line":45,"start_character":36,"end_line":45,"end_character":41},"updated":"2017-11-24 13:08:52.000000000","message":"field","commit_id":"3c20bd619e9e2d37caca91edf736734e06729ea9"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"b99bfedd0799bfbec8f552f92479ff0cef655427","unresolved":false,"context_lines":[{"line_number":43,"context_line":"        \u0027instance_uuid\u0027: fields.UUIDField(nullable\u003dFalse),"},{"line_number":44,"context_line":"        \u0027access_url_base\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":45,"context_line":"        # NOTE(PaulMurray)The token filed is not stored in the"},{"line_number":46,"context_line":"        # database, a hash of the token is stored instead."},{"line_number":47,"context_line":"        \u0027token\u0027: fields.StringField(nullable\u003dFalse),"},{"line_number":48,"context_line":"    }"},{"line_number":49,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"ff82abbf_fc644624","line":46,"range":{"start_line":46,"start_character":18,"end_line":46,"end_character":19},"updated":"2017-11-24 13:08:52.000000000","message":";","commit_id":"3c20bd619e9e2d37caca91edf736734e06729ea9"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"b99bfedd0799bfbec8f552f92479ff0cef655427","unresolved":false,"context_lines":[{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    @staticmethod"},{"line_number":74,"context_line":"    def get_masked_token(token):"},{"line_number":75,"context_line":"        return \u0027{SHA1}%s\u0027 % utils.get_sha1_str(token)"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    @base.remotable"},{"line_number":78,"context_line":"    def authorize(self, ttl):"}],"source_content_type":"text/x-python","patch_set":20,"id":"ff82abbf_bc38feed","line":75,"range":{"start_line":75,"start_character":8,"end_line":75,"end_character":53},"updated":"2017-11-24 13:08:52.000000000","message":"Seeing as this is mostly greenfield stuff, could we use SHA256 here given the note in \u0027nova/utils.py\u0027?","commit_id":"3c20bd619e9e2d37caca91edf736734e06729ea9"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"8f3de4673f107a03c904060356d55579e7941734","unresolved":false,"context_lines":[{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    @staticmethod"},{"line_number":74,"context_line":"    def get_masked_token(token):"},{"line_number":75,"context_line":"        return \u0027{SHA1}%s\u0027 % utils.get_sha1_str(token)"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    @base.remotable"},{"line_number":78,"context_line":"    def authorize(self, ttl):"}],"source_content_type":"text/x-python","patch_set":20,"id":"df87a7cf_bde70447","line":75,"range":{"start_line":75,"start_character":8,"end_line":75,"end_character":53},"in_reply_to":"df87a7cf_81ee7bea","updated":"2017-12-13 18:01:04.000000000","message":"Makes sense","commit_id":"3c20bd619e9e2d37caca91edf736734e06729ea9"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"34ad774d685ded91c2d99d808c5b3ebcb5189185","unresolved":false,"context_lines":[{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    @staticmethod"},{"line_number":74,"context_line":"    def get_masked_token(token):"},{"line_number":75,"context_line":"        return \u0027{SHA1}%s\u0027 % utils.get_sha1_str(token)"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    @base.remotable"},{"line_number":78,"context_line":"    def authorize(self, ttl):"}],"source_content_type":"text/x-python","patch_set":20,"id":"df87a7cf_81ee7bea","line":75,"range":{"start_line":75,"start_character":8,"end_line":75,"end_character":53},"in_reply_to":"ff82abbf_bc38feed","updated":"2017-12-12 19:56:09.000000000","message":"Yeah, I should probably do this a different way. For debugging, I was thinking it would be good to at least be able to correlate tokens in the log with auth failures. But we shouldn\u0027t reveal anything about the token, even a hash of it going forward. So I\u0027m thinking of using the oslo strutils.mask_password function instead.","commit_id":"3c20bd619e9e2d37caca91edf736734e06729ea9"},{"author":{"_account_id":7634,"name":"Takashi Natsume","email":"takanattie@gmail.com","username":"natsumet"},"change_message_id":"ceb6ba0d7faf9a5305db7ede2099fc49bbcde4ed","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        if self.obj_attr_is_set(\u0027id\u0027):"},{"line_number":90,"context_line":"            raise exception.ObjectActionError("},{"line_number":91,"context_line":"                action\u003d\u0027authorize\u0027,"},{"line_number":92,"context_line":"                reason\u003d\u0027must be a new object to authorize\u0027)"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"        token \u003d uuidutils.generate_uuid()"},{"line_number":95,"context_line":"        token_hash \u003d utils.get_sha256_str(token)"}],"source_content_type":"text/x-python","patch_set":20,"id":"3f4b6375_cb444d77","line":92,"range":{"start_line":92,"start_character":23,"end_line":92,"end_character":58},"updated":"2017-10-30 08:48:58.000000000","message":"Add a marker function _().","commit_id":"3c20bd619e9e2d37caca91edf736734e06729ea9"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"34ad774d685ded91c2d99d808c5b3ebcb5189185","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        if self.obj_attr_is_set(\u0027id\u0027):"},{"line_number":90,"context_line":"            raise exception.ObjectActionError("},{"line_number":91,"context_line":"                action\u003d\u0027authorize\u0027,"},{"line_number":92,"context_line":"                reason\u003d\u0027must be a new object to authorize\u0027)"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"        token \u003d uuidutils.generate_uuid()"},{"line_number":95,"context_line":"        token_hash \u003d utils.get_sha256_str(token)"}],"source_content_type":"text/x-python","patch_set":20,"id":"df87a7cf_4178738e","line":92,"range":{"start_line":92,"start_character":23,"end_line":92,"end_character":58},"in_reply_to":"3f4b6375_cb444d77","updated":"2017-12-12 19:56:09.000000000","message":"I thought we weren\u0027t translating log messages or exception messages anymore?","commit_id":"3c20bd619e9e2d37caca91edf736734e06729ea9"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"8f3de4673f107a03c904060356d55579e7941734","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        if self.obj_attr_is_set(\u0027id\u0027):"},{"line_number":90,"context_line":"            raise exception.ObjectActionError("},{"line_number":91,"context_line":"                action\u003d\u0027authorize\u0027,"},{"line_number":92,"context_line":"                reason\u003d\u0027must be a new object to authorize\u0027)"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"        token \u003d uuidutils.generate_uuid()"},{"line_number":95,"context_line":"        token_hash \u003d utils.get_sha256_str(token)"}],"source_content_type":"text/x-python","patch_set":20,"id":"df87a7cf_dd876861","line":92,"range":{"start_line":92,"start_character":23,"end_line":92,"end_character":58},"in_reply_to":"df87a7cf_4178738e","updated":"2017-12-13 18:01:04.000000000","message":"I think we still translate exceptions","commit_id":"3c20bd619e9e2d37caca91edf736734e06729ea9"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9994fe03fa2cbb3280f92714d4c603a602d566d4","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":34,"context_line":"class ConsoleConnection(base.NovaTimestampObject, base.NovaObject):"},{"line_number":35,"context_line":"    # Version 1.0: Initial version"},{"line_number":36,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":37,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"bf8cb3f7_ee213aa1","line":34,"range":{"start_line":34,"start_character":6,"end_line":34,"end_character":23},"updated":"2017-12-22 22:30:23.000000000","message":"It\u0027s weird that we call it this when the model in the DB is called ConsoleAuthToken.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a6e1f4453717e9514201aba5a35fc0d347fe6f27","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":34,"context_line":"class ConsoleConnection(base.NovaTimestampObject, base.NovaObject):"},{"line_number":35,"context_line":"    # Version 1.0: Initial version"},{"line_number":36,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":37,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"9f91af0f_636f7592","line":34,"range":{"start_line":34,"start_character":6,"end_line":34,"end_character":23},"in_reply_to":"bf8cb3f7_ee213aa1","updated":"2018-01-03 22:13:50.000000000","message":"Yeah, I think this object went through many revisions, starting out probably as a representation of the DB model but then branching out to a different name because of the \"authorize\" and \"validate\" methods. I can change the name to ConsoleAuthToken if you think it would be better.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9994fe03fa2cbb3280f92714d4c603a602d566d4","unresolved":false,"context_lines":[{"line_number":45,"context_line":"        \u0027access_url_base\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":46,"context_line":"        # NOTE(PaulMurray)The token field is not stored in the"},{"line_number":47,"context_line":"        # database. A hash of the token is stored instead."},{"line_number":48,"context_line":"        \u0027token\u0027: fields.StringField(nullable\u003dFalse),"},{"line_number":49,"context_line":"    }"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":24,"id":"bf8cb3f7_ee561a07","line":48,"range":{"start_line":48,"start_character":9,"end_line":48,"end_character":14},"updated":"2017-12-22 22:30:23.000000000","message":"So is this the unhashed or hashed token? If this is the same as the thing in the DB, this will get confusing:\n\nhttps://github.com/openstack/nova/blob/d11b842c888b4b767de1e52527eb468a899663c5/nova/db/sqlalchemy/models.py#L1587","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a6e1f4453717e9514201aba5a35fc0d347fe6f27","unresolved":false,"context_lines":[{"line_number":45,"context_line":"        \u0027access_url_base\u0027: fields.StringField(nullable\u003dTrue),"},{"line_number":46,"context_line":"        # NOTE(PaulMurray)The token field is not stored in the"},{"line_number":47,"context_line":"        # database. A hash of the token is stored instead."},{"line_number":48,"context_line":"        \u0027token\u0027: fields.StringField(nullable\u003dFalse),"},{"line_number":49,"context_line":"    }"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":24,"id":"9f91af0f_035549c6","line":48,"range":{"start_line":48,"start_character":9,"end_line":48,"end_character":14},"in_reply_to":"bf8cb3f7_ee561a07","updated":"2018-01-03 22:13:50.000000000","message":"This is unhashed and a dance is done to avoid storing it in the DB (at L97) if it\u0027s present, for example if someone calls authorize() twice in a row. After authorize() is called, the unhashed token is stored on the object for use by the access_url() method which is used by the websocketproxy to verify the origin protocol (verify_origin_proto()).","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9994fe03fa2cbb3280f92714d4c603a602d566d4","unresolved":false,"context_lines":[{"line_number":59,"context_line":"        specific to this authorization."},{"line_number":60,"context_line":"        \"\"\""},{"line_number":61,"context_line":"        if self.obj_attr_is_set(\u0027id\u0027):"},{"line_number":62,"context_line":"            return \u0027%s?token\u003d%s\u0027 % (self.access_url_base, self.token)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    @staticmethod"},{"line_number":65,"context_line":"    def _from_db_object(context, obj, db_obj):"}],"source_content_type":"text/x-python","patch_set":24,"id":"bf8cb3f7_8e474e4c","line":62,"range":{"start_line":62,"start_character":63,"end_line":62,"end_character":68},"updated":"2017-12-22 22:30:23.000000000","message":"I guess it\u0027s the unhashed token.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a6e1f4453717e9514201aba5a35fc0d347fe6f27","unresolved":false,"context_lines":[{"line_number":59,"context_line":"        specific to this authorization."},{"line_number":60,"context_line":"        \"\"\""},{"line_number":61,"context_line":"        if self.obj_attr_is_set(\u0027id\u0027):"},{"line_number":62,"context_line":"            return \u0027%s?token\u003d%s\u0027 % (self.access_url_base, self.token)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    @staticmethod"},{"line_number":65,"context_line":"    def _from_db_object(context, obj, db_obj):"}],"source_content_type":"text/x-python","patch_set":24,"id":"9f91af0f_a39c9d5d","line":62,"range":{"start_line":62,"start_character":63,"end_line":62,"end_character":68},"in_reply_to":"bf8cb3f7_8e474e4c","updated":"2018-01-03 22:13:50.000000000","message":"Yes.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9994fe03fa2cbb3280f92714d4c603a602d566d4","unresolved":false,"context_lines":[{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    @staticmethod"},{"line_number":65,"context_line":"    def _from_db_object(context, obj, db_obj):"},{"line_number":66,"context_line":"        # NOTE(PaulMurray): token is not stored in the database but"},{"line_number":67,"context_line":"        # this function assumes it is in db_obj"},{"line_number":68,"context_line":"        for field in obj.fields:"},{"line_number":69,"context_line":"            setattr(obj, field, db_obj[field])"},{"line_number":70,"context_line":"        obj._context \u003d context"},{"line_number":71,"context_line":"        obj.obj_reset_changes()"},{"line_number":72,"context_line":"        return obj"}],"source_content_type":"text/x-python","patch_set":24,"id":"bf8cb3f7_ee6ffac2","line":69,"range":{"start_line":66,"start_character":8,"end_line":69,"end_character":46},"updated":"2017-12-22 22:30:23.000000000","message":"Confused; this will set a token_hash attribute on this object, because that\u0027s the name of the column in the database:\n\nhttps://github.com/openstack/nova/blob/d11b842c888b4b767de1e52527eb468a899663c5/nova/db/sqlalchemy/models.py#L1587\n\nBut this doesn\u0027t actually set the token on this object.\n\nI see that authorize() sets \u0027token\u0027 in the db_obj below, this would be more clear if the comment mentions that.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a6e1f4453717e9514201aba5a35fc0d347fe6f27","unresolved":false,"context_lines":[{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    @staticmethod"},{"line_number":65,"context_line":"    def _from_db_object(context, obj, db_obj):"},{"line_number":66,"context_line":"        # NOTE(PaulMurray): token is not stored in the database but"},{"line_number":67,"context_line":"        # this function assumes it is in db_obj"},{"line_number":68,"context_line":"        for field in obj.fields:"},{"line_number":69,"context_line":"            setattr(obj, field, db_obj[field])"},{"line_number":70,"context_line":"        obj._context \u003d context"},{"line_number":71,"context_line":"        obj.obj_reset_changes()"},{"line_number":72,"context_line":"        return obj"}],"source_content_type":"text/x-python","patch_set":24,"id":"9f91af0f_03ad4987","line":69,"range":{"start_line":66,"start_character":8,"end_line":69,"end_character":46},"in_reply_to":"bf8cb3f7_ee6ffac2","updated":"2018-01-03 22:13:50.000000000","message":"Will add to the comment.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9994fe03fa2cbb3280f92714d4c603a602d566d4","unresolved":false,"context_lines":[{"line_number":80,"context_line":""},{"line_number":81,"context_line":"        The expires value is set for ttl seconds in the future"},{"line_number":82,"context_line":"        and the token is stored in the database. This function"},{"line_number":83,"context_line":"        can only be succeed if the token is unique and the object"},{"line_number":84,"context_line":"        has not already been stored."},{"line_number":85,"context_line":"        \"\"\""},{"line_number":86,"context_line":"        if self.obj_attr_is_set(\u0027id\u0027):"}],"source_content_type":"text/x-python","patch_set":24,"id":"bf8cb3f7_ae69f2be","line":83,"range":{"start_line":83,"start_character":17,"end_line":83,"end_character":27},"updated":"2017-12-22 22:30:23.000000000","message":"succeeed","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a6e1f4453717e9514201aba5a35fc0d347fe6f27","unresolved":false,"context_lines":[{"line_number":80,"context_line":""},{"line_number":81,"context_line":"        The expires value is set for ttl seconds in the future"},{"line_number":82,"context_line":"        and the token is stored in the database. This function"},{"line_number":83,"context_line":"        can only be succeed if the token is unique and the object"},{"line_number":84,"context_line":"        has not already been stored."},{"line_number":85,"context_line":"        \"\"\""},{"line_number":86,"context_line":"        if self.obj_attr_is_set(\u0027id\u0027):"}],"source_content_type":"text/x-python","patch_set":24,"id":"9f91af0f_43ccb169","line":83,"range":{"start_line":83,"start_character":17,"end_line":83,"end_character":27},"in_reply_to":"bf8cb3f7_ae69f2be","updated":"2018-01-03 22:13:50.000000000","message":"Ack.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9994fe03fa2cbb3280f92714d4c603a602d566d4","unresolved":false,"context_lines":[{"line_number":83,"context_line":"        can only be succeed if the token is unique and the object"},{"line_number":84,"context_line":"        has not already been stored."},{"line_number":85,"context_line":"        \"\"\""},{"line_number":86,"context_line":"        if self.obj_attr_is_set(\u0027id\u0027):"},{"line_number":87,"context_line":"            raise exception.ObjectActionError("},{"line_number":88,"context_line":"                action\u003d\u0027authorize\u0027,"},{"line_number":89,"context_line":"                reason\u003d_(\u0027must be a new object to authorize\u0027))"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"        token \u003d uuidutils.generate_uuid()"},{"line_number":92,"context_line":"        token_hash \u003d utils.get_sha256_str(token)"}],"source_content_type":"text/x-python","patch_set":24,"id":"bf8cb3f7_ced9d683","line":89,"range":{"start_line":86,"start_character":8,"end_line":89,"end_character":62},"updated":"2017-12-22 22:30:23.000000000","message":"There is no test for this.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a6e1f4453717e9514201aba5a35fc0d347fe6f27","unresolved":false,"context_lines":[{"line_number":83,"context_line":"        can only be succeed if the token is unique and the object"},{"line_number":84,"context_line":"        has not already been stored."},{"line_number":85,"context_line":"        \"\"\""},{"line_number":86,"context_line":"        if self.obj_attr_is_set(\u0027id\u0027):"},{"line_number":87,"context_line":"            raise exception.ObjectActionError("},{"line_number":88,"context_line":"                action\u003d\u0027authorize\u0027,"},{"line_number":89,"context_line":"                reason\u003d_(\u0027must be a new object to authorize\u0027))"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"        token \u003d uuidutils.generate_uuid()"},{"line_number":92,"context_line":"        token_hash \u003d utils.get_sha256_str(token)"}],"source_content_type":"text/x-python","patch_set":24,"id":"9f91af0f_c3dd2115","line":89,"range":{"start_line":86,"start_character":8,"end_line":89,"end_character":62},"in_reply_to":"bf8cb3f7_ced9d683","updated":"2018-01-03 22:13:50.000000000","message":"Will add.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9994fe03fa2cbb3280f92714d4c603a602d566d4","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        expires \u003d timeutils.utcnow_ts() + ttl"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":96,"context_line":"        if \u0027token\u0027 in updates:"},{"line_number":97,"context_line":"            del updates[\u0027token\u0027]"},{"line_number":98,"context_line":"        updates[\u0027token_hash\u0027] \u003d token_hash"},{"line_number":99,"context_line":"        updates[\u0027expires\u0027] \u003d expires"},{"line_number":100,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"bf8cb3f7_8e60aed0","line":97,"range":{"start_line":96,"start_character":8,"end_line":97,"end_character":32},"updated":"2017-12-22 22:30:23.000000000","message":"Why would \u0027token\u0027 be in updates? Should we fail if it is?","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"ac2168858e9f69b4ca14fe96b88a445329b8cd41","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        expires \u003d timeutils.utcnow_ts() + ttl"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":96,"context_line":"        if \u0027token\u0027 in updates:"},{"line_number":97,"context_line":"            del updates[\u0027token\u0027]"},{"line_number":98,"context_line":"        updates[\u0027token_hash\u0027] \u003d token_hash"},{"line_number":99,"context_line":"        updates[\u0027expires\u0027] \u003d expires"},{"line_number":100,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"9f91af0f_5c5a3a2a","line":97,"range":{"start_line":96,"start_character":8,"end_line":97,"end_character":32},"in_reply_to":"9f91af0f_a311fdae","updated":"2018-01-04 19:38:04.000000000","message":"While adding test coverage I found that authorize() can\u0027t be called twice because of L86 raising ObjectActionError. So this would be protecting against someone erroneously trying to set it on the object and then calling authorize(). \u0027token\u0027 is not a database table column, so trying to send it with updates would always result in an error.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a6e1f4453717e9514201aba5a35fc0d347fe6f27","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        expires \u003d timeutils.utcnow_ts() + ttl"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":96,"context_line":"        if \u0027token\u0027 in updates:"},{"line_number":97,"context_line":"            del updates[\u0027token\u0027]"},{"line_number":98,"context_line":"        updates[\u0027token_hash\u0027] \u003d token_hash"},{"line_number":99,"context_line":"        updates[\u0027expires\u0027] \u003d expires"},{"line_number":100,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"9f91af0f_a311fdae","line":97,"range":{"start_line":96,"start_character":8,"end_line":97,"end_character":32},"in_reply_to":"bf8cb3f7_8e60aed0","updated":"2018-01-03 22:13:50.000000000","message":"It would be if someone called authorize() twice in a row. The second time it\u0027s called on the same object to generate a new authorization, self.token would be set from the previous call. Maybe this possibility could be avoided by calling obj_reset_changes() before returning from this method.\n\nThen, the only way it could be set is if someone set the attribute explicitly. In that case, we would want to avoid ever trying to write it to the DB. I would think normally only \"fields\" would get written to the database, so maybe this method could be improved to do that instead of taking everything from obj_get_changes(). I\u0027ll look into it.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9994fe03fa2cbb3280f92714d4c603a602d566d4","unresolved":false,"context_lines":[{"line_number":99,"context_line":"        updates[\u0027expires\u0027] \u003d expires"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"        try:"},{"line_number":102,"context_line":"            db_obj \u003d db.console_auth_token_create(self._context, updates)"},{"line_number":103,"context_line":"            db_obj[\u0027token\u0027] \u003d token"},{"line_number":104,"context_line":"            self._from_db_object(self._context, self, db_obj)"},{"line_number":105,"context_line":"        except DBDuplicateEntry:"}],"source_content_type":"text/x-python","patch_set":24,"id":"bf8cb3f7_0ef81ee3","line":102,"updated":"2017-12-22 22:30:23.000000000","message":"Seems we should make sure that \u0027instance_uuid\u0027 is in updates, otherwise you\u0027ll get a confusing InstanceNotFound from this call with a None instance_uuid in the message.\n\nhttps://github.com/openstack/nova/blob/master/nova/db/sqlalchemy/api.py#L6613","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a6e1f4453717e9514201aba5a35fc0d347fe6f27","unresolved":false,"context_lines":[{"line_number":99,"context_line":"        updates[\u0027expires\u0027] \u003d expires"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"        try:"},{"line_number":102,"context_line":"            db_obj \u003d db.console_auth_token_create(self._context, updates)"},{"line_number":103,"context_line":"            db_obj[\u0027token\u0027] \u003d token"},{"line_number":104,"context_line":"            self._from_db_object(self._context, self, db_obj)"},{"line_number":105,"context_line":"        except DBDuplicateEntry:"}],"source_content_type":"text/x-python","patch_set":24,"id":"9f91af0f_838399cc","line":102,"in_reply_to":"bf8cb3f7_0ef81ee3","updated":"2018-01-03 22:13:50.000000000","message":"Okay, let me look into that too.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"ac2168858e9f69b4ca14fe96b88a445329b8cd41","unresolved":false,"context_lines":[{"line_number":99,"context_line":"        updates[\u0027expires\u0027] \u003d expires"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"        try:"},{"line_number":102,"context_line":"            db_obj \u003d db.console_auth_token_create(self._context, updates)"},{"line_number":103,"context_line":"            db_obj[\u0027token\u0027] \u003d token"},{"line_number":104,"context_line":"            self._from_db_object(self._context, self, db_obj)"},{"line_number":105,"context_line":"        except DBDuplicateEntry:"}],"source_content_type":"text/x-python","patch_set":24,"id":"9f91af0f_61eafbac","line":102,"in_reply_to":"bf8cb3f7_0ef81ee3","updated":"2018-01-04 19:38:04.000000000","message":"Okay, so instance_uuid is not a nullable field on the object, so it has to be set. It seems like we can\u0027t really be in the situation where instance_uuid isn\u0027t in the updates unless someone called obj_reset_changes() manually.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9994fe03fa2cbb3280f92714d4c603a602d566d4","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        LOG.debug(\"Authorized token with expiry %(expires)s for console \""},{"line_number":111,"context_line":"                  \"connection %(console)s\","},{"line_number":112,"context_line":"                  {\u0027expires\u0027: expires,"},{"line_number":113,"context_line":"                   \u0027console\u0027: self.obj_to_primitive()})"},{"line_number":114,"context_line":"        return token"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"    @base.remotable_classmethod"}],"source_content_type":"text/x-python","patch_set":24,"id":"bf8cb3f7_6eb8ca29","line":113,"range":{"start_line":113,"start_character":30,"end_line":113,"end_character":53},"updated":"2017-12-22 22:30:23.000000000","message":"This is just logging the token above which is a uuid, not the hashed token, so shouldn\u0027t be a concern. We shouldn\u0027t actually need to convert this to a primitive though, because that makes it look like a dict in the logs, but we actually have an object and versioned objects and their fields can be stringified. Could just change this to self later.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a6e1f4453717e9514201aba5a35fc0d347fe6f27","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        LOG.debug(\"Authorized token with expiry %(expires)s for console \""},{"line_number":111,"context_line":"                  \"connection %(console)s\","},{"line_number":112,"context_line":"                  {\u0027expires\u0027: expires,"},{"line_number":113,"context_line":"                   \u0027console\u0027: self.obj_to_primitive()})"},{"line_number":114,"context_line":"        return token"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"    @base.remotable_classmethod"}],"source_content_type":"text/x-python","patch_set":24,"id":"9f91af0f_e37ce5ec","line":113,"range":{"start_line":113,"start_character":30,"end_line":113,"end_character":53},"in_reply_to":"bf8cb3f7_6eb8ca29","updated":"2018-01-03 22:13:50.000000000","message":"Hm, but we don\u0027t want to log the token because it\u0027s all that\u0027s needed to access the instance\u0027s console (along with the access_url_base). So I missed this.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9994fe03fa2cbb3280f92714d4c603a602d566d4","unresolved":false,"context_lines":[{"line_number":130,"context_line":"        if db_obj is not None:"},{"line_number":131,"context_line":"            db_obj[\u0027token\u0027] \u003d token"},{"line_number":132,"context_line":"            obj \u003d cls._from_db_object(context, cls(), db_obj)"},{"line_number":133,"context_line":"            LOG.debug(\"Checking token is valid - console connection is \""},{"line_number":134,"context_line":"                      \"%(console)s\", {\u0027console\u0027: obj.obj_to_primitive()})"},{"line_number":135,"context_line":"            return obj"},{"line_number":136,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":24,"id":"bf8cb3f7_4e894673","line":133,"range":{"start_line":133,"start_character":23,"end_line":133,"end_character":46},"updated":"2017-12-22 22:30:23.000000000","message":"we\u0027re not checking anything here, we did that above, yeah? a bit confusing log message","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a6e1f4453717e9514201aba5a35fc0d347fe6f27","unresolved":false,"context_lines":[{"line_number":130,"context_line":"        if db_obj is not None:"},{"line_number":131,"context_line":"            db_obj[\u0027token\u0027] \u003d token"},{"line_number":132,"context_line":"            obj \u003d cls._from_db_object(context, cls(), db_obj)"},{"line_number":133,"context_line":"            LOG.debug(\"Checking token is valid - console connection is \""},{"line_number":134,"context_line":"                      \"%(console)s\", {\u0027console\u0027: obj.obj_to_primitive()})"},{"line_number":135,"context_line":"            return obj"},{"line_number":136,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":24,"id":"9f91af0f_c362013f","line":133,"range":{"start_line":133,"start_character":23,"end_line":133,"end_character":46},"in_reply_to":"bf8cb3f7_4e894673","updated":"2018-01-03 22:13:50.000000000","message":"Yeah ... I thought the same thing but couldn\u0027t come up with something better without thinking longer about it. I\u0027ll change it to something else.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9994fe03fa2cbb3280f92714d4c603a602d566d4","unresolved":false,"context_lines":[{"line_number":131,"context_line":"            db_obj[\u0027token\u0027] \u003d token"},{"line_number":132,"context_line":"            obj \u003d cls._from_db_object(context, cls(), db_obj)"},{"line_number":133,"context_line":"            LOG.debug(\"Checking token is valid - console connection is \""},{"line_number":134,"context_line":"                      \"%(console)s\", {\u0027console\u0027: obj.obj_to_primitive()})"},{"line_number":135,"context_line":"            return obj"},{"line_number":136,"context_line":"        else:"},{"line_number":137,"context_line":"            LOG.debug(\"Checking token is not valid\")"}],"source_content_type":"text/x-python","patch_set":24,"id":"bf8cb3f7_ae97b290","line":134,"range":{"start_line":134,"start_character":49,"end_line":134,"end_character":71},"updated":"2017-12-22 22:30:23.000000000","message":"same as above, we don\u0027t need to convert this to a primitive, but could clean that up later","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"}],"nova/tests/functional/db/test_console_connection.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9994fe03fa2cbb3280f92714d4c603a602d566d4","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from nova.tests import uuidsentinel"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class ComputeNodeTestCase(test.TestCase):"},{"line_number":23,"context_line":"    def setUp(self):"},{"line_number":24,"context_line":"        super(ComputeNodeTestCase, self).setUp()"},{"line_number":25,"context_line":"        self.context \u003d context.RequestContext(\u0027fake-user\u0027, \u0027fake-project\u0027)"}],"source_content_type":"text/x-python","patch_set":24,"id":"bf8cb3f7_aedc9274","line":22,"range":{"start_line":22,"start_character":6,"end_line":22,"end_character":25},"updated":"2017-12-22 22:30:23.000000000","message":"ConsoleConnectionTestCase?","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a6e1f4453717e9514201aba5a35fc0d347fe6f27","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from nova.tests import uuidsentinel"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class ComputeNodeTestCase(test.TestCase):"},{"line_number":23,"context_line":"    def setUp(self):"},{"line_number":24,"context_line":"        super(ComputeNodeTestCase, self).setUp()"},{"line_number":25,"context_line":"        self.context \u003d context.RequestContext(\u0027fake-user\u0027, \u0027fake-project\u0027)"}],"source_content_type":"text/x-python","patch_set":24,"id":"9f91af0f_4356f15e","line":22,"range":{"start_line":22,"start_character":6,"end_line":22,"end_character":25},"in_reply_to":"bf8cb3f7_aedc9274","updated":"2018-01-03 22:13:50.000000000","message":"lol, I never noticed that. Thanks for catching.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"}],"nova/tests/unit/objects/test_console_connection.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"42a992f36ac2a855b35a7d2fb52ec738159338ef","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        self.compare_obj(obj, expected)"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    @mock.patch(\u0027nova.db.console_auth_token_get_valid\u0027)"},{"line_number":69,"context_line":"    def test_validate(self, mock_get):"},{"line_number":70,"context_line":"        mock_get.return_value \u003d fakes.fake_token_dict"},{"line_number":71,"context_line":"        expected \u003d copy.deepcopy(fakes.fake_token_dict)"},{"line_number":72,"context_line":"        del expected[\u0027token_hash\u0027]"}],"source_content_type":"text/x-python","patch_set":10,"id":"7aa08908_727357e8","line":69,"updated":"2016-06-09 17:27:53.000000000","message":"You need to test the non-validating case right?","commit_id":"e6f5db166f7e91ac78de79fc1c05368ec3154822"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9994fe03fa2cbb3280f92714d4c603a602d566d4","unresolved":false,"context_lines":[{"line_number":131,"context_line":"        self.compare_obj(obj, expected)"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    @mock.patch(\u0027nova.db.console_auth_token_get_valid\u0027)"},{"line_number":134,"context_line":"    def test_validate_not_valid(self, mock_get):"},{"line_number":135,"context_line":"        mock_get.return_value \u003d None"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"        self.assertRaises("}],"source_content_type":"text/x-python","patch_set":24,"id":"bf8cb3f7_eecb7aa2","line":134,"updated":"2017-12-22 22:30:23.000000000","message":"This is a duplicate of the functional test, not sure the point.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a6e1f4453717e9514201aba5a35fc0d347fe6f27","unresolved":false,"context_lines":[{"line_number":131,"context_line":"        self.compare_obj(obj, expected)"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    @mock.patch(\u0027nova.db.console_auth_token_get_valid\u0027)"},{"line_number":134,"context_line":"    def test_validate_not_valid(self, mock_get):"},{"line_number":135,"context_line":"        mock_get.return_value \u003d None"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"        self.assertRaises("}],"source_content_type":"text/x-python","patch_set":24,"id":"9f91af0f_63d695c6","line":134,"in_reply_to":"bf8cb3f7_eecb7aa2","updated":"2018-01-03 22:13:50.000000000","message":"Hm, I didn\u0027t notice that. We can probably get rid of this and test_validate if I enhance the validate func test a bit.","commit_id":"40cdc0d02abc4a7de0fc8f4704c59176a1b12735"}],"nova/utils.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"8f3de4673f107a03c904060356d55579e7941734","unresolved":false,"context_lines":[{"line_number":1072,"context_line":"    return hashlib.md5(base_str).hexdigest()"},{"line_number":1073,"context_line":""},{"line_number":1074,"context_line":""},{"line_number":1075,"context_line":"def get_sha1_str(base_str):"},{"line_number":1076,"context_line":"    \"\"\"Returns string that represents SHA1 hash of base_str (in hex format)."},{"line_number":1077,"context_line":""},{"line_number":1078,"context_line":"    If base_str is a Unicode string, encode it to UTF-8."},{"line_number":1079,"context_line":"    \"\"\""},{"line_number":1080,"context_line":"    if isinstance(base_str, six.text_type):"},{"line_number":1081,"context_line":"        base_str \u003d base_str.encode(\u0027utf-8\u0027)"},{"line_number":1082,"context_line":"    return hashlib.sha1(base_str).hexdigest()"},{"line_number":1083,"context_line":""},{"line_number":1084,"context_line":""},{"line_number":1085,"context_line":"def get_sha256_str(base_str):"}],"source_content_type":"text/x-python","patch_set":22,"id":"df87a7cf_fdbd8c02","line":1082,"range":{"start_line":1075,"start_character":0,"end_line":1082,"end_character":45},"updated":"2017-12-13 18:01:04.000000000","message":"This is unused now","commit_id":"e59287a125356b4d8cfe47a41a6b0faa04420ff8"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"b44f02d97fa0c351e2f02bae615cc7548ead67c3","unresolved":false,"context_lines":[{"line_number":1072,"context_line":"    return hashlib.md5(base_str).hexdigest()"},{"line_number":1073,"context_line":""},{"line_number":1074,"context_line":""},{"line_number":1075,"context_line":"def get_sha1_str(base_str):"},{"line_number":1076,"context_line":"    \"\"\"Returns string that represents SHA1 hash of base_str (in hex format)."},{"line_number":1077,"context_line":""},{"line_number":1078,"context_line":"    If base_str is a Unicode string, encode it to UTF-8."},{"line_number":1079,"context_line":"    \"\"\""},{"line_number":1080,"context_line":"    if isinstance(base_str, six.text_type):"},{"line_number":1081,"context_line":"        base_str \u003d base_str.encode(\u0027utf-8\u0027)"},{"line_number":1082,"context_line":"    return hashlib.sha1(base_str).hexdigest()"},{"line_number":1083,"context_line":""},{"line_number":1084,"context_line":""},{"line_number":1085,"context_line":"def get_sha256_str(base_str):"}],"source_content_type":"text/x-python","patch_set":22,"id":"df87a7cf_77b43436","line":1082,"range":{"start_line":1075,"start_character":0,"end_line":1082,"end_character":45},"in_reply_to":"df87a7cf_fdbd8c02","updated":"2017-12-13 23:14:19.000000000","message":"Guh, thanks. Totally missed that.","commit_id":"e59287a125356b4d8cfe47a41a6b0faa04420ff8"}]}
