# Path: wwwhisper_auth/backend.py
# class AuthenticationError(Exception):
#     pass
# 
# class VerifiedEmailBackend(ModelBackend):
#     """"Backend that authenticates the user using verified email"""
# 
#     def authenticate(self, site, site_url, token):
#         """Token was a part of a login url that proves email ownership.
# 
#         Returns:
#              Object that represents a user with the verified email
#              encoded in the token or None.
#         Raises:
#             AuthenticationError: token is invalid, expired or
#             generated for a different site.
#         """
#         verified_email = login_token.load_login_token(site, site_url, token)
#         if verified_email is None:
#             raise AuthenticationError('Token invalid or expired.')
# 
#         return site.users.find_item_by_email(verified_email)
# 
# Path: wwwhisper_auth/login_token.py
# def generate_login_token(site, site_url, email):
#     """Returns a signed token to login a user with a given email.
# 
#     The token should be emailed to the user to verify that the user
#     indeed owns the email.
# 
#     The token is valid only for the current site (it will be discarded
#     if it is submitted to a different site protected by the same
#     wwwhisper instance).
# 
#     The token allows only for one succesful login.
#     """
#     timestamp = 0
#     user = site.users.find_item_by_email(email)
#     if user is not None and user.last_login is not None:
#         # Successul login changes user.last_login, which invalidates
#         # all tokens generated for the user.
#         timestamp = _datetime_to_timestamp(user.last_login)
#     token_data = {
#         'site': site_url,
#         'email': email,
#         'timestamp': timestamp
#     }
#     return signing.dumps(token_data, salt=site_url, compress=True)
# 
# Path: wwwhisper_auth/models.py
# class SitesCollection(object):
#     def create_item(self, site_id, **kwargs):
#         """Creates a new Site object.
# 
#         Args:
#            site_id: A domain or other id of the created site.
#         Raises:
#            ValidationError if a site with a given id already exists.
#         """
#         site =  Site.objects.create(site_id=site_id, **kwargs)
#         site.heavy_init()
#         return site
# 
#     def find_item(self, site_id):
#         site = _find(Site, site_id=site_id)
#         if site is not None:
#             site.heavy_init()
#         return site
# 
#     def delete_item(self, site_id):
#         site = self.find_item(site_id)
#         if site is None:
#             return False
#         # Users, Locations and Permissions have foreign key to the Site
#         # and are deleted automatically.
#         site.delete()
#         return True


from django.test import TestCase
from wwwhisper_auth.backend import AuthenticationError, VerifiedEmailBackend
from wwwhisper_auth.login_token import generate_login_token
from wwwhisper_auth.models import SitesCollection
TEST_SITE_URL = 'https://example.com'
TEST_USER_EMAIL = 'foo@example.com'

class VerifiedEmailBackendTest(TestCase):

    def setUp(self):
        self.sites = SitesCollection()
        self.site = self.sites.create_item(TEST_SITE_URL)
        self.backend = VerifiedEmailBackend()

    def user_token(self):
        return generate_login_token(self.site, TEST_SITE_URL, TEST_USER_EMAIL)

    def test_token_valid(self):
        user = self.site.users.create_item(TEST_USER_EMAIL)
        auth_user = self.backend.authenticate(
            self.site, TEST_SITE_URL, self.user_token())
        self.assertEqual(user, auth_user)

    def test_token_invalid(self):
        user = self.site.users.create_item(TEST_USER_EMAIL)
        self.assertRaisesRegexp(AuthenticationError,
                                'Token invalid or expired',
                                self.backend.authenticate,
                                self.site,
                                TEST_SITE_URL,
                                self.user_token() + 'x')

    def test_token_for_different_site(self):
        user = self.site.users.create_item(TEST_USER_EMAIL)

# Path: wwwhisper_auth/backend.py
# class AuthenticationError(Exception):
#     pass
# 
# class VerifiedEmailBackend(ModelBackend):
#     """"Backend that authenticates the user using verified email"""
# 
#     def authenticate(self, site, site_url, token):
#         """Token was a part of a login url that proves email ownership.
# 
#         Returns:
#              Object that represents a user with the verified email
#              encoded in the token or None.
#         Raises:
#             AuthenticationError: token is invalid, expired or
#             generated for a different site.
#         """
#         verified_email = login_token.load_login_token(site, site_url, token)
#         if verified_email is None:
#             raise AuthenticationError('Token invalid or expired.')
# 
#         return site.users.find_item_by_email(verified_email)
# 
# Path: wwwhisper_auth/login_token.py
# def generate_login_token(site, site_url, email):
#     """Returns a signed token to login a user with a given email.
# 
#     The token should be emailed to the user to verify that the user
#     indeed owns the email.
# 
#     The token is valid only for the current site (it will be discarded
#     if it is submitted to a different site protected by the same
#     wwwhisper instance).
# 
#     The token allows only for one succesful login.
#     """
#     timestamp = 0
#     user = site.users.find_item_by_email(email)
#     if user is not None and user.last_login is not None:
#         # Successul login changes user.last_login, which invalidates
#         # all tokens generated for the user.
#         timestamp = _datetime_to_timestamp(user.last_login)
#     token_data = {
#         'site': site_url,
#         'email': email,
#         'timestamp': timestamp
#     }
#     return signing.dumps(token_data, salt=site_url, compress=True)
# 
# Path: wwwhisper_auth/models.py
# class SitesCollection(object):
#     def create_item(self, site_id, **kwargs):
#         """Creates a new Site object.
# 
#         Args:
#            site_id: A domain or other id of the created site.
#         Raises:
#            ValidationError if a site with a given id already exists.
#         """
#         site =  Site.objects.create(site_id=site_id, **kwargs)
#         site.heavy_init()
#         return site
# 
#     def find_item(self, site_id):
#         site = _find(Site, site_id=site_id)
#         if site is not None:
#             site.heavy_init()
#         return site
# 
#     def delete_item(self, site_id):
#         site = self.find_item(site_id)
#         if site is None:
#             return False
#         # Users, Locations and Permissions have foreign key to the Site
#         # and are deleted automatically.
#         site.delete()
#         return True


# Path: wwwhisper_auth/tests/tests_backend.py
from django.test import TestCase
from wwwhisper_auth.backend import AuthenticationError, VerifiedEmailBackend
from wwwhisper_auth.login_token import generate_login_token
from wwwhisper_auth.models import SitesCollection

TEST_SITE_URL = 'https://example.com'
TEST_USER_EMAIL = 'foo@example.com'

class VerifiedEmailBackendTest(TestCase):

    def setUp(self):
        self.sites = SitesCollection()
        self.site = self.sites.create_item(TEST_SITE_URL)
        self.backend = VerifiedEmailBackend()

    def user_token(self):
        return generate_login_token(self.site, TEST_SITE_URL, TEST_USER_EMAIL)

    def test_token_valid(self):
        user = self.site.users.create_item(TEST_USER_EMAIL)
        auth_user = self.backend.authenticate(
            self.site, TEST_SITE_URL, self.user_token())
        self.assertEqual(user, auth_user)

    def test_token_invalid(self):
        user = self.site.users.create_item(TEST_USER_EMAIL)
        self.assertRaisesRegexp(AuthenticationError,
                                'Token invalid or expired',
                                self.backend.authenticate,
                                self.site,
                                TEST_SITE_URL,
                                self.user_token() + 'x')

    def test_token_for_different_site(self):
        user = self.site.users.create_item(TEST_USER_EMAIL)

        token = generate_login_token(