Mercurial > libervia-backend
diff src/core/sat_main.py @ 1591:0df9c6247474
core: profile session starting and connection are now separated. Moved profile session starting/authentication to memory module
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 14 Nov 2015 19:18:10 +0100 |
parents | 698d6755d62a |
children | d6d655238a93 |
line wrap: on
line diff
--- a/src/core/sat_main.py Sat Nov 14 19:18:10 2015 +0100 +++ b/src/core/sat_main.py Sat Nov 14 19:18:10 2015 +0100 @@ -18,7 +18,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. import sat -from sat.core.i18n import _, D_, languageSwitch +from sat.core.i18n import _, languageSwitch from twisted.application import service from twisted.internet import defer from twisted.words.protocols.jabber import jid @@ -32,7 +32,6 @@ log = getLogger(__name__) from sat.core.constants import Const as C from sat.memory.memory import Memory -from sat.memory.crypto import PasswordHasher from sat.tools import trigger from sat.tools import utils from sat.stdui import ui_contact_list, ui_profile_manager @@ -54,7 +53,7 @@ self._cb_map = {} # map from callback_id to callbacks self._menus = OrderedDict() # dynamic menus. key: callback_id, value: menu data (dictionnary) self.__private_data = {} # used for internal callbacks (key = id) FIXME: to be removed - self._initialised = defer.Deferred() + self.initialised = defer.Deferred() self.profiles = {} self.plugins = {} @@ -66,7 +65,7 @@ except exceptions.BridgeInitError: log.error(u"Bridge can't be initialised, can't start SàT core") sys.exit(1) - self.bridge.register("getReady", lambda: self._initialised) + self.bridge.register("getReady", lambda: self.initialised) self.bridge.register("getVersion", lambda: self.full_version) self.bridge.register("getFeatures", self.getFeatures) self.bridge.register("getProfileName", self.memory.getProfileName) @@ -75,7 +74,7 @@ self.bridge.register("getEntitiesData", self.memory._getEntitiesData) self.bridge.register("asyncCreateProfile", self.memory.asyncCreateProfile) self.bridge.register("asyncDeleteProfile", self.memory.asyncDeleteProfile) - self.bridge.register("asyncConnect", self.asyncConnect) + self.bridge.register("asyncConnect", self._asyncConnect) self.bridge.register("disconnect", self.disconnect) self.bridge.register("getContacts", self.getContacts) self.bridge.register("getContactsFromGroup", self.getContactsFromGroup) @@ -137,7 +136,7 @@ self._import_plugins() ui_contact_list.ContactList(self) ui_profile_manager.ProfileManager(self) - self._initialised.callback(None) + self.initialised.callback(None) log.info(_("Backend is ready")) def _import_plugins(self): @@ -244,39 +243,31 @@ defers_list.append(defer.maybeDeferred(unload)) return defers_list - def asyncConnect(self, profile_key=C.PROF_KEY_NONE, password=''): + def _asyncConnect(self, profile_key, password=''): + profile = self.memory.getProfileName(profile_key) + return self.asyncConnect(profile, password) + + def asyncConnect(self, profile, password=''): """Retrieve the individual parameters, authenticate the profile and initiate the connection to the associated XMPP server. @param password (string): the SàT profile password - @param profile_key: %(doc_profile_key)s - @return: Deferred: - - a deferred boolean if the profile authentication succeed: - - True if the XMPP connection was already established - - False if the XMPP connection has been initiated (it may still fail) - - a Failure if the profile authentication failed + @param profile: %(doc_profile)s + @return (D(bool)): + - True if the XMPP connection was already established + - False if the XMPP connection has been initiated (it may still fail) + @raise exceptions.PasswordError: Profile password is wrong """ - def backendInitialised(dummy): - profile = self.memory.getProfileName(profile_key) - if not profile: - log.error(_('Trying to connect a non-existant profile')) - raise exceptions.ProfileUnknownError(profile_key) + def connectXMPPClient(dummy=None): + if self.isConnected(profile): + log.info(_("already connected !")) + return True + d = self._connectXMPPClient(profile) + return d.addCallback(lambda dummy: False) - def connectXMPPClient(dummy=None): - if self.isConnected(profile): - log.info(_("already connected !")) - return True - self.memory.startProfileSession(profile) - d = self.memory.loadIndividualParams(profile) - d.addCallback(lambda dummy: self._connectXMPPClient(profile)) - return d.addCallback(lambda dummy: False) - - d = self._authenticateProfile(password, profile) - d.addCallback(connectXMPPClient) - return d - - self._initialised.addErrback(lambda dummy: None) # allow successive attempts - return self._initialised.addCallback(backendInitialised) + d = self.memory.startSession(password, profile) + d.addCallback(connectXMPPClient) + return d @defer.inlineCallbacks def _connectXMPPClient(self, profile): @@ -348,31 +339,6 @@ yield list_d.addCallback(logPluginResults) # FIXME: we should have a timeout here, and a way to know if a plugin freeze # TODO: mesure launch time of each plugin - def _authenticateProfile(self, password, profile): - """Authenticate the profile. - - @param password (string): the SàT profile password - @param profile: %(doc_profile)s - @return: Deferred: a deferred None in case of success, a failure otherwise. - """ - session_data = self.memory.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 %s') % profile) - raise exceptions.PasswordError(D_("The provided profile password doesn't match.")) - if not session_data: # avoid to create two profile sessions when password if specified - return self.memory.newAuthSession(password, profile) - - d = self.memory.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 disconnect(self, profile_key): """disconnect from jabber server""" if not self.isConnected(profile_key):