core: profile session starting and connection are now separated. Moved profile session starting/authentication to memory module

This commit is contained in:
Goffi 2015-11-14 19:18:10 +01:00
commit e0a28858a8

View file

@ -37,6 +37,7 @@ from sat.memory.persistent import PersistentDict
from sat.memory.params import Params
from sat.memory.disco import Discovery
from sat.memory.crypto import BlockCipher
from sat.memory.crypto import PasswordHasher
from sat.tools import config as tools_config
@ -316,11 +317,80 @@ class Memory(object):
## Profiles/Sessions management ##
def startProfileSession(self, profile):
def _startSession(self, password, profile_key):
profile = self.getProfileName(profile_key)
return self.startSession(password, profile)
def startSession(self, password, profile):
""""Iniatialise session for a profile
@param profile: %(doc_profile)s"""
log.info(_("[%s] Profile session started" % profile))
self._entities_cache[profile] = {}
@param password(unicode): profile session password
or empty string is no password is set
@param profile: %(doc_profile)s
"""
def createSession(dummy):
"""Called once params are loaded."""
self._entities_cache[profile] = {}
log.info(u"[{}] Profile session started".format(profile))
return False
def backendInitialised(dummy):
def doStartSession(dummy=None):
if self.isSessionStarted(profile):
log.info("Session already started!")
return True
try:
# if there is a value at this point in self._entities_cache,
# it is the loadIndividualParams Deferred, the session is starting
session_d = self._entities_cache[profile]
except KeyError:
# else we do request the params
session_d = self._entities_cache[profile] = self.loadIndividualParams(profile)
session_d.addCallback(createSession)
finally:
return session_d
auth_d = self.profileAuthenticate(password, profile)
auth_d.addCallback(doStartSession)
return auth_d
return self.host.initialised.addCallback(backendInitialised)
def _isSessionStarted(self, profile_key):
return self.isSessionStarted(self.getProfileName(profile_key))
def isSessionStarted(self, profile):
try:
# XXX: if the value in self._entities_cache is a Deferred,
# the session is starting but not started yet
return not isinstance(self._entities_cache[profile], defer.Deferred)
except KeyError:
return False
def profileAuthenticate(self, password, profile):
"""Authenticate the profile.
@param password (unicode): the SàT profile password
@param profile: %(doc_profile)s
@return (D): a deferred None in case of success, a failure otherwise.
"""
session_data = self.auth_sessions.profileGetUnique(profile)
if not password and session_data:
# XXX: this allows any frontend to connect with the empty password as soon as
# the profile has been authenticated at least once before. It is OK as long as
# submitting a form with empty passwords is restricted to local frontends.
return defer.succeed(None)
def check_result(result):
if not result:
log.warning(u'Authentication failure of profile {}'.format(profile))
raise exceptions.PasswordError(u"The provided profile password doesn't match.")
if not session_data: # avoid to create two profile sessions when password if specified
return self.newAuthSession(password, profile)
d = self.asyncGetParamA(C.PROFILE_PASS_PATH[1], C.PROFILE_PASS_PATH[0], profile_key=profile)
d.addCallback(lambda sat_cipher: PasswordHasher.verify(password, sat_cipher))
return d.addCallback(check_result)
def newAuthSession(self, key, profile):
"""Start a new session for the authenticated profile.