diff --git a/migrations/versions/aff5f350dcdf_added_role_is_default.py b/migrations/versions/aff5f350dcdf_added_role_is_default.py new file mode 100644 index 0000000000000000000000000000000000000000..b903fbd7078d2bedc91c9ffe3adb99de1f98583e --- /dev/null +++ b/migrations/versions/aff5f350dcdf_added_role_is_default.py @@ -0,0 +1,23 @@ +"""added role.is_default + +Revision ID: aff5f350dcdf +Revises: a594d3b3e05b +Create Date: 2021-06-15 21:24:13.158828 + +""" +from alembic import op +import sqlalchemy as sa + +# revision identifiers, used by Alembic. +revision = 'aff5f350dcdf' +down_revision = 'a594d3b3e05b' +branch_labels = None +depends_on = None + +def upgrade(): + with op.batch_alter_table('role', schema=None) as batch_op: + batch_op.add_column(sa.Column('is_default', sa.Boolean(name=op.f('ck_role_is_default')), nullable=False, default=False)) + +def downgrade(): + with op.batch_alter_table('role', schema=None) as batch_op: + batch_op.drop_column('is_default') diff --git a/tests/test_invite.py b/tests/test_invite.py index c21a15c16d370febac1744212ae77216fb7ac108..8d4b777362b9da9dc0376ed99a63cc00699aed1a 100644 --- a/tests/test_invite.py +++ b/tests/test_invite.py @@ -131,7 +131,7 @@ class TestInviteGrantModel(UffdTestCase): 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('baserole', [role.name for role in user.roles_recursive]) 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]) @@ -174,8 +174,7 @@ class TestInviteGrantModel(UffdTestCase): class TestInviteSignupModel(UffdTestCase): def create_base_roles(self): - self.app.config['ROLES_BASEROLES'] = ['base'] - baserole = Role(name='base') + baserole = Role(name='base', is_default=True) 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) @@ -204,7 +203,7 @@ class TestInviteSignupModel(UffdTestCase): 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(base_role, user.roles_recursive) self.assertIn(role1, user.roles) self.assertIn(role2, user.roles) self.assertIn(base_group1, user.groups) @@ -233,8 +232,8 @@ class TestInviteSignupModel(UffdTestCase): 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_role, user.roles_recursive) + self.assertEqual(len(user.roles_recursive), 1) self.assertIn(base_group1, user.groups) self.assertIn(base_group2, user.groups) self.assertEqual(len(user.groups), 2) @@ -637,8 +636,7 @@ class TestInviteUseViews(UffdTestCase): 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 = Role(name='base', is_default=True) 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) diff --git a/tests/test_role.py b/tests/test_role.py index 74f4550e02ca06e2dc29b4727af651b2196cfc6a..4cadd82d532642b8665a418fb15890da4a57a160 100644 --- a/tests/test_role.py +++ b/tests/test_role.py @@ -4,7 +4,8 @@ import time from flask import url_for, session # These imports are required, because otherwise we get circular imports?! -from uffd import ldap, user +from uffd.ldap import ldap +from uffd import user from uffd.user.models import User, Group from uffd.role.models import Role @@ -16,13 +17,14 @@ class TestUserRoleAttributes(UffdTestCase): def test_roles_recursive(self): user1 = User.query.get('uid=testuser,ou=users,dc=example,dc=com') user1.update_groups() - baserole = Role(name='base') - role1 = Role(name='role1', members=[user1], included_roles=[baserole]) - role2 = Role(name='role2', included_roles=[baserole]) - db.session.add_all([baserole, role1, role2]) - self.assertSetEqual(user1.roles_recursive, {baserole, role1}) - baserole.included_roles.append(role2) - self.assertSetEqual(user1.roles_recursive, {baserole, role1, role2}) + included_role = Role(name='included') + default_role = Role(name='default', is_default=True) + role1 = Role(name='role1', members=[user1], included_roles=[included_role]) + role2 = Role(name='role2', included_roles=[included_role]) + db.session.add_all([included_role, default_role, role1, role2]) + self.assertSetEqual(user1.roles_recursive, {included_role, default_role, role1}) + included_role.included_roles.append(role2) + self.assertSetEqual(user1.roles_recursive, {included_role, default_role, role1, role2}) def test_update_groups(self): user1 = User.query.get('uid=testuser,ou=users,dc=example,dc=com') @@ -42,12 +44,12 @@ class TestUserRoleAttributes(UffdTestCase): class TestRoleModel(UffdTestCase): def test_indirect_members(self): user1 = User.query.get('uid=testuser,ou=users,dc=example,dc=com') - user1.update_groups() user2 = User.query.get('uid=testadmin,ou=users,dc=example,dc=com') - user2.update_groups() - baserole = Role(name='base', members=[user1]) - role1 = Role(name='role1', included_roles=[baserole], members=[user2]) - self.assertSetEqual(baserole.indirect_members, {user2}) + included_role = Role(name='included', members=[user1]) + default_role = Role(name='default', is_default=True) + role1 = Role(name='role1', included_roles=[included_role], members=[user2]) + self.assertSetEqual(included_role.indirect_members, {user2}) + self.assertSetEqual(default_role.indirect_members, {user1, user2}) self.assertSetEqual(role1.indirect_members, set()) def test_included_roles_recursive(self): @@ -184,5 +186,65 @@ class TestRoleViews(UffdTestCase): self.assertIsNone(Role.query.get(role_id)) # TODO: verify that group memberships are updated (currently not possible with ldap mock!) + def test_set_default(self): + for user in User.query.filter_by(loginname='service').all(): + ldap.session.delete(user) + ldap.session.add(User(loginname='service', is_service_user=True, mail='service@example.com', displayname='Service')) + ldap.session.commit() + role = Role(name='test') + db.session.add(role) + user1 = User.query.get('uid=testuser,ou=users,dc=example,dc=com') + user2 = User.query.get('uid=testadmin,ou=users,dc=example,dc=com') + service_user = User.query.get('uid=service,ou=users,dc=example,dc=com') + self.assertSetEqual(set(user1.roles_recursive), set()) + self.assertSetEqual(set(user2.roles_recursive), set()) + self.assertSetEqual(set(service_user.roles_recursive), set()) + role.members.add(user1) + role.members.add(service_user) + self.assertSetEqual(set(user1.roles_recursive), {role}) + self.assertSetEqual(set(user2.roles_recursive), set()) + self.assertSetEqual(set(service_user.roles_recursive), {role}) + db.session.commit() + role_id = role.id + self.assertSetEqual(set(role.members), {user1, service_user}) + r = self.client.get(path=url_for('role.set_default', roleid=role.id), follow_redirects=True) + dump('role_set_default', r) + self.assertEqual(r.status_code, 200) + role = Role.query.get(role_id) + service_user = User.query.get('uid=service,ou=users,dc=example,dc=com') + self.assertSetEqual(set(role.members), {service_user}) + self.assertSetEqual(set(user1.roles_recursive), {role}) + self.assertSetEqual(set(user2.roles_recursive), {role}) + ldap.session.delete(service_user) + ldap.session.commit() + + def test_unset_default(self): + for user in User.query.filter_by(loginname='service').all(): + ldap.session.delete(user) + ldap.session.add(User(loginname='service', is_service_user=True, mail='service@example.com', displayname='Service')) + ldap.session.commit() + role = Role(name='test', is_default=True) + db.session.add(role) + user1 = User.query.get('uid=testuser,ou=users,dc=example,dc=com') + user2 = User.query.get('uid=testadmin,ou=users,dc=example,dc=com') + service_user = User.query.get('uid=service,ou=users,dc=example,dc=com') + role.members.add(service_user) + self.assertSetEqual(set(user1.roles_recursive), {role}) + self.assertSetEqual(set(user2.roles_recursive), {role}) + self.assertSetEqual(set(service_user.roles_recursive), {role}) + db.session.commit() + role_id = role.id + self.assertSetEqual(set(role.members), {service_user}) + r = self.client.get(path=url_for('role.unset_default', roleid=role.id), follow_redirects=True) + dump('role_unset_default', r) + self.assertEqual(r.status_code, 200) + role = Role.query.get(role_id) + service_user = User.query.get('uid=service,ou=users,dc=example,dc=com') + self.assertSetEqual(set(role.members), {service_user}) + self.assertSetEqual(set(user1.roles_recursive), set()) + self.assertSetEqual(set(user2.roles_recursive), set()) + ldap.session.delete(service_user) + ldap.session.commit() + class TestRoleViewsOL(TestRoleViews): use_openldap = True diff --git a/tests/test_user.py b/tests/test_user.py index f9fb574b7f5d1f66308d59878d7d24104307278a..e2e03de35b495e9cec6c024919090107efd363c9 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -67,7 +67,7 @@ class TestUserViews(UffdTestCase): self.assertEqual(r.status_code, 200) def test_new(self): - db.session.add(Role(name='base')) + db.session.add(Role(name='base', is_default=True)) role1 = Role(name='role1') db.session.add(role1) role2 = Role(name='role2') @@ -84,7 +84,7 @@ class TestUserViews(UffdTestCase): dump('user_new_submit', r) self.assertEqual(r.status_code, 200) user = User.query.get('uid=newuser,ou=users,dc=example,dc=com') - roles = sorted([r.name for r in user.roles]) + roles = sorted([r.name for r in user.roles_recursive]) self.assertIsNotNone(user) self.assertFalse(user.is_service_user) self.assertEqual(user.loginname, 'newuser') @@ -97,7 +97,7 @@ class TestUserViews(UffdTestCase): #self.assertTrue(ldap.test_user_bind(user.dn, 'newpassword')) def test_new_service(self): - db.session.add(Role(name='base')) + db.session.add(Role(name='base', is_default=True)) role1 = Role(name='role1') db.session.add(role1) role2 = Role(name='role2') @@ -160,7 +160,7 @@ class TestUserViews(UffdTestCase): def test_update(self): user = get_user() - db.session.add(Role(name='base')) + db.session.add(Role(name='base', is_default=True)) role1 = Role(name='role1') db.session.add(role1) role2 = Role(name='role2') @@ -177,7 +177,7 @@ class TestUserViews(UffdTestCase): dump('user_update_submit', r) self.assertEqual(r.status_code, 200) _user = get_user() - roles = sorted([r.name for r in _user.roles]) + roles = sorted([r.name for r in _user.roles_recursive]) self.assertEqual(_user.displayname, 'New User') self.assertEqual(_user.mail, 'newuser@example.com') self.assertEqual(_user.uid, user.uid) @@ -261,7 +261,6 @@ class TestUserViews(UffdTestCase): self.assertIsNone(get_user()) def test_csvimport(self): - db.session.add(Role(name='base')) role1 = Role(name='role1') db.session.add(role1) role2 = Role(name='role2') @@ -293,42 +292,42 @@ newuser12,newuser12@example.com,{role1.id};{role1.id} self.assertEqual(user.displayname, 'newuser1') self.assertEqual(user.mail, 'newuser1@example.com') roles = sorted([r.name for r in user.roles]) - self.assertEqual(roles, ['base']) + self.assertEqual(roles, []) user = User.query.get('uid=newuser2,ou=users,dc=example,dc=com') self.assertIsNotNone(user) self.assertEqual(user.loginname, 'newuser2') self.assertEqual(user.displayname, 'newuser2') self.assertEqual(user.mail, 'newuser2@example.com') roles = sorted([r.name for r in user.roles]) - self.assertEqual(roles, ['base', 'role1']) + self.assertEqual(roles, ['role1']) user = User.query.get('uid=newuser3,ou=users,dc=example,dc=com') self.assertIsNotNone(user) self.assertEqual(user.loginname, 'newuser3') self.assertEqual(user.displayname, 'newuser3') self.assertEqual(user.mail, 'newuser3@example.com') roles = sorted([r.name for r in user.roles]) - self.assertEqual(roles, ['base', 'role1', 'role2']) + self.assertEqual(roles, ['role1', 'role2']) user = User.query.get('uid=newuser4,ou=users,dc=example,dc=com') self.assertIsNotNone(user) self.assertEqual(user.loginname, 'newuser4') self.assertEqual(user.displayname, 'newuser4') self.assertEqual(user.mail, 'newuser4@example.com') roles = sorted([r.name for r in user.roles]) - self.assertEqual(roles, ['base']) + self.assertEqual(roles, []) user = User.query.get('uid=newuser5,ou=users,dc=example,dc=com') self.assertIsNotNone(user) self.assertEqual(user.loginname, 'newuser5') self.assertEqual(user.displayname, 'newuser5') self.assertEqual(user.mail, 'newuser5@example.com') roles = sorted([r.name for r in user.roles]) - self.assertEqual(roles, ['base']) + self.assertEqual(roles, []) user = User.query.get('uid=newuser6,ou=users,dc=example,dc=com') self.assertIsNotNone(user) self.assertEqual(user.loginname, 'newuser6') self.assertEqual(user.displayname, 'newuser6') self.assertEqual(user.mail, 'newuser6@example.com') roles = sorted([r.name for r in user.roles]) - self.assertEqual(roles, ['base', 'role1', 'role2']) + self.assertEqual(roles, ['role1', 'role2']) self.assertIsNone(User.query.get('uid=newuser7,ou=users,dc=example,dc=com')) self.assertIsNone(User.query.get('uid=newuser8,ou=users,dc=example,dc=com')) self.assertIsNone(User.query.get('uid=newuser9,ou=users,dc=example,dc=com')) @@ -338,7 +337,7 @@ newuser12,newuser12@example.com,{role1.id};{role1.id} self.assertEqual(user.displayname, 'newuser10') self.assertEqual(user.mail, 'newuser10@example.com') roles = sorted([r.name for r in user.roles]) - self.assertEqual(roles, ['base']) + self.assertEqual(roles, []) user = User.query.get('uid=newuser11,ou=users,dc=example,dc=com') self.assertIsNotNone(user) self.assertEqual(user.loginname, 'newuser11') @@ -346,15 +345,15 @@ newuser12,newuser12@example.com,{role1.id};{role1.id} self.assertEqual(user.mail, 'newuser11@example.com') # Currently the csv import is not very robust, imho newuser11 should have role1 and role2! roles = sorted([r.name for r in user.roles]) - #self.assertEqual(roles, ['base', 'role1', 'role2']) - self.assertEqual(roles, ['base', 'role2']) + #self.assertEqual(roles, ['role1', 'role2']) + self.assertEqual(roles, ['role2']) user = User.query.get('uid=newuser12,ou=users,dc=example,dc=com') self.assertIsNotNone(user) self.assertEqual(user.loginname, 'newuser12') self.assertEqual(user.displayname, 'newuser12') self.assertEqual(user.mail, 'newuser12@example.com') roles = sorted([r.name for r in user.roles]) - self.assertEqual(roles, ['base', 'role1']) + self.assertEqual(roles, ['role1']) class TestUserViewsOL(TestUserViews): use_openldap = True @@ -390,7 +389,7 @@ class TestUserViewsOLUserAsUser(UffdTestCase): def test_update_other_user(self): user_ = get_admin() - db.session.add(Role(name='base')) + db.session.add(Role(name='base', is_default=True)) role1 = Role(name='role1') db.session.add(role1) role2 = Role(name='role2') @@ -413,7 +412,7 @@ class TestUserViewsOLUserAsUser(UffdTestCase): self.assertEqual(_user.loginname, user_.loginname) def test_new(self): - db.session.add(Role(name='base')) + db.session.add(Role(name='base', is_default=True)) role1 = Role(name='role1') db.session.add(role1) role2 = Role(name='role2') diff --git a/uffd/default_config.cfg b/uffd/default_config.cfg index 022657fe3cfac6311f35881939c54b95f2697863..61a93cd1b40385e09eab223b2baa98f538631efe 100644 --- a/uffd/default_config.cfg +++ b/uffd/default_config.cfg @@ -79,8 +79,6 @@ LOGINNAME_BLACKLIST=['^admin$', '^root$'] #MFA_RP_ID = 'example.com' # If unset, hostname from current request is used MFA_RP_NAME = 'Uffd Test Service' # Service name passed to U2F/FIDO2 authenticators -ROLES_BASEROLES=['base'] - SQLALCHEMY_TRACK_MODIFICATIONS=False FOOTER_LINKS=[{"url": "https://example.com", "title": "example"}] diff --git a/uffd/invite/models.py b/uffd/invite/models.py index 47826cd06f43944939df29780212656f7a73b2ed..876984556183f56d6b8369204ab9411ab808f1d0 100644 --- a/uffd/invite/models.py +++ b/uffd/invite/models.py @@ -113,7 +113,6 @@ class InviteSignup(Signup): return None, 'Invite link is invalid' user, msg = super().finish(password) if user is not None: - # super().finish() already added ROLES_BASEROLES for role in self.invite.roles: user.roles.add(role) user.update_groups() diff --git a/uffd/invite/templates/invite/new.html b/uffd/invite/templates/invite/new.html index a27d50d6d00f2517700f298963fc653d3d82071f..c6731bd8285a024197a177fab0a86a46784ec850 100644 --- a/uffd/invite/templates/invite/new.html +++ b/uffd/invite/templates/invite/new.html @@ -37,7 +37,7 @@ </tr> </thead> <tbody> - {% for role in roles|sort(attribute="name") if role.name not in config['ROLES_BASEROLES'] %} + {% for role in roles|sort(attribute="name") if not role.is_default %} <tr> <td> <div class="form-check"> diff --git a/uffd/role/models.py b/uffd/role/models.py index dad00f53800a3115812f8d57e4d718c5dcb06240..f8bce7566aec0661af94239fa059d8045ac4eb95 100644 --- a/uffd/role/models.py +++ b/uffd/role/models.py @@ -51,7 +51,10 @@ def flatten_recursive(objs, attr): return objs def get_roles_recursive(user): - return flatten_recursive(user.roles, 'included_roles') + base = set(user.roles) + if not user.is_service_user: + base.update(Role.query.filter_by(is_default=True)) + return flatten_recursive(base, 'included_roles') User.roles_recursive = property(get_roles_recursive) @@ -96,11 +99,17 @@ class Role(db.Model): # and groups as well as deletion in the web interface. locked = Column(Boolean(), default=False, nullable=False) + is_default = Column(Boolean(), default=False, nullable=False) + @property def indirect_members(self): users = set() for role in flatten_recursive(self.including_roles, 'including_roles'): users.update(role.members) + if self.is_default: + for user in User.query.all(): + if not user.is_service_user: + users.add(user) return users @property diff --git a/uffd/role/templates/role/show.html b/uffd/role/templates/role/show.html index 81d96395bdf6b8f5c2580acd42fb0ea7948d4b52..db2c38109ed97dbbd2e615d9e067cda611b628cc 100644 --- a/uffd/role/templates/role/show.html +++ b/uffd/role/templates/role/show.html @@ -13,8 +13,14 @@ Name, moderator group, included roles and groups of this role are managed extern <button type="submit" class="btn btn-primary"><i class="fa fa-save" aria-hidden="true"></i> Save</button> <a href="{{ url_for("role.index") }}" class="btn btn-secondary">Cancel</a> {% if role.id %} + {% if not role.is_default %} + <a href="{{ url_for("role.set_default", roleid=role.id) }}" onClick="return confirm('All non-service users will be removed as members from this role and get its permissions implicitly. Are you sure?');" class="btn btn-secondary">Set as default</a> + {% else %} + <a href="{{ url_for("role.unset_default", roleid=role.id) }}" onClick="return confirm('Are you sure?');" class="btn btn-secondary">Unset as default</a> + {% endif %} <a href="{{ url_for("role.delete", roleid=role.id) }}" onClick="return confirm('Are you sure?');" class="btn btn-danger {{ 'disabled' if role.locked }}"><i class="fa fa-trash" aria-hidden="true"></i> Delete</a> {% else %} + <a href="#" class="btn btn-secondary disabled">Set as default</a> <a href="#" class="btn btn-danger disabled"><i class="fa fa-trash" aria-hidden="true"></i> Delete</a> {% endif %} </div> diff --git a/uffd/role/views.py b/uffd/role/views.py index a613a191522abe99499b860c20d98954cd8a68c8..3036a86d3990939c172a9d89ab912ae9b165a3c0 100644 --- a/uffd/role/views.py +++ b/uffd/role/views.py @@ -116,3 +116,33 @@ def unlock(roleid): role.locked = False db.session.commit() return redirect(url_for('role.show', roleid=role.id)) + +@bp.route("/<int:roleid>/setdefault") +@csrf_protect(blueprint=bp) +def set_default(roleid): + role = Role.query.filter_by(id=roleid).one() + if role.is_default: + return redirect(url_for('role.show', roleid=role.id)) + role.is_default = True + for user in set(role.members): + if not user.is_service_user: + role.members.discard(user) + role.update_member_groups() + db.session.commit() + ldap.session.commit() + return redirect(url_for('role.show', roleid=role.id)) + +@bp.route("/<int:roleid>/unsetdefault") +@csrf_protect(blueprint=bp) +def unset_default(roleid): + role = Role.query.filter_by(id=roleid).one() + if not role.is_default: + return redirect(url_for('role.show', roleid=role.id)) + old_members = set(role.members).union(role.indirect_members) + role.is_default = False + for user in old_members: + if not user.is_service_user: + user.update_groups() + db.session.commit() + ldap.session.commit() + return redirect(url_for('role.show', roleid=role.id)) diff --git a/uffd/selfservice/templates/selfservice/self.html b/uffd/selfservice/templates/selfservice/self.html index 8d328be7a8a01f97266b872f822b7d36278443d1..85d7b9033418f8dfbe793aad8e7a665a891737ce 100644 --- a/uffd/selfservice/templates/selfservice/self.html +++ b/uffd/selfservice/templates/selfservice/self.html @@ -48,7 +48,7 @@ You currently have these roles: {% endif %} <ul> - {% for role in user.roles|sort(attribute="name") if role.name not in config["ROLES_BASEROLES"] %} + {% for role in user.roles|sort(attribute="name") %} <li>{{ role.name }}</li> {% endfor %} </ul> diff --git a/uffd/signup/models.py b/uffd/signup/models.py index 2fabc8e587766a5f6f4e0f98ae83d410369cf2f1..7c8dd6658fd8286b80de2c394e7dbc531c490ffd 100644 --- a/uffd/signup/models.py +++ b/uffd/signup/models.py @@ -2,14 +2,12 @@ import secrets import datetime from crypt import crypt -from flask import current_app from sqlalchemy import Column, String, Text, DateTime from ldapalchemy.dbutils import DBRelationship from uffd.database import db from uffd.ldap import ldap from uffd.user.models import User -from uffd.role.models import Role class Signup(db.Model): '''Model that represents a self-signup request @@ -100,9 +98,6 @@ class Signup(db.Model): return None, 'A user with this login name already exists' user = User(loginname=self.loginname, displayname=self.displayname, mail=self.mail, password=password) ldap.session.add(user) - for name in current_app.config['ROLES_BASEROLES']: - for role in Role.query.filter_by(name=name).all(): - user.roles.add(role) user.update_groups() self.user = user self.loginname = None diff --git a/uffd/user/templates/user/list.html b/uffd/user/templates/user/list.html index 93d7da5264b7e5e1625ed6f724bd9f2e7cff23d3..a6854d9f54e417e0d36457f359661e5c92d41f2b 100644 --- a/uffd/user/templates/user/list.html +++ b/uffd/user/templates/user/list.html @@ -38,7 +38,7 @@ {{ user.displayname }} </td> <td> - {% for role in user.roles|sort(attribute="name") if not role.name in config["ROLES_BASEROLES"] or user.is_service_user %} + {% for role in user.roles|sort(attribute="name") %} <a href="{{ url_for("role.show", roleid=role.id) }}">{{ role.name }}</a>{% if not loop.last %}, {% endif %} {% endfor %} </td> diff --git a/uffd/user/templates/user/show.html b/uffd/user/templates/user/show.html index d638f7fc287820a287189010c48f7e6577b96849..1511e74b7d305a532bfe1580972134c8430dbc6c 100644 --- a/uffd/user/templates/user/show.html +++ b/uffd/user/templates/user/show.html @@ -106,7 +106,7 @@ <div class="form-check"> <input class="form-check-input" type="checkbox" id="role-{{ role.id }}-checkbox" name="role-{{ role.id }}" value="1" aria-label="enabled" {% if user in role.members %}checked {% endif %} - {% if role.name in config["ROLES_BASEROLES"] and not user.is_service_user %}disabled {% endif %}> + {% if role.is_default and not user.is_service_user %}disabled {% endif %}> </div> </td> <td> diff --git a/uffd/user/views_user.py b/uffd/user/views_user.py index a76beceb53ff8defc75b62b74db756ec9dbc981a..193a3507c2537f6e522ff8612bd0a88aa5dab09c 100644 --- a/uffd/user/views_user.py +++ b/uffd/user/views_user.py @@ -62,10 +62,10 @@ def update(uid=None): ldap.session.add(user) user.roles.clear() for role in Role.query.all(): + if not user.is_service_user and role.is_default: + continue if request.values.get('role-{}'.format(role.id), False): user.roles.add(role) - elif not user.is_service_user and role.name in current_app.config["ROLES_BASEROLES"]: - user.roles.add(role) user.update_groups() ldap.session.commit() db.session.commit() @@ -100,7 +100,7 @@ def csvimport(): ignore_blacklist = request.values.get('ignore-loginname-blacklist', False) - roles = Role.query.all() + roles = Role.query.filter_by(is_default=False).all() usersadded = 0 with io.StringIO(initial_value=csvdata) as csvfile: csvreader = csv.reader(csvfile) @@ -117,7 +117,7 @@ def csvimport(): continue ldap.session.add(newuser) for role in roles: - if (str(role.id) in row[2].split(';')) or role.name in current_app.config["ROLES_BASEROLES"]: + if str(role.id) in row[2].split(';'): role.members.add(newuser) newuser.update_groups() try: