# 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/login_token.py
# def load_login_token(site, site_url, token):
#     """Verifies the login token.
# 
#     Returns email encoded in the token if the token is valid, None
#     otherwise.
#     """
#     try:
#         token_data = signing.loads(
#             token, salt=site_url, max_age=settings.AUTH_TOKEN_SECONDS_VALID)
#         # site_url in the token seems like an overkill. site_url is
#         # already used as salt which should give adequate protection
#         # against using a token for sites different than the one for
#         # which the token was generated.
#         if token_data['site'] != site_url:
#             return None
#         email = token_data['email']
#         timestamp = token_data['timestamp']
#         user = site.users.find_item_by_email(email)
#         if user is not None and user.last_login is not None:
#             if _datetime_to_timestamp(user.last_login) != timestamp:
#                 return None
#         elif timestamp != 0:
#             return None
#         return email
#     except signing.BadSignature:
#         return None
# 
# 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/models.py
# SINGLE_SITE_ID = 'theone'


from django.test import TestCase
from wwwhisper_auth.login_token import generate_login_token
from wwwhisper_auth.login_token import load_login_token
from wwwhisper_auth.models import SitesCollection
from wwwhisper_auth.models import SINGLE_SITE_ID
# wwwhisper - web access control.
# Copyright (C) 2016 Jan Wrobel <jan@mixedbit.org>


TEST_SITE = 'https://foo.example.org:8080'

class LoginToken(TestCase):

    def setUp(self):
        self.sites = SitesCollection()
        # For each test case, test site must exist, so it can be set
        # by SetSiteMiddleware
        self.site = self.sites.create_item(SINGLE_SITE_ID)
        self.site.aliases.create_item(TEST_SITE)

    def test_load_valid_token(self):
        token = generate_login_token(self.site, TEST_SITE, 'alice@example.org')
        email = load_login_token(self.site, TEST_SITE, token)
        self.assertEqual('alice@example.org', email)

    def test_load_invalid_token(self):
        token = generate_login_token(self.site, TEST_SITE, 'alice@example.org')
        self.assertIsNone(load_login_token(self.site, TEST_SITE, token + 'x'))

    def test_load_valid_token_for_different_site(self):
        token = generate_login_token(self.site, TEST_SITE, 'alice@example.org')

# 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/login_token.py
# def load_login_token(site, site_url, token):
#     """Verifies the login token.
# 
#     Returns email encoded in the token if the token is valid, None
#     otherwise.
#     """
#     try:
#         token_data = signing.loads(
#             token, salt=site_url, max_age=settings.AUTH_TOKEN_SECONDS_VALID)
#         # site_url in the token seems like an overkill. site_url is
#         # already used as salt which should give adequate protection
#         # against using a token for sites different than the one for
#         # which the token was generated.
#         if token_data['site'] != site_url:
#             return None
#         email = token_data['email']
#         timestamp = token_data['timestamp']
#         user = site.users.find_item_by_email(email)
#         if user is not None and user.last_login is not None:
#             if _datetime_to_timestamp(user.last_login) != timestamp:
#                 return None
#         elif timestamp != 0:
#             return None
#         return email
#     except signing.BadSignature:
#         return None
# 
# 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/models.py
# SINGLE_SITE_ID = 'theone'


# Path: wwwhisper_auth/tests/tests_login_token.py
from django.test import TestCase
from wwwhisper_auth.login_token import generate_login_token
from wwwhisper_auth.login_token import load_login_token
from wwwhisper_auth.models import SitesCollection
from wwwhisper_auth.models import SINGLE_SITE_ID

# wwwhisper - web access control.
# Copyright (C) 2016 Jan Wrobel <jan@mixedbit.org>


TEST_SITE = 'https://foo.example.org:8080'

class LoginToken(TestCase):

    def setUp(self):
        self.sites = SitesCollection()
        # For each test case, test site must exist, so it can be set
        # by SetSiteMiddleware
        self.site = self.sites.create_item(SINGLE_SITE_ID)
        self.site.aliases.create_item(TEST_SITE)

    def test_load_valid_token(self):
        token = generate_login_token(self.site, TEST_SITE, 'alice@example.org')
        email = load_login_token(self.site, TEST_SITE, token)
        self.assertEqual('alice@example.org', email)

    def test_load_invalid_token(self):
        token = generate_login_token(self.site, TEST_SITE, 'alice@example.org')
        self.assertIsNone(load_login_token(self.site, TEST_SITE, token + 'x'))

    def test_load_valid_token_for_different_site(self):
        token = generate_login_token(self.site, TEST_SITE, 'alice@example.org')

        self.assertIsNone(load_login_token(self.site, 'https://foo.org', token))