class _JellyableAvatarMixin: """ Helper class for code which deals with avatars which PB must be capable of sending to a peer. """ def _cbLogin(self, (interface, avatar, logout)): """ Ensure that the avatar to be returned to the client is jellyable and set up disconnection notification to call the realm's logout object. """ if not IJellyable.providedBy(avatar): avatar = AsReferenceable(avatar, "perspective") puid = avatar.processUniqueID() # only call logout once, whether the connection is dropped (disconnect) # or a logout occurs (cleanup), and be careful to drop the reference to # it in either case logout = [logout] def maybeLogout(): if not logout: return fn = logout[0] del logout[0] fn() self.broker._localCleanup[puid] = maybeLogout self.broker.notifyOnDisconnect(maybeLogout) return avatar
class _JellyableAvatarMixin: """ Helper class for code which deals with avatars which PB must be capable of sending to a peer. """ def _cbLogin(self, (interface, avatar, logout)): """ Ensure that the avatar to be returned to the client is jellyable and set up disconnection notification to call the realm's logout object. """ if not IJellyable.providedBy(avatar): avatar = AsReferenceable(avatar, "perspective") puid = avatar.processUniqueID() def dereferenceLogout(): self.broker.dontNotifyOnDisconnect(logout) logout() self.broker._localCleanup[puid] = dereferenceLogout # No special helper function is necessary for notifyOnDisconnect # because dereference callbacks won't be invoked if the connection is # randomly dropped. I'm not sure those are ideal semantics, but this # is the only user of the (private) API at the moment and it works just # fine as things are. -exarkun self.broker.notifyOnDisconnect(logout) return avatar
def _cbLogin(self, result): """ Ensure that the avatar to be returned to the client is jellyable and set up disconnection notification to call the realm's logout object. """ (interface, avatar, logout) = result if not IJellyable.providedBy(avatar): avatar = AsReferenceable(avatar, "perspective") puid = avatar.processUniqueID() # only call logout once, whether the connection is dropped (disconnect) # or a logout occurs (cleanup), and be careful to drop the reference to # it in either case logout = [ logout ] def maybeLogout(): if not logout: return fn = logout[0] del logout[0] fn() self.broker._localCleanup[puid] = maybeLogout self.broker.notifyOnDisconnect(maybeLogout) return avatar
def _cbLogin(self, result): """ Ensure that the avatar to be returned to the client is jellyable and set up disconnection notification to call the realm's logout object. """ (interface, avatar, logout) = result if not IJellyable.providedBy(avatar): avatar = AsReferenceable(avatar, "perspective") puid = avatar.processUniqueID() # only call logout once, whether the connection is dropped (disconnect) # or a logout occurs (cleanup), and be careful to drop the reference to # it in either case logout = [logout] def maybeLogout(): if not logout: return fn = logout[0] del logout[0] fn() self.broker._localCleanup[puid] = maybeLogout self.broker.notifyOnDisconnect(maybeLogout) return avatar
class _JellyableAvatarMixin: """ Helper class for code which deals with avatars which PB must be capable of sending to a peer. """ def _cbLogin(self, (interface, avatar, logout)): """ Ensure that the avatar to be returned to the client is jellyable and set up disconnection notification to call the realm's logout object. """ if not IJellyable.providedBy(avatar): avatar = AsReferenceable(avatar, "perspective") self.broker.notifyOnDisconnect(logout) return avatar
class _PortalWrapper(Referenceable): """Root Referenceable object, used to login to portal.""" def __init__(self, portal, broker): self.portal = portal self.broker = broker # Have to return two rhings def remote_login(self, creds, mind): """Start of username/password login.""" username = creds['username'] password = creds['password'] self.mUPCred = credentials.UsernamePassword(username, password) if 'win32' == sys.platform: domain = creds['domain'] import winchecker self.mWindowsCred = winchecker.WindowsUsernamePassword( username, password, domain) d = self.portal.login(self.mWindowsCred, mind, pb.IPerspective) else: import pamchecker conv = pamchecker.makeConv({1: password, 2: username, 3: ''}) self.mPAMCred = credentials.PluggableAuthenticationModules( username, conv) d = self.portal.login(self.mPAMCred, mind, pb.IPerspective) d.addCallback(self._loggedIn, creds) #.addErrback(self.tryNext, mind) return d def tryNext(self, oldDeffered, mind): d = self.portal.login(self.mUPCred, mind, pb.IPerspective) d.addCallback(self._loggedIn) return d def _loggedIn(self, (interface, perspective, logout), creds): logging.getLogger('maestrod._PortalWrapper').info("Log-in successful.") perspective.setCredentials(creds) if not IJellyable.providedBy(perspective): perspective = pb.AsReferenceable(perspective, "perspective") self.broker.notifyOnDisconnect(logout) return perspective
class _PortalAuthChallenger(Referenceable): """Called with response to password challenge.""" implements(IUsernameHashedPassword, IUsernameMD5Password) def __init__(self, portalWrapper, username, challenge): self.portalWrapper = portalWrapper self.username = username self.challenge = challenge def remote_respond(self, response, mind): self.response = response d = self.portalWrapper.portal.login(self, mind, IPerspective) d.addCallback(self._loggedIn) return d def _loggedIn(self, (interface, perspective, logout)): if not IJellyable.providedBy(perspective): perspective = AsReferenceable(perspective, "perspective") self.portalWrapper.broker.notifyOnDisconnect(logout) return perspective
def prepareAvatar(self, avatar): self.mBroker.notifyOnDisconnect(avatar.logout) if not IJellyable.providedBy(avatar): avatar = pb.AsReferenceable(avatar, "perspective") return avatar
from twisted.python import log from twisted.spread.interfaces import IJellyable def patch(): log.msg("Applying patch for http://twistedmatrix.com/trac/ticket/5079") if not hasattr(pb, '_JellyableAvatarMixin'): log.msg("..patch not applicable; please file a bug at buildbot.net") else: pb._JellyableAvatarMixin._cbLogin = _fixed_cbLogin def _fixed_cbLogin(self, (interface, avatar, logout)): """ Ensure that the avatar to be returned to the client is jellyable and set up disconnection notification to call the realm's logout object. """ if not IJellyable.providedBy(avatar): avatar = pb.AsReferenceable(avatar, "perspective") puid = avatar.processUniqueID() # only call logout once, whether the connection is dropped (disconnect) # or a logout occurs (cleanup), and be careful to drop the reference to # it in either case logout = [ logout ] def maybeLogout(): if not logout: return fn = logout[0] del logout[0] fn() self.broker._localCleanup[puid] = maybeLogout self.broker.notifyOnDisconnect(maybeLogout)
def patch(): log.msg("Applying patch for http://twistedmatrix.com/trac/ticket/5079") if not hasattr(pb, '_JellyableAvatarMixin'): log.msg("..patch not applicable; please file a bug at buildbot.net") else: pb._JellyableAvatarMixin._cbLogin = _fixed_cbLogin def _fixed_cbLogin(self, (interface, avatar, logout)): """ Ensure that the avatar to be returned to the client is jellyable and set up disconnection notification to call the realm's logout object. """ if not IJellyable.providedBy(avatar): avatar = pb.AsReferenceable(avatar, "perspective") puid = avatar.processUniqueID() # only call logout once, whether the connection is dropped (disconnect) # or a logout occurs (cleanup), and be careful to drop the reference to # it in either case logout = [logout] def maybeLogout(): if not logout: return fn = logout[0] del logout[0] fn()