def requestAvatarId(self, credentials): if IAnonymous.providedBy(credentials): return defer.succeed(Anonymous()) uuid = credentials.username token = credentials.password # lookup key is a hash of the token to prevent timing attacks. # TODO cache the tokens already! db = self._tokens_db() token = db.get(sha512(token).hexdigest()) if token is None: return defer.fail(error.UnauthorizedLogin()) # TODO -- use cryptography constant time builtin comparison. # we compare uuid hashes to avoid possible timing attacks that # might exploit python's builtin comparison operator behaviour, # which fails immediatelly when non-matching bytes are found. couch_uuid_hash = sha512(token[self.TOKENS_USER_ID_KEY]).digest() req_uuid_hash = sha512(uuid).digest() if token[self.TOKENS_TYPE_KEY] != self.TOKENS_TYPE_DEF \ or couch_uuid_hash != req_uuid_hash: return defer.fail(error.UnauthorizedLogin()) return defer.succeed(uuid)
def requestAvatar(self, avatarId, mind, *interfaces): # Anonymous access if IAnonymous.providedBy(avatarId): return (IResource, self.anon_resource, lambda: None) # Authenticated access else: if IResource in interfaces: return (IResource, self.auth_resource, lambda: None) raise NotImplementedError()
def requestAvatarId(self, credentials): self._invariant() assert IAnonymous.providedBy(credentials) d = defer.maybeDeferred(self.app.getAuth().allowAnonymousAccess, self.app) d.addCallback(self.authCallback, credentials) d.addErrback(authenticationErrorHandler) assert isinstance(d, defer.Deferred) return d
def requestAvatarId(self, credentials): if IAnonymous.providedBy(credentials): return defer.succeed(Anonymous()) service = credentials.username token = credentials.password # TODO: Use constant time comparison if self._trusted_services_tokens[service] != token: return defer.fail(error.UnauthorizedLogin()) return defer.succeed(service)
def __init__(self, credentials, api, provider_cert): # TODO move provider_cert to api object. # On creation, it should be able to retrieve all the info it needs # (calling bootstrap). # TODO could get a "provider" object instead. # this provider can have an api attribute, # and a "autoconfig" attribute passed on initialization. # TODO get a file-descriptor for password if not in credentials # TODO merge self._request with config.Provider._http_request ? if IAnonymous.providedBy(credentials): self.username = None self.password = None elif IUsernamePassword.providedBy(credentials): self.username = credentials.username self.password = credentials.password self._provider_cert = provider_cert self._api = api self._initialize_session()
def login(self, credentials, client=None): """ Login and get perspective from remote PB server. Currently the following credentials are supported:: L{twisted.cred.credentials.IUsernamePassword} L{twisted.cred.credentials.IAnonymous} @rtype: L{Deferred} @return: A L{Deferred} which will be called back with a L{RemoteReference} for the avatar logged in to, or which will errback if login fails. """ d = self.getRootObject() if IAnonymous.providedBy(credentials): d.addCallback(self._cbLoginAnonymous, client) else: d.addCallback(self._cbSendUsername, credentials.username, credentials.password, client) return d
class SessionManager(object): """ SessionManager """ implements(IResource) isLeaf = False session_life_time = 60 sessions = set() def __init__(self, portal): """ Initialize a session wrapper """ self._portal = portal def render(self, request): """ Find the L{IResource} avatar suitable for the given request, if possible, and render it. Otherwise, perhaps render an error page requiring authorization or describing an internal server failure. """ return self._authorizedResource(request).render(request) def getChildWithDefault(self, path, request): request.postpath.insert(0, request.prepath.pop()) return self._authorizedResource(request) def check_credentials(self, request): if request.args.get('username')==None \ or request.args.get('password')==None: return False return True def get_credentials(self, request): username = request.args.get('username', [''])[0] password = request.args.get('password', [''])[0] return UsernamePassword(username, password) def _authorizedResource(self, request): """ Get the L{IResource} which the given request is authorized to receive. If the proper authorization """ sess = request.getSession() if sess.uid not in self.sessions: # New Session self.sessions.add(sess.uid) sess.notifyOnExpire(lambda: self._expired(sess)) # Session is authenticated already if sess.is_authed(): return util.DeferredResource( self._login(SessionCookie(request), sess)) # Perform an Anonymous login if not self.check_credentials(request): return util.DeferredResource(self._login(Anonymous(), sess)) # Try to authenticate the session return util.DeferredResource( self._login(self.get_credentials(request), sess)) def _expired(self, session): print "Session {0} has expired.".format(session.uid) from goliat.session.usermanager import UserManager from goliat.session.user import IUser user = IUser(session) UserManager().unregister(user) self.sessions.remove(session.uid) def _login(self, credentials, session): """ Get the L{IResource} avatar for the given credentials. """ d = self._portal.login(credentials, None, IResource) d.addCallbacks(self._login_success, self._login_fail, (credentials, session)) return d def _logout(self, request): session = request.getSession() if session.authed: session.expire() def _login_success(self, (interface, avatar, avatarId, logout), credentials, session): """ Handle login success by wrapping the resulting L{IResource} avatar so that the C{logout} callback will be invoked when rendering is complete. """ if IAnonymous.providedBy(credentials): pass else: if not session.is_authed(): session.authenticate() if type(avatarId) == int: from goliat.session.usermanager import UserManager if not UserManager().exists(avatarId): user = UserManager().get(avatarId, session) user.set_last_login() user.save() else: # TODO: Prepare orbited to send notification # Remove the previous logged session user = UserManager().get(avatarId) if user: user.get_session().expire() # Generate a new session user = UserManager().get(avatarId, session) user.set_last_login() user.save() return ResourceWrapper(avatar)