summaryrefslogtreecommitdiff
path: root/src/leap/bitmask/backend.py
diff options
context:
space:
mode:
authorIvan Alejandro <ivanalejandro0@gmail.com>2014-03-19 16:06:07 -0300
committerIvan Alejandro <ivanalejandro0@gmail.com>2014-04-15 15:00:07 -0300
commit6444c6c9c758b1f4bd291d5e4e5455b84345ec9b (patch)
tree08d2289107f0c4759e2b0ded3104bec17384441b /src/leap/bitmask/backend.py
parentc8137a8829668270d4391c7909b39c56b64f604c (diff)
Move SRPAuth to the backend.
* Move methods from SRPAuth to backend: login, logout, change_password. * Add backend section to hold temporary hack code, needed in the process of splitting frontend and backend. * Replace pyside signals with Signaler signals. * Move all the signaling and thread launching in SRPAuth inside of __impl. * Move defer handling code (callbacks/errbacks) to the backend and left only signal handling in the GUI. [Closes #5347]
Diffstat (limited to 'src/leap/bitmask/backend.py')
-rw-r--r--src/leap/bitmask/backend.py199
1 files changed, 198 insertions, 1 deletions
diff --git a/src/leap/bitmask/backend.py b/src/leap/bitmask/backend.py
index 3c9991be..d78a9a6a 100644
--- a/src/leap/bitmask/backend.py
+++ b/src/leap/bitmask/backend.py
@@ -29,6 +29,7 @@ from twisted.python import log
import zope.interface
from leap.bitmask.config.providerconfig import ProviderConfig
+from leap.bitmask.crypto.srpauth import SRPAuth
from leap.bitmask.crypto.srpregister import SRPRegister
from leap.bitmask.provider import get_provider_path
from leap.bitmask.provider.providerbootstrapper import ProviderBootstrapper
@@ -149,6 +150,7 @@ class Provider(object):
self._provider_bootstrapper = ProviderBootstrapper(signaler,
bypass_checks)
self._download_provider_defer = None
+ self._provider_config = ProviderConfig()
def setup_provider(self, provider):
"""
@@ -186,7 +188,7 @@ class Provider(object):
"""
d = None
- config = ProviderConfig()
+ config = self._provider_config
if get_provider_config(config, provider):
d = self._provider_bootstrapper.run_provider_setup_checks(
self._provider_config,
@@ -247,6 +249,113 @@ class Register(object):
logger.error("Could not load provider configuration.")
+class Authenticate(object):
+ """
+ Interfaces with setup and bootstrapping operations for a provider
+ """
+
+ zope.interface.implements(ILEAPComponent)
+
+ def __init__(self, signaler=None):
+ """
+ Constructor for the Authenticate component
+
+ :param signaler: Object in charge of handling communication
+ back to the frontend
+ :type signaler: Signaler
+ """
+ object.__init__(self)
+ self.key = "authenticate"
+ self._signaler = signaler
+ self._srp_auth = None
+
+ def login(self, domain, username, password):
+ """
+ Executes the whole authentication process for a user
+
+ :param domain: the domain where we need to authenticate.
+ :type domain: unicode
+ :param username: username for this session
+ :type username: str
+ :param password: password for this user
+ :type password: str
+
+ :returns: the defer for the operation running in a thread.
+ :rtype: twisted.internet.defer.Deferred
+ """
+ config = ProviderConfig()
+ if get_provider_config(config, domain):
+ self._srp_auth = SRPAuth(config, self._signaler)
+ self._login_defer = self._srp_auth.authenticate(username, password)
+ return self._login_defer
+ else:
+ if self._signaler is not None:
+ self._signaler.signal(self._signaler.srp_auth_error)
+ logger.error("Could not load provider configuration.")
+
+ def cancel_login(self):
+ """
+ Cancel the ongoing login defer (if any).
+ """
+ d = self._login_defer
+ if d is not None:
+ d.cancel()
+
+ def change_password(self, current_password, new_password):
+ """
+ Changes the user's password.
+
+ :param current_password: the current password of the user.
+ :type current_password: str
+ :param new_password: the new password for the user.
+ :type new_password: str
+
+ :returns: a defer to interact with.
+ :rtype: twisted.internet.defer.Deferred
+ """
+ if not self._is_logged_in():
+ if self._signaler is not None:
+ self._signaler.signal(self._signaler.SRP_NOT_LOGGED_IN_ERROR)
+ return
+
+ return self._srp_auth.change_password(current_password, new_password)
+
+ def logout(self):
+ """
+ Logs out the current session.
+ Expects a session_id to exists, might raise AssertionError
+ """
+ if not self._is_logged_in():
+ if self._signaler is not None:
+ self._signaler.signal(self._signaler.SRP_NOT_LOGGED_IN_ERROR)
+ return
+
+ self._srp_auth.logout()
+
+ def _is_logged_in(self):
+ """
+ Return whether the user is logged in or not.
+
+ :rtype: bool
+ """
+ return self._srp_auth.is_authenticated()
+
+ def get_logged_in_status(self):
+ """
+ Signals if the user is currently logged in or not.
+ """
+ if self._signaler is None:
+ return
+
+ signal = None
+ if self._is_logged_in():
+ signal = self._signaler.SRP_STATUS_LOGGED_IN
+ else:
+ signal = self._signaler.SRP_STATUS_NOT_LOGGED_IN
+
+ self._signaler.signal(signal)
+
+
class EIP(object):
"""
Interfaces with setup and launch of EIP
@@ -338,6 +447,21 @@ class Signaler(QtCore.QObject):
eip_cancelled_setup = QtCore.Signal(object)
+ # Signals for SRPAuth
+ srp_auth_ok = QtCore.Signal(object)
+ srp_auth_error = QtCore.Signal(object)
+ srp_auth_server_error = QtCore.Signal(object)
+ srp_auth_connection_error = QtCore.Signal(object)
+ srp_auth_bad_user_or_password = QtCore.Signal(object)
+ srp_logout_ok = QtCore.Signal(object)
+ srp_logout_error = QtCore.Signal(object)
+ srp_password_change_ok = QtCore.Signal(object)
+ srp_password_change_error = QtCore.Signal(object)
+ srp_password_change_badpw = QtCore.Signal(object)
+ srp_not_logged_in_error = QtCore.Signal(object)
+ srp_status_logged_in = QtCore.Signal(object)
+ srp_status_not_logged_in = QtCore.Signal(object)
+
####################
# These will exist both in the backend AND the front end.
# The frontend might choose to not "interpret" all the signals
@@ -357,6 +481,19 @@ class Signaler(QtCore.QObject):
SRP_REGISTRATION_FINISHED = "srp_registration_finished"
SRP_REGISTRATION_FAILED = "srp_registration_failed"
SRP_REGISTRATION_TAKEN = "srp_registration_taken"
+ SRP_AUTH_OK = "srp_auth_ok"
+ SRP_AUTH_ERROR = "srp_auth_error"
+ SRP_AUTH_SERVER_ERROR = "srp_auth_server_error"
+ SRP_AUTH_CONNECTION_ERROR = "srp_auth_connection_error"
+ SRP_AUTH_BAD_USER_OR_PASSWORD = "srp_auth_bad_user_or_password"
+ SRP_LOGOUT_OK = "srp_logout_ok"
+ SRP_LOGOUT_ERROR = "srp_logout_error"
+ SRP_PASSWORD_CHANGE_OK = "srp_password_change_ok"
+ SRP_PASSWORD_CHANGE_ERROR = "srp_password_change_error"
+ SRP_PASSWORD_CHANGE_BADPW = "srp_password_change_badpw"
+ SRP_NOT_LOGGED_IN_ERROR = "srp_not_logged_in_error"
+ SRP_STATUS_LOGGED_IN = "srp_status_logged_in"
+ SRP_STATUS_NOT_LOGGED_IN = "srp_status_not_logged_in"
# TODO change the name of "download_config" signal to
# something less confusing (config_ready maybe)
@@ -396,6 +533,20 @@ class Signaler(QtCore.QObject):
self.EIP_DOWNLOAD_CONFIG,
self.EIP_DOWNLOAD_CLIENT_CERTIFICATE,
self.EIP_CANCELLED_SETUP,
+
+ self.SRP_AUTH_OK,
+ self.SRP_AUTH_ERROR,
+ self.SRP_AUTH_SERVER_ERROR,
+ self.SRP_AUTH_CONNECTION_ERROR,
+ self.SRP_AUTH_BAD_USER_OR_PASSWORD,
+ self.SRP_LOGOUT_OK,
+ self.SRP_LOGOUT_ERROR,
+ self.SRP_PASSWORD_CHANGE_OK,
+ self.SRP_PASSWORD_CHANGE_ERROR,
+ self.SRP_PASSWORD_CHANGE_BADPW,
+ self.SRP_NOT_LOGGED_IN_ERROR,
+ self.SRP_STATUS_LOGGED_IN,
+ self.SRP_STATUS_NOT_LOGGED_IN,
]
for sig in signals:
@@ -455,6 +606,7 @@ class Backend(object):
# Component registration
self._register(Provider(self._signaler, bypass_checks))
self._register(Register(self._signaler))
+ self._register(Authenticate(self._signaler))
self._register(EIP(self._signaler))
# We have a looping call on a thread executing all the
@@ -579,3 +731,48 @@ class Backend(object):
def cancel_setup_eip(self):
self._call_queue.put(("eip", "cancel_setup_eip", None))
+
+ def login(self, provider, username, password):
+ self._call_queue.put(("authenticate", "login", None, provider,
+ username, password))
+
+ def logout(self):
+ self._call_queue.put(("authenticate", "logout", None))
+
+ def cancel_login(self):
+ self._call_queue.put(("authenticate", "cancel_login", None))
+
+ def change_password(self, current_password, new_password):
+ self._call_queue.put(("authenticate", "change_password", None,
+ current_password, new_password))
+
+ def get_logged_in_status(self):
+ self._call_queue.put(("authenticate", "get_logged_in_status", None))
+
+ ###########################################################################
+ # XXX HACK: this section is meant to be a place to hold methods and
+ # variables needed in the meantime while we migrate all to the backend.
+
+ def srpauth_get_username(self):
+ srp_auth = self._components["authenticate"]._srp_auth
+ if srp_auth is not None:
+ return srp_auth.get_username()
+
+ def srpauth_get_session_id(self):
+ srp_auth = self._components["authenticate"]._srp_auth
+ if srp_auth is not None:
+ return srp_auth.get_session_id()
+
+ def srpauth_get_uuid(self):
+ srp_auth = self._components["authenticate"]._srp_auth
+ if srp_auth is not None:
+ return srp_auth.get_uuid()
+
+ def srpauth_get_token(self):
+ srp_auth = self._components["authenticate"]._srp_auth
+ if srp_auth is not None:
+ return srp_auth.get_token()
+
+ def get_provider_config(self):
+ provider_config = self._components["provider"]._provider_config
+ return provider_config