Implemented shared sessions between webclient and website - logging into either will also log in the player to the other. This is addresses the first point of #613.
This commit is contained in:
parent
eebd41f46d
commit
f04c82fa17
7 changed files with 111 additions and 81 deletions
|
|
@ -53,20 +53,27 @@ class WebSocketClient(Protocol, Session):
|
|||
self.transport.validationMade = self.validationMade
|
||||
client_address = self.transport.client
|
||||
client_address = client_address[0] if client_address else None
|
||||
print ("connectionMade: webclient address", client_address, self.transport.client, self.transport.client.__dict__, self.transport.__dict__)
|
||||
|
||||
self.init_session("websocket", client_address, self.factory.sessionhandler)
|
||||
# watch for dead links
|
||||
self.transport.setTcpKeepAlive(1)
|
||||
self.sessionhandler.connect(self)
|
||||
|
||||
def validationMade(self):
|
||||
"""
|
||||
This is called from the (modified) txws websocket library when
|
||||
the ws handshake and validation has completed fully.
|
||||
|
||||
"""
|
||||
#print "validationMade:", self.transport.location.split("?", 1)[1]
|
||||
pass
|
||||
|
||||
self.csessid = self.transport.location.split("?", 1)[1]
|
||||
csession = _CLIENT_SESSIONS(session_key=self.csessid)
|
||||
uid = csession and csession.get("logged_in", False)
|
||||
if uid:
|
||||
# the client session is already logged in.
|
||||
self.uid = uid
|
||||
self.logged_in = True
|
||||
|
||||
# watch for dead links
|
||||
self.transport.setTcpKeepAlive(1)
|
||||
# actually do the connection
|
||||
self.sessionhandler.connect(self)
|
||||
|
||||
def disconnect(self, reason=None):
|
||||
"""
|
||||
|
|
@ -139,19 +146,6 @@ class WebSocketClient(Protocol, Session):
|
|||
|
||||
"""
|
||||
|
||||
if "csessid" in kwargs and self.csessid is None:
|
||||
# only allow to change csessid on the very first connect
|
||||
# - this is a safety measure to avoid a clself.transport.client.__dict__, ient to manually
|
||||
# change its csessid later.
|
||||
self.csessid = kwargs.pop("csessid")
|
||||
csession = _CLIENT_SESSIONS(session_key=self.csessid)
|
||||
uid = csession and csession.get("logged_in", False)
|
||||
if uid:
|
||||
# the browser session is already logged in.
|
||||
self.uid = uid
|
||||
self.logged_in = True
|
||||
return
|
||||
|
||||
if "websocket_close" in kwargs:
|
||||
self.disconnect()
|
||||
return
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ from evennia.utils import utils
|
|||
from evennia.utils.text2html import parse_html
|
||||
from evennia.server import session
|
||||
|
||||
_CLIENT_SESSIONS = utils.mod_import(settings.SESSION_ENGINE).SessionStore
|
||||
_RE_SCREENREADER_REGEX = re.compile(r"%s" % settings.SCREENREADER_REGEX_STRIP, re.DOTALL + re.MULTILINE)
|
||||
_SERVERNAME = settings.SERVERNAME
|
||||
_KEEPALIVE = 30 # how often to check keepalive
|
||||
|
|
@ -149,7 +150,7 @@ class WebClient(resource.Resource):
|
|||
request (Request): Incoming request.
|
||||
|
||||
"""
|
||||
csessid = request.args.get('csessid')
|
||||
csessid = request.args.get('csessid')[0]
|
||||
|
||||
remote_addr = request.getClientIP()
|
||||
host_string = "%s (%s:%s)" % (_SERVERNAME, request.getRequestHostname(), request.getHost().port)
|
||||
|
|
@ -157,7 +158,15 @@ class WebClient(resource.Resource):
|
|||
sess = WebClientSession()
|
||||
sess.client = self
|
||||
sess.init_session("ajax/comet", remote_addr, self.sessionhandler)
|
||||
|
||||
sess.csessid = csessid
|
||||
csession = _CLIENT_SESSIONS(session_key=sess.csessid)
|
||||
uid = csession and csession.get("logged_in", False)
|
||||
if uid:
|
||||
# the client session is already logged in
|
||||
sess.uid = uid
|
||||
sess.logged_in = True
|
||||
|
||||
sess.sessionhandler.connect(sess)
|
||||
|
||||
self.last_alive[csessid] = (time(), False)
|
||||
|
|
|
|||
|
|
@ -227,10 +227,10 @@ class ServerSession(Session):
|
|||
# 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.browserid)
|
||||
csession["logged_in"] = player.id
|
||||
csession.save()
|
||||
print ("serversession.login:", csession.session_key)
|
||||
csession = ClientSessionStore(session_key=self.csessid)
|
||||
if not csession.get("logged_in"):
|
||||
csession["logged_in"] = player.id
|
||||
csession.save()
|
||||
|
||||
# Update account's last login time.
|
||||
self.player.last_login = timezone.now()
|
||||
|
|
|
|||
|
|
@ -252,14 +252,24 @@ class ServerSessionHandler(SessionHandler):
|
|||
sess = _ServerSession()
|
||||
sess.sessionhandler = self
|
||||
sess.load_sync_data(portalsessiondata)
|
||||
if sess.logged_in and sess.uid:
|
||||
# this can happen in the case of auto-authenticating
|
||||
# protocols like SSH
|
||||
sess.player = _PlayerDB.objects.get_player_from_uid(sess.uid)
|
||||
sess.at_sync()
|
||||
# validate all scripts
|
||||
_ScriptDB.objects.validate()
|
||||
self[sess.sessid] = sess
|
||||
|
||||
if sess.logged_in and sess.uid:
|
||||
# Session is already logged in. This can happen in the
|
||||
# case of auto-authenticating protocols like SSH or
|
||||
# webclient's session sharing
|
||||
player = _PlayerDB.objects.get_player_from_uid(sess.uid)
|
||||
if player:
|
||||
self.login(sess, player, force=True)
|
||||
return
|
||||
else:
|
||||
sess.logged_in = False
|
||||
sess.uid = None
|
||||
|
||||
# show the first login command
|
||||
self.data_in(sess, text=[[CMD_LOGINSTART],{}])
|
||||
|
||||
def portal_session_sync(self, portalsessiondata):
|
||||
|
|
@ -355,7 +365,7 @@ class ServerSessionHandler(SessionHandler):
|
|||
self.server.amp_protocol.send_AdminServer2Portal(DUMMYSESSION,
|
||||
operation=SSHUTD)
|
||||
|
||||
def login(self, session, player, testmode=False):
|
||||
def login(self, session, player, force=False, testmode=False):
|
||||
"""
|
||||
Log in the previously unloggedin session and the player we by
|
||||
now should know is connected to it. After this point we assume
|
||||
|
|
@ -364,12 +374,14 @@ class ServerSessionHandler(SessionHandler):
|
|||
Args:
|
||||
session (Session): The Session to authenticate.
|
||||
player (Player): The Player identified as associated with this Session.
|
||||
force (bool): Login also if the session thinks it's already logged in
|
||||
(this can happen for auto-authenticating protocols)
|
||||
testmode (bool, optional): This is used by unittesting for
|
||||
faking login without any AMP being actually active.
|
||||
|
||||
"""
|
||||
|
||||
if session.logged_in:
|
||||
if session.logged_in and not force:
|
||||
# don't log in a session that is already logged in.
|
||||
return
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue