From cdac9678b926d300a6095470a9b1132ab5ed9b70 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 20 Aug 2017 20:36:35 +0200 Subject: [PATCH] Add smarter shared login on website/webclient. Resolves #1063. This makes it so that logging into the website will auto-log you into the webclient and vice-versa when you refresh the page. But if you log out of the web client will have to manually log in again. If you log out of the website and reload the webclient page you will have to log back into the client too (this is because logging out of the website flushes the browser session, it doesn't seem worth the effort to override django.auth in this). --- evennia/server/inputfuncs.py | 26 ------------------- evennia/server/portal/portalsessionhandler.py | 3 ++- evennia/server/portal/webclient.py | 12 ++++----- evennia/server/serversession.py | 11 -------- evennia/server/sessionhandler.py | 3 ++- evennia/web/webclient/views.py | 24 +++++++---------- evennia/web/website/views.py | 8 +----- 7 files changed, 20 insertions(+), 67 deletions(-) diff --git a/evennia/server/inputfuncs.py b/evennia/server/inputfuncs.py index 53d5a73bff..9c7098a7db 100644 --- a/evennia/server/inputfuncs.py +++ b/evennia/server/inputfuncs.py @@ -137,32 +137,6 @@ def default(session, cmdname, *args, **kwargs): log_err(err) -def browser_sessid(session, *args, **kwargs): - """ - This is a utility function for the webclient (only) to communicate its - current browser session hash. This is important in order to link - the browser session to the evennia session. Only the very first - storage request will be accepted, the following ones will be ignored. - - Args: - browserid (str): Browser session hash - - """ - if not session.browserid: - print "stored browserid:", session, args[0] - session.browserid = args[0] - if not session.logged_in: - # automatic log in if the django browser session already authenticated. - browsersession = BrowserSessionStore(session_key=args[0]) - uid = browsersession.get("logged_in", None) - if uid: - try: - account = AccountDB.objects.get(pk=uid) - except Exception: - return - session.sessionhandler.login(session, account) - - def client_options(session, *args, **kwargs): """ This allows the client an OOB way to inform us about its name and capabilities. diff --git a/evennia/server/portal/portalsessionhandler.py b/evennia/server/portal/portalsessionhandler.py index 54827931fb..7da1dd1ec1 100644 --- a/evennia/server/portal/portalsessionhandler.py +++ b/evennia/server/portal/portalsessionhandler.py @@ -268,8 +268,9 @@ class PortalSessionHandler(SessionHandler): data (dict): The session sync data. """ - session.at_login() + print("server_logged_in: %s: %s" % (session, data)) session.load_sync_data(data) + session.at_login() def server_session_sync(self, serversessions, clean=True): """ diff --git a/evennia/server/portal/webclient.py b/evennia/server/portal/webclient.py index 36eb80c6a6..7d769ec899 100644 --- a/evennia/server/portal/webclient.py +++ b/evennia/server/portal/webclient.py @@ -42,7 +42,7 @@ class WebSocketClient(Protocol, Session): client_address = client_address[0] if client_address else None self.init_session("websocket", client_address, self.factory.sessionhandler) - def get_browser_session(self): + def get_client_session(self): """ Get the Client browser session (used for auto-login based on browser session) @@ -67,9 +67,8 @@ class WebSocketClient(Protocol, Session): the ws handshake and validation has completed fully. """ - csession = self.get_browser_session() + csession = self.get_client_session() uid = csession and csession.get("webclient_authenticated_uid", None) - print("In validationMade csession uid=", uid) if uid: # the client session is already logged in. self.uid = uid @@ -95,8 +94,8 @@ class WebSocketClient(Protocol, Session): if csession: print("In disconnect: csession uid=%s" % csession.get("webclient_authenticated_uid", None)) - #csession["webclient_authenticated_uid"] = None - #csession.save() + csession["webclient_authenticated_uid"] = None + csession.save() self.logged_in = False self.connectionLost(reason) @@ -138,8 +137,7 @@ class WebSocketClient(Protocol, Session): return self.transport.write(line) def at_login(self): - csession = self.get_browser_session() - print("Weblient at_login. Session: %s" % csession.session_key) + csession = self.get_client_session() if csession: csession["webclient_authenticated_uid"] = self.uid csession.save() diff --git a/evennia/server/serversession.py b/evennia/server/serversession.py index 8d5567a5a9..e84f5cf7bd 100644 --- a/evennia/server/serversession.py +++ b/evennia/server/serversession.py @@ -20,8 +20,6 @@ from evennia.commands.cmdsethandler import CmdSetHandler from evennia.server.session import Session from evennia.scripts.monitorhandler import MONITOR_HANDLER -ClientSessionStore = importlib.import_module(settings.SESSION_ENGINE).SessionStore - _GA = object.__getattribute__ _SA = object.__setattr__ _ObjectDB = None @@ -227,15 +225,6 @@ class ServerSession(Session): self.puppet = None self.cmdset_storage = settings.CMDSET_SESSION - if self.csessid: - # An existing client sessid is registered, thus a matching - # Client Session must also exist. Update it so the website - # can also see we are logged in. - csession = ClientSessionStore(session_key=self.csessid) - if not csession.get("logged_in"): - csession["logged_in"] = account.id - csession.save() - # Update account's last login time. self.account.last_login = timezone.now() self.account.save() diff --git a/evennia/server/sessionhandler.py b/evennia/server/sessionhandler.py index 53c4671fce..33b04d1386 100644 --- a/evennia/server/sessionhandler.py +++ b/evennia/server/sessionhandler.py @@ -476,7 +476,8 @@ class ServerSessionHandler(SessionHandler): if not testmode: self.server.amp_protocol.send_AdminServer2Portal(session, operation=SLOGIN, - sessiondata={"logged_in": True}) + sessiondata={"logged_in": True, + "uid": session.uid}) account.at_post_login(session=session) def disconnect(self, session, reason="", sync_portal=True): diff --git a/evennia/web/webclient/views.py b/evennia/web/webclient/views.py index d2faf78e23..94ecffb0e2 100644 --- a/evennia/web/webclient/views.py +++ b/evennia/web/webclient/views.py @@ -26,26 +26,22 @@ def _shared_login(request): website_uid = csession.get("website_authenticated_uid", None) webclient_uid = csession.get("webclient_authenticated_uid", None) - print("webclient website_uid=%s, webclient_uid=%s, session_key=%s" % (website_uid, webclient_uid, csession.session_key)) # check if user has authenticated to website - if csession.session_key is None: + if not csession.session_key: # this is necessary to build the sessid key - print("Webclient created a new browser session key") csession.save() if webclient_uid: # The webclient has previously registered a login to this browser_session - if not account.is_authenticated(): - # not logged into website - if website_uid is None: - account = AccountDB.objects.get(id=webclient_uid) - try: - # calls our custom authenticate in web/utils/backends.py - account = authenticate(autologin=account) - login(request, account) - csession["website_authenticated_uid"] = webclient_uid - except AttributeError: - logger.log_trace() + if not account.is_authenticated() and not website_uid: + account = AccountDB.objects.get(id=webclient_uid) + try: + # calls our custom authenticate in web/utils/backends.py + account = authenticate(autologin=account) + login(request, account) + csession["website_authenticated_uid"] = webclient_uid + except AttributeError: + logger.log_trace() def webclient(request): diff --git a/evennia/web/website/views.py b/evennia/web/website/views.py index 367d7b8500..fe93b06426 100644 --- a/evennia/web/website/views.py +++ b/evennia/web/website/views.py @@ -28,17 +28,11 @@ def _shared_login(request): """ csession = request.session account = request.user - # these can have 3 values: - # None - previously unused (auto-login) - # False - actively logged out (don't auto-login) - # - logged in User/Account id website_uid = csession.get("website_authenticated_uid", None) webclient_uid = csession.get("webclient_authenticated_uid", None) - print("website website_uid=%s, webclient_uid=%s, session_key=%s" % (website_uid, webclient_uid, csession.session_key)) - if csession.session_key is None: + if not csession.session_key: # this is necessary to build the sessid key - print("Website created a new browser session key") csession.save() if account.is_authenticated():