Getting an improved version of the shared session system vaguely in shape.

This commit is contained in:
Griatch 2016-05-31 20:17:07 +02:00
parent a31441b3ce
commit eebd41f46d
11 changed files with 143 additions and 130 deletions

View file

@ -27,7 +27,6 @@ from evennia.players.models import PlayerDB
from evennia.utils.logger import log_err from evennia.utils.logger import log_err
from evennia.utils.utils import to_str, to_unicode from evennia.utils.utils import to_str, to_unicode
# django browser sessions
BrowserSessionStore = importlib.import_module(settings.SESSION_ENGINE).SessionStore BrowserSessionStore = importlib.import_module(settings.SESSION_ENGINE).SessionStore

View file

@ -137,7 +137,7 @@ class PortalSessionHandler(SessionHandler):
sessdata = dict((key, val) for key, val in sessdata.items() if key in ("protocol_key", sessdata = dict((key, val) for key, val in sessdata.items() if key in ("protocol_key",
"address", "address",
"sessid", "sessid",
"suid", "csessid",
"conn_time", "conn_time",
"protocol_flags", "protocol_flags",
"server_data",)) "server_data",))
@ -274,20 +274,20 @@ class PortalSessionHandler(SessionHandler):
""" """
return len(self.get_sessions(include_unloggedin=include_unloggedin)) return len(self.get_sessions(include_unloggedin=include_unloggedin))
def session_from_suid(self, suid): def session_from_csessid(self, csessid):
""" """
Given a session id, retrieve the session (this is primarily Given a session id, retrieve the session (this is primarily
intended to be called by web clients) intended to be called by web clients)
Args: Args:
suid (int): Session id. csessid (int): Session id.
Returns: Returns:
session (list): The matching session, if found. session (list): The matching session, if found.
""" """
return [sess for sess in self.get_sessions(include_unloggedin=True) return [sess for sess in self.get_sessions(include_unloggedin=True)
if hasattr(sess, 'suid') and sess.suid == suid] if hasattr(sess, 'csessid') and sess.csessid == csessid]
def announce_all(self, message): def announce_all(self, message):
""" """

View file

@ -32,11 +32,12 @@ import json
from twisted.internet.protocol import Protocol from twisted.internet.protocol import Protocol
from django.conf import settings from django.conf import settings
from evennia.server.session import Session from evennia.server.session import Session
from evennia.utils.utils import to_str from evennia.utils.utils import to_str, mod_import
from evennia.utils.ansi import parse_ansi from evennia.utils.ansi import parse_ansi
from evennia.utils.text2html import parse_html from evennia.utils.text2html import parse_html
_RE_SCREENREADER_REGEX = re.compile(r"%s" % settings.SCREENREADER_REGEX_STRIP, re.DOTALL + re.MULTILINE) _RE_SCREENREADER_REGEX = re.compile(r"%s" % settings.SCREENREADER_REGEX_STRIP, re.DOTALL + re.MULTILINE)
_CLIENT_SESSIONS = mod_import(settings.SESSION_ENGINE).SessionStore
class WebSocketClient(Protocol, Session): class WebSocketClient(Protocol, Session):
@ -52,6 +53,8 @@ class WebSocketClient(Protocol, Session):
self.transport.validationMade = self.validationMade self.transport.validationMade = self.validationMade
client_address = self.transport.client client_address = self.transport.client
client_address = client_address[0] if client_address else None 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) self.init_session("websocket", client_address, self.factory.sessionhandler)
# watch for dead links # watch for dead links
self.transport.setTcpKeepAlive(1) self.transport.setTcpKeepAlive(1)
@ -123,15 +126,36 @@ class WebSocketClient(Protocol, Session):
kwargs (any): Options from protocol. kwargs (any): Options from protocol.
Notes: Notes:
The websocket client can send the At initilization, the client will send the special
"websocket_close" command to report 'csessid' command to identify its browser session hash
that the client has been closed and with the Evennia side.
that the session should be disconnected.
The websocket client will also pass 'websocket_close' command
to report that the client has been closed and that the
session should be disconnected.
Both those commands are parsed and extracted already at
this point.
""" """
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: if "websocket_close" in kwargs:
self.disconnect() self.disconnect()
return return
self.sessionhandler.data_in(self, **kwargs) self.sessionhandler.data_in(self, **kwargs)
def data_out(self, **kwargs): def data_out(self, **kwargs):

View file

@ -20,7 +20,6 @@ import json
import re import re
from time import time from time import time
from hashlib import md5
from twisted.web import server, resource from twisted.web import server, resource
from twisted.internet.task import LoopingCall from twisted.internet.task import LoopingCall
from django.utils.functional import Promise from django.utils.functional import Promise
@ -71,10 +70,10 @@ class WebClient(resource.Resource):
self.last_alive = {} self.last_alive = {}
self.keep_alive = None self.keep_alive = None
def _responseFailed(self, failure, suid, request): def _responseFailed(self, failure, csessid, request):
"callback if a request is lost/timed out" "callback if a request is lost/timed out"
try: try:
del self.requests[suid] del self.requests[csessid]
except KeyError: except KeyError:
pass pass
@ -84,62 +83,62 @@ class WebClient(resource.Resource):
""" """
now = time() now = time()
to_remove = [] to_remove = []
keep_alives = ((suid, remove) for suid, (t, remove) keep_alives = ((csessid, remove) for csessid, (t, remove)
in self.last_alive.iteritems() if now - t > _KEEPALIVE) in self.last_alive.iteritems() if now - t > _KEEPALIVE)
for suid, remove in keep_alives: for csessid, remove in keep_alives:
if remove: if remove:
# keepalive timeout. Line is dead. # keepalive timeout. Line is dead.
to_remove.append(suid) to_remove.append(csessid)
else: else:
# normal timeout - send keepalive # normal timeout - send keepalive
self.last_alive[suid] = (now, True) self.last_alive[csessid] = (now, True)
self.lineSend(suid, ["ajax_keepalive", [], {}]) self.lineSend(csessid, ["ajax_keepalive", [], {}])
# remove timed-out sessions # remove timed-out sessions
for suid in to_remove: for csessid in to_remove:
sess = self.sessionhandler.session_from_suid(suid) sess = self.sessionhandler.sessions_from_csessid(csessid)
if sess: if sess:
sess[0].disconnect() sess[0].disconnect()
self.last_alive.pop(suid, None) self.last_alive.pop(csessid, None)
if not self.last_alive: if not self.last_alive:
# no more ajax clients. Stop the keepalive # no more ajax clients. Stop the keepalive
self.keep_alive.stop() self.keep_alive.stop()
self.keep_alive = None self.keep_alive = None
def lineSend(self, suid, data): def lineSend(self, csessid, data):
""" """
This adds the data to the buffer and/or sends it to the client This adds the data to the buffer and/or sends it to the client
as soon as possible. as soon as possible.
Args: Args:
suid (int): Session id. csessid (int): Session id.
data (list): A send structure [cmdname, [args], {kwargs}]. data (list): A send structure [cmdname, [args], {kwargs}].
""" """
request = self.requests.get(suid) request = self.requests.get(csessid)
if request: if request:
# we have a request waiting. Return immediately. # we have a request waiting. Return immediately.
request.write(jsonify(data)) request.write(jsonify(data))
request.finish() request.finish()
del self.requests[suid] del self.requests[csessid]
else: else:
# no waiting request. Store data in buffer # no waiting request. Store data in buffer
dataentries = self.databuffer.get(suid, []) dataentries = self.databuffer.get(csessid, [])
dataentries.append(jsonify(data)) dataentries.append(jsonify(data))
self.databuffer[suid] = dataentries self.databuffer[csessid] = dataentries
def client_disconnect(self, suid): def client_disconnect(self, csessid):
""" """
Disconnect session with given suid. Disconnect session with given csessid.
Args: Args:
suid (int): Session id. csessid (int): Session id.
""" """
if suid in self.requests: if csessid in self.requests:
self.requests[suid].finish() self.requests[csessid].finish()
del self.requests[suid] del self.requests[csessid]
if suid in self.databuffer: if csessid in self.databuffer:
del self.databuffer[suid] del self.databuffer[csessid]
def mode_init(self, request): def mode_init(self, request):
""" """
@ -150,38 +149,32 @@ class WebClient(resource.Resource):
request (Request): Incoming request. request (Request): Incoming request.
""" """
suid = request.args.get('suid', ['0'])[0] csessid = request.args.get('csessid')
remote_addr = request.getClientIP() remote_addr = request.getClientIP()
host_string = "%s (%s:%s)" % (_SERVERNAME, request.getRequestHostname(), request.getHost().port) host_string = "%s (%s:%s)" % (_SERVERNAME, request.getRequestHostname(), request.getHost().port)
if suid == '0':
# creating a unique id hash string
suid = md5(str(time())).hexdigest()
self.databuffer[suid] = []
sess = WebClientSession() sess = WebClientSession()
sess.client = self sess.client = self
sess.init_session("ajax/comet", remote_addr, self.sessionhandler) sess.init_session("ajax/comet", remote_addr, self.sessionhandler)
sess.suid = suid sess.csessid = csessid
sess.sessionhandler.connect(sess) sess.sessionhandler.connect(sess)
self.last_alive[suid] = (time(), False) self.last_alive[csessid] = (time(), False)
if not self.keep_alive: if not self.keep_alive:
# the keepalive is not running; start it. # the keepalive is not running; start it.
self.keep_alive = LoopingCall(self._keepalive) self.keep_alive = LoopingCall(self._keepalive)
self.keep_alive.start(_KEEPALIVE, now=False) self.keep_alive.start(_KEEPALIVE, now=False)
return jsonify({'msg': host_string, 'suid': suid}) return jsonify({'msg': host_string, 'csessid': csessid})
def mode_keepalive(self, request): def mode_keepalive(self, request):
""" """
This is called by render_POST when the This is called by render_POST when the
client is replying to the keepalive. client is replying to the keepalive.
""" """
suid = request.args.get('suid', ['0'])[0] csessid = request.args.get('csessid')[0]
if suid == '0': self.last_alive[csessid] = (time(), False)
return '""'
self.last_alive[suid] = (time(), False)
return '""' return '""'
def mode_input(self, request): def mode_input(self, request):
@ -193,12 +186,10 @@ class WebClient(resource.Resource):
request (Request): Incoming request. request (Request): Incoming request.
""" """
suid = request.args.get('suid', ['0'])[0] csessid = request.args.get('csessid')[0]
if suid == '0':
return '""'
self.last_alive[suid] = (time(), False) self.last_alive[csessid] = (time(), False)
sess = self.sessionhandler.session_from_suid(suid) sess = self.sessionhandler.session_from_csessid(csessid)
if sess: if sess:
sess = sess[0] sess = sess[0]
cmdarray = json.loads(request.args.get('data')[0]) cmdarray = json.loads(request.args.get('data')[0])
@ -216,18 +207,16 @@ class WebClient(resource.Resource):
request (Request): Incoming request. request (Request): Incoming request.
""" """
suid = request.args.get('suid', ['0'])[0] csessid = request.args.get('csessid')[0]
if suid == '0': self.last_alive[csessid] = (time(), False)
return '""'
self.last_alive[suid] = (time(), False)
dataentries = self.databuffer.get(suid, []) dataentries = self.databuffer.get(csessid, [])
if dataentries: if dataentries:
return dataentries.pop(0) return dataentries.pop(0)
request.notifyFinish().addErrback(self._responseFailed, suid, request) request.notifyFinish().addErrback(self._responseFailed, csessid, request)
if suid in self.requests: if csessid in self.requests:
self.requests[suid].finish() # Clear any stale request. self.requests[csessid].finish() # Clear any stale request.
self.requests[suid] = request self.requests[csessid] = request
return server.NOT_DONE_YET return server.NOT_DONE_YET
def mode_close(self, request): def mode_close(self, request):
@ -239,15 +228,12 @@ class WebClient(resource.Resource):
request (Request): Incoming request. request (Request): Incoming request.
""" """
suid = request.args.get('suid', ['0'])[0] csessid = request.args.get('csessid')[0]
if suid == '0':
self.client_disconnect(suid)
else:
try: try:
sess = self.sessionhandler.session_from_suid(suid)[0] sess = self.sessionhandler.session_from_csessid(csessid)[0]
sess.sessionhandler.disconnect(sess) sess.sessionhandler.disconnect(sess)
except IndexError: except IndexError:
self.client_disconnect(suid) self.client_disconnect(csessid)
pass pass
return '""' return '""'
@ -306,8 +292,8 @@ class WebClientSession(session.Session):
Args: Args:
reason (str): Motivation for the disconnect. reason (str): Motivation for the disconnect.
""" """
self.client.lineSend(self.suid, ["connection_close", [reason], {}]) self.client.lineSend(self.csessid, ["connection_close", [reason], {}])
self.client.client_disconnect(self.suid) self.client.client_disconnect(self.csessid)
self.sessionhandler.disconnect(self) self.sessionhandler.disconnect(self)
def data_out(self, **kwargs): def data_out(self, **kwargs):
@ -363,7 +349,7 @@ class WebClientSession(session.Session):
args[0] = parse_html(text, strip_ansi=nomarkup) args[0] = parse_html(text, strip_ansi=nomarkup)
# send to client on required form [cmdname, args, kwargs] # send to client on required form [cmdname, args, kwargs]
self.client.lineSend(self.suid, [cmd, args, kwargs]) self.client.lineSend(self.csessid, [cmd, args, kwargs])
def send_prompt(self, *args, **kwargs): def send_prompt(self, *args, **kwargs):
kwargs["options"].update({"send_prompt": True}) kwargs["options"].update({"send_prompt": True})
@ -385,4 +371,4 @@ class WebClientSession(session.Session):
""" """
if not cmdname == "options": if not cmdname == "options":
#print "ajax.send_default", cmdname, args, kwargs #print "ajax.send_default", cmdname, args, kwargs
self.client.lineSend(self.suid, [cmdname, args, kwargs]) self.client.lineSend(self.csessid, [cmdname, args, kwargs])

View file

@ -20,7 +20,7 @@ from evennia.utils.utils import make_iter, lazy_property
from evennia.commands.cmdsethandler import CmdSetHandler from evennia.commands.cmdsethandler import CmdSetHandler
from evennia.server.session import Session from evennia.server.session import Session
BrowserSessionStore = importlib.import_module(settings.SESSION_ENGINE).SessionStore ClientSessionStore = importlib.import_module(settings.SESSION_ENGINE).SessionStore
_GA = object.__getattribute__ _GA = object.__getattribute__
_SA = object.__setattr__ _SA = object.__setattr__
@ -163,7 +163,6 @@ class ServerSession(Session):
"Initiate to avoid AttributeErrors down the line" "Initiate to avoid AttributeErrors down the line"
self.puppet = None self.puppet = None
self.player = None self.player = None
self.browserid = None
self.cmdset_storage_string = "" self.cmdset_storage_string = ""
self.cmdset = CmdSetHandler(self, True) self.cmdset = CmdSetHandler(self, True)
@ -224,12 +223,14 @@ class ServerSession(Session):
self.puppet = None self.puppet = None
self.cmdset_storage = settings.CMDSET_SESSION self.cmdset_storage = settings.CMDSET_SESSION
if self.browserid: if self.csessid:
# this is only set by a webclient inputcommand. # An existing client sessid is registered, thus a matching
bsession = BrowserSessionStore(session_key=self.browserid) # Client Session must also exist. Update it so the website
bsession["logged_in"] = player.id # this also saves the bsession # can also see we are logged in.
bsession.save() csession = ClientSessionStore(session_key=self.browserid)
print ("serversession.login:", bsession.session_key) csession["logged_in"] = player.id
csession.save()
print ("serversession.login:", csession.session_key)
# Update account's last login time. # Update account's last login time.
self.player.last_login = timezone.now() self.player.last_login = timezone.now()

View file

@ -36,7 +36,7 @@ class Session(object):
""" """
# names of attributes that should be affected by syncing. # names of attributes that should be affected by syncing.
_attrs_to_sync = ('protocol_key', 'address', 'suid', 'sessid', 'uid', _attrs_to_sync = ('protocol_key', 'address', 'suid', 'sessid', 'uid', 'csessid',
'uname', 'logged_in', 'puid', 'uname', 'logged_in', 'puid',
'conn_time', 'cmd_last', 'cmd_last_visible', 'cmd_total', 'conn_time', 'cmd_last', 'cmd_last_visible', 'cmd_total',
'protocol_flags', 'server_data', "cmdset_storage_string") 'protocol_flags', 'server_data', "cmdset_storage_string")
@ -64,6 +64,8 @@ class Session(object):
# unique id for this session # unique id for this session
self.sessid = 0 # no sessid yet self.sessid = 0 # no sessid yet
# client session id, if given by the client
self.csessid = None
# database id for the user connected to this session # database id for the user connected to this session
self.uid = None self.uid = None
# user name, for easier tracking of sessions # user name, for easier tracking of sessions

View file

@ -593,16 +593,17 @@ class ServerSessionHandler(SessionHandler):
return sessions[0] if len(sessions) == 1 else sessions return sessions[0] if len(sessions) == 1 else sessions
sessions_from_character = sessions_from_puppet sessions_from_character = sessions_from_puppet
def sessions_from_browserid(self, browserid): def sessions_from_csessid(self, csessid):
""" """
Given a browserid, return all sessions having this id. Given a cliend identification hash (for session types that offer them) return all sessions with
a matching hash.
Args Args
browserid (str): The browserid hash csessid (str): The session hash
""" """
return [session for session in self.values() return [session for session in self.values()
if session.browserid and session.browserid == browserid] if session.csessid and session.csessid == csessid]
def announce_all(self, message): def announce_all(self, message):
""" """

View file

@ -217,20 +217,21 @@ An "emitter" object must have a function
var ever_open = false; var ever_open = false;
var websocket = null; var websocket = null;
var wsurl = window.wsurl; var wsurl = window.wsurl;
var csessid = window.csessid;
var connect = function() { var connect = function() {
if (websocket && websocket.readyState != websocket.CLOSED) { if (websocket && websocket.readyState != websocket.CLOSED) {
// No-op if a connection is already open. // No-op if a connection is already open.
return; return;
} }
websocket = new WebSocket(wsurl); websocket = new WebSocket(wsurl + '?' + csessid);
// Handle Websocket open event // Handle Websocket open event
websocket.onopen = function (event) { websocket.onopen = function (event) {
open = true; open = true;
ever_open = true; ever_open = true;
Evennia.emit('connection_open', ["websocket"], event); Evennia.emit('connection_open', ["websocket"], event);
Evennia.msg('browser_sessid', [browser_sessid], {}); Evennia.msg('csessid', [csessid], {});
}; };
// Handle Websocket close event // Handle Websocket close event
websocket.onclose = function (event) { websocket.onclose = function (event) {
@ -295,22 +296,22 @@ An "emitter" object must have a function
// //
var AjaxCometConnection = function() { var AjaxCometConnection = function() {
log("Trying ajax ..."); log("Trying ajax ...");
var client_hash = '0'; var open = false;
var stop_polling = false; var stop_polling = false;
var is_closing = false; var is_closing = false;
var csessid = window.csessid;
// initialize connection and get hash // initialize connection, send csessid
var init = function() { var init = function() {
$.ajax({type: "POST", url: "/webclientdata", $.ajax({type: "POST", url: "/webclientdata",
async: true, cache: false, timeout: 50000, async: true, cache: false, timeout: 50000,
datatype: "json", datatype: "json",
data: {mode: "init", suid: client_hash}, data: {mode: "init", csessid: csessid},
success: function(data) { success: function(data) {
open = true;
data = JSON.parse(data); data = JSON.parse(data);
log ("connection_open", ["AJAX/COMET"], data); log ("connection_open", ["AJAX/COMET"], data);
Evennia.msg("browser_sessid", [browser_sessid], {});
client_hash = data.suid;
stop_polling = false; stop_polling = false;
poll(); poll();
}, },
@ -331,7 +332,7 @@ An "emitter" object must have a function
async: true, cache: false, timeout: 30000, async: true, cache: false, timeout: 30000,
dataType: "json", dataType: "json",
data: {mode: inmode == null ? 'input' : inmode, data: {mode: inmode == null ? 'input' : inmode,
data: JSON.stringify(data), 'suid': client_hash}, data: JSON.stringify(data), 'csessid': csessid},
success: function(req, stat, err) { success: function(req, stat, err) {
stop_polling = false; stop_polling = false;
}, },
@ -351,7 +352,7 @@ An "emitter" object must have a function
$.ajax({type: "POST", url: "/webclientdata", $.ajax({type: "POST", url: "/webclientdata",
async: true, cache: false, timeout: 60000, async: true, cache: false, timeout: 60000,
dataType: "json", dataType: "json",
data: {mode: 'receive', 'suid': client_hash}, data: {mode: 'receive', 'csessid': csessid},
success: function(data) { success: function(data) {
// log("ajax data received:", data); // log("ajax data received:", data);
if (data[0] === "ajax_keepalive") { if (data[0] === "ajax_keepalive") {
@ -393,7 +394,7 @@ An "emitter" object must have a function
// Kill the connection and do house cleaning on the server. // Kill the connection and do house cleaning on the server.
var close = function webclient_close(){ var close = function webclient_close(){
if (is_closing || client_hash === '0') { if (is_closing || !(open)) {
// Already closed or trying to close. // Already closed or trying to close.
return; return;
} }
@ -406,11 +407,11 @@ An "emitter" object must have a function
cache: false, cache: false,
timeout: 50000, timeout: 50000,
dataType: "json", dataType: "json",
data: {mode: 'close', 'suid': client_hash}, data: {mode: 'close', 'csessid': csessid},
success: function(data){ success: function(data){
is_closing = false; is_closing = false;
client_hash = '0'; open = false;
Evennia.emit("connection_close", ["AJAX/COMET"], {}); Evennia.emit("connection_close", ["AJAX/COMET"], {});
log("AJAX/COMET connection closed cleanly.") log("AJAX/COMET connection closed cleanly.")
}, },
@ -419,13 +420,13 @@ An "emitter" object must have a function
Evennia.emit("connection_error", ["AJAX/COMET close error"], err); Evennia.emit("connection_error", ["AJAX/COMET close error"], err);
// Also emit a close event so that the COMET API mirrors the websocket API. // Also emit a close event so that the COMET API mirrors the websocket API.
Evennia.emit("connection_close", ["AJAX/COMET close unclean"], err); Evennia.emit("connection_close", ["AJAX/COMET close unclean"], err);
client_hash = '0'; open = false;
} }
}); });
}; };
var isOpen = function () { var isOpen = function () {
return !(is_closing || client_hash === '0'); return !(is_closing || !(open));
} }
// init // init

View file

@ -36,9 +36,9 @@ JQuery available.
{% endif %} {% endif %}
{% if browser_sessid %} {% if browser_sessid %}
var browser_sessid = "{{browser_sessid}}"; var csessid = "{{browser_sessid}}";
{% else %} {% else %}
var browser_sessid = false; var csessid = false;
{% endif %} {% endif %}
{% if websocket_url %} {% if websocket_url %}

View file

@ -18,27 +18,26 @@ def webclient(request):
""" """
print ("webclient session:", request.session.session_key, request.user, request.user.is_authenticated()) print ("webclient session:", request.session.session_key, request.user, request.user.is_authenticated())
browser_session = request.session csession = request.session
browserid = request.session.session_key csessid = request.session.session_key
player = request.user player = request.user
# check if user has authenticated to website # check if user has authenticated to website
if player.is_authenticated(): if player.is_authenticated():
print ("webclient: player auth, trying to connect sessions") print ("webclient: player auth, trying to connect sessions")
# Try to login all the player's webclient sessions - only # Try to login all the player's webclient sessions - only
# unloggedin ones will actually be logged in. # unloggedin ones will actually be logged in.
for session in SESSION_HANDLER.sessions_from_browserid(browserid): for session in SESSION_HANDLER.sessions_from_csessid(csessid):
print ("session to connect:", session) print ("session to connect:", session)
if session.protocol_key in ("websocket", "ajax/comet"): if session.protocol_key in ("websocket", "ajax/comet"):
SESSION_HANDLER.login(session, player) SESSION_HANDLER.login(session, player)
session.browserid = browser_session.session_key csession["logged_in"] = player.id
browser_session["logged_in"] = player.id elif csession.get("logged_in"):
elif browser_session.get("logged_in"):
# The webclient has previously registered a login to this browser_session # The webclient has previously registered a login to this browser_session
print ("webclient: browser_session logged in, trying to login") print ("webclient: browser_session logged in, trying to login")
player = PlayerDB.objects.get(browser_session.get("uid")) player = PlayerDB.objects.get(csession.get("logged_in"))
login(player, request) login(player, request)
else: else:
browser_session["logged_in"] = False csession["logged_in"] = False
# make sure to store the browser session's hash so the webclient can get to it # make sure to store the browser session's hash so the webclient can get to it
pagevars = {'browser_sessid': request.session.session_key} pagevars = {'browser_sessid': request.session.session_key}

View file

@ -26,27 +26,27 @@ def page_index(request):
# handle webclient-website shared login # handle webclient-website shared login
browser_session = request.session csession = request.session
browserid = request.session.session_key csessid = request.session.session_key
player = request.user player = request.user
# check if user has authenticated to website # check if user has authenticated to website
if player.is_authenticated(): if player.is_authenticated():
# Try to login all the player's webclient sessions - only # Try to login all the player's webclient sessions - only
# unloggedin ones will actually be logged in. # unloggedin ones will actually be logged in.
print "website: player auth, trying to connect sessions" print "website: player auth, trying to connect sessions"
for session in SESSION_HANDLER.sessions_from_browserid(browserid): for session in SESSION_HANDLER.sessions_from_csessid(csessid):
print "session to connect:", session print "session to connect:", session
if session.protocol_key in ("websocket", "ajax/comet"): if session.protocol_key in ("websocket", "ajax/comet"):
SESSION_HANDLER.login(session, player) SESSION_HANDLER.login(session, player)
session.browserid = browser_session.session_key session.csessid = csession.session_key
browser_session["logged_in"] = player.id csession["logged_in"] = player.id
elif browser_session.get("logged_in"): elif csession.get("logged_in"):
# The webclient has previously registered a login to this browser_session # The webclient has previously registered a login to this csession
print "website: browser_session logged in, trying to login" print "website: csession logged in, trying to login"
player = PlayerDB.objects.get(id=browser_session.get("logged_in")) player = PlayerDB.objects.get(id=csession.get("logged_in"))
login(request, player) login(request, player)
else: else:
browser_session["logged_in"] = None csession["logged_in"] = None
print ("website session:", request.session.session_key, request.user, request.user.is_authenticated()) print ("website session:", request.session.session_key, request.user, request.user.is_authenticated())