class TestSQLBackend(unittest.TestCase): """ Tests for the SQL access backend """ @classmethod def setUpClass(cls): super(TestSQLBackend, cls).setUpClass() settings = { 'auth.db.url': 'sqlite:///:memory:', } SQLAccessBackend.configure(settings) def setUp(self): super(TestSQLBackend, self).setUp() self.db = SQLAccessBackend.dbmaker() self.access = SQLAccessBackend(MagicMock()) def tearDown(self): super(TestSQLBackend, self).tearDown() transaction.abort() self.db.query(User).delete() self.db.query(UserPermission).delete() self.db.query(GroupPermission).delete() self.db.query(Group).delete() self.db.execute(association_table.delete()) # pylint: disable=E1120 transaction.commit() self.access.db.close() self.db.close() def test_verify(self): """ Verify login credentials against database """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() valid = self.access.verify_user('foo', 'bar') self.assertTrue(valid) valid = self.access.verify_user('foo', 'barrrr') self.assertFalse(valid) def test_verify_pending(self): """ Pending users fail to verify """ user = make_user('foo', 'bar') self.db.add(user) transaction.commit() valid = self.access.verify_user('foo', 'bar') self.assertFalse(valid) def test_admin(self): """ Retrieve admin status from database """ user = make_user('foo', 'bar', False) user.admin = True self.db.add(user) transaction.commit() is_admin = self.access.is_admin('foo') self.assertTrue(is_admin) def test_admin_default_false(self): """ The default admin status is False """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() is_admin = self.access.is_admin('foo') self.assertFalse(is_admin) def test_user_groups(self): """ Retrieve a user's groups from database """ user = make_user('foo', 'bar', False) g1 = Group('brotatos') g2 = Group('sharkfest') user.groups.update([g1, g2]) self.db.add_all([user, g1, g2]) transaction.commit() groups = self.access.groups('foo') self.assertItemsEqual(groups, ['brotatos', 'sharkfest']) def test_groups(self): """ Retrieve all groups from database """ user = make_user('foo', 'bar', False) g1 = Group('brotatos') g2 = Group('sharkfest') user.groups.add(g1) user.groups.add(g2) self.db.add(user) transaction.commit() groups = self.access.groups() self.assertItemsEqual(groups, ['brotatos', 'sharkfest']) def test_group_members(self): """ Fetch all members of a group """ u1 = make_user('u1', 'bar', False) u2 = make_user('u2', 'bar', False) u3 = make_user('u3', 'bar', False) g1 = Group('g1') g1.users.update([u1, u2]) self.db.add_all([u1, u2, u3, g1]) transaction.commit() users = self.access.group_members('g1') self.assertItemsEqual(users, ['u1', 'u2']) def test_all_user_permissions(self): """ Retrieve all user permissions on package from database """ user = make_user('foo', 'bar', False) user2 = make_user('foo2', 'bar', False) p1 = UserPermission('pkg1', 'foo', True, False) p2 = UserPermission('pkg1', 'foo2', True, True) self.db.add_all([user, user2, p1, p2]) transaction.commit() perms = self.access.user_permissions('pkg1') self.assertEqual(perms, { 'foo': ['read'], 'foo2': ['read', 'write'], }) def test_user_permissions(self): """ Retrieve a user's permissions on package from database """ user = make_user('foo', 'bar', False) user2 = make_user('foo2', 'bar', False) p1 = UserPermission('pkg1', 'foo', True, False) p2 = UserPermission('pkg1', 'foo2', True, True) self.db.add_all([user, user2, p1, p2]) transaction.commit() perms = self.access.user_permissions('pkg1', 'foo') self.assertEqual(perms, ['read']) def test_all_group_permissions(self): """ Retrieve all group permissions from database """ g1 = Group('brotatos') g2 = Group('sharkfest') p1 = GroupPermission('pkg1', 'brotatos', True, False) p2 = GroupPermission('pkg1', 'sharkfest', True, True) self.db.add_all([g1, g2, p1, p2]) transaction.commit() perms = self.access.group_permissions('pkg1') self.assertEqual(perms, { 'brotatos': ['read'], 'sharkfest': ['read', 'write'], }) def test_group_permissions(self): """ Retrieve a group's permissions from database """ g1 = Group('brotatos') g2 = Group('sharkfest') p1 = GroupPermission('pkg1', 'brotatos', True, False) p2 = GroupPermission('pkg1', 'sharkfest', True, True) self.db.add_all([g1, g2, p1, p2]) transaction.commit() perms = self.access.group_permissions('pkg1', 'brotatos') self.assertEqual(perms, ['read']) def test_user_package_perms(self): """ Fetch all packages a user has permissions on """ user = make_user('foo', 'bar', False) p1 = UserPermission('pkg1', 'foo', True, False) p2 = UserPermission('pkg2', 'foo', True, True) self.db.add_all([user, p1, p2]) transaction.commit() perms = self.access.user_package_permissions('foo') self.assertEqual(perms, [ {'package': 'pkg1', 'permissions': ['read']}, {'package': 'pkg2', 'permissions': ['read', 'write']}, ]) def test_group_package_perms(self): """ Fetch all packages a group has permissions on """ g1 = Group('foo') p1 = GroupPermission('pkg1', 'foo', True, False) p2 = GroupPermission('pkg2', 'foo', True, True) self.db.add_all([g1, p1, p2]) transaction.commit() perms = self.access.group_package_permissions('foo') self.assertEqual(perms, [ {'package': 'pkg1', 'permissions': ['read']}, {'package': 'pkg2', 'permissions': ['read', 'write']}, ]) def test_user_data(self): """ Retrieve all users """ u1 = make_user('foo', 'bar', False) u1.admin = True u2 = make_user('bar', 'bar', False) g1 = Group('foobars') u2.groups.add(g1) self.db.add_all([u1, u2, g1]) transaction.commit() users = self.access.user_data() self.assertItemsEqual(users, [ {'username': '******', 'admin': True}, {'username': '******', 'admin': False}, ]) def test_single_user_data(self): """ Retrieve a single user's data """ u1 = make_user('foo', 'bar', False) u1.admin = True g1 = Group('foobars') u1.groups.add(g1) self.db.add_all([u1, g1]) transaction.commit() user = self.access.user_data('foo') self.assertEqual(user, { 'username': '******', 'admin': True, 'groups': ['foobars'], }) def test_no_need_admin(self): """ If admin exists, don't need an admin """ user = make_user('foo', 'bar', False) user.admin = True self.db.add(user) transaction.commit() self.assertFalse(self.access.need_admin()) def test_need_admin(self): """ If admin doesn't exist, need an admin """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() self.assertTrue(self.access.need_admin()) # Tests for mutable backend methods def test_register(self): """ Register a new user """ self.access.register('foo', 'bar') transaction.commit() user = self.db.query(User).first() self.assertEqual(user.username, 'foo') def test_pending(self): """ Registering a user puts them in pending list """ user = make_user('foo', 'bar') self.db.add(user) transaction.commit() users = self.access.pending_users() self.assertEqual(users, ['foo']) def test_pending_not_in_users(self): """ Pending users are not listed in all_users """ user = make_user('foo', 'bar') self.db.add(user) transaction.commit() users = self.access.user_data() self.assertEqual(users, []) def test_approve(self): """ Approving user marks them as not pending """ user = make_user('foo', 'bar') self.db.add(user) transaction.commit() self.access.approve_user('foo') transaction.commit() user = self.db.query(User).first() self.assertFalse(user.pending) def test_edit_password(self): """ Users can edit their passwords """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() self.access.edit_user_password('foo', 'baz') transaction.commit() user = self.db.query(User).first() self.assertTrue(self.access.verify_user('foo', 'baz')) def test_delete_user(self): """ Can delete users """ user = make_user('foo', 'bar', False) group = Group('foobar') user.groups.add(group) self.db.add_all([user, group]) transaction.commit() self.access.delete_user('foo') transaction.commit() user = self.db.query(User).first() self.assertIsNone(user) count = self.db.query(association_table).count() self.assertEqual(count, 0) def test_make_admin(self): """ Can make a user an admin """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() self.access.set_user_admin('foo', True) transaction.commit() self.db.add(user) self.assertTrue(user.admin) def test_remove_admin(self): """ Can demote an admin to normal user """ user = make_user('foo', 'bar', False) user.admin = True self.db.add(user) transaction.commit() self.access.set_user_admin('foo', False) transaction.commit() self.db.add(user) self.assertFalse(user.admin) def test_add_user_to_group(self): """ Can add a user to a group """ user = make_user('foo', 'bar', False) group = Group('g1') self.db.add_all([user, group]) transaction.commit() self.access.edit_user_group('foo', 'g1', True) transaction.commit() self.db.add(user) self.assertEqual([g.name for g in user.groups], ['g1']) def test_remove_user_from_group(self): """ Can remove a user from a group """ user = make_user('foo', 'bar', False) group = Group('g1') user.groups.add(group) self.db.add_all([user, group]) transaction.commit() self.access.edit_user_group('foo', 'g1', False) transaction.commit() self.db.add(user) self.assertEqual(len(user.groups), 0) def test_create_group(self): """ Can create a group """ self.access.create_group('g1') transaction.commit() group = self.db.query(Group).first() self.assertIsNotNone(group) self.assertEqual(group.name, 'g1') def test_delete_group(self): """ Can delete groups """ user = make_user('foo', 'bar') group = Group('foobar') user.groups.add(group) self.db.add_all([user, group]) transaction.commit() self.access.delete_group('foobar') transaction.commit() count = self.db.query(Group).count() self.assertEqual(count, 0) count = self.db.query(association_table).count() self.assertEqual(count, 0) def test_grant_user_permission(self): """ Can give users permissions on a package """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() self.access.edit_user_permission('pkg1', 'foo', 'read', True) transaction.commit() self.db.add(user) self.assertEqual(len(user.permissions), 1) perm = user.permissions[0] self.assertEqual(perm.package, 'pkg1') self.assertTrue(perm.read) self.assertFalse(perm.write) def test_revoke_user_permission(self): """ Can revoke user permissions on a package """ user = make_user('foo', 'bar', False) perm = UserPermission('pkg1', 'foo', read=True) self.db.add_all([user, perm]) transaction.commit() self.access.edit_user_permission('pkg1', 'foo', 'read', False) transaction.commit() self.db.add(user) self.assertEqual(len(user.permissions), 0) def test_grant_group_permission(self): """ Can give groups permissions on a package """ g = Group('foo') self.db.add(g) transaction.commit() self.access.edit_group_permission('pkg1', 'foo', 'read', True) transaction.commit() self.db.add(g) self.assertEqual(len(g.permissions), 1) perm = g.permissions[0] self.assertEqual(perm.package, 'pkg1') self.assertTrue(perm.read) self.assertFalse(perm.write) def test_revoke_group_permission(self): """ Can revoke group permissions on a package """ g = Group('foo') perm = GroupPermission('pkg1', 'foo', read=True) self.db.add_all([g, perm]) transaction.commit() self.access.edit_group_permission('pkg1', 'foo', 'read', False) transaction.commit() self.db.add(g) self.assertEqual(len(g.permissions), 0)
class TestSQLiteBackend(unittest.TestCase): """ Tests for the SQL access backend """ DB_URL = 'sqlite://' @classmethod def setUpClass(cls): super(TestSQLiteBackend, cls).setUpClass() cls.settings = { 'auth.db.url': cls.DB_URL, } try: cls.kwargs = SQLAccessBackend.configure(cls.settings) except OperationalError: raise unittest.SkipTest("Couldn't connect to database") def setUp(self): super(TestSQLiteBackend, self).setUp() transaction.begin() request = MagicMock() request.tm = transaction.manager self.access = SQLAccessBackend(request, **self.kwargs) self.db = self.kwargs['dbmaker']() zope.sqlalchemy.register(self.db, transaction_manager=transaction.manager) def tearDown(self): super(TestSQLiteBackend, self).tearDown() transaction.abort() self.access.db.close() self.db.close() self._drop_and_recreate() def _drop_and_recreate(self): """ Drop all tables and recreate them """ Base.metadata.drop_all(bind=self.db.get_bind()) Base.metadata.create_all(bind=self.db.get_bind()) def test_verify(self): """ Verify login credentials against database """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() valid = self.access.verify_user('foo', 'bar') self.assertTrue(valid) valid = self.access.verify_user('foo', 'barrrr') self.assertFalse(valid) def test_verify_pending(self): """ Pending users fail to verify """ user = make_user('foo', 'bar') self.db.add(user) transaction.commit() valid = self.access.verify_user('foo', 'bar') self.assertFalse(valid) def test_admin(self): """ Retrieve admin status from database """ user = make_user('foo', 'bar', False) user.admin = True self.db.add(user) transaction.commit() is_admin = self.access.is_admin('foo') self.assertTrue(is_admin) def test_admin_default_false(self): """ The default admin status is False """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() is_admin = self.access.is_admin('foo') self.assertFalse(is_admin) def test_user_groups(self): """ Retrieve a user's groups from database """ user = make_user('foo', 'bar', False) g1 = Group('brotatos') g2 = Group('sharkfest') user.groups.update([g1, g2]) self.db.add_all([user, g1, g2]) transaction.commit() groups = self.access.groups('foo') self.assertItemsEqual(groups, ['brotatos', 'sharkfest']) def test_groups(self): """ Retrieve all groups from database """ user = make_user('foo', 'bar', False) g1 = Group('brotatos') g2 = Group('sharkfest') user.groups.add(g1) user.groups.add(g2) self.db.add(user) transaction.commit() groups = self.access.groups() self.assertItemsEqual(groups, ['brotatos', 'sharkfest']) def test_group_members(self): """ Fetch all members of a group """ u1 = make_user('u1', 'bar', False) u2 = make_user('u2', 'bar', False) u3 = make_user('u3', 'bar', False) g1 = Group('g1') g1.users.update([u1, u2]) self.db.add_all([u1, u2, u3, g1]) transaction.commit() users = self.access.group_members('g1') self.assertItemsEqual(users, ['u1', 'u2']) def test_all_user_permissions(self): """ Retrieve all user permissions on package from database """ user = make_user('foo', 'bar', False) user2 = make_user('foo2', 'bar', False) p1 = UserPermission('pkg1', 'foo', True, False) p2 = UserPermission('pkg1', 'foo2', True, True) self.db.add_all([user, user2, p1, p2]) transaction.commit() perms = self.access.user_permissions('pkg1') self.assertEqual(perms, { 'foo': ['read'], 'foo2': ['read', 'write'], }) def test_all_group_permissions(self): """ Retrieve all group permissions from database """ g1 = Group('brotatos') g2 = Group('sharkfest') p1 = GroupPermission('pkg1', 'brotatos', True, False) p2 = GroupPermission('pkg1', 'sharkfest', True, True) self.db.add_all([g1, g2, p1, p2]) transaction.commit() perms = self.access.group_permissions('pkg1') self.assertEqual(perms, { 'brotatos': ['read'], 'sharkfest': ['read', 'write'], }) def test_user_package_perms(self): """ Fetch all packages a user has permissions on """ user = make_user('foo', 'bar', False) p1 = UserPermission('pkg1', 'foo', True, False) p2 = UserPermission('pkg2', 'foo', True, True) self.db.add_all([user, p1, p2]) transaction.commit() perms = self.access.user_package_permissions('foo') self.assertEqual(perms, [ { 'package': 'pkg1', 'permissions': ['read'] }, { 'package': 'pkg2', 'permissions': ['read', 'write'] }, ]) def test_group_package_perms(self): """ Fetch all packages a group has permissions on """ g1 = Group('foo') p1 = GroupPermission('pkg1', 'foo', True, False) p2 = GroupPermission('pkg2', 'foo', True, True) self.db.add_all([g1, p1, p2]) transaction.commit() perms = self.access.group_package_permissions('foo') self.assertEqual(perms, [ { 'package': 'pkg1', 'permissions': ['read'] }, { 'package': 'pkg2', 'permissions': ['read', 'write'] }, ]) def test_user_data(self): """ Retrieve all users """ u1 = make_user('foo', 'bar', False) u1.admin = True u2 = make_user('bar', 'bar', False) g1 = Group('foobars') u2.groups.add(g1) self.db.add_all([u1, u2, g1]) transaction.commit() users = self.access.user_data() self.assertItemsEqual(users, [ { 'username': '******', 'admin': True }, { 'username': '******', 'admin': False }, ]) def test_single_user_data(self): """ Retrieve a single user's data """ u1 = make_user('foo', 'bar', False) u1.admin = True g1 = Group('foobars') u1.groups.add(g1) self.db.add_all([u1, g1]) transaction.commit() user = self.access.user_data('foo') self.assertEqual(user, { 'username': '******', 'admin': True, 'groups': ['foobars'], }) def test_no_need_admin(self): """ If admin exists, don't need an admin """ user = make_user('foo', 'bar', False) user.admin = True self.db.add(user) transaction.commit() self.assertFalse(self.access.need_admin()) def test_need_admin(self): """ If admin doesn't exist, need an admin """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() self.assertTrue(self.access.need_admin()) # Tests for mutable backend methods def test_register(self): """ Register a new user """ self.access.register('foo', 'bar') transaction.commit() user = self.db.query(User).first() self.assertEqual(user.username, 'foo') self.assertTrue(pwd_context.verify('bar', user.password)) def test_pending(self): """ Registering a user puts them in pending list """ user = make_user('foo', 'bar') self.db.add(user) transaction.commit() users = self.access.pending_users() self.assertEqual(users, ['foo']) def test_pending_not_in_users(self): """ Pending users are not listed in all_users """ user = make_user('foo', 'bar') self.db.add(user) transaction.commit() users = self.access.user_data() self.assertEqual(users, []) def test_approve(self): """ Approving user marks them as not pending """ user = make_user('foo', 'bar') self.db.add(user) transaction.commit() self.access.approve_user('foo') transaction.commit() user = self.db.query(User).first() self.assertFalse(user.pending) def test_edit_password(self): """ Users can edit their passwords """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() self.access.edit_user_password('foo', 'baz') transaction.commit() user = self.db.query(User).first() self.assertTrue(self.access.verify_user('foo', 'baz')) def test_delete_user(self): """ Can delete users """ user = make_user('foo', 'bar', False) p1 = UserPermission('pkg1', 'foo', True, False) group = Group('foobar') user.groups.add(group) self.db.add_all([user, group, p1]) transaction.commit() self.access.delete_user('foo') transaction.commit() user = self.db.query(User).first() self.assertIsNone(user) count = self.db.query(association_table).count() self.assertEqual(count, 0) def test_make_admin(self): """ Can make a user an admin """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() self.access.set_user_admin('foo', True) transaction.commit() self.db.add(user) self.assertTrue(user.admin) def test_remove_admin(self): """ Can demote an admin to normal user """ user = make_user('foo', 'bar', False) user.admin = True self.db.add(user) transaction.commit() self.access.set_user_admin('foo', False) transaction.commit() self.db.add(user) self.assertFalse(user.admin) def test_add_user_to_group(self): """ Can add a user to a group """ user = make_user('foo', 'bar', False) group = Group('g1') self.db.add_all([user, group]) transaction.commit() self.access.edit_user_group('foo', 'g1', True) transaction.commit() self.db.add(user) self.assertEqual([g.name for g in user.groups], ['g1']) def test_remove_user_from_group(self): """ Can remove a user from a group """ user = make_user('foo', 'bar', False) group = Group('g1') user.groups.add(group) self.db.add_all([user, group]) transaction.commit() self.access.edit_user_group('foo', 'g1', False) transaction.commit() self.db.add(user) self.assertEqual(len(user.groups), 0) def test_create_group(self): """ Can create a group """ self.access.create_group('g1') transaction.commit() group = self.db.query(Group).first() self.assertIsNotNone(group) self.assertEqual(group.name, 'g1') def test_delete_group(self): """ Can delete groups """ user = make_user('foo', 'bar') group = Group('foobar') user.groups.add(group) self.db.add_all([user, group]) transaction.commit() self.access.edit_group_permission('pkg1', 'foobar', 'read', True) transaction.commit() self.access.delete_group('foobar') transaction.commit() count = self.db.query(Group).count() self.assertEqual(count, 0) count = self.db.query(association_table).count() self.assertEqual(count, 0) def test_grant_user_read_permission(self): """ Can give users read permissions on a package """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() self.access.edit_user_permission('pkg1', 'foo', 'read', True) transaction.commit() self.db.add(user) self.assertEqual(len(user.permissions), 1) perm = user.permissions[0] self.assertEqual(perm.package, 'pkg1') self.assertTrue(perm.read) self.assertFalse(perm.write) def test_grant_user_write_permission(self): """ Can give users write permissions on a package """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() self.access.edit_user_permission('pkg1', 'foo', 'write', True) transaction.commit() self.db.add(user) self.assertEqual(len(user.permissions), 1) perm = user.permissions[0] self.assertEqual(perm.package, 'pkg1') self.assertFalse(perm.read) self.assertTrue(perm.write) def test_grant_user_bad_permission(self): """ Attempting to grant a bad permission raises ValueError """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() with self.assertRaises(ValueError): self.access.edit_user_permission('pkg1', 'foo', 'wiggle', True) def test_revoke_user_permission(self): """ Can revoke user permissions on a package """ user = make_user('foo', 'bar', False) perm = UserPermission('pkg1', 'foo', read=True) self.db.add_all([user, perm]) transaction.commit() self.access.edit_user_permission('pkg1', 'foo', 'read', False) transaction.commit() self.db.add(user) self.assertEqual(len(user.permissions), 0) def test_grant_group_read_permission(self): """ Can give groups read permissions on a package """ g = Group('foo') self.db.add(g) transaction.commit() self.access.edit_group_permission('pkg1', 'foo', 'read', True) transaction.commit() self.db.add(g) self.assertEqual(len(g.permissions), 1) perm = g.permissions[0] self.assertEqual(perm.package, 'pkg1') self.assertTrue(perm.read) self.assertFalse(perm.write) def test_grant_group_write_permission(self): """ Can give groups write permissions on a package """ g = Group('foo') self.db.add(g) transaction.commit() self.access.edit_group_permission('pkg1', 'foo', 'write', True) transaction.commit() self.db.add(g) self.assertEqual(len(g.permissions), 1) perm = g.permissions[0] self.assertEqual(perm.package, 'pkg1') self.assertFalse(perm.read) self.assertTrue(perm.write) def test_grant_group_bad_permission(self): """ Attempting to grant a bad permission raises ValueError """ g = Group('foo') self.db.add(g) transaction.commit() with self.assertRaises(ValueError): self.access.edit_group_permission('pkg1', 'foo', 'wiggle', True) def test_revoke_group_permission(self): """ Can revoke group permissions on a package """ g = Group('foo') perm = GroupPermission('pkg1', 'foo', read=True) self.db.add_all([g, perm]) transaction.commit() self.access.edit_group_permission('pkg1', 'foo', 'read', False) transaction.commit() self.db.add(g) self.assertEqual(len(g.permissions), 0) def test_enable_registration(self): """ Can set the 'enable registration' flag """ self.access.set_allow_register(True) self.assertTrue(self.access.allow_register()) self.access.set_allow_register(False) self.assertFalse(self.access.allow_register()) def test_dump(self): """ Can dump all data to json format """ user1 = make_user('user1', 'user1', True) user2 = make_user('user2', 'user2', False) user3 = make_user('user3', 'user3', False) user3.admin = True self.db.add_all([user1, user2, user3]) transaction.commit() self.access.set_allow_register(False) self.access.create_group('g1') self.access.create_group('g2') self.access.edit_user_group('user2', 'g1', True) self.access.edit_user_group('user2', 'g2', True) self.access.edit_user_group('user3', 'g2', True) self.access.edit_user_permission('pkg1', 'user2', 'read', True) self.access.edit_user_permission('pkg2', 'user3', 'read', True) self.access.edit_user_permission('pkg2', 'user3', 'write', True) self.access.edit_group_permission('pkg1', 'g1', 'read', True) self.access.edit_group_permission('pkg2', 'g2', 'read', True) self.access.edit_group_permission('pkg2', 'g2', 'write', True) data = self.access.dump() self.assertFalse(data['allow_register']) # users self.assertEqual(len(data['users']), 2) for user in data['users']: self.assertTrue( pwd_context.verify(user['username'], user['password'])) self.assertFalse(user['admin'] ^ (user['username'] == 'user3')) # pending users self.assertEqual(len(data['pending_users']), 1) user = data['pending_users'][0] self.assertTrue(pwd_context.verify(user['username'], user['password'])) # groups self.assertEqual(len(data['groups']), 2) self.assertItemsEqual(data['groups']['g1'], ['user2']) self.assertItemsEqual(data['groups']['g2'], ['user2', 'user3']) # user package perms self.assertEqual( data['packages']['users'], { 'pkg1': { 'user2': ['read'], }, 'pkg2': { 'user3': ['read', 'write'], }, }) # group package perms self.assertEqual(data['packages']['groups'], { 'pkg1': { 'g1': ['read'], }, 'pkg2': { 'g2': ['read', 'write'], }, }) def test_load(self): """ Access control can load universal format data """ user1 = make_user('user1', 'user1', True) user2 = make_user('user2', 'user2', False) user3 = make_user('user3', 'user3', False) user3.admin = True self.db.add_all([user1, user2, user3]) transaction.commit() self.access.set_allow_register(False) self.access.create_group('g1') self.access.create_group('g2') self.access.edit_user_group('user2', 'g1', True) self.access.edit_user_group('user2', 'g2', True) self.access.edit_user_group('user3', 'g2', True) self.access.edit_user_permission('pkg1', 'user2', 'read', True) self.access.edit_user_permission('pkg2', 'user3', 'read', True) self.access.edit_user_permission('pkg2', 'user3', 'write', True) self.access.edit_group_permission('pkg1', 'g1', 'read', True) self.access.edit_group_permission('pkg2', 'g2', 'read', True) self.access.edit_group_permission('pkg2', 'g2', 'write', True) transaction.commit() data1 = self.access.dump() self.access.db.close() self.db.close() self._drop_and_recreate() kwargs = SQLAccessBackend.configure(self.settings) self.access = SQLAccessBackend(MagicMock(), **kwargs) self.access.load(data1) data2 = self.access.dump() def assert_nice_equals(obj1, obj2): """ Assertion that handles unordered lists inside dicts """ if isinstance(obj1, dict): self.assertEqual(len(obj1), len(obj2)) for key, val in six.iteritems(obj1): assert_nice_equals(val, obj2[key]) elif isinstance(obj1, list): self.assertItemsEqual(obj1, obj2) else: self.assertEqual(obj1, obj2) assert_nice_equals(data2, data1) # Load operation should be idempotent self.access.load(data2) data3 = self.access.dump() assert_nice_equals(data3, data2) def test_save_unicode(self): """ register() can accept a username with unicode """ username, passw = 'foo™', 'bar™' self.access.register(username, passw) transaction.commit() user = self.db.query(User).first() self.assertEqual(user.username, username) self.assertTrue(pwd_context.verify(passw, user.password))
class TestSQLBackend(unittest.TestCase): """ Tests for the SQL access backend """ @classmethod def setUpClass(cls): super(TestSQLBackend, cls).setUpClass() cls.settings = { 'auth.db.url': 'sqlite:///:memory:', } cls.kwargs = SQLAccessBackend.configure(cls.settings) def setUp(self): super(TestSQLBackend, self).setUp() self.db = self.kwargs['dbmaker']() self.access = SQLAccessBackend(MagicMock(), **self.kwargs) def tearDown(self): super(TestSQLBackend, self).tearDown() transaction.abort() self.db.query(User).delete() self.db.query(UserPermission).delete() self.db.query(GroupPermission).delete() self.db.query(Group).delete() self.db.execute(association_table.delete()) # pylint: disable=E1120 transaction.commit() self.access.db.close() self.db.close() def test_verify(self): """ Verify login credentials against database """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() valid = self.access.verify_user('foo', 'bar') self.assertTrue(valid) valid = self.access.verify_user('foo', 'barrrr') self.assertFalse(valid) def test_verify_pending(self): """ Pending users fail to verify """ user = make_user('foo', 'bar') self.db.add(user) transaction.commit() valid = self.access.verify_user('foo', 'bar') self.assertFalse(valid) def test_admin(self): """ Retrieve admin status from database """ user = make_user('foo', 'bar', False) user.admin = True self.db.add(user) transaction.commit() is_admin = self.access.is_admin('foo') self.assertTrue(is_admin) def test_admin_default_false(self): """ The default admin status is False """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() is_admin = self.access.is_admin('foo') self.assertFalse(is_admin) def test_user_groups(self): """ Retrieve a user's groups from database """ user = make_user('foo', 'bar', False) g1 = Group('brotatos') g2 = Group('sharkfest') user.groups.update([g1, g2]) self.db.add_all([user, g1, g2]) transaction.commit() groups = self.access.groups('foo') self.assertItemsEqual(groups, ['brotatos', 'sharkfest']) def test_groups(self): """ Retrieve all groups from database """ user = make_user('foo', 'bar', False) g1 = Group('brotatos') g2 = Group('sharkfest') user.groups.add(g1) user.groups.add(g2) self.db.add(user) transaction.commit() groups = self.access.groups() self.assertItemsEqual(groups, ['brotatos', 'sharkfest']) def test_group_members(self): """ Fetch all members of a group """ u1 = make_user('u1', 'bar', False) u2 = make_user('u2', 'bar', False) u3 = make_user('u3', 'bar', False) g1 = Group('g1') g1.users.update([u1, u2]) self.db.add_all([u1, u2, u3, g1]) transaction.commit() users = self.access.group_members('g1') self.assertItemsEqual(users, ['u1', 'u2']) def test_all_user_permissions(self): """ Retrieve all user permissions on package from database """ user = make_user('foo', 'bar', False) user2 = make_user('foo2', 'bar', False) p1 = UserPermission('pkg1', 'foo', True, False) p2 = UserPermission('pkg1', 'foo2', True, True) self.db.add_all([user, user2, p1, p2]) transaction.commit() perms = self.access.user_permissions('pkg1') self.assertEqual(perms, { 'foo': ['read'], 'foo2': ['read', 'write'], }) def test_user_permissions(self): """ Retrieve a user's permissions on package from database """ user = make_user('foo', 'bar', False) user2 = make_user('foo2', 'bar', False) p1 = UserPermission('pkg1', 'foo', True, False) p2 = UserPermission('pkg1', 'foo2', True, True) self.db.add_all([user, user2, p1, p2]) transaction.commit() perms = self.access.user_permissions('pkg1', 'foo') self.assertEqual(perms, ['read']) def test_all_group_permissions(self): """ Retrieve all group permissions from database """ g1 = Group('brotatos') g2 = Group('sharkfest') p1 = GroupPermission('pkg1', 'brotatos', True, False) p2 = GroupPermission('pkg1', 'sharkfest', True, True) self.db.add_all([g1, g2, p1, p2]) transaction.commit() perms = self.access.group_permissions('pkg1') self.assertEqual(perms, { 'brotatos': ['read'], 'sharkfest': ['read', 'write'], }) def test_group_permissions(self): """ Retrieve a group's permissions from database """ g1 = Group('brotatos') g2 = Group('sharkfest') p1 = GroupPermission('pkg1', 'brotatos', True, False) p2 = GroupPermission('pkg1', 'sharkfest', True, True) self.db.add_all([g1, g2, p1, p2]) transaction.commit() perms = self.access.group_permissions('pkg1', 'brotatos') self.assertEqual(perms, ['read']) def test_user_package_perms(self): """ Fetch all packages a user has permissions on """ user = make_user('foo', 'bar', False) p1 = UserPermission('pkg1', 'foo', True, False) p2 = UserPermission('pkg2', 'foo', True, True) self.db.add_all([user, p1, p2]) transaction.commit() perms = self.access.user_package_permissions('foo') self.assertEqual(perms, [ {'package': 'pkg1', 'permissions': ['read']}, {'package': 'pkg2', 'permissions': ['read', 'write']}, ]) def test_group_package_perms(self): """ Fetch all packages a group has permissions on """ g1 = Group('foo') p1 = GroupPermission('pkg1', 'foo', True, False) p2 = GroupPermission('pkg2', 'foo', True, True) self.db.add_all([g1, p1, p2]) transaction.commit() perms = self.access.group_package_permissions('foo') self.assertEqual(perms, [ {'package': 'pkg1', 'permissions': ['read']}, {'package': 'pkg2', 'permissions': ['read', 'write']}, ]) def test_user_data(self): """ Retrieve all users """ u1 = make_user('foo', 'bar', False) u1.admin = True u2 = make_user('bar', 'bar', False) g1 = Group('foobars') u2.groups.add(g1) self.db.add_all([u1, u2, g1]) transaction.commit() users = self.access.user_data() self.assertItemsEqual(users, [ {'username': '******', 'admin': True}, {'username': '******', 'admin': False}, ]) def test_single_user_data(self): """ Retrieve a single user's data """ u1 = make_user('foo', 'bar', False) u1.admin = True g1 = Group('foobars') u1.groups.add(g1) self.db.add_all([u1, g1]) transaction.commit() user = self.access.user_data('foo') self.assertEqual(user, { 'username': '******', 'admin': True, 'groups': ['foobars'], }) def test_no_need_admin(self): """ If admin exists, don't need an admin """ user = make_user('foo', 'bar', False) user.admin = True self.db.add(user) transaction.commit() self.assertFalse(self.access.need_admin()) def test_need_admin(self): """ If admin doesn't exist, need an admin """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() self.assertTrue(self.access.need_admin()) # Tests for mutable backend methods def test_register(self): """ Register a new user """ self.access.register('foo', 'bar') transaction.commit() user = self.db.query(User).first() self.assertEqual(user.username, 'foo') self.assertTrue(pwd_context.verify('bar', user.password)) def test_pending(self): """ Registering a user puts them in pending list """ user = make_user('foo', 'bar') self.db.add(user) transaction.commit() users = self.access.pending_users() self.assertEqual(users, ['foo']) def test_pending_not_in_users(self): """ Pending users are not listed in all_users """ user = make_user('foo', 'bar') self.db.add(user) transaction.commit() users = self.access.user_data() self.assertEqual(users, []) def test_approve(self): """ Approving user marks them as not pending """ user = make_user('foo', 'bar') self.db.add(user) transaction.commit() self.access.approve_user('foo') transaction.commit() user = self.db.query(User).first() self.assertFalse(user.pending) def test_edit_password(self): """ Users can edit their passwords """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() self.access.edit_user_password('foo', 'baz') transaction.commit() user = self.db.query(User).first() self.assertTrue(self.access.verify_user('foo', 'baz')) def test_delete_user(self): """ Can delete users """ user = make_user('foo', 'bar', False) group = Group('foobar') user.groups.add(group) self.db.add_all([user, group]) transaction.commit() self.access.delete_user('foo') transaction.commit() user = self.db.query(User).first() self.assertIsNone(user) count = self.db.query(association_table).count() self.assertEqual(count, 0) def test_make_admin(self): """ Can make a user an admin """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() self.access.set_user_admin('foo', True) transaction.commit() self.db.add(user) self.assertTrue(user.admin) def test_remove_admin(self): """ Can demote an admin to normal user """ user = make_user('foo', 'bar', False) user.admin = True self.db.add(user) transaction.commit() self.access.set_user_admin('foo', False) transaction.commit() self.db.add(user) self.assertFalse(user.admin) def test_add_user_to_group(self): """ Can add a user to a group """ user = make_user('foo', 'bar', False) group = Group('g1') self.db.add_all([user, group]) transaction.commit() self.access.edit_user_group('foo', 'g1', True) transaction.commit() self.db.add(user) self.assertEqual([g.name for g in user.groups], ['g1']) def test_remove_user_from_group(self): """ Can remove a user from a group """ user = make_user('foo', 'bar', False) group = Group('g1') user.groups.add(group) self.db.add_all([user, group]) transaction.commit() self.access.edit_user_group('foo', 'g1', False) transaction.commit() self.db.add(user) self.assertEqual(len(user.groups), 0) def test_create_group(self): """ Can create a group """ self.access.create_group('g1') transaction.commit() group = self.db.query(Group).first() self.assertIsNotNone(group) self.assertEqual(group.name, 'g1') def test_delete_group(self): """ Can delete groups """ user = make_user('foo', 'bar') group = Group('foobar') user.groups.add(group) self.db.add_all([user, group]) transaction.commit() self.access.delete_group('foobar') transaction.commit() count = self.db.query(Group).count() self.assertEqual(count, 0) count = self.db.query(association_table).count() self.assertEqual(count, 0) def test_grant_user_read_permission(self): """ Can give users read permissions on a package """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() self.access.edit_user_permission('pkg1', 'foo', 'read', True) transaction.commit() self.db.add(user) self.assertEqual(len(user.permissions), 1) perm = user.permissions[0] self.assertEqual(perm.package, 'pkg1') self.assertTrue(perm.read) self.assertFalse(perm.write) def test_grant_user_write_permission(self): """ Can give users write permissions on a package """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() self.access.edit_user_permission('pkg1', 'foo', 'write', True) transaction.commit() self.db.add(user) self.assertEqual(len(user.permissions), 1) perm = user.permissions[0] self.assertEqual(perm.package, 'pkg1') self.assertFalse(perm.read) self.assertTrue(perm.write) def test_grant_user_bad_permission(self): """ Attempting to grant a bad permission raises ValueError """ user = make_user('foo', 'bar', False) self.db.add(user) transaction.commit() with self.assertRaises(ValueError): self.access.edit_user_permission('pkg1', 'foo', 'wiggle', True) def test_revoke_user_permission(self): """ Can revoke user permissions on a package """ user = make_user('foo', 'bar', False) perm = UserPermission('pkg1', 'foo', read=True) self.db.add_all([user, perm]) transaction.commit() self.access.edit_user_permission('pkg1', 'foo', 'read', False) transaction.commit() self.db.add(user) self.assertEqual(len(user.permissions), 0) def test_grant_group_read_permission(self): """ Can give groups read permissions on a package """ g = Group('foo') self.db.add(g) transaction.commit() self.access.edit_group_permission('pkg1', 'foo', 'read', True) transaction.commit() self.db.add(g) self.assertEqual(len(g.permissions), 1) perm = g.permissions[0] self.assertEqual(perm.package, 'pkg1') self.assertTrue(perm.read) self.assertFalse(perm.write) def test_grant_group_write_permission(self): """ Can give groups write permissions on a package """ g = Group('foo') self.db.add(g) transaction.commit() self.access.edit_group_permission('pkg1', 'foo', 'write', True) transaction.commit() self.db.add(g) self.assertEqual(len(g.permissions), 1) perm = g.permissions[0] self.assertEqual(perm.package, 'pkg1') self.assertFalse(perm.read) self.assertTrue(perm.write) def test_grant_group_bad_permission(self): """ Attempting to grant a bad permission raises ValueError """ g = Group('foo') self.db.add(g) transaction.commit() with self.assertRaises(ValueError): self.access.edit_group_permission('pkg1', 'foo', 'wiggle', True) def test_revoke_group_permission(self): """ Can revoke group permissions on a package """ g = Group('foo') perm = GroupPermission('pkg1', 'foo', read=True) self.db.add_all([g, perm]) transaction.commit() self.access.edit_group_permission('pkg1', 'foo', 'read', False) transaction.commit() self.db.add(g) self.assertEqual(len(g.permissions), 0) def test_enable_registration(self): """ Can set the 'enable registration' flag """ self.access.set_allow_register(True) self.assertTrue(self.access.allow_register()) self.access.set_allow_register(False) self.assertFalse(self.access.allow_register()) def test_dump(self): """ Can dump all data to json format """ user1 = make_user('user1', 'user1', True) user2 = make_user('user2', 'user2', False) user3 = make_user('user3', 'user3', False) user3.admin = True self.db.add_all([user1, user2, user3]) transaction.commit() self.access.set_allow_register(False) self.access.create_group('g1') self.access.create_group('g2') self.access.edit_user_group('user2', 'g1', True) self.access.edit_user_group('user2', 'g2', True) self.access.edit_user_group('user3', 'g2', True) self.access.edit_user_permission('pkg1', 'user2', 'read', True) self.access.edit_user_permission('pkg2', 'user3', 'read', True) self.access.edit_user_permission('pkg2', 'user3', 'write', True) self.access.edit_group_permission('pkg1', 'g1', 'read', True) self.access.edit_group_permission('pkg2', 'g2', 'read', True) self.access.edit_group_permission('pkg2', 'g2', 'write', True) data = self.access.dump() self.assertFalse(data['allow_register']) # users self.assertEqual(len(data['users']), 2) for user in data['users']: self.assertTrue(pwd_context.verify(user['username'], user['password'])) self.assertFalse(user['admin'] ^ (user['username'] == 'user3')) # pending users self.assertEqual(len(data['pending_users']), 1) user = data['pending_users'][0] self.assertTrue(pwd_context.verify(user['username'], user['password'])) # groups self.assertEqual(len(data['groups']), 2) self.assertItemsEqual(data['groups']['g1'], ['user2']) self.assertItemsEqual(data['groups']['g2'], ['user2', 'user3']) # user package perms self.assertEqual(data['packages']['users'], { 'pkg1': { 'user2': ['read'], }, 'pkg2': { 'user3': ['read', 'write'], }, }) # group package perms self.assertEqual(data['packages']['groups'], { 'pkg1': { 'g1': ['read'], }, 'pkg2': { 'g2': ['read', 'write'], }, }) def test_load(self): """ Access control can load universal format data """ user1 = make_user('user1', 'user1', True) user2 = make_user('user2', 'user2', False) user3 = make_user('user3', 'user3', False) user3.admin = True self.db.add_all([user1, user2, user3]) transaction.commit() self.access.set_allow_register(False) self.access.create_group('g1') self.access.create_group('g2') self.access.edit_user_group('user2', 'g1', True) self.access.edit_user_group('user2', 'g2', True) self.access.edit_user_group('user3', 'g2', True) self.access.edit_user_permission('pkg1', 'user2', 'read', True) self.access.edit_user_permission('pkg2', 'user3', 'read', True) self.access.edit_user_permission('pkg2', 'user3', 'write', True) self.access.edit_group_permission('pkg1', 'g1', 'read', True) self.access.edit_group_permission('pkg2', 'g2', 'read', True) self.access.edit_group_permission('pkg2', 'g2', 'write', True) data1 = self.access.dump() SQLAccessBackend.configure(self.settings) kwargs = SQLAccessBackend.configure(self.settings) access2 = SQLAccessBackend(MagicMock(), **kwargs) access2.load(data1) data2 = access2.dump() def assert_nice_equals(obj1, obj2): """ Assertion that handles unordered lists inside dicts """ if isinstance(obj1, dict): self.assertEqual(len(obj1), len(obj2)) for key, val in obj1.iteritems(): assert_nice_equals(val, obj2[key]) elif isinstance(obj1, list): self.assertItemsEqual(obj1, obj2) else: self.assertEqual(obj1, obj2) assert_nice_equals(data2, data1) # Load operation should be idempotent access2.load(data2) data3 = access2.dump() assert_nice_equals(data3, data2)