import unittest import datetime import time from flask import url_for, session, current_app # These imports are required, because otherwise we get circular imports?! from uffd import user from uffd.ldap import ldap from uffd import create_app, db from uffd.invite.models import Invite, InviteGrant, InviteSignup from uffd.user.models import User, Group from uffd.role.models import Role from uffd.session.views import login_get_user from utils import dump, UffdTestCase, db_flush class TestInviteModel(UffdTestCase): def test_expire(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60)) self.assertFalse(invite.expired) self.assertTrue(invite.active) invite.valid_until = datetime.datetime.now() - datetime.timedelta(seconds=60) self.assertTrue(invite.expired) self.assertFalse(invite.active) def test_void(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), single_use=False) self.assertFalse(invite.voided) self.assertTrue(invite.active) invite.used = True self.assertFalse(invite.voided) self.assertTrue(invite.active) invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), single_use=True) self.assertFalse(invite.voided) self.assertTrue(invite.active) invite.used = True self.assertTrue(invite.voided) self.assertFalse(invite.active) def test_permitted(self): role = Role(name='testrole') invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True, roles=[role]) self.assertTrue(invite.permitted) self.assertTrue(invite.active) invite.creator_dn = 'uid=doesnotexist,ou=users,dc=example,dc=com' self.assertFalse(invite.permitted) self.assertFalse(invite.active) invite.creator_dn = 'uid=testadmin,ou=users,dc=example,dc=com' self.assertTrue(invite.permitted) self.assertTrue(invite.active) invite.creator_dn = 'uid=testuser,ou=users,dc=example,dc=com' self.assertFalse(invite.permitted) self.assertFalse(invite.active) role.moderator_group_dn = 'cn=uffd_access,ou=groups,dc=example,dc=com' current_app.config['ACL_SIGNUP_GROUP'] = 'uffd_access' self.assertTrue(invite.permitted) self.assertTrue(invite.active) role.moderator_group_dn = None self.assertFalse(invite.permitted) self.assertFalse(invite.active) role.moderator_group_dn = 'cn=uffd_access,ou=groups,dc=example,dc=com' current_app.config['ACL_SIGNUP_GROUP'] = 'uffd_admin' self.assertFalse(invite.permitted) self.assertFalse(invite.active) def test_disable(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60)) self.assertTrue(invite.active) invite.disable() self.assertFalse(invite.active) def test_reset_disabled(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60)) invite.disable() self.assertFalse(invite.active) invite.reset() self.assertTrue(invite.active) def test_reset_expired(self): invite = Invite(valid_until=datetime.datetime.now() - datetime.timedelta(seconds=60)) self.assertFalse(invite.active) invite.reset() self.assertFalse(invite.active) def test_reset_single_use(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), single_use=False) invite.used = True invite.disable() self.assertFalse(invite.active) invite.reset() self.assertTrue(invite.active) def test_short_token(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60)) db.session.add(invite) db.session.commit() self.assertTrue(len(invite.short_token) <= len(invite.token)/3) class TestInviteGrantModel(UffdTestCase): def test_success(self): user = User.query.get('uid=testuser,ou=users,dc=example,dc=com') group0 = Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com') role0 = Role(name='baserole', groups=[group0]) db.session.add(role0) user.roles.add(role0) user.update_groups() group1 = Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com') role1 = Role(name='testrole1', groups=[group1]) db.session.add(role1) role2 = Role(name='testrole2') db.session.add(role2) invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), roles=[role1, role2]) self.assertIn(role0, user.roles) self.assertNotIn(role1, user.roles) self.assertNotIn(role2, user.roles) self.assertIn(group0, user.groups) self.assertNotIn(group1, user.groups) self.assertFalse(invite.used) grant = InviteGrant(invite=invite, user=user) success, msg = grant.apply() self.assertTrue(success) self.assertIn(role0, user.roles) self.assertIn(role1, user.roles) self.assertIn(role2, user.roles) self.assertIn(group0, user.groups) self.assertIn(group1, user.groups) self.assertTrue(invite.used) db.session.commit() ldap.session.commit() db_flush() user = User.query.get('uid=testuser,ou=users,dc=example,dc=com') self.assertIn('baserole', [role.name for role in user.roles]) self.assertIn('testrole1', [role.name for role in user.roles]) self.assertIn('testrole2', [role.name for role in user.roles]) self.assertIn('cn=uffd_access,ou=groups,dc=example,dc=com', [group.dn for group in user.groups]) self.assertIn('cn=uffd_admin,ou=groups,dc=example,dc=com', [group.dn for group in user.groups]) def test_inactive(self): user = User.query.get('uid=testuser,ou=users,dc=example,dc=com') group = Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com') role = Role(name='testrole1', groups=[group]) db.session.add(role) invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), roles=[role], single_use=True, used=True) self.assertFalse(invite.active) grant = InviteGrant(invite=invite, user=user) success, msg = grant.apply() self.assertFalse(success) self.assertIsInstance(msg, str) self.assertNotIn(role, user.roles) self.assertNotIn(group, user.groups) def test_no_roles(self): user = User.query.get('uid=testuser,ou=users,dc=example,dc=com') invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60)) self.assertTrue(invite.active) grant = InviteGrant(invite=invite, user=user) success, msg = grant.apply() self.assertFalse(success) self.assertIsInstance(msg, str) def test_no_new_roles(self): user = User.query.get('uid=testuser,ou=users,dc=example,dc=com') role = Role(name='testrole1') db.session.add(role) user.roles.add(role) invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), roles=[role]) self.assertTrue(invite.active) grant = InviteGrant(invite=invite, user=user) success, msg = grant.apply() self.assertFalse(success) self.assertIsInstance(msg, str) class TestInviteSignupModel(UffdTestCase): def create_base_roles(self): self.app.config['ROLES_BASEROLES'] = ['base'] baserole = Role(name='base') baserole.groups.add(Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')) baserole.groups.add(Group.query.get('cn=users,ou=groups,dc=example,dc=com')) db.session.add(baserole) db.session.commit() def test_success(self): self.create_base_roles() base_role = Role.query.filter_by(name='base').one() base_group1 = Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com') base_group2 = Group.query.get('cn=users,ou=groups,dc=example,dc=com') group = Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com') role1 = Role(name='testrole1', groups=[group]) db.session.add(role1) role2 = Role(name='testrole2') db.session.add(role2) invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), roles=[role1, role2], allow_signup=True) signup = InviteSignup(invite=invite, loginname='newuser', displayname='New User', mail='test@example.com', password='notsecret') self.assertFalse(invite.used) valid, msg = signup.validate() self.assertTrue(valid) self.assertFalse(invite.used) user, msg = signup.finish('notsecret') self.assertIsInstance(user, User) self.assertTrue(invite.used) self.assertEqual(user.loginname, 'newuser') self.assertEqual(user.displayname, 'New User') self.assertEqual(user.mail, 'test@example.com') self.assertEqual(signup.user.dn, user.dn) self.assertIn(base_role, user.roles) self.assertIn(role1, user.roles) self.assertIn(role2, user.roles) self.assertIn(base_group1, user.groups) self.assertIn(base_group2, user.groups) self.assertIn(group, user.groups) db.session.commit() ldap.session.commit() db_flush() self.assertEqual(len(User.query.filter_by(loginname='newuser').all()), 1) def test_success_no_roles(self): self.create_base_roles() base_role = Role.query.filter_by(name='base').one() base_group1 = Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com') base_group2 = Group.query.get('cn=users,ou=groups,dc=example,dc=com') invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True) signup = InviteSignup(invite=invite, loginname='newuser', displayname='New User', mail='test@example.com', password='notsecret') self.assertFalse(invite.used) valid, msg = signup.validate() self.assertTrue(valid) self.assertFalse(invite.used) user, msg = signup.finish('notsecret') self.assertIsInstance(user, User) self.assertTrue(invite.used) self.assertEqual(user.loginname, 'newuser') self.assertEqual(user.displayname, 'New User') self.assertEqual(user.mail, 'test@example.com') self.assertEqual(signup.user.dn, user.dn) self.assertIn(base_role, user.roles) self.assertEqual(len(user.roles), 1) self.assertIn(base_group1, user.groups) self.assertIn(base_group2, user.groups) self.assertEqual(len(user.groups), 2) db.session.commit() ldap.session.commit() db_flush() self.assertEqual(len(User.query.filter_by(loginname='newuser').all()), 1) def test_inactive(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True, single_use=True, used=True) self.assertFalse(invite.active) signup = InviteSignup(invite=invite, loginname='newuser', displayname='New User', mail='test@example.com', password='notsecret') valid, msg = signup.validate() self.assertFalse(valid) self.assertIsInstance(msg, str) user, msg = signup.finish('notsecret') self.assertIsNone(user) self.assertIsInstance(msg, str) def test_invalid(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True) self.assertTrue(invite.active) signup = InviteSignup(invite=invite, loginname='', displayname='New User', mail='test@example.com', password='notsecret') valid, msg = signup.validate() self.assertFalse(valid) self.assertIsInstance(msg, str) def test_invalid2(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True) self.assertTrue(invite.active) signup = InviteSignup(invite=invite, loginname='newuser', displayname='New User', mail='test@example.com', password='notsecret') user, msg = signup.finish('wrongpassword') self.assertIsNone(user) self.assertIsInstance(msg, str) def test_no_signup(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=False) self.assertTrue(invite.active) signup = InviteSignup(invite=invite, loginname='newuser', displayname='New User', mail='test@example.com', password='notsecret') valid, msg = signup.validate() self.assertFalse(valid) self.assertIsInstance(msg, str) user, msg = signup.finish('notsecret') self.assertIsNone(user) self.assertIsInstance(msg, str) class TestInviteAdminViews(UffdTestCase): def setUpApp(self): self.app.config['SELF_SIGNUP'] = False self.app.last_mail = None def login_admin(self): self.client.post(path=url_for('session.login'), data={'loginname': 'testadmin', 'password': 'adminpassword'}, follow_redirects=True) def login_user(self): self.client.post(path=url_for('session.login'), data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=True) def test_index(self): valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60) valid_until_expired = datetime.datetime.now() - datetime.timedelta(seconds=60) user1 = User.query.get('uid=testuser,ou=users,dc=example,dc=com') user2 = User.query.get('uid=testadmin,ou=users,dc=example,dc=com') role1 = Role(name='testrole1') db.session.add(role1) role2 = Role(name='testrole2') db.session.add(role2) # All possible states db.session.add(Invite(valid_until=valid_until, single_use=False)) db.session.add(Invite(valid_until=valid_until, single_use=True, used=False)) db.session.add(Invite(valid_until=valid_until, single_use=True, used=True, signups=[InviteSignup(user=user1)])) db.session.add(Invite(valid_until=valid_until_expired)) db.session.add(Invite(valid_until=valid_until, disabled=True)) # Different permissions db.session.add(Invite(valid_until=valid_until, allow_signup=True)) db.session.add(Invite(valid_until=valid_until, allow_signup=False)) db.session.add(Invite(valid_until=valid_until, allow_signup=True, roles=[role1], grants=[InviteGrant(user=user2)])) db.session.add(Invite(valid_until=valid_until, allow_signup=False, roles=[role1, role2])) db.session.commit() self.login_admin() r = self.client.get(path=url_for('invite.index'), follow_redirects=True) dump('invite_index', r) self.assertEqual(r.status_code, 200) def test_index_empty(self): self.login_admin() r = self.client.get(path=url_for('invite.index'), follow_redirects=True) dump('invite_index_empty', r) self.assertEqual(r.status_code, 200) def test_index_nologin(self): r = self.client.get(path=url_for('invite.index'), follow_redirects=True) dump('invite_index_nologin', r) self.assertEqual(r.status_code, 200) def test_index_noaccess(self): self.login_user() r = self.client.get(path=url_for('invite.index'), follow_redirects=True) dump('invite_index_noaccess', r) self.assertEqual(r.status_code, 200) self.assertIn('Access denied'.encode(), r.data) def test_index_signupperm(self): current_app.config['ACL_SIGNUP_GROUP'] = 'uffd_access' valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60) invite1 = Invite(valid_until=valid_until, allow_signup=True, creator_dn='uid=testadmin,ou=users,dc=example,dc=com') db.session.add(invite1) invite2 = Invite(valid_until=valid_until, allow_signup=True, creator_dn='uid=testuser,ou=users,dc=example,dc=com') db.session.add(invite2) invite3 = Invite(valid_until=valid_until, allow_signup=True) db.session.add(invite3) db.session.commit() token1 = invite1.short_token token2 = invite2.short_token token3 = invite3.short_token self.login_user() r = self.client.get(path=url_for('invite.index'), follow_redirects=True) self.assertEqual(r.status_code, 200) self.assertNotIn('Access denied'.encode(), r.data) self.assertNotIn(token1.encode(), r.data) self.assertIn(token2.encode(), r.data) self.assertNotIn(token3.encode(), r.data) def test_index_rolemod(self): role1 = Role(name='testrole1') db.session.add(role1) role2 = Role(name='testrole2', moderator_group_dn='cn=uffd_access,ou=groups,dc=example,dc=com') db.session.add(role2) valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60) db.session.add(Invite(valid_until=valid_until, roles=[role1])) db.session.add(Invite(valid_until=valid_until, roles=[role2])) db.session.commit() self.login_user() r = self.client.get(path=url_for('invite.index'), follow_redirects=True) self.assertEqual(r.status_code, 200) self.assertNotIn('Access denied'.encode(), r.data) self.assertNotIn('testrole1'.encode(), r.data) self.assertIn('testrole2'.encode(), r.data) def test_new(self): self.login_admin() role = Role(name='testrole1') db.session.add(role) db.session.commit() role_id = role.id r = self.client.get(path=url_for('invite.new'), follow_redirects=True) dump('invite_new', r) self.assertEqual(r.status_code, 200) valid_until = (datetime.datetime.now() + datetime.timedelta(seconds=60)).isoformat() self.assertListEqual(Invite.query.all(), []) r = self.client.post(path=url_for('invite.new_submit'), data={'single-use': '1', 'valid-until': valid_until, 'allow-signup': '1', 'role-%d'%role_id: '1'}, follow_redirects=True) dump('invite_new_submit', r) invite = Invite.query.one() role = Role.query.get(role_id) self.assertTrue(invite.active) self.assertTrue(invite.single_use) self.assertTrue(invite.allow_signup) self.assertListEqual(invite.roles, [role]) def test_new_noperm(self): current_app.config['ACL_SIGNUP_GROUP'] = 'uffd_access' self.login_user() role = Role(name='testrole1') db.session.add(role) db.session.commit() role_id = role.id valid_until = (datetime.datetime.now() + datetime.timedelta(seconds=60)).isoformat() r = self.client.post(path=url_for('invite.new_submit'), data={'single-use': '1', 'valid-until': valid_until, 'allow-signup': '1', 'role-%d'%role_id: '1'}, follow_redirects=True) dump('invite_new_noperm', r) self.assertIsNone(Invite.query.first()) def test_new_empty(self): current_app.config['ACL_SIGNUP_GROUP'] = 'uffd_access' self.login_user() valid_until = (datetime.datetime.now() + datetime.timedelta(seconds=60)).isoformat() r = self.client.post(path=url_for('invite.new_submit'), data={'single-use': '1', 'valid-until': valid_until, 'allow-signup': '0'}, follow_redirects=True) dump('invite_new_empty', r) self.assertIsNone(Invite.query.first()) def test_disable(self): self.login_admin() valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60) invite = Invite(valid_until=valid_until) db.session.add(invite) db.session.commit() id = invite.id self.assertTrue(Invite.query.get(id).active) r = self.client.post(path=url_for('invite.disable', invite_id=id), follow_redirects=True) dump('invite_disable', r) self.assertTrue(Invite.query.get(id).disabled) def test_disable_own(self): current_app.config['ACL_SIGNUP_GROUP'] = 'uffd_access' self.login_user() valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60) invite = Invite(valid_until=valid_until, creator_dn='uid=testuser,ou=users,dc=example,dc=com') db.session.add(invite) db.session.commit() id = invite.id self.assertTrue(Invite.query.get(id).active) r = self.client.post(path=url_for('invite.disable', invite_id=id), follow_redirects=True) dump('invite_disable', r) self.assertTrue(Invite.query.get(id).disabled) def test_disable_rolemod(self): self.login_user() valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60) role = Role(name='testrole', moderator_group_dn='cn=uffd_access,ou=groups,dc=example,dc=com') db.session.add(role) invite = Invite(valid_until=valid_until, creator_dn='uid=testadmin,ou=users,dc=example,dc=com', roles=[role]) db.session.add(invite) db.session.commit() id = invite.id self.assertTrue(Invite.query.get(id).active) r = self.client.post(path=url_for('invite.disable', invite_id=id), follow_redirects=True) self.assertTrue(Invite.query.get(id).disabled) def test_disable_noperm(self): self.login_user() valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60) db.session.add(Role(name='testrole1', moderator_group_dn='cn=uffd_access,ou=groups,dc=example,dc=com')) role = Role(name='testrole2', moderator_group_dn='cn=uffd_admin,ou=groups,dc=example,dc=com') db.session.add(role) invite = Invite(valid_until=valid_until, creator_dn='uid=testadmin,ou=users,dc=example,dc=com', roles=[role]) db.session.add(invite) db.session.commit() id = invite.id r = self.client.post(path=url_for('invite.disable', invite_id=id), follow_redirects=True) self.assertFalse(Invite.query.get(id).disabled) self.assertTrue(Invite.query.get(id).active) def test_reset_disabled(self): self.login_admin() valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60) invite = Invite(valid_until=valid_until, disabled=True) db.session.add(invite) db.session.commit() id = invite.id self.assertFalse(Invite.query.get(id).active) r = self.client.post(path=url_for('invite.reset', invite_id=id), follow_redirects=True) dump('invite_reset_disabled', r) self.assertTrue(Invite.query.get(id).active) def test_reset_voided(self): self.login_admin() valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60) invite = Invite(valid_until=valid_until, single_use=True, used=True) db.session.add(invite) db.session.commit() id = invite.id self.assertFalse(Invite.query.get(id).active) r = self.client.post(path=url_for('invite.reset', invite_id=id), follow_redirects=True) dump('invite_reset_voided', r) self.assertTrue(Invite.query.get(id).active) def test_reset_own(self): current_app.config['ACL_SIGNUP_GROUP'] = 'uffd_access' self.login_user() valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60) invite = Invite(valid_until=valid_until, disabled=True, creator_dn='uid=testuser,ou=users,dc=example,dc=com') db.session.add(invite) db.session.commit() id = invite.id self.assertFalse(Invite.query.get(id).active) r = self.client.post(path=url_for('invite.reset', invite_id=id), follow_redirects=True) dump('invite_reset_own', r) self.assertTrue(Invite.query.get(id).active) def test_reset_foreign(self): self.login_user() valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60) role = Role(name='testrole', moderator_group_dn='cn=uffd_access,ou=groups,dc=example,dc=com') db.session.add(role) invite = Invite(valid_until=valid_until, disabled=True, creator_dn='uid=testadmin,ou=users,dc=example,dc=com', roles=[role]) db.session.add(invite) db.session.commit() id = invite.id self.assertFalse(Invite.query.get(id).active) r = self.client.post(path=url_for('invite.reset', invite_id=id), follow_redirects=True) self.assertFalse(Invite.query.get(id).active) class TestInviteUseViews(UffdTestCase): def setUpApp(self): self.app.config['SELF_SIGNUP'] = False self.app.last_mail = None def login_user(self): self.client.post(path=url_for('session.login'), data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=True) def test_use(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True, roles=[Role(name='testrole1'), Role(name='testrole2')]) db.session.add(invite) db.session.commit() token = invite.token r = self.client.get(path=url_for('invite.use', token=token), follow_redirects=True) dump('invite_use', r) self.assertEqual(r.status_code, 200) def test_use_loggedin(self): self.login_user() invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True, roles=[Role(name='testrole1'), Role(name='testrole2')]) db.session.add(invite) db.session.commit() token = invite.token r = self.client.get(path=url_for('invite.use', token=token), follow_redirects=True) dump('invite_use_loggedin', r) self.assertEqual(r.status_code, 200) def test_use_inactive(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), disabled=True) db.session.add(invite) db.session.commit() token = invite.token r = self.client.get(path=url_for('invite.use', token=token), follow_redirects=True) dump('invite_use_inactive', r) self.assertEqual(r.status_code, 200) # TODO: test cases for {logged in, not logged in} x (signup-only, grant-only, both, none?} def test_grant(self): user = User.query.get('uid=testuser,ou=users,dc=example,dc=com') group0 = Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com') role0 = Role(name='baserole', groups=[group0]) db.session.add(role0) user.roles.add(role0) user.update_groups() group1 = Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com') role1 = Role(name='testrole1', groups=[group1]) db.session.add(role1) role2 = Role(name='testrole2') db.session.add(role2) invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), roles=[role1, role2]) db.session.add(invite) db.session.commit() ldap.session.commit() token = invite.token self.assertIn(role0, user.roles) self.assertNotIn(role1, user.roles) self.assertNotIn(role2, user.roles) self.assertIn(group0, user.groups) self.assertNotIn(group1, user.groups) self.assertFalse(invite.used) self.login_user() r = self.client.post(path=url_for('invite.grant', token=token), follow_redirects=True) dump('invite_grant', r) self.assertEqual(r.status_code, 200) db_flush() invite = Invite.query.filter_by(token=token).first() user = User.query.get('uid=testuser,ou=users,dc=example,dc=com') self.assertTrue(invite.used) self.assertIn('baserole', [role.name for role in user.roles]) self.assertIn('testrole1', [role.name for role in user.roles]) self.assertIn('testrole2', [role.name for role in user.roles]) self.assertIn('cn=uffd_access,ou=groups,dc=example,dc=com', [group.dn for group in user.groups]) self.assertIn('cn=uffd_admin,ou=groups,dc=example,dc=com', [group.dn for group in user.groups]) def test_grant_invalid_invite(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), disabled=True) db.session.add(invite) db.session.commit() token = invite.token self.login_user() r = self.client.post(path=url_for('invite.grant', token=token), follow_redirects=True) dump('invite_grant_invalid_invite', r) self.assertEqual(r.status_code, 200) self.assertFalse(Invite.query.filter_by(token=token).first().used) def test_grant_no_roles(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60)) db.session.add(invite) db.session.commit() token = invite.token self.login_user() r = self.client.post(path=url_for('invite.grant', token=token), follow_redirects=True) dump('invite_grant_no_roles', r) self.assertEqual(r.status_code, 200) self.assertFalse(Invite.query.filter_by(token=token).first().used) def test_grant_no_new_roles(self): user = User.query.get('uid=testuser,ou=users,dc=example,dc=com') role = Role(name='testrole') db.session.add(role) user.roles.add(role) invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), roles=[role]) db.session.add(invite) db.session.commit() token = invite.token self.login_user() r = self.client.post(path=url_for('invite.grant', token=token), follow_redirects=True) dump('invite_grant_no_new_roles', r) self.assertEqual(r.status_code, 200) self.assertFalse(Invite.query.filter_by(token=token).first().used) def test_signup(self): self.app.config['ROLES_BASEROLES'] = ['base'] baserole = Role(name='base') baserole.groups.add(Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')) baserole.groups.add(Group.query.get('cn=users,ou=groups,dc=example,dc=com')) db.session.add(baserole) group = Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com') role1 = Role(name='testrole1', groups=[group]) db.session.add(role1) role2 = Role(name='testrole2') db.session.add(role2) invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), roles=[role1, role2], allow_signup=True) db.session.add(invite) db.session.commit() token = invite.token r = self.client.get(path=url_for('invite.signup_start', token=token), follow_redirects=True) dump('invite_signup_start', r) self.assertEqual(r.status_code, 200) r = self.client.post(path=url_for('invite.signup_submit', token=token), data={'loginname': 'newuser', 'displayname': 'New User', 'mail': 'test@example.com', 'password1': 'notsecret', 'password2': 'notsecret'}, follow_redirects=True) dump('invite_signup_submit', r) self.assertEqual(r.status_code, 200) signup = InviteSignup.query.one() self.assertEqual(signup.loginname, 'newuser') self.assertEqual(signup.displayname, 'New User') self.assertEqual(signup.mail, 'test@example.com') self.assertIn(signup.token, str(self.app.last_mail.get_content())) self.assertTrue(signup.check_password('notsecret')) self.assertTrue(signup.validate()[0]) def test_signup_invalid_invite(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True, disabled=True) db.session.add(invite) db.session.commit() r = self.client.get(path=url_for('invite.signup_start', token=invite.token), follow_redirects=True) dump('invite_signup_invalid_invite', r) self.assertEqual(r.status_code, 200) def test_signup_nosignup(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=False) db.session.add(invite) db.session.commit() r = self.client.get(path=url_for('invite.signup_start', token=invite.token), follow_redirects=True) dump('invite_signup_nosignup', r) self.assertEqual(r.status_code, 200) def test_signup_wrongpassword(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True) db.session.add(invite) db.session.commit() r = self.client.post(path=url_for('invite.signup_submit', token=invite.token), data={'loginname': 'newuser', 'displayname': 'New User', 'mail': 'test@example.com', 'password1': 'notsecret', 'password2': 'notthesame'}, follow_redirects=True) dump('invite_signup_wrongpassword', r) self.assertEqual(r.status_code, 200) def test_signup_invalid(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True) db.session.add(invite) db.session.commit() r = self.client.post(path=url_for('invite.signup_submit', token=invite.token), data={'loginname': '', 'displayname': 'New User', 'mail': 'test@example.com', 'password1': 'notsecret', 'password2': 'notsecret'}, follow_redirects=True) dump('invite_signup_invalid', r) self.assertEqual(r.status_code, 200) def test_signup_mailerror(self): self.app.config['MAIL_SKIP_SEND'] = 'fail' invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True) db.session.add(invite) db.session.commit() r = self.client.post(path=url_for('invite.signup_submit', token=invite.token), data={'loginname': 'newuser', 'displayname': 'New User', 'mail': 'test@example.com', 'password1': 'notsecret', 'password2': 'notsecret'}, follow_redirects=True) dump('invite_signup_mailerror', r) self.assertEqual(r.status_code, 200) def test_signup_hostlimit(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True) db.session.add(invite) db.session.commit() token = invite.token for i in range(20): r = self.client.post(path=url_for('invite.signup_submit', token=token), data={'loginname': 'newuser%d'%i, 'displayname': 'New User', 'mail': 'test%d@example.com'%i, 'password1': 'notsecret', 'password2': 'notsecret'}, follow_redirects=True) self.assertEqual(r.status_code, 200) self.app.last_mail = None r = self.client.post(path=url_for('invite.signup_submit', token=token), data={'loginname': 'newuser', 'displayname': 'New User', 'mail': 'test@example.com', 'password1': 'notsecret', 'password2': 'notsecret'}, follow_redirects=True) dump('invite_signup_hostlimit', r) self.assertEqual(r.status_code, 200) self.assertEqual(InviteSignup.query.filter_by(loginname='newuser').all(), []) self.assertIsNone(self.app.last_mail) def test_signup_mailimit(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True) db.session.add(invite) db.session.commit() token = invite.token for i in range(3): r = self.client.post(path=url_for('invite.signup_submit', token=token), data={'loginname': 'newuser%d'%i, 'displayname': 'New User', 'mail': 'test@example.com', 'password1': 'notsecret', 'password2': 'notsecret'}, follow_redirects=True) self.assertEqual(r.status_code, 200) self.app.last_mail = None r = self.client.post(path=url_for('invite.signup_submit', token=token), data={'loginname': 'newuser', 'displayname': 'New User', 'mail': 'test@example.com', 'password1': 'notsecret', 'password2': 'notsecret'}, follow_redirects=True) dump('invite_signup_maillimit', r) self.assertEqual(r.status_code, 200) self.assertEqual(InviteSignup.query.filter_by(loginname='newuser').all(), []) self.assertIsNone(self.app.last_mail) def test_signup_check(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True) db.session.add(invite) db.session.commit() token = invite.token r = self.client.post(path=url_for('invite.signup_check', token=token), follow_redirects=True, data={'loginname': 'newuser'}) self.assertEqual(r.status_code, 200) self.assertEqual(r.content_type, 'application/json') self.assertEqual(r.json['status'], 'ok') def test_signup_check_invalid(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True) db.session.add(invite) db.session.commit() token = invite.token r = self.client.post(path=url_for('invite.signup_check', token=token), follow_redirects=True, data={'loginname': ''}) self.assertEqual(r.status_code, 200) self.assertEqual(r.content_type, 'application/json') self.assertEqual(r.json['status'], 'invalid') def test_signup_check_exists(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True) db.session.add(invite) db.session.commit() token = invite.token r = self.client.post(path=url_for('invite.signup_check', token=token), follow_redirects=True, data={'loginname': 'testuser'}) self.assertEqual(r.status_code, 200) self.assertEqual(r.content_type, 'application/json') self.assertEqual(r.json['status'], 'exists') def test_signup_check_nosignup(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=False) db.session.add(invite) db.session.commit() token = invite.token r = self.client.post(path=url_for('invite.signup_check', token=token), follow_redirects=True, data={'loginname': 'testuser'}) self.assertEqual(r.status_code, 403) self.assertEqual(r.content_type, 'application/json') self.assertEqual(r.json['status'], 'error') def test_signup_check_error(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True, disabled=True) db.session.add(invite) db.session.commit() token = invite.token r = self.client.post(path=url_for('invite.signup_check', token=token), follow_redirects=True, data={'loginname': 'testuser'}) self.assertEqual(r.status_code, 403) self.assertEqual(r.content_type, 'application/json') self.assertEqual(r.json['status'], 'error') def test_signup_check_ratelimited(self): invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True) db.session.add(invite) db.session.commit() token = invite.token for i in range(20): r = self.client.post(path=url_for('invite.signup_check', token=token), follow_redirects=True, data={'loginname': 'testuser'}) self.assertEqual(r.status_code, 200) self.assertEqual(r.content_type, 'application/json') r = self.client.post(path=url_for('invite.signup_check', token=token), follow_redirects=True, data={'loginname': 'testuser'}) self.assertEqual(r.status_code, 200) self.assertEqual(r.content_type, 'application/json') self.assertEqual(r.json['status'], 'ratelimited') class TestInviteUseViewsOL(TestInviteUseViews): use_openldap = True