# -*- coding: utf-8; -*- from unittest import TestCase from wuttjamaican import auth as mod from wuttjamaican.conf import WuttaConfig try: import sqlalchemy as sa except ImportError: pass else: class TestAuthHandler(TestCase): def setUp(self): self.config = WuttaConfig() self.app = self.config.get_app() self.handler = mod.AuthHandler(self.config) self.engine = sa.create_engine('sqlite://') self.app.model.Base.metadata.create_all(bind=self.engine) self.session = self.make_session() def tearDown(self): self.session.close() self.app.model.Base.metadata.drop_all(bind=self.engine) def make_session(self): return self.app.make_session(bind=self.engine) def test_authenticate_user(self): model = self.app.model barney = model.User(username='barney') self.handler.set_user_password(barney, 'goodpass') self.session.add(barney) self.session.commit() # login ok user = self.handler.authenticate_user(self.session, 'barney', 'goodpass') self.assertIs(user, barney) # can also pass user instead of username user = self.handler.authenticate_user(self.session, barney, 'goodpass') self.assertIs(user, barney) # bad password user = self.handler.authenticate_user(self.session, 'barney', 'BADPASS') self.assertIsNone(user) # bad username user = self.handler.authenticate_user(self.session, 'NOBODY', 'goodpass') self.assertIsNone(user) # inactive user user = self.handler.authenticate_user(self.session, 'barney', 'goodpass') self.assertIs(user, barney) barney.active = False user = self.handler.authenticate_user(self.session, 'barney', 'goodpass') self.assertIsNone(user) def test_check_user_password(self): model = self.app.model barney = model.User(username='barney') self.handler.set_user_password(barney, 'goodpass') self.session.add(barney) self.session.commit() # basics self.assertTrue(self.handler.check_user_password(barney, 'goodpass')) self.assertFalse(self.handler.check_user_password(barney, 'BADPASS')) def test_get_role(self): model = self.app.model myrole = model.Role(name="My Role") self.session.add(myrole) self.session.commit() # empty key is ignored role = self.handler.get_role(self.session, None) self.assertIsNone(role) # key may be uuid role = self.handler.get_role(self.session, myrole.uuid) self.assertIs(role, myrole) # key may be name role = self.handler.get_role(self.session, myrole.name) self.assertIs(role, myrole) # key may be represented within a setting self.config.usedb = True role = self.handler.get_role(self.session, 'mykey') self.assertIsNone(role) setting = model.Setting(name='wutta.role.mykey', value=myrole.uuid) self.session.add(setting) self.session.commit() role = self.handler.get_role(self.session, 'mykey') self.assertIs(role, myrole) def test_get_user(self): model = self.app.model myuser = model.User(username='myuser') self.session.add(myuser) self.session.commit() # empty obj is ignored user = self.handler.get_user(None) self.assertIsNone(user) # user is returned as-is user = self.handler.get_user(myuser) self.assertIs(user, myuser) # match on User.uuid user = self.handler.get_user(myuser.uuid, session=self.session) self.assertIs(user, myuser) # match on User.username user = self.handler.get_user(myuser.username, session=self.session) self.assertIs(user, myuser) # find user from person myperson = model.Person(full_name='My Name') self.session.add(myperson) user.person = myperson self.session.commit() user = self.handler.get_user(myperson) self.assertIs(user, myuser) def test_make_user(self): model = self.app.model # empty user user = self.handler.make_user() self.assertIsInstance(user, model.User) self.assertIsNone(user.username) # user is added to session user = self.handler.make_user(session=self.session) self.assertIn(user, self.session) self.session.rollback() self.assertNotIn(user, self.session) # default username # nb. this behavior requires a session user = self.handler.make_user(session=self.session) self.assertEqual(user.username, 'newuser') def test_delete_user(self): model = self.app.model # basics myuser = model.User(username='myuser') self.session.add(myuser) self.session.commit() user = self.session.query(model.User).one() self.assertIs(user, myuser) self.handler.delete_user(user) self.session.commit() self.assertEqual(self.session.query(model.User).count(), 0) def test_make_preferred_username(self): model = self.app.model # default name = self.handler.make_preferred_username(self.session) self.assertEqual(name, 'newuser') # person/first+last person = model.Person(first_name='Barney', last_name='Rubble') name = self.handler.make_preferred_username(self.session, person=person) self.assertEqual(name, 'barney.rubble') # person/first person = model.Person(first_name='Barney') name = self.handler.make_preferred_username(self.session, person=person) self.assertEqual(name, 'barney') # person/last person = model.Person(last_name='Rubble') name = self.handler.make_preferred_username(self.session, person=person) self.assertEqual(name, 'rubble') def test_make_unique_username(self): model = self.app.model # default name = self.handler.make_unique_username(self.session) self.assertEqual(name, 'newuser') user = model.User(username=name) self.session.add(user) self.session.commit() # counter invoked if name exists name = self.handler.make_unique_username(self.session) self.assertEqual(name, 'newuser01') user = model.User(username=name) self.session.add(user) self.session.commit() # starts by getting preferred name person = model.Person(first_name='Barney', last_name='Rubble') name = self.handler.make_unique_username(self.session, person=person) self.assertEqual(name, 'barney.rubble') user = model.User(username=name) self.session.add(user) self.session.commit() # counter invoked if name exists name = self.handler.make_unique_username(self.session, person=person) self.assertEqual(name, 'barney.rubble01') def test_set_user_password(self): model = self.app.model myuser = model.User(username='myuser') self.session.add(myuser) # basics self.assertIsNone(myuser.password) self.handler.set_user_password(myuser, 'goodpass') self.session.commit() self.assertIsNotNone(myuser.password) # nb. password is hashed self.assertNotEqual(myuser.password, 'goodpass') # confirm login works with new password user = self.handler.authenticate_user(self.session, 'myuser', 'goodpass') self.assertIs(user, myuser) def test_get_role_administrator(self): model = self.app.model self.assertEqual(self.session.query(model.Role).count(), 0) role = self.handler.get_role_administrator(self.session) self.assertEqual(self.session.query(model.Role).count(), 1) self.assertEqual(role.name, "Administrator") def test_get_role_anonymous(self): model = self.app.model self.assertEqual(self.session.query(model.Role).count(), 0) role = self.handler.get_role_anonymous(self.session) self.assertEqual(self.session.query(model.Role).count(), 1) self.assertEqual(role.name, "Anonymous") def test_get_role_authenticated(self): model = self.app.model self.assertEqual(self.session.query(model.Role).count(), 0) role = self.handler.get_role_authenticated(self.session) self.assertEqual(self.session.query(model.Role).count(), 1) self.assertEqual(role.name, "Authenticated") def test_user_is_admin(self): model = self.app.model # non-user is not admin self.assertFalse(self.handler.user_is_admin(None)) # new user but not yet admin user = self.handler.make_user(session=self.session) self.session.commit() self.assertFalse(self.handler.user_is_admin(user)) # but we can make them an admin admin = self.handler.get_role_administrator(self.session) user.roles.append(admin) self.session.commit() self.assertTrue(self.handler.user_is_admin(user)) def test_get_permissions(self): model = self.app.model # empty default for role role = model.Role() perms = self.handler.get_permissions(self.session, role) self.assertIsInstance(perms, set) self.assertEqual(len(perms), 0) # empty default for user user = model.User() perms = self.handler.get_permissions(self.session, user) self.assertIsInstance(perms, set) self.assertEqual(len(perms), 0) # role perms myrole = model.Role(name='My Role') self.session.add(myrole) self.handler.grant_permission(myrole, 'foo') self.session.commit() perms = self.handler.get_permissions(self.session, myrole) self.assertEqual(perms, {'foo'}) # user perms myuser = model.User(username='myuser') self.session.add(myuser) self.session.commit() perms = self.handler.get_permissions(self.session, myuser) self.assertEqual(len(perms), 0) myuser.roles.append(myrole) self.session.commit() perms = self.handler.get_permissions(self.session, myuser) self.assertEqual(perms, {'foo'}) # invalid principal perms = self.handler.get_permissions(self.session, RuntimeError) self.assertEqual(perms, set()) # missing principal perms = self.handler.get_permissions(self.session, None) self.assertEqual(perms, set()) def test_has_permission(self): model = self.app.model # false default for role role = model.Role() self.assertFalse(self.handler.has_permission(self.session, role, 'foo')) # empty default for user user = model.User() self.assertFalse(self.handler.has_permission(self.session, user, 'foo')) # role perms myrole = model.Role(name='My Role') self.session.add(myrole) self.session.commit() self.assertFalse(self.handler.has_permission(self.session, myrole, 'foo')) self.handler.grant_permission(myrole, 'foo') self.session.commit() self.assertTrue(self.handler.has_permission(self.session, myrole, 'foo')) # user perms myuser = model.User(username='myuser') self.session.add(myuser) self.session.commit() self.assertFalse(self.handler.has_permission(self.session, myuser, 'foo')) myuser.roles.append(myrole) self.session.commit() self.assertTrue(self.handler.has_permission(self.session, myuser, 'foo')) # invalid principal self.assertFalse(self.handler.has_permission(self.session, RuntimeError, 'foo')) # missing principal self.assertFalse(self.handler.has_permission(self.session, None, 'foo')) def test_grant_permission(self): model = self.app.model myrole = model.Role(name='My Role') self.session.add(myrole) self.session.commit() # no perms yet self.assertEqual(self.session.query(model.Permission).count(), 0) # grant one perm, and confirm self.handler.grant_permission(myrole, 'foo') self.session.commit() self.assertEqual(self.session.query(model.Permission).count(), 1) perm = self.session.query(model.Permission).one() self.assertIs(perm.role, myrole) self.assertEqual(perm.permission, 'foo') # grant same perm again, confirm just one exists self.handler.grant_permission(myrole, 'foo') self.session.commit() self.assertEqual(self.session.query(model.Permission).count(), 1) perm = self.session.query(model.Permission).one() self.assertIs(perm.role, myrole) self.assertEqual(perm.permission, 'foo') def test_revoke_permission(self): model = self.app.model myrole = model.Role(name='My Role') self.session.add(myrole) self.handler.grant_permission(myrole, 'foo') self.session.commit() # just the one perm self.assertEqual(self.session.query(model.Permission).count(), 1) # revoke it, then confirm self.handler.revoke_permission(myrole, 'foo') self.session.commit() self.assertEqual(self.session.query(model.Permission).count(), 0) # revoke again, confirm self.handler.revoke_permission(myrole, 'foo') self.session.commit() self.assertEqual(self.session.query(model.Permission).count(), 0)