Auth refactor, extracted many methods into a base class for more generic auth mechanisms.
Partially addresses #1526 Includes a solution for IS_LOWER and IS_UPPER validator problems I mentioned in #1353
This commit is contained in:
+1020
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,7 @@ from .test_contribs import *
|
||||
from .test_routes import *
|
||||
from .test_router import *
|
||||
from .test_validators import *
|
||||
from .test_authapi import *
|
||||
from .test_tools import *
|
||||
from .test_utils import *
|
||||
from .test_serializers import *
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Unit tests for authapi """
|
||||
import os
|
||||
import unittest
|
||||
from gluon.globals import Request, Response, Session
|
||||
from gluon.languages import translator
|
||||
from gluon.dal import DAL, Field
|
||||
from gluon.authapi import AuthAPI
|
||||
from gluon.storage import Storage
|
||||
from gluon._compat import to_bytes, to_native, add_charset
|
||||
|
||||
DEFAULT_URI = os.getenv('DB', 'sqlite:memory')
|
||||
|
||||
|
||||
class TestAuthAPI(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.request = Request(env={})
|
||||
self.request.application = 'a'
|
||||
self.request.controller = 'c'
|
||||
self.request.function = 'f'
|
||||
self.request.folder = 'applications/admin'
|
||||
self.response = Response()
|
||||
self.session = Session()
|
||||
T = translator('', 'en')
|
||||
self.session.connect(self.request, self.response)
|
||||
from gluon.globals import current
|
||||
self.current = current
|
||||
self.current.request = self.request
|
||||
self.current.response = self.response
|
||||
self.current.session = self.session
|
||||
self.current.T = T
|
||||
self.db = DAL(DEFAULT_URI, check_reserved=['all'])
|
||||
self.auth = AuthAPI(self.db)
|
||||
self.auth.define_tables(username=True, signature=False)
|
||||
# Create a user
|
||||
self.auth.table_user().validate_and_insert(first_name='Bart',
|
||||
last_name='Simpson',
|
||||
username='bart',
|
||||
email='bart@simpson.com',
|
||||
password='bart_password',
|
||||
registration_key='',
|
||||
registration_id=''
|
||||
)
|
||||
self.db.commit()
|
||||
|
||||
def test_login(self):
|
||||
result = self.auth.login(**{'username': 'bart', 'password': 'bart_password'})
|
||||
self.assertTrue(self.auth.is_logged_in())
|
||||
self.assertTrue(result['user']['email'] == 'bart@simpson.com')
|
||||
self.auth.logout()
|
||||
self.assertFalse(self.auth.is_logged_in())
|
||||
self.auth.settings.username_case_sensitive = False
|
||||
result = self.auth.login(**{'username': 'BarT', 'password': 'bart_password'})
|
||||
self.assertTrue(self.auth.is_logged_in())
|
||||
|
||||
def test_logout(self):
|
||||
self.auth.login(**{'username': 'bart', 'password': 'bart_password'})
|
||||
self.assertTrue(self.auth.is_logged_in())
|
||||
result = self.auth.logout()
|
||||
self.assertTrue(not self.auth.is_logged_in())
|
||||
self.assertTrue(result['user'] is None)
|
||||
|
||||
def test_register(self):
|
||||
self.auth.settings.login_after_registration = True
|
||||
result = self.auth.register(**{
|
||||
'username': 'lisa',
|
||||
'first_name': 'Lisa',
|
||||
'last_name': 'Simpson',
|
||||
'email': 'lisa@simpson.com',
|
||||
'password': 'lisa_password'
|
||||
})
|
||||
self.assertTrue(result['user']['email'] == 'lisa@simpson.com')
|
||||
self.assertTrue(self.auth.is_logged_in())
|
||||
with self.assertRaises(AssertionError): # Can't register if you're logged in
|
||||
result = self.auth.register(**{
|
||||
'username': 'lisa',
|
||||
'first_name': 'Lisa',
|
||||
'last_name': 'Simpson',
|
||||
'email': 'lisa@simpson.com',
|
||||
'password': 'lisa_password'
|
||||
})
|
||||
self.auth.logout()
|
||||
self.auth.settings.login_after_registration = False
|
||||
result = self.auth.register(**{
|
||||
'username': 'barney',
|
||||
'first_name': 'Barney',
|
||||
'last_name': 'Gumble',
|
||||
'email': 'barney@simpson.com',
|
||||
'password': 'barney_password'
|
||||
})
|
||||
self.assertTrue(result['user']['email'] == 'barney@simpson.com')
|
||||
self.assertFalse(self.auth.is_logged_in())
|
||||
self.auth.settings.login_userfield = 'email'
|
||||
result = self.auth.register(**{
|
||||
'username': 'lisa',
|
||||
'first_name': 'Lisa',
|
||||
'last_name': 'Simpson',
|
||||
'email': 'lisa@simpson.com',
|
||||
'password': 'lisa_password'
|
||||
})
|
||||
self.assertTrue(result['errors']['email'] == self.auth.messages.email_taken)
|
||||
self.assertTrue(result['user'] is None)
|
||||
self.auth.settings.registration_requires_verification = True
|
||||
result = self.auth.register(**{
|
||||
'username': 'homer',
|
||||
'first_name': 'Homer',
|
||||
'last_name': 'Simpson',
|
||||
'email': 'homer@simpson.com',
|
||||
'password': 'homer_password'
|
||||
})
|
||||
self.assertTrue('key' in result['user'])
|
||||
|
||||
def test_profile(self):
|
||||
with self.assertRaises(AssertionError):
|
||||
# We are not logged in
|
||||
self.auth.profile()
|
||||
self.auth.login(**{'username': 'bart', 'password': 'bart_password'})
|
||||
self.assertTrue(self.auth.is_logged_in())
|
||||
result = self.auth.profile(email='bartolo@simpson.com')
|
||||
self.assertTrue(result['user']['email'] == 'bartolo@simpson.com')
|
||||
self.assertTrue(self.auth.table_user()[result['user']['id']].email == 'bartolo@simpson.com')
|
||||
|
||||
def test_change_password(self):
|
||||
with self.assertRaises(AssertionError):
|
||||
# We are not logged in
|
||||
self.auth.change_password()
|
||||
self.auth.login(**{'username': 'bart', 'password': 'bart_password'})
|
||||
self.assertTrue(self.auth.is_logged_in())
|
||||
self.auth.change_password(old_password='bart_password', new_password='1234', new_password2='1234')
|
||||
self.auth.logout()
|
||||
self.assertTrue(not self.auth.is_logged_in())
|
||||
self.auth.login(username='bart', password='1234')
|
||||
self.assertTrue(self.auth.is_logged_in())
|
||||
result = self.auth.change_password(old_password='bart_password', new_password='1234', new_password2='5678')
|
||||
self.assertTrue('new_password2' in result['errors'])
|
||||
result = self.auth.change_password(old_password='bart_password', new_password='1234', new_password2='1234')
|
||||
self.assertTrue('old_password' in result['errors'])
|
||||
|
||||
def test_verify_key(self):
|
||||
self.auth.settings.registration_requires_verification = True
|
||||
result = self.auth.register(**{
|
||||
'username': 'homer',
|
||||
'first_name': 'Homer',
|
||||
'last_name': 'Simpson',
|
||||
'email': 'homer@simpson.com',
|
||||
'password': 'homer_password'
|
||||
})
|
||||
self.assertTrue('key' in result['user'])
|
||||
homer_id = result['user']['id']
|
||||
homers_key = result['user']['key']
|
||||
result = self.auth.verify_key(key=None)
|
||||
self.assertTrue(result['errors'] is not None)
|
||||
result = self.auth.verify_key(key='12345')
|
||||
self.assertTrue(result['errors'] is not None)
|
||||
result = self.auth.verify_key(key=homers_key)
|
||||
self.assertTrue(result['errors'] is None)
|
||||
self.assertEqual(self.auth.table_user()[homer_id].registration_key, '')
|
||||
self.auth.settings.registration_requires_approval = True
|
||||
result = self.auth.register(**{
|
||||
'username': 'lisa',
|
||||
'first_name': 'Lisa',
|
||||
'last_name': 'Simpson',
|
||||
'email': 'lisa@simpson.com',
|
||||
'password': 'lisa_password'
|
||||
})
|
||||
lisa_id = result['user']['id']
|
||||
result = self.auth.verify_key(key=result['user']['key'])
|
||||
self.assertEqual(self.auth.table_user()[lisa_id].registration_key, 'pending')
|
||||
@@ -702,15 +702,19 @@ class TestValidators(unittest.TestCase):
|
||||
|
||||
def test_IS_LOWER(self):
|
||||
rtn = IS_LOWER()('ABC')
|
||||
self.assertEqual(rtn, ('abc', None))
|
||||
rtn = IS_LOWER()(b'ABC')
|
||||
self.assertEqual(rtn, (b'abc', None))
|
||||
rtn = IS_LOWER()('Ñ')
|
||||
self.assertEqual(rtn, (b'\xc3\xb1', None))
|
||||
self.assertEqual(rtn, ('ñ', None))
|
||||
|
||||
def test_IS_UPPER(self):
|
||||
rtn = IS_UPPER()('abc')
|
||||
self.assertEqual(rtn, ('ABC', None))
|
||||
rtn = IS_UPPER()(b'abc')
|
||||
self.assertEqual(rtn, (b'ABC', None))
|
||||
rtn = IS_UPPER()('ñ')
|
||||
self.assertEqual(rtn, (b'\xc3\x91', None))
|
||||
self.assertEqual(rtn, ('Ñ', None))
|
||||
|
||||
def test_IS_SLUG(self):
|
||||
rtn = IS_SLUG()('abc123')
|
||||
|
||||
+226
-808
File diff suppressed because it is too large
Load Diff
+14
-3
@@ -2478,9 +2478,14 @@ class IS_LOWER(Validator):
|
||||
('\\xc3\\xb1', None)
|
||||
|
||||
"""
|
||||
|
||||
def __call__(self, value):
|
||||
return (to_bytes(to_unicode(value).lower()), None)
|
||||
cast_back = lambda x: x
|
||||
if isinstance(value, str):
|
||||
cast_back = to_native
|
||||
elif isinstance(value, bytes):
|
||||
cast_back = to_bytes
|
||||
value = to_unicode(value).lower()
|
||||
return (cast_back(value), None)
|
||||
|
||||
|
||||
class IS_UPPER(Validator):
|
||||
@@ -2495,7 +2500,13 @@ class IS_UPPER(Validator):
|
||||
"""
|
||||
|
||||
def __call__(self, value):
|
||||
return (to_bytes(to_unicode(value).upper()), None)
|
||||
cast_back = lambda x: x
|
||||
if isinstance(value, str):
|
||||
cast_back = to_native
|
||||
elif isinstance(value, bytes):
|
||||
cast_back = to_bytes
|
||||
value = to_unicode(value).upper()
|
||||
return (cast_back(value), None)
|
||||
|
||||
|
||||
def urlify(s, maxlen=80, keep_underscores=False):
|
||||
|
||||
Reference in New Issue
Block a user