From cf7d2c516a897e6b19e0e11fd8c104e68a0951ad Mon Sep 17 00:00:00 2001 From: Tulio Casagrande Date: Thu, 9 Feb 2017 19:43:48 -0200 Subject: [#907] Remove unused login error handler The handle_error_deferred method is supposed to return the error message before the request is finished. This is not the case during the user services setup, since the request was already finished and returned with the interstitial page. --- service/pixelated/resources/login_resource.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/service/pixelated/resources/login_resource.py b/service/pixelated/resources/login_resource.py index 4d78174f..424e051b 100644 --- a/service/pixelated/resources/login_resource.py +++ b/service/pixelated/resources/login_resource.py @@ -20,7 +20,7 @@ from xml.sax import SAXParseException from pixelated.authentication import Authenticator from pixelated.config.leap import BootstrapUserServices from pixelated.resources import BaseResource, UnAuthorizedResource, IPixelatedSession -from pixelated.resources import handle_error_deferred, get_startup_folder +from pixelated.resources import get_startup_folder from twisted.cred.error import UnauthorizedLogin from twisted.internet import defer from twisted.logger import Logger @@ -139,8 +139,6 @@ class LoginResource(BaseResource): d = self._handle_login(request) d.addCallbacks(render_response, render_error) - d.addErrback(handle_error_deferred, request) - return NOT_DONE_YET @defer.inlineCallbacks @@ -151,7 +149,7 @@ class LoginResource(BaseResource): defer.returnValue(user_auth) def _complete_bootstrap(self, user_auth, request): - def log_error(error): + def login_error(error): log.error('Login error during %s services setup: %s \n %s' % (user_auth.username, error.getErrorMessage(), error.getTraceback())) def set_session_cookies(_): @@ -162,4 +160,4 @@ class LoginResource(BaseResource): password = request.args['password'][0] d = self._bootstrap_user_services.setup(user_auth, password, language) d.addCallback(set_session_cookies) - d.addErrback(log_error) + d.addErrback(login_error) -- cgit v1.2.3 From 29034222ca16c29e9301b769802a2e49446e9075 Mon Sep 17 00:00:00 2001 From: Tulio Casagrande Date: Fri, 10 Feb 2017 14:12:04 -0200 Subject: [#907] Add login status to session --- service/pixelated/resources/login_resource.py | 14 ++++--- service/pixelated/resources/session.py | 15 ++++++++ service/test/unit/resources/test_login_resource.py | 45 +++++++++++++++++++++- 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/service/pixelated/resources/login_resource.py b/service/pixelated/resources/login_resource.py index 424e051b..ddc22b2a 100644 --- a/service/pixelated/resources/login_resource.py +++ b/service/pixelated/resources/login_resource.py @@ -149,15 +149,19 @@ class LoginResource(BaseResource): defer.returnValue(user_auth) def _complete_bootstrap(self, user_auth, request): - def login_error(error): + def login_error(error, session): log.error('Login error during %s services setup: %s \n %s' % (user_auth.username, error.getErrorMessage(), error.getTraceback())) + session.login_error() - def set_session_cookies(_): - session = IPixelatedSession(request.getSession()) + def set_session_cookies(_, session): session.user_uuid = user_auth.uuid + session.login_completed() language = parse_accept_language(request.getAllHeaders()) password = request.args['password'][0] + session = IPixelatedSession(request.getSession()) + session.login_started() + d = self._bootstrap_user_services.setup(user_auth, password, language) - d.addCallback(set_session_cookies) - d.addErrback(login_error) + d.addCallback(set_session_cookies, session) + d.addErrback(login_error, session) diff --git a/service/pixelated/resources/session.py b/service/pixelated/resources/session.py index 9ade8d29..84f2ebeb 100644 --- a/service/pixelated/resources/session.py +++ b/service/pixelated/resources/session.py @@ -21,6 +21,7 @@ from twisted.web.server import Session class IPixelatedSession(Interface): user_uuid = Attribute('The uuid of the currently logged in user') + login_status = Attribute('The status during user login') class PixelatedSession(object): @@ -28,12 +29,26 @@ class PixelatedSession(object): def __init__(self, session): self.user_uuid = None + self.login_status = None def is_logged_in(self): return self.user_uuid is not None def expire(self): self.user_uuid = None + self.login_status = None + + def login_started(self): + self.login_status = 'started' + + def login_completed(self): + self.login_status = 'completed' + + def login_error(self): + self.login_status = 'error' + + def check_login_status(self): + return self.login_status registerAdapter(PixelatedSession, Session, IPixelatedSession) diff --git a/service/test/unit/resources/test_login_resource.py b/service/test/unit/resources/test_login_resource.py index cec57123..6dea7abb 100644 --- a/service/test/unit/resources/test_login_resource.py +++ b/service/test/unit/resources/test_login_resource.py @@ -259,7 +259,7 @@ class TestLoginPOST(unittest.TestCase): @patch('pixelated.config.leap.BootstrapUserServices.setup') @patch('pixelated.authentication.Authenticator.authenticate') - def test_successful_adds_cookies_to_indicat_logged_in_status_when_services_are_loaded(self, mock_authenticate, mock_user_bootstrap_setup): + def test_successful_adds_cookies_to_indicate_logged_in_status_when_services_are_loaded(self, mock_authenticate, mock_user_bootstrap_setup): mock_authenticate.return_value = self.user_auth irrelevant = None mock_user_bootstrap_setup.return_value = defer.succeed(irrelevant) @@ -271,3 +271,46 @@ class TestLoginPOST(unittest.TestCase): d.addCallback(assert_login_setup_service_for_user) return d + + @patch('pixelated.resources.session.PixelatedSession.login_started') + @patch('pixelated.authentication.Authenticator.authenticate') + def test_session_adds_login_started_status_after_authentication(self, mock_authenticate, mock_login_started): + mock_authenticate.return_value = self.user_auth + + d = self.web.get(self.request) + + def assert_login_started_called(_): + mock_login_started.assert_called_once() + + d.addCallback(assert_login_started_called) + return d + + @patch('pixelated.resources.session.PixelatedSession.login_completed') + @patch('pixelated.config.leap.BootstrapUserServices.setup') + @patch('pixelated.authentication.Authenticator.authenticate') + def test_session_adds_login_completed_status_when_services_setup_finishes(self, mock_authenticate, mock_user_bootstrap_setup, mock_login_completed): + mock_authenticate.return_value = self.user_auth + mock_user_bootstrap_setup.return_value = defer.succeed(None) + + d = self.web.get(self.request) + + def assert_login_completed_called(_): + mock_login_completed.assert_called_once() + + d.addCallback(assert_login_completed_called) + return d + + @patch('pixelated.resources.session.PixelatedSession.login_error') + @patch('pixelated.config.leap.BootstrapUserServices.setup') + @patch('pixelated.authentication.Authenticator.authenticate') + def test_session_adds_login_error_status_when_services_setup_gets_error(self, mock_authenticate, mock_user_bootstrap_setup, mock_login_error): + mock_authenticate.return_value = self.user_auth + mock_user_bootstrap_setup.return_value = defer.fail(Exception('Could not setup user services')) + + d = self.web.get(self.request) + + def assert_login_error_called(_): + mock_login_error.assert_called_once() + + d.addCallback(assert_login_error_called) + return d -- cgit v1.2.3 From 8639b2ce3fa922cdb0871235d3791ab0fb65e810 Mon Sep 17 00:00:00 2001 From: Tulio Casagrande Date: Fri, 10 Feb 2017 15:38:03 -0200 Subject: [#907] Encapsulate user_uuid on login complete with @akanim --- service/pixelated/resources/login_resource.py | 3 +-- service/pixelated/resources/session.py | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/service/pixelated/resources/login_resource.py b/service/pixelated/resources/login_resource.py index ddc22b2a..74369605 100644 --- a/service/pixelated/resources/login_resource.py +++ b/service/pixelated/resources/login_resource.py @@ -154,8 +154,7 @@ class LoginResource(BaseResource): session.login_error() def set_session_cookies(_, session): - session.user_uuid = user_auth.uuid - session.login_completed() + session.login_completed(user_auth.uuid) language = parse_accept_language(request.getAllHeaders()) password = request.args['password'][0] diff --git a/service/pixelated/resources/session.py b/service/pixelated/resources/session.py index 84f2ebeb..5f48a090 100644 --- a/service/pixelated/resources/session.py +++ b/service/pixelated/resources/session.py @@ -41,7 +41,8 @@ class PixelatedSession(object): def login_started(self): self.login_status = 'started' - def login_completed(self): + def login_completed(self, user_uuid): + self.user_uuid = user_uuid self.login_status = 'completed' def login_error(self): -- cgit v1.2.3 From 00f35893e37ec8cec8a0cb10b41400ad7e782ed5 Mon Sep 17 00:00:00 2001 From: Tulio Casagrande Date: Fri, 10 Feb 2017 16:18:03 -0200 Subject: [#907] Change interstitial to query for new status resource with @akanim --- service/pixelated/assets/Interstitial.js | 6 +++--- service/pixelated/resources/login_resource.py | 13 +++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/service/pixelated/assets/Interstitial.js b/service/pixelated/assets/Interstitial.js index ac5a789a..cda56a4b 100644 --- a/service/pixelated/assets/Interstitial.js +++ b/service/pixelated/assets/Interstitial.js @@ -1,7 +1,7 @@ if ($('#hive').length) { var hive = new Snap('#hive'); var img_width = $('#hive').width(); - var left_pos = img_width * .5; + var left_pos = img_width * 0.5; var pixelated = hive.path("M12.4,20.3v31.8l28,15.8l28-15.8V20.3l-28-15.8L12.4,20.3z M39.2,56.4l-16.3-9V27.9l16.3,9.3L39.2,56.4z M57.7,47.4l-16.1,9l0-19.2l16.1-9.4V47.4z M57.7,25.2L40.4,35.5L22.9,25.2l17.5-9.4L57.7,25.2z").transform("translate(319, 50)").attr("fill", "#908e8e"); var all = hive.group().transform("matrix(2, 0, 0, 2, -100, -100)"); @@ -42,9 +42,9 @@ $(function () { var handler = setInterval(function () { $.ajax({ method: 'GET', - url: '/' + url: '/login/status' }).success(function (data) { - if (/Pixelated Mail/g.test(data)) { + if (data === 'completed' || data === 'error') { window.location="/"; } }); diff --git a/service/pixelated/resources/login_resource.py b/service/pixelated/resources/login_resource.py index 74369605..2a9be77b 100644 --- a/service/pixelated/resources/login_resource.py +++ b/service/pixelated/resources/login_resource.py @@ -106,6 +106,8 @@ class LoginResource(BaseResource): return self if path == 'login': return self + if path == 'status': + return LoginStatusResource(self._services_factory) if not self.is_logged_in(request): return UnAuthorizedResource() return NoResource() @@ -164,3 +166,14 @@ class LoginResource(BaseResource): d = self._bootstrap_user_services.setup(user_auth, password, language) d.addCallback(set_session_cookies, session) d.addErrback(login_error, session) + + +class LoginStatusResource(BaseResource): + isLeaf = True + + def __init__(self, services_factory): + BaseResource.__init__(self, services_factory) + + def render_GET(self, request): + session = IPixelatedSession(request.getSession()) + return format(session.check_login_status()) -- cgit v1.2.3 From 0edf2078caf98be00bcd48846acec563df630616 Mon Sep 17 00:00:00 2001 From: Tulio Casagrande Date: Mon, 13 Feb 2017 12:54:59 -0200 Subject: [#907] Rename successful login variables and methods --- service/pixelated/resources/login_resource.py | 6 +++--- service/pixelated/resources/session.py | 2 +- service/test/unit/resources/test_login_resource.py | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/service/pixelated/resources/login_resource.py b/service/pixelated/resources/login_resource.py index 2a9be77b..77ebca70 100644 --- a/service/pixelated/resources/login_resource.py +++ b/service/pixelated/resources/login_resource.py @@ -155,8 +155,8 @@ class LoginResource(BaseResource): log.error('Login error during %s services setup: %s \n %s' % (user_auth.username, error.getErrorMessage(), error.getTraceback())) session.login_error() - def set_session_cookies(_, session): - session.login_completed(user_auth.uuid) + def login_successful(_, session): + session.login_successful(user_auth.uuid) language = parse_accept_language(request.getAllHeaders()) password = request.args['password'][0] @@ -164,7 +164,7 @@ class LoginResource(BaseResource): session.login_started() d = self._bootstrap_user_services.setup(user_auth, password, language) - d.addCallback(set_session_cookies, session) + d.addCallback(login_successful, session) d.addErrback(login_error, session) diff --git a/service/pixelated/resources/session.py b/service/pixelated/resources/session.py index 5f48a090..5dfa52e6 100644 --- a/service/pixelated/resources/session.py +++ b/service/pixelated/resources/session.py @@ -41,7 +41,7 @@ class PixelatedSession(object): def login_started(self): self.login_status = 'started' - def login_completed(self, user_uuid): + def login_successful(self, user_uuid): self.user_uuid = user_uuid self.login_status = 'completed' diff --git a/service/test/unit/resources/test_login_resource.py b/service/test/unit/resources/test_login_resource.py index 6dea7abb..834b9710 100644 --- a/service/test/unit/resources/test_login_resource.py +++ b/service/test/unit/resources/test_login_resource.py @@ -285,19 +285,19 @@ class TestLoginPOST(unittest.TestCase): d.addCallback(assert_login_started_called) return d - @patch('pixelated.resources.session.PixelatedSession.login_completed') + @patch('pixelated.resources.session.PixelatedSession.login_successful') @patch('pixelated.config.leap.BootstrapUserServices.setup') @patch('pixelated.authentication.Authenticator.authenticate') - def test_session_adds_login_completed_status_when_services_setup_finishes(self, mock_authenticate, mock_user_bootstrap_setup, mock_login_completed): + def test_session_adds_login_successful_status_when_services_setup_finishes(self, mock_authenticate, mock_user_bootstrap_setup, mock_login_successful): mock_authenticate.return_value = self.user_auth mock_user_bootstrap_setup.return_value = defer.succeed(None) d = self.web.get(self.request) - def assert_login_completed_called(_): - mock_login_completed.assert_called_once() + def assert_login_successful_called(_): + mock_login_successful.assert_called_once() - d.addCallback(assert_login_completed_called) + d.addCallback(assert_login_successful_called) return d @patch('pixelated.resources.session.PixelatedSession.login_error') -- cgit v1.2.3 From 7fdf9f62c785835c4ea0863dae36bee9611221a5 Mon Sep 17 00:00:00 2001 From: Tulio Casagrande Date: Mon, 13 Feb 2017 15:23:11 -0200 Subject: [#907] Change login status to return json with @anikarni --- service/pixelated/assets/Interstitial.js | 2 +- service/pixelated/resources/login_resource.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/service/pixelated/assets/Interstitial.js b/service/pixelated/assets/Interstitial.js index cda56a4b..2eaa7a1c 100644 --- a/service/pixelated/assets/Interstitial.js +++ b/service/pixelated/assets/Interstitial.js @@ -44,7 +44,7 @@ $(function () { method: 'GET', url: '/login/status' }).success(function (data) { - if (data === 'completed' || data === 'error') { + if (data.status === 'completed' || data.status === 'error') { window.location="/"; } }); diff --git a/service/pixelated/resources/login_resource.py b/service/pixelated/resources/login_resource.py index 77ebca70..4bbceb89 100644 --- a/service/pixelated/resources/login_resource.py +++ b/service/pixelated/resources/login_resource.py @@ -20,7 +20,7 @@ from xml.sax import SAXParseException from pixelated.authentication import Authenticator from pixelated.config.leap import BootstrapUserServices from pixelated.resources import BaseResource, UnAuthorizedResource, IPixelatedSession -from pixelated.resources import get_startup_folder +from pixelated.resources import get_startup_folder, respond_json from twisted.cred.error import UnauthorizedLogin from twisted.internet import defer from twisted.logger import Logger @@ -176,4 +176,5 @@ class LoginStatusResource(BaseResource): def render_GET(self, request): session = IPixelatedSession(request.getSession()) - return format(session.check_login_status()) + response = {'status': str(session.check_login_status())} + return respond_json(response, request) -- cgit v1.2.3