def __logout(self): """ Do logout """ if constants.PERSISTENT_LOGIN_NAME in self.request.cookies: token_cookie = self.request.cookies[constants.PERSISTENT_LOGIN_NAME] token = LoginToken.get_token_data(token_cookie) if token is not None: token.delete() self.response.delete_cookie(constants.PERSISTENT_LOGIN_NAME, '/') if self.user_email is not None and self.user_email != '': user = User.getUser(self.user_email.lower()) if user is not None: user.logout() self.ok('/')
def __login(self): """ Validate incoming parameters and log in user if all is ok """ # Validate email and get user from db email = self.request.get(constants.VAR_NAME_EMAIL) logging.info('User logging in: ' + str(email)) if not User.isEmailValid(email) or not User.isAlreadyRegistered(email): logging.error('Email mismatched or not registered') self.set_error(constants.STATUS_BAD_REQUEST, self.gettext('LOGIN_ERROR'), url=self.request.url) return user = User.getUser(email.lower()) # Calculate password hash password = self.request.get(constants.VAR_NAME_PASSWORD) if not User.isPasswordValid(password): logging.error('Invalid password') self.set_error(constants.STATUS_BAD_REQUEST, self.gettext('LOGIN_ERROR'), url=self.request.url) return key = CryptoUtil.getKey(password, user.salt) # Validate password if not user.password == key: logging.error('Incorrect password for email') self.set_error(constants.STATUS_BAD_REQUEST, self.gettext('LOGIN_ERROR'), url=self.request.url) return # Check remember me remember_string = self.request.get('remember').lower() remember = remember_string != '' and remember_string != 'false' if remember: token_id = LoginToken.generate_id() token = LoginToken() token.tokenid = token_id token.ip = self.request.remote_addr token.user = email token.put() cookie_value = token.get_cookie_value() delta = timedelta(days=constants.PERSISTENT_LOGIN_LIFETIME_DAYS) self.response.set_cookie(constants.PERSISTENT_LOGIN_NAME, cookie_value, expires=datetime.utcnow() + delta, path="/", httponly=True, secure=True) # Log in user if user.verified: user.login(self.request.remote_addr) session = get_current_session() url = session.pop(constants.VAR_NAME_REDIRECT) if url is None: url = "/" self.ok(url) else: logging.error('User unverified') self.set_error(constants.STATUS_FORBIDDEN, self.gettext('UNVERIFIED_PRE') + ' <a href=\"/User/Verify">' + self.gettext('UNVERIFIED_HERE') + '</a> ' + self.gettext('UNVERIFIED_POST'), url=self.request.url) return
def test(self): good_email = '*****@*****.**' bad_email = '*****@*****.**' good_id = LoginToken.generate_id() good_token = LoginToken() good_token.tokenid = good_id good_token.ip = '127.0.0.1' good_token.user = good_email good_token.put() bad_id = LoginToken.generate_id() bad_token = LoginToken() bad_token.tokenid = bad_id bad_token.ip = '192.168.10.1' bad_token.user = bad_email bad_token.put() # Test for invalid input self.assertIsNone(LoginToken.get_token_data(''), 'We should not get a valid token for empty string') self.assertIsNone(LoginToken.get_token_data('*****@*****.**'+LoginToken.SEPARATOR+'sometoken')) # Test for valid query cookie_value = good_email + LoginToken.SEPARATOR + str(good_id) queried_token = LoginToken.get_token_data(cookie_value) self.assertIsNotNone(queried_token, 'None returned for valid persistent token') self.assertEqual(good_token.user, queried_token.user, 'Valid persistent token not found.') self.assertEqual(good_token.tokenid, queried_token.tokenid, 'Valid persistent token not found.') # Test for hijacking bad_cookie_value = bad_email + LoginToken.SEPARATOR + str(bad_id) queried_token = LoginToken.get_token_data(bad_cookie_value) self.assertIsNotNone(queried_token, 'None returned for valid persistent token') self.assertEqual(bad_token.user, queried_token.user, 'Valid persistent token not found.') self.assertEqual(bad_token.tokenid, queried_token.tokenid, 'Valid persistent token not found.') bad_cookie_value = bad_email + LoginToken.SEPARATOR + str(good_id) queried_token = LoginToken.get_token_data(bad_cookie_value) self.assertIsNone(queried_token, 'Session hijacking danger') LoginToken.delete_user_tokens(bad_cookie_value) bad_cookie_value = bad_email + LoginToken.SEPARATOR + str(bad_id) queried_token = LoginToken.get_token_data(bad_cookie_value) self.assertIsNone(queried_token, 'Session hijacking danger')