forked from Github-Mirrors/canaille
Renamed group attributes to match SCIM naming convention
This commit is contained in:
parent
41edb53ff4
commit
3406428f13
14 changed files with 58 additions and 47 deletions
|
@ -334,7 +334,7 @@ def registration(data, hash):
|
|||
if "groups" not in form and invitation.groups:
|
||||
form["groups"] = wtforms.SelectMultipleField(
|
||||
_("Groups"),
|
||||
choices=[(group.id, group.name) for group in Group.query()],
|
||||
choices=[(group.id, group.display_name) for group in Group.query()],
|
||||
render_kw={"readonly": "true"},
|
||||
)
|
||||
form.process(CombinedMultiDict((request.files, request.form)) or None, data=data)
|
||||
|
|
|
@ -235,7 +235,7 @@ def profile_form(write_field_names, readonly_field_names):
|
|||
if "groups" in write_field_names | readonly_field_names and Group.query():
|
||||
fields["groups"] = wtforms.SelectMultipleField(
|
||||
_("Groups"),
|
||||
choices=[(group.id, group.name) for group in Group.query()],
|
||||
choices=[(group.id, group.display_name) for group in Group.query()],
|
||||
render_kw={"placeholder": _("users, admins …")},
|
||||
)
|
||||
|
||||
|
@ -248,7 +248,7 @@ def profile_form(write_field_names, readonly_field_names):
|
|||
|
||||
|
||||
class CreateGroupForm(FlaskForm):
|
||||
name = wtforms.StringField(
|
||||
display_name = wtforms.StringField(
|
||||
_("Name"),
|
||||
validators=[wtforms.validators.DataRequired(), unique_group],
|
||||
render_kw={
|
||||
|
@ -262,7 +262,7 @@ class CreateGroupForm(FlaskForm):
|
|||
|
||||
|
||||
class EditGroupForm(FlaskForm):
|
||||
name = wtforms.StringField(
|
||||
display_name = wtforms.StringField(
|
||||
_("Name"),
|
||||
validators=[wtforms.validators.DataRequired()],
|
||||
render_kw={
|
||||
|
@ -297,6 +297,6 @@ class InvitationForm(FlaskForm):
|
|||
)
|
||||
groups = wtforms.SelectMultipleField(
|
||||
_("Groups"),
|
||||
choices=lambda: [(group.id, group.name) for group in Group.query()],
|
||||
choices=lambda: [(group.id, group.display_name) for group in Group.query()],
|
||||
render_kw={},
|
||||
)
|
||||
|
|
|
@ -38,15 +38,18 @@ def create_group(user):
|
|||
flash(_("Group creation failed."), "error")
|
||||
else:
|
||||
group = Group()
|
||||
group.member = [user]
|
||||
group.cn = [form.name.data]
|
||||
group.members = [user]
|
||||
group.display_name = [form.display_name.data]
|
||||
group.description = [form.description.data]
|
||||
group.save()
|
||||
flash(
|
||||
_("The group %(group)s has been sucessfully created", group=group.name),
|
||||
_(
|
||||
"The group %(group)s has been sucessfully created",
|
||||
group=group.display_name,
|
||||
),
|
||||
"success",
|
||||
)
|
||||
return redirect(url_for("groups.group", groupname=group.name))
|
||||
return redirect(url_for("groups.group", groupname=group.display_name))
|
||||
|
||||
return render_template("group.html", form=form, edited_group=None, members=None)
|
||||
|
||||
|
@ -80,7 +83,7 @@ def edit_group(group):
|
|||
form = EditGroupForm(
|
||||
request.form or None,
|
||||
data={
|
||||
"name": group.name,
|
||||
"display_name": group.display_name,
|
||||
"description": group.description[0] if group.description else "",
|
||||
},
|
||||
)
|
||||
|
@ -90,10 +93,13 @@ def edit_group(group):
|
|||
group.description = [form.description.data]
|
||||
group.save()
|
||||
flash(
|
||||
_("The group %(group)s has been sucessfully edited.", group=group.name),
|
||||
_(
|
||||
"The group %(group)s has been sucessfully edited.",
|
||||
group=group.display_name,
|
||||
),
|
||||
"success",
|
||||
)
|
||||
return redirect(url_for("groups.group", groupname=group.name))
|
||||
return redirect(url_for("groups.group", groupname=group.display_name))
|
||||
else:
|
||||
flash(_("Group edition failed."), "error")
|
||||
|
||||
|
@ -108,7 +114,7 @@ def edit_group(group):
|
|||
|
||||
def delete_group(group):
|
||||
flash(
|
||||
_("The group %(group)s has been sucessfully deleted", group=group.name),
|
||||
_("The group %(group)s has been sucessfully deleted", group=group.display_name),
|
||||
"success",
|
||||
)
|
||||
group.delete()
|
||||
|
|
|
@ -154,8 +154,8 @@ def validate_configuration(config):
|
|||
user.save(conn)
|
||||
|
||||
group = Group(
|
||||
cn=f"canaille_{uuid.uuid4()}",
|
||||
member=[user],
|
||||
display_name=f"canaille_{uuid.uuid4()}",
|
||||
members=[user],
|
||||
)
|
||||
group.save(conn)
|
||||
group.delete(conn)
|
||||
|
|
|
@ -111,8 +111,10 @@ class LDAPObject(metaclass=LDAPObjectMetaclass):
|
|||
setattr(self, name, value)
|
||||
|
||||
def __repr__(self):
|
||||
reverse_attributes = {v: k for k, v in (self.attribute_table or {}).items()}
|
||||
attribute_name = reverse_attributes.get(self.rdn_attribute, self.rdn_attribute)
|
||||
return (
|
||||
f"<{self.__class__.__name__} {self.rdn_attribute}={self.rdn_value}>"
|
||||
f"<{self.__class__.__name__} {attribute_name}={self.rdn_value}>"
|
||||
if self.rdn_attribute
|
||||
else "<LDAPOBject>"
|
||||
)
|
||||
|
|
|
@ -183,6 +183,9 @@ class Group(LDAPObject):
|
|||
|
||||
attribute_table = {
|
||||
"id": "dn",
|
||||
"display_name": "cn",
|
||||
"members": "member",
|
||||
"description": "description",
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -193,17 +196,17 @@ class Group(LDAPObject):
|
|||
super().__init__(*args, **kwargs)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
def display_name(self):
|
||||
attribute = current_app.config["LDAP"].get(
|
||||
"GROUP_NAME_ATTRIBUTE", Group.DEFAULT_NAME_ATTRIBUTE
|
||||
)
|
||||
return self[attribute][0]
|
||||
|
||||
def get_members(self, conn=None):
|
||||
return [member for member in self.member if member]
|
||||
return [member for member in self.members if member]
|
||||
|
||||
def add_member(self, user):
|
||||
self.member = self.member + [user]
|
||||
self.members = self.members + [user]
|
||||
|
||||
def remove_member(self, user):
|
||||
self.member = [m for m in self.member if m != user]
|
||||
self.members = [m for m in self.members if m != user]
|
||||
|
|
|
@ -119,7 +119,7 @@ def generate_user_claims(user, claims, jwt_mapping_config=None):
|
|||
# it's better to not insert a null or empty string value
|
||||
data[claim] = formatted_claim
|
||||
if claim == "groups":
|
||||
data[claim] = [group.name for group in user.groups]
|
||||
data[claim] = [group.display_name for group in user.groups]
|
||||
return data
|
||||
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
class="ui form"
|
||||
>
|
||||
{{ form.hidden_tag() if form.hidden_tag }}
|
||||
{{ sui.render_field(form.name) }}
|
||||
{{ sui.render_field(form.display_name) }}
|
||||
{{ sui.render_field(form.description) }}
|
||||
|
||||
{% if not edited_group %}
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
{% for group in table_form.items_slice %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{ url_for('groups.group', groupname=group.name) }}">
|
||||
<a href="{{ url_for('groups.group', groupname=group.display_name) }}">
|
||||
<i class="users circular black inverted icon"></i>
|
||||
</a>
|
||||
</td>
|
||||
<td><a href="{{ url_for('groups.group', groupname=group.name) }}">{{ group.name }}</a></td>
|
||||
<td><a href="{{ url_for('groups.group', groupname=group.display_name) }}">{{ group.display_name }}</a></td>
|
||||
<td>{% if group.description %}{{ group.description[0] }}{% endif %}</td>
|
||||
<td>{{ group.member|len }}</td>
|
||||
</tr>
|
||||
|
|
|
@ -45,8 +45,8 @@
|
|||
{% if user.can_manage_groups %}
|
||||
<td>
|
||||
{% for group in watched_user.groups %}
|
||||
<a class="ui label" href="{{ url_for('groups.group', groupname=group.name) }}"{% if group.description %} title="{{ group.description[0] }}"{% endif %}>
|
||||
{{ group.name }}
|
||||
<a class="ui label" href="{{ url_for('groups.group', groupname=group.display_name) }}"{% if group.description %} title="{{ group.description[0] }}"{% endif %}>
|
||||
{{ group.display_name }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</td>
|
||||
|
|
|
@ -233,8 +233,8 @@ def logged_moderator(moderator, testclient):
|
|||
def foo_group(app, user, slapd_connection):
|
||||
Group.ldap_object_classes(slapd_connection)
|
||||
group = Group(
|
||||
member=[user],
|
||||
cn="foo",
|
||||
members=[user],
|
||||
display_name="foo",
|
||||
)
|
||||
group.save()
|
||||
user.load_groups()
|
||||
|
@ -247,8 +247,8 @@ def foo_group(app, user, slapd_connection):
|
|||
def bar_group(app, admin, slapd_connection):
|
||||
Group.ldap_object_classes(slapd_connection)
|
||||
group = Group(
|
||||
member=[admin],
|
||||
cn="bar",
|
||||
members=[admin],
|
||||
display_name="bar",
|
||||
)
|
||||
group.save()
|
||||
admin.load_groups()
|
||||
|
|
|
@ -29,7 +29,7 @@ def test_object_creation(slapd_connection):
|
|||
|
||||
|
||||
def test_repr(slapd_connection, foo_group, user):
|
||||
assert repr(foo_group) == "<Group cn=foo>"
|
||||
assert repr(foo_group) == "<Group display_name=foo>"
|
||||
assert repr(user) == "<User cn=John (johnny) Doe>"
|
||||
|
||||
|
||||
|
|
|
@ -51,16 +51,16 @@ def test_group_list_bad_pages(testclient, logged_admin):
|
|||
def test_group_list_search(testclient, logged_admin, foo_group, bar_group):
|
||||
res = testclient.get("/groups")
|
||||
assert "2 items" in res
|
||||
assert foo_group.name in res
|
||||
assert bar_group.name in res
|
||||
assert foo_group.display_name in res
|
||||
assert bar_group.display_name in res
|
||||
|
||||
form = res.forms["search"]
|
||||
form["query"] = "oo"
|
||||
res = form.submit()
|
||||
|
||||
assert "1 items" in res, res.text
|
||||
assert foo_group.name in res
|
||||
assert bar_group.name not in res
|
||||
assert foo_group.display_name in res
|
||||
assert bar_group.display_name not in res
|
||||
|
||||
|
||||
def test_set_groups(app, user, foo_group, bar_group):
|
||||
|
@ -125,14 +125,14 @@ def test_moderator_can_create_edit_and_delete_group(
|
|||
# Fill the form for a new group
|
||||
res = testclient.get("/groups/add", status=200)
|
||||
form = res.forms["creategroupform"]
|
||||
form["name"] = "bar"
|
||||
form["display_name"] = "bar"
|
||||
form["description"] = "yolo"
|
||||
|
||||
# Group has been created
|
||||
res = form.submit(status=302).follow(status=200)
|
||||
|
||||
bar_group = Group.get("bar")
|
||||
assert bar_group.name == "bar"
|
||||
assert bar_group.display_name == "bar"
|
||||
assert bar_group.description == ["yolo"]
|
||||
assert [member.id for member in bar_group.get_members()] == [
|
||||
logged_moderator.id
|
||||
|
@ -142,13 +142,13 @@ def test_moderator_can_create_edit_and_delete_group(
|
|||
# Group name can not be edited
|
||||
res = testclient.get("/groups/bar", status=200)
|
||||
form = res.forms["editgroupform"]
|
||||
form["name"] = "bar2"
|
||||
form["display_name"] = "bar2"
|
||||
form["description"] = ["yolo2"]
|
||||
|
||||
res = form.submit(name="action", value="edit").follow()
|
||||
|
||||
bar_group = Group.get("bar")
|
||||
assert bar_group.name == "bar"
|
||||
assert bar_group.display_name == "bar"
|
||||
assert bar_group.description == ["yolo2"]
|
||||
assert Group.get("bar2") is None
|
||||
members = bar_group.get_members()
|
||||
|
@ -162,7 +162,7 @@ def test_moderator_can_create_edit_and_delete_group(
|
|||
|
||||
|
||||
def test_cannot_create_already_existing_group(testclient, logged_moderator, foo_group):
|
||||
res = testclient.post("/groups/add", {"name": "foo"}, status=200)
|
||||
res = testclient.post("/groups/add", {"display_name": "foo"}, status=200)
|
||||
|
||||
assert "Group creation failed." in res
|
||||
assert "The group 'foo' already exists" in res
|
||||
|
@ -206,7 +206,7 @@ def test_edition_failed(testclient, logged_moderator, foo_group):
|
|||
res = form.submit(name="action", value="edit")
|
||||
assert "Group edition failed." in res
|
||||
foo_group = Group.get(foo_group.id)
|
||||
assert foo_group.name == "foo"
|
||||
assert foo_group.display_name == "foo"
|
||||
|
||||
|
||||
def test_user_list_pagination(testclient, logged_admin, foo_group):
|
||||
|
|
|
@ -90,8 +90,8 @@ def test_edition(
|
|||
("cn=bar,ou=groups,dc=mydomain,dc=tld", False, "bar"),
|
||||
}
|
||||
assert logged_user.groups == [foo_group]
|
||||
assert foo_group.member == [logged_user]
|
||||
assert bar_group.member == [admin]
|
||||
assert foo_group.members == [logged_user]
|
||||
assert bar_group.members == [admin]
|
||||
assert res.form["groups"].attrs["readonly"]
|
||||
assert res.form["uid"].attrs["readonly"]
|
||||
|
||||
|
@ -130,8 +130,8 @@ def test_edition(
|
|||
foo_group.reload()
|
||||
bar_group.reload()
|
||||
assert logged_user.groups == [foo_group]
|
||||
assert foo_group.member == [logged_user]
|
||||
assert bar_group.member == [admin]
|
||||
assert foo_group.members == [logged_user]
|
||||
assert bar_group.members == [admin]
|
||||
|
||||
assert logged_user.check_password("correct horse battery staple")
|
||||
|
||||
|
@ -339,8 +339,8 @@ def test_user_creation_edition_and_deletion(
|
|||
|
||||
foo_group.reload()
|
||||
bar_group.reload()
|
||||
assert george in set(foo_group.member)
|
||||
assert george in set(bar_group.member)
|
||||
assert george in set(foo_group.members)
|
||||
assert george in set(bar_group.members)
|
||||
assert set(george.groups) == {foo_group, bar_group}
|
||||
assert "george" in testclient.get("/users", status=200).text
|
||||
assert "george" in testclient.get("/users", status=200).text
|
||||
|
|
Loading…
Reference in a new issue