Hi,

I have an AMP service that does cred-based auth with IBoxReceiver as the 
interface (see mantissa). On login, the user gets a different API depending if 
they're a staff member or not.

Additionally, I wrote a composing IResponderLocator. It takes a bunch of 
responder locators and calls them in sequence to see if they can provide a 
responder. The reason it exists is because I want to put behavior in their 
separate, related modules, but @Command.responder is only supposed to work at 
class definition time. Here's the implementation:

class ComposedLocator(object):
   """
   A responder locator that consists of other locators.
   """
   interface.implements(amp.IResponderLocator)

   class __metaclass__(type):
       def __new__(meta, name, bases, attrs):
           """
           Makes sure every subclass gets its own set of locator classes.
           """
           attrs["_locatorClasses"] = []
           return type.__new__(meta, name, bases, attrs)


   def __init__(self, *args, **kwargs):
       self._locators = [l(*args, **kwargs) for l in self._locatorClasses]


   def locateResponder(self, name):
       """
       Locates a responder from all the component responders.
       """
       for locator in self._locators:
           responder = locator.locateResponder(name)
           if responder is not None:
               return responder


   @classmethod
   def component(cls, locatorClass):
       """
       Registers a component locator.
       """
       cls._locatorClasses.append(locatorClass)
       return locatorClass



This has worked fine so far, but I've hit something so annoying to fix that I'm 
wondering if I'm not doing something very stupid and overlooking the obvious.

I'm trying to implement a command called "Become" that allows a staff member to 
work as if he was the user himself. The most obvious way (to me at least) to do 
that  to create the customer API (an IBoxReceiver/amp.BoxDispatcher subclass) 
for that customer (that'd normally be the Realm's job -- but since we're 
already logged in as an administrator, we don't go through Cred again), and 
hook up the current connection with that box receiver. Yay, code reuse!

Except, no. Because of the composed locator detailed above, the responding 
method has no reference to the box sender and box receiver.  It's it's own 
little standalone object, with barely any AMP-specific knowledge. Ordinarily 
elegant, now annoying.

The only reason it ever worked before is because the default AMP implementation 
basically just involves subclassing everything into one object (self is 
self.boxReceiver is self.boxSender)

I don't see an obvious way to get a reference to the boxReceiver/boxSender from 
the responder method using documented APIs. Does this just mean I have to leak 
a reference to them all the way down? Am I doing something stupid?


cheers
lvh



_______________________________________________
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

Reply via email to