)]}'
{"horizon/base.py":[{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"0dce13982cc9f5716e57480531c62ca1f46472ee","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        if self._access_cache(request) is None:"},{"line_number":63,"context_line":"            self._access_cache(request, func(self, context))"},{"line_number":64,"context_line":"        return self._access_cache(request)"},{"line_number":65,"context_line":"    return inner"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"class NotRegistered(Exception):"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa98f980_56e1af28","line":65,"updated":"2014-09-12 14:59:16.000000000","message":"I believe this cache needs to be invalidated when the user gets a new token or switches projects.","commit_id":"9f300fc01fd6abfc20b828d472ba4a968138aa40"},{"author":{"_account_id":9981,"name":"Doug Fish","email":"drfish@us.ibm.com","username":"doug-fish"},"change_message_id":"cc8fe55160635efea2a373b3659f9e761068c1be","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        if self._access_cache(request) is None:"},{"line_number":63,"context_line":"            self._access_cache(request, func(self, context))"},{"line_number":64,"context_line":"        return self._access_cache(request)"},{"line_number":65,"context_line":"    return inner"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"class NotRegistered(Exception):"}],"source_content_type":"text/x-python","patch_set":2,"id":"da9df570_cf957941","line":65,"in_reply_to":"da9df570_0c94efe0","updated":"2014-09-23 12:55:47.000000000","message":"Shouldn\u0027t this be a matter of just inspecting request.user.token.id and comparing it to a previous value stored in the session?","commit_id":"9f300fc01fd6abfc20b828d472ba4a968138aa40"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"c3162a7cc209267cb3e95c983d5f779f912849a7","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        if self._access_cache(request) is None:"},{"line_number":63,"context_line":"            self._access_cache(request, func(self, context))"},{"line_number":64,"context_line":"        return self._access_cache(request)"},{"line_number":65,"context_line":"    return inner"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"class NotRegistered(Exception):"}],"source_content_type":"text/x-python","patch_set":2,"id":"da9df570_28a0b69e","line":65,"in_reply_to":"da9df570_cf957941","updated":"2014-09-23 16:36:51.000000000","message":"Done","commit_id":"9f300fc01fd6abfc20b828d472ba4a968138aa40"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"a65ab2725faee37bccbaf1b782d66147a9440dea","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        if self._access_cache(request) is None:"},{"line_number":63,"context_line":"            self._access_cache(request, func(self, context))"},{"line_number":64,"context_line":"        return self._access_cache(request)"},{"line_number":65,"context_line":"    return inner"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"class NotRegistered(Exception):"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa98f980_96d95759","line":65,"in_reply_to":"fa98f980_56e1af28","updated":"2014-09-12 15:07:19.000000000","message":"Does the session remain the same when this happens? or is a new session created?  Do you know of any way to detect that the project or token has changed?","commit_id":"9f300fc01fd6abfc20b828d472ba4a968138aa40"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"e141bf600527dcf316a116984dd401181b990f78","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        if self._access_cache(request) is None:"},{"line_number":63,"context_line":"            self._access_cache(request, func(self, context))"},{"line_number":64,"context_line":"        return self._access_cache(request)"},{"line_number":65,"context_line":"    return inner"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"class NotRegistered(Exception):"}],"source_content_type":"text/x-python","patch_set":2,"id":"da9df570_0c94efe0","line":65,"in_reply_to":"fa98f980_96d95759","updated":"2014-09-23 12:36:31.000000000","message":"Sorry for the delay. I don\u0027t know how to do it, I suppose I would ask the people at #horizon for advice.","commit_id":"9f300fc01fd6abfc20b828d472ba4a968138aa40"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"0dce13982cc9f5716e57480531c62ca1f46472ee","unresolved":false,"context_lines":[{"line_number":99,"context_line":"                urlpatterns \u003d patterns(\u0027\u0027)"},{"line_number":100,"context_line":"        return urlpatterns"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"    @access_cached"},{"line_number":103,"context_line":"    def can_access(self, context):"},{"line_number":104,"context_line":"        \"\"\"Checks to see that the user has role based access to this component."},{"line_number":105,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"fa98f980_368d0b7d","line":102,"updated":"2014-09-12 14:59:16.000000000","message":"Instead of putting this on each an every can_access method, can we simply cache it where they are called?","commit_id":"9f300fc01fd6abfc20b828d472ba4a968138aa40"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"a65ab2725faee37bccbaf1b782d66147a9440dea","unresolved":false,"context_lines":[{"line_number":99,"context_line":"                urlpatterns \u003d patterns(\u0027\u0027)"},{"line_number":100,"context_line":"        return urlpatterns"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"    @access_cached"},{"line_number":103,"context_line":"    def can_access(self, context):"},{"line_number":104,"context_line":"        \"\"\"Checks to see that the user has role based access to this component."},{"line_number":105,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"fa98f980_7606b3cf","line":102,"in_reply_to":"fa98f980_368d0b7d","updated":"2014-09-12 15:07:19.000000000","message":"It is called (at least from what I can tell) from several different places, there isn\u0027t a singular location can_access is called from, so for consistency and to ensure it gets the cache every time I added the decorator.","commit_id":"9f300fc01fd6abfc20b828d472ba4a968138aa40"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"e141bf600527dcf316a116984dd401181b990f78","unresolved":false,"context_lines":[{"line_number":99,"context_line":"                urlpatterns \u003d patterns(\u0027\u0027)"},{"line_number":100,"context_line":"        return urlpatterns"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"    @access_cached"},{"line_number":103,"context_line":"    def can_access(self, context):"},{"line_number":104,"context_line":"        \"\"\"Checks to see that the user has role based access to this component."},{"line_number":105,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"da9df570_4cbd1768","line":102,"in_reply_to":"fa98f980_7606b3cf","updated":"2014-09-23 12:36:31.000000000","message":"Ah, OK.","commit_id":"9f300fc01fd6abfc20b828d472ba4a968138aa40"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"3d2f3656cddca77cba03fe0b8c9663999c55f2ef","unresolved":false,"context_lines":[{"line_number":60,"context_line":"    def inner(self, context):"},{"line_number":61,"context_line":"        request \u003d context[\u0027request\u0027]"},{"line_number":62,"context_line":"        if self._access_cache(request) is None:"},{"line_number":63,"context_line":"            self._access_cache(request, func(self, context))"},{"line_number":64,"context_line":"        return self._access_cache(request)"},{"line_number":65,"context_line":"    return inner"},{"line_number":66,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"da9df570_941c4615","line":63,"updated":"2014-09-24 13:11:00.000000000","message":"IMHO, it would be better to move _access_cache logic into this decorator, which helps to avoid having function behaving either like getter or setter depending on its arguments (makes code a bit less readable). Consider as a nitpicking.","commit_id":"b763a58de3c04d6b054be2890219d2b4589ad33a"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"93d109530361ddf8bfb5bbd1e8f3a584ef98fb41","unresolved":false,"context_lines":[{"line_number":60,"context_line":"    def inner(self, context):"},{"line_number":61,"context_line":"        request \u003d context[\u0027request\u0027]"},{"line_number":62,"context_line":"        if self._access_cache(request) is None:"},{"line_number":63,"context_line":"            self._access_cache(request, func(self, context))"},{"line_number":64,"context_line":"        return self._access_cache(request)"},{"line_number":65,"context_line":"    return inner"},{"line_number":66,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"da9df570_3a0e218e","line":63,"in_reply_to":"da9df570_941c4615","updated":"2014-09-24 14:22:40.000000000","message":"Done. Moving the code out to the decorator actually really cleans things up and makes it more readable.","commit_id":"b763a58de3c04d6b054be2890219d2b4589ad33a"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"14360edd8c5c550c5c4c4d9f56ca3633ff4a5dc8","unresolved":false,"context_lines":[{"line_number":63,"context_line":"            or not request.session[\u0027allowed\u0027].get(\u0027valid_for\u0027) \\"},{"line_number":64,"context_line":"                \u003d\u003d request.session.get(\u0027token\u0027):"},{"line_number":65,"context_line":"            request.session[\u0027allowed\u0027] \u003d \\"},{"line_number":66,"context_line":"                {\"valid_for\": request.session.get(\u0027token\u0027)}"},{"line_number":67,"context_line":"        allowed \u003d request.session[\u0027allowed\u0027]"},{"line_number":68,"context_line":"        if allowed.get(str(self.__class__)) is not None:"},{"line_number":69,"context_line":"            return allowed.get(str(self.__class__))"}],"source_content_type":"text/x-python","patch_set":5,"id":"da9df570_86bb21e4","line":66,"updated":"2014-09-25 07:03:23.000000000","message":"Please use () for breaking long line, and not \\. For instance:\n\nsession \u003d request.session\nif not (session.get(allowed) and \n         session[\u0027allowed\u0027].get(\u0027valid_for\u0027) \u003d\u003d\n         session.get(\u0027token\u0027)):\n\nAlso, it\u0027s easier to ask for forgiveness than to get permission, so you can catch the KeyError (or whatever session trows) instead:\n\ntry:\n    allowed \u003d request.session[\u0027allowed\u0027]\n    if allowed.get(\u0027valid_for\u0027) !\u003d allowed.get(\u0027token\u0027):\n        raise KeyError(\u0027expired\u0027)\nexcept KeyError:\n    allowed \u003d {...}\n    request.session[\u0027allowed\u0027] \u003d allowed","commit_id":"f0b6b308e0b44630081ca3803b5b6a1bbe0e3c9b"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"97313043c8b68f5464143c3ee66d040272925130","unresolved":false,"context_lines":[{"line_number":63,"context_line":"            or not request.session[\u0027allowed\u0027].get(\u0027valid_for\u0027) \\"},{"line_number":64,"context_line":"                \u003d\u003d request.session.get(\u0027token\u0027):"},{"line_number":65,"context_line":"            request.session[\u0027allowed\u0027] \u003d \\"},{"line_number":66,"context_line":"                {\"valid_for\": request.session.get(\u0027token\u0027)}"},{"line_number":67,"context_line":"        allowed \u003d request.session[\u0027allowed\u0027]"},{"line_number":68,"context_line":"        if allowed.get(str(self.__class__)) is not None:"},{"line_number":69,"context_line":"            return allowed.get(str(self.__class__))"}],"source_content_type":"text/x-python","patch_set":5,"id":"da9df570_8a723f0f","line":66,"in_reply_to":"da9df570_86bb21e4","updated":"2014-09-25 13:00:15.000000000","message":"Done","commit_id":"f0b6b308e0b44630081ca3803b5b6a1bbe0e3c9b"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"14360edd8c5c550c5c4c4d9f56ca3633ff4a5dc8","unresolved":false,"context_lines":[{"line_number":66,"context_line":"                {\"valid_for\": request.session.get(\u0027token\u0027)}"},{"line_number":67,"context_line":"        allowed \u003d request.session[\u0027allowed\u0027]"},{"line_number":68,"context_line":"        if allowed.get(str(self.__class__)) is not None:"},{"line_number":69,"context_line":"            return allowed.get(str(self.__class__))"},{"line_number":70,"context_line":"        else:"},{"line_number":71,"context_line":"            allowed[str(self.__class__)] \u003d func(self, context)"},{"line_number":72,"context_line":"            request.session.modified \u003d True"}],"source_content_type":"text/x-python","patch_set":5,"id":"da9df570_4677793a","line":69,"updated":"2014-09-25 07:03:23.000000000","message":"This gives you an ugly \"\u003cclass \u0027__main__.A\u0027\u003e\". How about a self.__class__.__name__ instead?\n\nAlso, you are repeating the same code twice just to check if the key exists. Just catch the KeyError instead.","commit_id":"f0b6b308e0b44630081ca3803b5b6a1bbe0e3c9b"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"97313043c8b68f5464143c3ee66d040272925130","unresolved":false,"context_lines":[{"line_number":66,"context_line":"                {\"valid_for\": request.session.get(\u0027token\u0027)}"},{"line_number":67,"context_line":"        allowed \u003d request.session[\u0027allowed\u0027]"},{"line_number":68,"context_line":"        if allowed.get(str(self.__class__)) is not None:"},{"line_number":69,"context_line":"            return allowed.get(str(self.__class__))"},{"line_number":70,"context_line":"        else:"},{"line_number":71,"context_line":"            allowed[str(self.__class__)] \u003d func(self, context)"},{"line_number":72,"context_line":"            request.session.modified \u003d True"}],"source_content_type":"text/x-python","patch_set":5,"id":"da9df570_6a751bf9","line":69,"in_reply_to":"da9df570_4677793a","updated":"2014-09-25 13:00:15.000000000","message":"The reason I use __class__ instead of __class__.__name__ is to ensure that things like dashboard.admin.networks.tables.NetworksTable and dashboard.project.networks.tables.NetworksTable are treated separately, if I just used __name__ then every class name in horizon would have to be unique for this to work.","commit_id":"f0b6b308e0b44630081ca3803b5b6a1bbe0e3c9b"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"152c64954b8f393d77c2436a3d218e1082801108","unresolved":false,"context_lines":[{"line_number":66,"context_line":"                {\"valid_for\": request.session.get(\u0027token\u0027)}"},{"line_number":67,"context_line":"        allowed \u003d request.session[\u0027allowed\u0027]"},{"line_number":68,"context_line":"        if allowed.get(str(self.__class__)) is not None:"},{"line_number":69,"context_line":"            return allowed.get(str(self.__class__))"},{"line_number":70,"context_line":"        else:"},{"line_number":71,"context_line":"            allowed[str(self.__class__)] \u003d func(self, context)"},{"line_number":72,"context_line":"            request.session.modified \u003d True"}],"source_content_type":"text/x-python","patch_set":5,"id":"da9df570_76e50637","line":69,"in_reply_to":"da9df570_6a751bf9","updated":"2014-09-25 13:15:36.000000000","message":"hmm, how about:\n\ndef class_path(obj):\n    return obj.__class__.__module__ + \u0027.\u0027 + obj.__class__.__name__","commit_id":"f0b6b308e0b44630081ca3803b5b6a1bbe0e3c9b"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"2b354efa738695b0f7062cb6b645661b6f4e6ac9","unresolved":false,"context_lines":[{"line_number":66,"context_line":"                {\"valid_for\": request.session.get(\u0027token\u0027)}"},{"line_number":67,"context_line":"        allowed \u003d request.session[\u0027allowed\u0027]"},{"line_number":68,"context_line":"        if allowed.get(str(self.__class__)) is not None:"},{"line_number":69,"context_line":"            return allowed.get(str(self.__class__))"},{"line_number":70,"context_line":"        else:"},{"line_number":71,"context_line":"            allowed[str(self.__class__)] \u003d func(self, context)"},{"line_number":72,"context_line":"            request.session.modified \u003d True"}],"source_content_type":"text/x-python","patch_set":5,"id":"da9df570_b6d5ae1d","line":69,"in_reply_to":"da9df570_76e50637","updated":"2014-09-25 13:23:29.000000000","message":"There is actually such a function already! Take a look at django.utils.unittest.util.strclass","commit_id":"f0b6b308e0b44630081ca3803b5b6a1bbe0e3c9b"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"a87ede5503032be55b7d700269e27ebcebdbb126","unresolved":false,"context_lines":[{"line_number":66,"context_line":"                {\"valid_for\": request.session.get(\u0027token\u0027)}"},{"line_number":67,"context_line":"        allowed \u003d request.session[\u0027allowed\u0027]"},{"line_number":68,"context_line":"        if allowed.get(str(self.__class__)) is not None:"},{"line_number":69,"context_line":"            return allowed.get(str(self.__class__))"},{"line_number":70,"context_line":"        else:"},{"line_number":71,"context_line":"            allowed[str(self.__class__)] \u003d func(self, context)"},{"line_number":72,"context_line":"            request.session.modified \u003d True"}],"source_content_type":"text/x-python","patch_set":5,"id":"da9df570_2d7248ad","line":69,"in_reply_to":"da9df570_b6d5ae1d","updated":"2014-09-25 14:25:17.000000000","message":"Done","commit_id":"f0b6b308e0b44630081ca3803b5b6a1bbe0e3c9b"},{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"903c3d6fe7efaffd2ca53e45e7e584c5d653edef","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        session \u003d context[\u0027request\u0027].session"},{"line_number":62,"context_line":"        try:"},{"line_number":63,"context_line":"            if session[\u0027allowed\u0027][\u0027valid_for\u0027] !\u003d session.get(\u0027token\u0027):"},{"line_number":64,"context_line":"                raise KeyError"},{"line_number":65,"context_line":"        except KeyError:"},{"line_number":66,"context_line":"            session[\u0027allowed\u0027] \u003d {\"valid_for\": session.get(\u0027token\u0027)}"},{"line_number":67,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"da9df570_2016cf55","line":64,"updated":"2014-09-25 15:16:43.000000000","message":"please raise an instance of an exception, not a class","commit_id":"d1d98fd24ad81744ff0f2c2e5167f920a98d2edb"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"e09242198aa032f7bae69bf65be6ae9d975a63c8","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        session \u003d context[\u0027request\u0027].session"},{"line_number":62,"context_line":"        try:"},{"line_number":63,"context_line":"            if session[\u0027allowed\u0027][\u0027valid_for\u0027] !\u003d session.get(\u0027token\u0027):"},{"line_number":64,"context_line":"                raise KeyError"},{"line_number":65,"context_line":"        except KeyError:"},{"line_number":66,"context_line":"            session[\u0027allowed\u0027] \u003d {\"valid_for\": session.get(\u0027token\u0027)}"},{"line_number":67,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"da9df570_63c38189","line":64,"in_reply_to":"da9df570_2016cf55","updated":"2014-09-25 15:22:52.000000000","message":"Done, my bad.","commit_id":"d1d98fd24ad81744ff0f2c2e5167f920a98d2edb"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"2697dc6dff4ca50d564320b43090a82d413ab4f1","unresolved":false,"context_lines":[{"line_number":107,"context_line":"                urlpatterns \u003d patterns(\u0027\u0027)"},{"line_number":108,"context_line":"        return urlpatterns"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    @access_cached"},{"line_number":111,"context_line":"    def can_access(self, context):"},{"line_number":112,"context_line":"        \"\"\"Checks to see that the user has role based access to this component."},{"line_number":113,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"da9df570_89d4e8bd","line":110,"updated":"2014-09-26 13:47:00.000000000","message":"IMHO it is better to avoid requiring subclasses to use @access_method decorator. Requiring the decorator in subclasses potentially causes programming error.\n\nHow about making _can_access a public method intended to be overridden bu subclasses and renaming it to allowed().\nAccording to my test it works fine.","commit_id":"7575b6e099e72b88c71f018fcdc431b16be41aa8"}],"horizon/test/tests/base.py":[{"author":{"_account_id":8648,"name":"Radomir Dopieralski","email":"openstack@dopieralski.pl","username":"thesheep"},"change_message_id":"14360edd8c5c550c5c4c4d9f56ca3633ff4a5dc8","unresolved":false,"context_lines":[{"line_number":514,"context_line":""},{"line_number":515,"context_line":"        class FakeRequest(object):"},{"line_number":516,"context_line":"            def __init__(self):"},{"line_number":517,"context_line":"                self.session \u003d FakeSession()"},{"line_number":518,"context_line":""},{"line_number":519,"context_line":"        context \u003d {\u0027request\u0027: FakeRequest()}"},{"line_number":520,"context_line":"        cats \u003d horizon.get_dashboard(\"cats\")"}],"source_content_type":"text/x-python","patch_set":5,"id":"da9df570_06a491a4","line":517,"updated":"2014-09-25 07:03:23.000000000","message":"Why not use mock here?","commit_id":"f0b6b308e0b44630081ca3803b5b6a1bbe0e3c9b"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"97313043c8b68f5464143c3ee66d040272925130","unresolved":false,"context_lines":[{"line_number":514,"context_line":""},{"line_number":515,"context_line":"        class FakeRequest(object):"},{"line_number":516,"context_line":"            def __init__(self):"},{"line_number":517,"context_line":"                self.session \u003d FakeSession()"},{"line_number":518,"context_line":""},{"line_number":519,"context_line":"        context \u003d {\u0027request\u0027: FakeRequest()}"},{"line_number":520,"context_line":"        cats \u003d horizon.get_dashboard(\"cats\")"}],"source_content_type":"text/x-python","patch_set":5,"id":"da9df570_10a922df","line":517,"in_reply_to":"da9df570_06a491a4","updated":"2014-09-25 13:00:15.000000000","message":"I have discovered that the parent class of this provides a self.request object so have changed the code in the next patch to use that instead of mocking my own request.","commit_id":"f0b6b308e0b44630081ca3803b5b6a1bbe0e3c9b"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"768ae2b90699b23d1fdd1c4cbc6fac1c9e7e22c2","unresolved":false,"context_lines":[{"line_number":57,"context_line":"    name \u003d \"RBAC Panel No\""},{"line_number":58,"context_line":"    slug \u003d \"rbac_panel_no\""},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def _can_access(self, request):"},{"line_number":61,"context_line":"        return False"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"da9df570_f000f5ac","line":60,"updated":"2014-09-26 16:25:09.000000000","message":"I prefer to allowed() here.","commit_id":"2f29d29d410f8416bd127c79477c3be6959e37da"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"e79ed559daadce52e7a0d8be00b14b85107198cb","unresolved":false,"context_lines":[{"line_number":57,"context_line":"    name \u003d \"RBAC Panel No\""},{"line_number":58,"context_line":"    slug \u003d \"rbac_panel_no\""},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def _can_access(self, request):"},{"line_number":61,"context_line":"        return False"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"baa201ad_a18f45cb","line":60,"in_reply_to":"da9df570_f000f5ac","updated":"2014-10-02 17:00:27.000000000","message":"Done","commit_id":"2f29d29d410f8416bd127c79477c3be6959e37da"}],"openstack_dashboard/dashboards/project/firewalls/panel.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"2697dc6dff4ca50d564320b43090a82d413ab4f1","unresolved":false,"context_lines":[{"line_number":24,"context_line":"    slug \u003d \"firewalls\""},{"line_number":25,"context_line":"    permissions \u003d (\u0027openstack.services.network\u0027,)"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    @horizon.base.access_cached"},{"line_number":28,"context_line":"    def can_access(self, context):"},{"line_number":29,"context_line":"        request \u003d context[\u0027request\u0027]"},{"line_number":30,"context_line":"        if not request.user.has_perms(self.permissions):"}],"source_content_type":"text/x-python","patch_set":8,"id":"da9df570_469754ec","line":27,"updated":"2014-09-26 13:47:00.000000000","message":"Hopefully we would like to avoid using the decorator in subclasses. Requiring the decorator in subclasses potentially causes  programming error. I am exploring a solution with a small change.","commit_id":"7575b6e099e72b88c71f018fcdc431b16be41aa8"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"768ae2b90699b23d1fdd1c4cbc6fac1c9e7e22c2","unresolved":false,"context_lines":[{"line_number":13,"context_line":"from django.utils.translation import ugettext_lazy as _"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import horizon"},{"line_number":16,"context_line":"import horizon.base"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from openstack_dashboard.api import neutron"},{"line_number":19,"context_line":"from openstack_dashboard.dashboards.project import dashboard"}],"source_content_type":"text/x-python","patch_set":9,"id":"da9df570_10fe59ae","line":16,"updated":"2014-09-26 16:25:09.000000000","message":"Unnecessary (not sure why flake8 does not detect it)","commit_id":"2f29d29d410f8416bd127c79477c3be6959e37da"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"e79ed559daadce52e7a0d8be00b14b85107198cb","unresolved":false,"context_lines":[{"line_number":13,"context_line":"from django.utils.translation import ugettext_lazy as _"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import horizon"},{"line_number":16,"context_line":"import horizon.base"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from openstack_dashboard.api import neutron"},{"line_number":19,"context_line":"from openstack_dashboard.dashboards.project import dashboard"}],"source_content_type":"text/x-python","patch_set":9,"id":"baa201ad_c1bd296a","line":16,"in_reply_to":"da9df570_10fe59ae","updated":"2014-10-02 17:00:27.000000000","message":"Done","commit_id":"2f29d29d410f8416bd127c79477c3be6959e37da"}],"openstack_dashboard/dashboards/project/vpn/panel.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"768ae2b90699b23d1fdd1c4cbc6fac1c9e7e22c2","unresolved":false,"context_lines":[{"line_number":17,"context_line":"from django.utils.translation import ugettext_lazy as _"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"import horizon"},{"line_number":20,"context_line":"import horizon.base"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from openstack_dashboard.api import neutron"},{"line_number":23,"context_line":"from openstack_dashboard.dashboards.project import dashboard"}],"source_content_type":"text/x-python","patch_set":9,"id":"da9df570_302efd43","line":20,"updated":"2014-09-26 16:25:09.000000000","message":"Unnecessary","commit_id":"2f29d29d410f8416bd127c79477c3be6959e37da"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"e79ed559daadce52e7a0d8be00b14b85107198cb","unresolved":false,"context_lines":[{"line_number":17,"context_line":"from django.utils.translation import ugettext_lazy as _"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"import horizon"},{"line_number":20,"context_line":"import horizon.base"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from openstack_dashboard.api import neutron"},{"line_number":23,"context_line":"from openstack_dashboard.dashboards.project import dashboard"}],"source_content_type":"text/x-python","patch_set":9,"id":"baa201ad_e1c06de2","line":20,"in_reply_to":"da9df570_302efd43","updated":"2014-10-02 17:00:27.000000000","message":"Done","commit_id":"2f29d29d410f8416bd127c79477c3be6959e37da"}]}
