Get access to Avatar from Resource object?

I am trying to understand how Twisted Web security works, based on a few links: http://jcalderone.livejournal.com/53074.html http://twistedmatrix.com/documents/current/web/howto/web-in-60/http-auth.htm... They all explain how to set up a web app with let's say HTTP auth. But there are no examples on how a Resource method (let;s say render_GET) could get access to the current Avatar object? And does the Avatar object need to implement some specific interface? What I want to do in CorePost is to allow fine grained privilege-based security *per method* (similar in style to Spring Security, for those who know it), e.g.: @route("/user",Http.GET) @secured("BROWSE_USER") def getUser(self,request,**kwargs): return ...some user info... @route("/user",Http.POST) @secured("UPDATE_USER") def updateUser(self,request,userId,**kwargs): ...create new user, etc... If the Avatar does not have the required privileges (e.g. "BROWSE_USER" or "UPDATE_USER" in the example above), I want to throw a 403 Access Denied automatically. Thanks for any pointers Jacek https://github.com/jacek99/corepost

On Feb 22, 2012, at 11:02 AM, Jacek Furmankiewicz wrote:
But there are no examples on how a Resource method (let;s say render_GET) could get access to the current Avatar object?
The avatar is a resource, and therefore it can pass itself (or any relevant authentication or authorization information) to its children as they are created. twisted.web doesn't implement role-based authorization or anything like it. If it did, it would use a specific object that implemented that role-based auth, not the avatar (which is an implementation of a protocol interface).
And does the Avatar object need to implement some specific interface?
Yes, the Avatar object must provide IResource. -glyph

I am a bit more confused after this than before :-) How can Avatar be a resource? It represents the actual user, correct? Isnt' there a concept of a Principal / User that has nothing to do with actual URL responses / routing / etc. Sorry if I am asking basic questions, but sometimes it is hard to figure out from the high-level docs how all the pieces fit together... Thank you in advance Jacek On Wed, Feb 22, 2012 at 11:59 AM, Glyph <glyph@twistedmatrix.com> wrote:
On Feb 22, 2012, at 11:02 AM, Jacek Furmankiewicz wrote:
But there are no examples on how a Resource method (let;s say render_GET) could get access to the current Avatar object?
The avatar is a resource, and therefore it can pass itself (or any relevant authentication or authorization information) to its children as they are created.
twisted.web doesn't implement role-based authorization or anything like it. If it did, it would use a specific object that implemented that role-based auth, not the avatar (which is an implementation of a protocol interface).
And does the Avatar object need to implement some specific interface?
Yes, the Avatar object must provide IResource.
-glyph
_______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web

On Feb 22, 2012, at 12:46 PM, Jacek Furmankiewicz wrote:
I am a bit more confused after this than before :-)
How can Avatar be a resource? It represents the actual user, correct?
An avatar is a resource because that's the way that cred works: the avatar is the entity that implements protocol-specific logic for a user. For IMAP, the avatar is an IAccount; for POP it's an IMailbox, for IRC (and hopefully, one day, other chat protocols) it's an IUser.
Isnt' there a concept of a Principal / User that has nothing to do with actual URL responses / routing / etc.
No. Twisted does not have a concept of a user, because it doesn't need one in order to implement cross-protocol authentication. Twisted may one day get some concept of a user so that we can integrate more cleanly with directory services, but that sort of integration is highly complex, since everybody has a slightly different schema for what they expect a "user" to be and you end up having to accommodate them all. Plus, many people mistakenly want to have attributes of users deeply intermingled with the authentication or authorization process, when cred demonstrates that this is unnecessary and overcomplex :-). I also want to make sure that if we do incorporate such a model, it's sufficiently well fleshed out that it meets a decent set of use-cases and can interoperate with existing relevant standards. If you want to see what happens if you codify too simple a schema too early in your development, talk to anyone who has used Django about how much they love django.contrib.auth.
Sorry if I am asking basic questions, but sometimes it is hard to figure out from the high-level docs how all the pieces fit together...
It's no problem. cred is one of the most nuanced parts of twisted, and it is unfortunately difficult to explain and to understand. Feel free to keep hammering away with questions :). -glyph

Well, in my Java day job we use Spring Security, which I have to say works very well and is very flexible. So I was trying to go with a similar approach and trying to figure out the best way to integrate it with the current twisted.web approach for CorePost: a) a common security filter that intercepts incoming requests. Can be configured per URL pattern (e.g. "/services/rest","/services/operations" requires security, but "/services/public" does not) b) a separate config for the security filter that defines required privileges (per sub root, e.g. "/services/rest" may require "ADMIN_USER", but "/services/rest" may require "OPERATIONS_USER") c) additional optional feature where every REST method can be annotated with additional privileges (so a GET on a REST resource may need different privileges vs a POST, PUT or DELETE, etc.) d) every incoming request creates a Principal (which is a user overriden type if necessary) that holds info about the current user making the REST request (e.g. name, roles, privileges, etc.) I tried looking through twisted.web docs to see if there is a concept of a generic filter (that can be applied across multiple resources) but didn't really find anything. Hence I implemented it manually myself in CorePost 0.0.11. I will dig further to see how the Spring Security approach (which I like and it works very well on a huge complex SaaS platform we have) could maybe be applied on top of the current twisted.web APIs as part of CorePost. Any suggestions, comments or pointers would be welcome. Cheers Jacek

I am trying to understand how it works in the context of twisted.web and Resources, but I always get an exception on the portal object Here is the core code: passwords = {"admin":"password"} users = {"admin":"Administrator"} realm = TestRealm(users) p = portal.Portal(TestRealm(users),(PasswordDictChecker(passwords),)) credentialFactory = BasicCredentialFactory("CorePost") resource = HTTPAuthSessionWrapper(portal, [credentialFactory]) print "Running..." factory = Site(resource) reactor.listenTCP(8084, factory) reactor.run() Error: Unhandled Error Traceback (most recent call last): File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux-x86_64.egg/twisted/protocols/basic.py", line 564, in dataReceived why = self.lineReceived(line) File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux-x86_64.egg/twisted/web/http.py", line 1551, in lineReceived self.allContentReceived() File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux-x86_64.egg/twisted/web/http.py", line 1618, in allContentReceived req.requestReceived(command, path, version) File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux-x86_64.egg/twisted/web/http.py", line 773, in requestReceived self.process() --- <exception caught here> --- File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux-x86_64.egg/twisted/web/server.py", line 131, in process resrc = self.site.getResourceFor(self) File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux-x86_64.egg/twisted/web/server.py", line 562, in getResourceFor return resource.getChildForRequest(self.resource, request) File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux-x86_64.egg/twisted/web/resource.py", line 65, in getChildForRequest resource = resource.getChildWithDefault(pathElement, request) File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux-x86_64.egg/twisted/web/_auth/wrapper.py", line 142, in getChildWithDefault return self._authorizedResource(request) File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux-x86_64.egg/twisted/web/_auth/wrapper.py", line 106, in _authorizedResource return util.DeferredResource(self._login(Anonymous())) File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux-x86_64.egg/twisted/web/_auth/wrapper.py", line 152, in _login d = self._portal.login(credentials, None, IResource) *exceptions.AttributeError: 'module' object has no attribute 'login'* * * Attached the full file. Not sure I understand what I am doing right here. The app starts up fine, but throws the error on any request. Also, how do I hook up actual Resources? Do I do it do the HttpAuthSessionWrapper? It is an IResources, but complains that it does not have a putChild() on it? Should my TestRealm extend a Resource and I add my child Resource there? Sorry for all the questions, but the docs don't really cover the A-Z scenario of getting a running twisted.web app with Http auth... :-( Jacek

On 04:28 pm, jacek99@gmail.com wrote:
I am trying to understand how it works in the context of twisted.web and Resources, but I always get an exception on the portal object Here is the core code:
passwords = {"admin":"password"} users = {"admin":"Administrator"}
realm = TestRealm(users)
p = portal.Portal(TestRealm(users),(PasswordDictChecker(passwords),))
Your Portal instance is named `p`
credentialFactory = BasicCredentialFactory("CorePost") resource = HTTPAuthSessionWrapper(portal, [credentialFactory])
But you pass in the `portal` module instead. Jean-Paul
print "Running..."
factory = Site(resource) reactor.listenTCP(8084, factory) reactor.run()
Error:
Unhandled Error Traceback (most recent call last): File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux- x86_64.egg/twisted/protocols/basic.py", line 564, in dataReceived why = self.lineReceived(line) File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux- x86_64.egg/twisted/web/http.py", line 1551, in lineReceived self.allContentReceived() File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux- x86_64.egg/twisted/web/http.py", line 1618, in allContentReceived req.requestReceived(command, path, version) File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux- x86_64.egg/twisted/web/http.py", line 773, in requestReceived self.process() --- <exception caught here> --- File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux- x86_64.egg/twisted/web/server.py", line 131, in process resrc = self.site.getResourceFor(self) File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux- x86_64.egg/twisted/web/server.py", line 562, in getResourceFor return resource.getChildForRequest(self.resource, request) File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux- x86_64.egg/twisted/web/resource.py", line 65, in getChildForRequest resource = resource.getChildWithDefault(pathElement, request) File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux- x86_64.egg/twisted/web/_auth/wrapper.py", line 142, in getChildWithDefault return self._authorizedResource(request) File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux- x86_64.egg/twisted/web/_auth/wrapper.py", line 106, in _authorizedResource return util.DeferredResource(self._login(Anonymous())) File "/usr/local/lib/python2.7/dist-packages/Twisted-12.0.0-py2.7-linux- x86_64.egg/twisted/web/_auth/wrapper.py", line 152, in _login d = self._portal.login(credentials, None, IResource) *exceptions.AttributeError: 'module' object has no attribute 'login'* * * Attached the full file.
Not sure I understand what I am doing right here. The app starts up fine, but throws the error on any request. Also, how do I hook up actual Resources? Do I do it do the HttpAuthSessionWrapper? It is an IResources, but complains that it does not have a putChild() on it? Should my TestRealm extend a Resource and I add my child Resource there?
Sorry for all the questions, but the docs don't really cover the A-Z scenario of getting a running twisted.web app with Http auth... :-(
Jacek

D'oh! That's what happens when you copy code from the web, sorry :-( So just a follow up to my other question: how do I add my child resources? Does my TestRealm need to extend Resource? Is that the recommended approach? Thank you

On 05:37 pm, jacek99@gmail.com wrote:
D'oh! That's what happens when you copy code from the web, sorry :-(
So just a follow up to my other question: how do I add my child resources? Does my TestRealm need to extend Resource? Is that the recommended approach?
Your TestRealm is responsible for giving out avatars, in this case IResource implementations. If you want to add child resources, they need to be added to the IResource implementation that TestRealm is going to give out. I don't remember if you gave the implementation of TestRealm anywhere in this thread already, but take this simple imaginary version: class User(Resource): def __init__(self): Resource.__init__(self) self.addChild("innocuous", InnocuousResource()) class Administrator(User): def __init__(self): User.__init__(self) self.addChild("sensitive", SensitiveResource()) class TestRealmobject): ... def requestAvatar(self, avatarId, mind, *interfaces): ... if self.isAdministrator(avatarId): avatar = Administrator() else: avatar = User() return IResource, avatar, logout Put another way, the resources given out by TestRealm are just resources. Treat them as you would treat any other resources. Jean-Paul

On Feb 23, 2012, at 12:37 PM, Jacek Furmankiewicz wrote:
D'oh! That's what happens when you copy code from the web, sorry :-(
So just a follow up to my other question: how do I add my child resources?
However you like! I'm not sure what you're asking here; TestRealm returns a resource object, to which you may add child resources in any manner you see fit. Usually this is done simply by having methods on that object (getChild) which can synthesize appropriate child resources when asked for them, but I wouldn't call that a "best practice" or anything; it's just something that makes sense a lot of the time.
Does my TestRealm need to extend Resource? Is that the recommended approach?
No. TestRealm should *return* IResource providers (when asked for them - that's what the 'interfaces' argument is for). It itself should just provide IRealm, and it definitely shouldn't inherit from anything else. -glyph

Okay, No one asked me, so I have the right to show off my ignorance :-) But it sounds to me like you should build something called "secureRealm", which which does security checks before requesting a resource from the IRealm? Jerry On February 23, 2012 at 1:33 PM Glyph Lefkowitz <glyph@twistedmatrix.com> wrote:
On Feb 23, 2012, at 12:37 PM, Jacek Furmankiewicz wrote:
D'oh! That's what happens when you copy code from the web, sorry :-(
So just a follow up to my other question: how do I add my child
resources?
However you like! I'm not sure what you're asking here; TestRealm
returns a resource object, to which you may add child resources in any manner you see fit. Usually this is done simply by having methods on that object (getChild) which can synthesize appropriate child resources when asked for them, but I wouldn't call that a "best practice" or anything; it's just something that makes sense a lot of the time.
Does my TestRealm need to extend Resource? Is that the recommended
approach?
No. TestRealm should *return* IResource providers (when asked for them -
that's what the 'interfaces' argument is for). It itself should just provide IRealm, and it definitely shouldn't inherit from anything else.
-glyph _______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web

Ah, I think I get it. So Avatar = root resource that this user can access, correct? That is quite flexible actually. It's like you can serve a totally different application (i.e. resource) to the user depending on their credentials/roles/etc. I will wrap my head around it a bit more in the coming weeks and see how I can add the functionality I want (able to add fine grained security per REST method on a resource) while working in spirit with the twisted.web.guard approach. Thanks to everyone for your help Jacek On Thu, Feb 23, 2012 at 2:09 PM, Jerry Westrick <jerry@westrick.com> wrote:
**
Okay, No one asked me, so I have the right to show off my ignorance :-)
But it sounds to me like you should build something called "secureRealm", which
which does security checks before requesting a resource from the IRealm?
Jerry
On February 23, 2012 at 1:33 PM Glyph Lefkowitz <glyph@twistedmatrix.com> wrote:
On Feb 23, 2012, at 12:37 PM, Jacek Furmankiewicz wrote:
D'oh! That's what happens when you copy code from the web, sorry :-(
So just a follow up to my other question: how do I add my child
resources?
However you like! I'm not sure what you're asking here; TestRealm
returns a resource object, to which you may add child resources in any manner you see fit. Usually this is done simply by having methods on that object (getChild) which can synthesize appropriate child resources when asked for them, but I wouldn't call that a "best practice" or anything; it's just something that makes sense a lot of the time.
Does my TestRealm need to extend Resource? Is that the recommended
approach?
No. TestRealm should *return* IResource providers (when asked for them
- that's what the 'interfaces' argument is for). It itself should just provide IRealm, and it definitely shouldn't inherit from anything else.
-glyph _______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web
_______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web

Just to throw some two-cents in: What JP described is essentially what I did when I consulted for IncrediblePear back in 2008. I built an async REST API service with Twisted (and cred powering a fairly elaborate permissions system). The customer was PBS.org. It's what underlies their TV scheduling on their main site and all the affiliate stations that make use of the main site's scheduling API. (lots of memcached... they are a HUGE site in reqs/s). Twisted is a good choice :-) Best of luck! d On Thu, Feb 23, 2012 at 4:09 PM, Jacek Furmankiewicz <jacek99@gmail.com> wrote:
Ah, I think I get it.
So Avatar = root resource that this user can access, correct?
That is quite flexible actually. It's like you can serve a totally different application (i.e. resource) to the user depending on their credentials/roles/etc.
I will wrap my head around it a bit more in the coming weeks and see how I can add the functionality I want (able to add fine grained security per REST method on a resource) while working in spirit with the twisted.web.guard approach.
Thanks to everyone for your help
Jacek
On Thu, Feb 23, 2012 at 2:09 PM, Jerry Westrick <jerry@westrick.com> wrote:
Okay, No one asked me, so I have the right to show off my ignorance :-)
But it sounds to me like you should build something called "secureRealm", which
which does security checks before requesting a resource from the IRealm?
Jerry
On February 23, 2012 at 1:33 PM Glyph Lefkowitz <glyph@twistedmatrix.com> wrote:
On Feb 23, 2012, at 12:37 PM, Jacek Furmankiewicz wrote:
D'oh! That's what happens when you copy code from the web, sorry :-(
So just a follow up to my other question: how do I add my child resources?
However you like! I'm not sure what you're asking here; TestRealm returns a resource object, to which you may add child resources in any manner you see fit. Usually this is done simply by having methods on that object (getChild) which can synthesize appropriate child resources when asked for them, but I wouldn't call that a "best practice" or anything; it's just something that makes sense a lot of the time.
Does my TestRealm need to extend Resource? Is that the recommended approach?
No. TestRealm should *return* IResource providers (when asked for them - that's what the 'interfaces' argument is for). It itself should just provide IRealm, and it definitely shouldn't inherit from anything else.
-glyph _______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web
_______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web
_______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web

On Feb 23, 2012, at 4:09 PM, Jacek Furmankiewicz wrote:
Ah, I think I get it.
Hooray!
So Avatar = root resource that this user can access, correct?
Yes, that is exactly correct! (More generally: root protocol-specific thing that a user can access, since this applies to other authenticated protocols as well, and ideally, eventually, all protocols within Twisted.)
That is quite flexible actually. It's like you can serve a totally different application (i.e. resource) to the user depending on their credentials/roles/etc.
Yup. And you can write wrappers in whatever way you see fit. The idea is that instead of inserting "self.makeSureItIsSecure()" checks in (or decorators on) every single method, users without the proper authentication can't even access the objects whose methods they want to call; there's no security error, just a 404. This means that it's much harder to make the mistake where you grant too much authority to anonymous users.
I will wrap my head around it a bit more in the coming weeks and see how I can add the functionality I want (able to add fine grained security per REST method on a resource) while working in spirit with the twisted.web.guard approach.
Great. I'm really enthusiastic to see what you come up with. Feel free to continue discussing ideas on this list as you're thinking through them - this is an area of Twisted that could stand to be talked about a lot more :).
Thanks to everyone for your help
Always happy to help someone through to the point of actual understanding! -glyph

Hi, I have an extra question going back to our original discussion on security. If I serve a Resource Avatar from a Realm, is there any built-in way to attach something to the request as it is being intercepted by the Realm? For example, for every request I would like to create a Principal object (username,first name,last name, list of privileges, etc.) and attach it to every request that has been authenticated.
From the API I see, it seems you can serve a customized Resource (and that is fine for simpler admin vs read-only authentication schemes), but in some cases you need really fine-grained APIs (where a decorator per each REST method may be the only option), so it would be good for every request to be linked with the Principal that represents the user making the request.
Thanks for any suggestions Jacek On Thu, Feb 23, 2012 at 4:53 PM, Glyph <glyph@twistedmatrix.com> wrote:
On Feb 23, 2012, at 4:09 PM, Jacek Furmankiewicz wrote:
Ah, I think I get it.
Hooray!
So Avatar = root resource that this user can access, correct?
Yes, that is exactly correct!
(More generally: root protocol-specific thing that a user can access, since this applies to other authenticated protocols as well, and ideally, eventually, all protocols within Twisted.)
That is quite flexible actually. It's like you can serve a totally different application (i.e. resource) to the user depending on their credentials/roles/etc.
Yup. And you can write wrappers in whatever way you see fit. The idea is that instead of inserting "self.makeSureItIsSecure()" checks in (or decorators on) every single method, users without the proper authentication can't even *access the objects* whose methods they want to call; there's no security error, just a 404. This means that it's much harder to make the mistake where you grant too much authority to anonymous users.
I will wrap my head around it a bit more in the coming weeks and see how I can add the functionality I want (able to add fine grained security per REST method on a resource) while working in spirit with the twisted.web.guard approach.
Great. I'm really enthusiastic to see what you come up with. Feel free to continue discussing ideas on this list as you're thinking through them - this is an area of Twisted that could stand to be talked about a lot more :).
Thanks to everyone for your help
Always happy to help someone through to the point of actual understanding!
-glyph
_______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web

On 02:58 pm, jacek99@gmail.com wrote:
Hi, I have an extra question going back to our original discussion on security.
If I serve a Resource Avatar from a Realm, is there any built-in way to attach something to the request as it is being intercepted by the Realm?
For example, for every request I would like to create a Principal object (username,first name,last name, list of privileges, etc.) and attach it to every request that has been authenticated.
From the API I see, it seems you can serve a customized Resource (and that is fine for simpler admin vs read-only authentication schemes), but in some cases you need really fine-grained APIs
It's actually fine for all cases, since it lets you do anything you want. For example, make the principal an argument to your custom Resource, save it as an attribute, and use it to make future access control decisions. Jean-Paul
(where a decorator per each REST method may be the only option), so it would be good for every request to be linked with the Principal that represents the user making the request.
Thanks for any suggestions Jacek

Hm, I would prefer to avoid that. In my case, the cost of creating a new Resource is high (since it needs to parse all the URLs it can dispatch to for all the REST services), therefore I would prefer to cache a single ReadOnlyResource vs AdminResource (as an example) and just serve one or the other. I guess that doesn't fit into the typical Twisted model that well :-( Is there some sort of "post authentication" hook that I could listen to? Jacek On Mon, Mar 5, 2012 at 10:09 AM, <exarkun@twistedmatrix.com> wrote:
On 02:58 pm, jacek99@gmail.com wrote:
Hi, I have an extra question going back to our original discussion on security.
If I serve a Resource Avatar from a Realm, is there any built-in way to attach something to the request as it is being intercepted by the Realm?
For example, for every request I would like to create a Principal object (username,first name,last name, list of privileges, etc.) and attach it to every request that has been authenticated.
From the API I see, it seems you can serve a customized Resource (and that is fine for simpler admin vs read-only authentication schemes), but in some cases you need really fine-grained APIs
It's actually fine for all cases, since it lets you do anything you want. For example, make the principal an argument to your custom Resource, save it as an attribute, and use it to make future access control decisions.
Jean-Paul
(where a decorator per each REST method may be the only option), so it would be good for every request to be linked with the Principal that represents the user making the request.
Thanks for any suggestions Jacek
_______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web

On 05/03/12 15:19, Jacek Furmankiewicz wrote:
Hm, I would prefer to avoid that.
In my case, the cost of creating a new Resource is high (since it needs to parse all the URLs it can dispatch to for all the REST services), therefore I would prefer to cache a single ReadOnlyResource vs AdminResource (as an example)
If you search the archives, you will find discussions on this. The general conclusion was: Resource objects should be lightweight and fast. If you've got expensive stuff, pre-computer / cache / share / whatever, and make your Resource objects talk to the cache.
and just serve one or the other.
So? Do that: avatars = {} class MyRealm: def requestAvatar(...): if is_admin(avatarId): if not 'admin' in avatars: avatars['admin'] = MyAdmin() return avatars['admin'], ... Of course, you'll be re-using the same avatar for all admins, and won't be able to distinguish them, or access their usernames. Alternatively you might have a lightweight resource that just does simple authorization / logging, and passes render calls through to the heavyweight resource: class MyAdmin(): def render(...): request.username = self.username return CachedHeavyAdmin.render(request, ...) class MyRealm(): def requestAvatar(...): if is_admin(avatarId): r = MyAdmin() r.username = avatarId return r

Got it. The latter approach makes sense. Thank you Jacek On Mon, Mar 5, 2012 at 12:45 PM, Phil Mayers <p.mayers@imperial.ac.uk>wrote:
On 05/03/12 15:19, Jacek Furmankiewicz wrote:
Hm, I would prefer to avoid that.
In my case, the cost of creating a new Resource is high (since it needs to parse all the URLs it can dispatch to for all the REST services), therefore I would prefer to cache a single ReadOnlyResource vs AdminResource (as an example)
If you search the archives, you will find discussions on this.
The general conclusion was: Resource objects should be lightweight and fast. If you've got expensive stuff, pre-computer / cache / share / whatever, and make your Resource objects talk to the cache.
and just serve one or the other.
So? Do that:
avatars = {}
class MyRealm: def requestAvatar(...):
if is_admin(avatarId): if not 'admin' in avatars: avatars['admin'] = MyAdmin() return avatars['admin'], ...
Of course, you'll be re-using the same avatar for all admins, and won't be able to distinguish them, or access their usernames.
Alternatively you might have a lightweight resource that just does simple authorization / logging, and passes render calls through to the heavyweight resource:
class MyAdmin(): def render(...): request.username = self.username return CachedHeavyAdmin.render(request, ...)
class MyRealm(): def requestAvatar(...): if is_admin(avatarId): r = MyAdmin() r.username = avatarId return r
_______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web
participants (7)
-
Duncan McGreggor
-
exarkun@twistedmatrix.com
-
Glyph
-
Glyph Lefkowitz
-
Jacek Furmankiewicz
-
Jerry Westrick
-
Phil Mayers