forked from Github-Mirrors/canaille
fix: display an error message when trying to remove the last user from a group
This commit is contained in:
parent
fe2665ae32
commit
5aaccca4cf
5 changed files with 135 additions and 84 deletions
|
@ -2,6 +2,7 @@
|
||||||
Fixed
|
Fixed
|
||||||
^^^^^
|
^^^^^
|
||||||
- LDAP user group removal.
|
- LDAP user group removal.
|
||||||
|
- Display an error message when trying to remove the last user from a group.
|
||||||
|
|
||||||
[0.0.48] - 2024-04-08
|
[0.0.48] - 2024-04-08
|
||||||
---------------------
|
---------------------
|
||||||
|
|
|
@ -256,7 +256,7 @@ class IDToModel:
|
||||||
|
|
||||||
def __call__(self, data):
|
def __call__(self, data):
|
||||||
model = getattr(models, self.model_name)
|
model = getattr(models, self.model_name)
|
||||||
instance = data if isinstance(data, model) else model.get(id=data)
|
instance = data if isinstance(data, model) else model.get(data)
|
||||||
if not instance:
|
if not instance:
|
||||||
raise wtforms.ValidationError()
|
raise wtforms.ValidationError()
|
||||||
return instance
|
return instance
|
||||||
|
|
|
@ -56,6 +56,24 @@ def existing_login(form, field):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def non_empty_groups(form, field):
|
||||||
|
"""LDAP groups cannot be empty because groupOfNames.member is a MUST
|
||||||
|
attribute.
|
||||||
|
|
||||||
|
https://www.rfc-editor.org/rfc/rfc2256.html#section-7.10
|
||||||
|
"""
|
||||||
|
if not form.user:
|
||||||
|
return
|
||||||
|
|
||||||
|
for group in form.user.groups:
|
||||||
|
if len(group.members) == 1 and group not in field.data:
|
||||||
|
raise wtforms.ValidationError(
|
||||||
|
_(
|
||||||
|
"The group '{group}' cannot be removed, because it must have at least one user left."
|
||||||
|
).format(group=group.display_name)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class LoginForm(Form):
|
class LoginForm(Form):
|
||||||
login = wtforms.StringField(
|
login = wtforms.StringField(
|
||||||
_("Login"),
|
_("Login"),
|
||||||
|
@ -279,6 +297,7 @@ PROFILE_FORM_FIELDS = dict(
|
||||||
choices=lambda: [(group, group.display_name) for group in models.Group.query()],
|
choices=lambda: [(group, group.display_name) for group in models.Group.query()],
|
||||||
render_kw={"placeholder": _("users, admins …")},
|
render_kw={"placeholder": _("users, admins …")},
|
||||||
coerce=IDToModel("Group"),
|
coerce=IDToModel("Group"),
|
||||||
|
validators=[non_empty_groups],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PROJECT VERSION\n"
|
"Project-Id-Version: PROJECT VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2024-04-07 19:49+0200\n"
|
"POT-Creation-Date: 2024-04-08 14:43+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -41,36 +41,36 @@ msgstr ""
|
||||||
msgid "Not a valid datetime value."
|
msgid "Not a valid datetime value."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/backends/ldap/backend.py:94
|
#: canaille/backends/ldap/backend.py:97
|
||||||
msgid "Could not connect to the LDAP server '{uri}'"
|
msgid "Could not connect to the LDAP server '{uri}'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/backends/ldap/backend.py:101
|
#: canaille/backends/ldap/backend.py:104
|
||||||
msgid "LDAP authentication failed with user '{user}'"
|
msgid "LDAP authentication failed with user '{user}'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/backends/ldap/backend.py:170
|
#: canaille/backends/ldap/backend.py:173
|
||||||
msgid "John Doe"
|
msgid "John Doe"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/backends/ldap/backend.py:173 canaille/core/endpoints/forms.py:127
|
#: canaille/backends/ldap/backend.py:176 canaille/core/endpoints/forms.py:146
|
||||||
#: canaille/core/endpoints/forms.py:375
|
#: canaille/core/endpoints/forms.py:395
|
||||||
msgid "jdoe"
|
msgid "jdoe"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/backends/ldap/backend.py:176
|
#: canaille/backends/ldap/backend.py:179
|
||||||
msgid "john@doe.com"
|
msgid "john@doe.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/backends/ldap/backend.py:178
|
#: canaille/backends/ldap/backend.py:181
|
||||||
msgid " or "
|
msgid " or "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/backends/ldap/models.py:98
|
#: canaille/backends/ldap/backend.py:236
|
||||||
msgid "Your account has been locked."
|
msgid "Your account has been locked."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/backends/ldap/models.py:103
|
#: canaille/backends/ldap/backend.py:241
|
||||||
msgid "You should change your password."
|
msgid "You should change your password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -128,8 +128,8 @@ msgstr ""
|
||||||
msgid "You are already logged in, you cannot create an account."
|
msgid "You are already logged in, you cannot create an account."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/account.py:297 canaille/core/endpoints/forms.py:276
|
#: canaille/core/endpoints/account.py:297 canaille/core/endpoints/forms.py:295
|
||||||
#: canaille/core/endpoints/forms.py:393 canaille/core/templates/groups.html:5
|
#: canaille/core/endpoints/forms.py:413 canaille/core/templates/groups.html:5
|
||||||
#: canaille/core/templates/groups.html:23
|
#: canaille/core/templates/groups.html:23
|
||||||
#: canaille/core/templates/partial/users.html:18
|
#: canaille/core/templates/partial/users.html:18
|
||||||
#: canaille/templates/base.html:57
|
#: canaille/templates/base.html:57
|
||||||
|
@ -175,12 +175,12 @@ msgid "User account creation succeed."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/account.py:609
|
#: canaille/core/endpoints/account.py:609
|
||||||
#: canaille/core/endpoints/account.py:771
|
#: canaille/core/endpoints/account.py:770
|
||||||
msgid "Profile edition failed."
|
msgid "Profile edition failed."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/account.py:613
|
#: canaille/core/endpoints/account.py:613
|
||||||
#: canaille/core/endpoints/account.py:786
|
#: canaille/core/endpoints/account.py:785
|
||||||
msgid "Profile updated successfully."
|
msgid "Profile updated successfully."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ msgid ""
|
||||||
"It should be received within a few minutes."
|
"It should be received within a few minutes."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/account.py:689 canaille/core/endpoints/auth.py:137
|
#: canaille/core/endpoints/account.py:689 canaille/core/endpoints/auth.py:136
|
||||||
msgid "Could not send the password initialization email"
|
msgid "Could not send the password initialization email"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -234,12 +234,12 @@ msgstr ""
|
||||||
msgid "The account has been unlocked"
|
msgid "The account has been unlocked"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/account.py:806
|
#: canaille/core/endpoints/account.py:805
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "The user %(user)s has been sucessfuly deleted"
|
msgid "The user %(user)s has been sucessfuly deleted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/account.py:824 canaille/core/endpoints/auth.py:93
|
#: canaille/core/endpoints/account.py:823 canaille/core/endpoints/auth.py:92
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Connection successful. Welcome %(user)s"
|
msgid "Connection successful. Welcome %(user)s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -249,10 +249,10 @@ msgstr ""
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/admin.py:29 canaille/core/endpoints/forms.py:63
|
#: canaille/core/endpoints/admin.py:29 canaille/core/endpoints/forms.py:82
|
||||||
#: canaille/core/endpoints/forms.py:83 canaille/core/endpoints/forms.py:172
|
#: canaille/core/endpoints/forms.py:102 canaille/core/endpoints/forms.py:191
|
||||||
#: canaille/core/endpoints/forms.py:361 canaille/core/endpoints/forms.py:387
|
#: canaille/core/endpoints/forms.py:381 canaille/core/endpoints/forms.py:407
|
||||||
#: canaille/core/endpoints/forms.py:408 canaille/core/endpoints/forms.py:424
|
#: canaille/core/endpoints/forms.py:428 canaille/core/endpoints/forms.py:444
|
||||||
msgid "jane@doe.com"
|
msgid "jane@doe.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -272,96 +272,102 @@ msgstr ""
|
||||||
msgid "Email confirmation on {website_name}"
|
msgid "Email confirmation on {website_name}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/auth.py:51 canaille/core/endpoints/auth.py:77
|
#: canaille/core/endpoints/auth.py:50 canaille/core/endpoints/auth.py:76
|
||||||
#: canaille/core/endpoints/auth.py:85
|
#: canaille/core/endpoints/auth.py:84
|
||||||
msgid "Login failed, please check your information"
|
msgid "Login failed, please check your information"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/auth.py:105
|
#: canaille/core/endpoints/auth.py:104
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "You have been disconnected. See you next time %(user)s"
|
msgid "You have been disconnected. See you next time %(user)s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/auth.py:130
|
#: canaille/core/endpoints/auth.py:129
|
||||||
msgid ""
|
msgid ""
|
||||||
"A password initialization link has been sent at your email address. You "
|
"A password initialization link has been sent at your email address. You "
|
||||||
"should receive it within a few minutes."
|
"should receive it within a few minutes."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/auth.py:153
|
#: canaille/core/endpoints/auth.py:152
|
||||||
msgid "Could not send the password reset link."
|
msgid "Could not send the password reset link."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/auth.py:157
|
#: canaille/core/endpoints/auth.py:156
|
||||||
msgid ""
|
msgid ""
|
||||||
"A password reset link has been sent at your email address. You should "
|
"A password reset link has been sent at your email address. You should "
|
||||||
"receive it within a few minutes."
|
"receive it within a few minutes."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/auth.py:169
|
#: canaille/core/endpoints/auth.py:168
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"The user '%(user)s' does not have permissions to update their password. "
|
"The user '%(user)s' does not have permissions to update their password. "
|
||||||
"We cannot send a password reset email."
|
"We cannot send a password reset email."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/auth.py:185
|
#: canaille/core/endpoints/auth.py:184
|
||||||
msgid "We encountered an issue while we sent the password recovery email."
|
msgid "We encountered an issue while we sent the password recovery email."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/auth.py:208
|
#: canaille/core/endpoints/auth.py:207
|
||||||
msgid "The password reset link that brought you here was invalid."
|
msgid "The password reset link that brought you here was invalid."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/auth.py:217
|
#: canaille/core/endpoints/auth.py:216
|
||||||
msgid "Your password has been updated successfully"
|
msgid "Your password has been updated successfully"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:29
|
#: canaille/core/endpoints/forms.py:30
|
||||||
msgid "The user name '{user_name}' already exists"
|
msgid "The user name '{user_name}' already exists"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:38
|
#: canaille/core/endpoints/forms.py:39
|
||||||
msgid "The email '{email}' is already used"
|
msgid "The email '{email}' is already used"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:45
|
#: canaille/core/endpoints/forms.py:46
|
||||||
msgid "The group '{group}' already exists"
|
msgid "The group '{group}' already exists"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:54
|
#: canaille/core/endpoints/forms.py:55
|
||||||
msgid "The login '{login}' does not exist"
|
msgid "The login '{login}' does not exist"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:60 canaille/core/endpoints/forms.py:80
|
#: canaille/core/endpoints/forms.py:71
|
||||||
|
msgid ""
|
||||||
|
"The group '{group}' cannot be removed, because it must have at least one "
|
||||||
|
"user left."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: canaille/core/endpoints/forms.py:79 canaille/core/endpoints/forms.py:99
|
||||||
#: canaille/core/templates/partial/users.html:9
|
#: canaille/core/templates/partial/users.html:9
|
||||||
msgid "Login"
|
msgid "Login"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:73 canaille/core/endpoints/forms.py:92
|
#: canaille/core/endpoints/forms.py:92 canaille/core/endpoints/forms.py:111
|
||||||
#: canaille/core/endpoints/forms.py:226
|
#: canaille/core/endpoints/forms.py:245
|
||||||
#: canaille/core/templates/profile_settings.html:63
|
#: canaille/core/templates/profile_settings.html:63
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:99 canaille/core/endpoints/forms.py:236
|
#: canaille/core/endpoints/forms.py:118 canaille/core/endpoints/forms.py:255
|
||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:102 canaille/core/endpoints/forms.py:239
|
#: canaille/core/endpoints/forms.py:121 canaille/core/endpoints/forms.py:258
|
||||||
msgid "Password and confirmation do not match."
|
msgid "Password and confirmation do not match."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:121
|
#: canaille/core/endpoints/forms.py:140
|
||||||
msgid "Automatic"
|
msgid "Automatic"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:126
|
#: canaille/core/endpoints/forms.py:145
|
||||||
msgid "Username"
|
msgid "Username"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:130 canaille/core/endpoints/forms.py:324
|
#: canaille/core/endpoints/forms.py:149 canaille/core/endpoints/forms.py:344
|
||||||
#: canaille/core/endpoints/forms.py:338
|
#: canaille/core/endpoints/forms.py:358
|
||||||
#: canaille/core/templates/partial/groups.html:6
|
#: canaille/core/templates/partial/groups.html:6
|
||||||
#: canaille/core/templates/partial/users.html:12
|
#: canaille/core/templates/partial/users.html:12
|
||||||
#: canaille/oidc/endpoints/forms.py:26
|
#: canaille/oidc/endpoints/forms.py:26
|
||||||
|
@ -369,165 +375,165 @@ msgstr ""
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:132
|
#: canaille/core/endpoints/forms.py:151
|
||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:132
|
#: canaille/core/endpoints/forms.py:151
|
||||||
msgid "Vice president"
|
msgid "Vice president"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:135
|
#: canaille/core/endpoints/forms.py:154
|
||||||
msgid "Given name"
|
msgid "Given name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:137
|
#: canaille/core/endpoints/forms.py:156
|
||||||
msgid "John"
|
msgid "John"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:143
|
#: canaille/core/endpoints/forms.py:162
|
||||||
msgid "Family Name"
|
msgid "Family Name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:146
|
#: canaille/core/endpoints/forms.py:165
|
||||||
msgid "Doe"
|
msgid "Doe"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:152
|
#: canaille/core/endpoints/forms.py:171
|
||||||
msgid "Display Name"
|
msgid "Display Name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:155
|
#: canaille/core/endpoints/forms.py:174
|
||||||
msgid "Johnny"
|
msgid "Johnny"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:162 canaille/core/endpoints/forms.py:414
|
#: canaille/core/endpoints/forms.py:181 canaille/core/endpoints/forms.py:434
|
||||||
#: canaille/core/templates/profile_edit.html:176
|
#: canaille/core/templates/profile_edit.html:176
|
||||||
msgid "Email addresses"
|
msgid "Email addresses"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:168 canaille/core/endpoints/forms.py:404
|
#: canaille/core/endpoints/forms.py:187 canaille/core/endpoints/forms.py:424
|
||||||
msgid ""
|
msgid ""
|
||||||
"This email will be used as a recovery address to reset the password if "
|
"This email will be used as a recovery address to reset the password if "
|
||||||
"needed"
|
"needed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:182
|
#: canaille/core/endpoints/forms.py:201
|
||||||
msgid "Phone numbers"
|
msgid "Phone numbers"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:183
|
#: canaille/core/endpoints/forms.py:202
|
||||||
msgid "555-000-555"
|
msgid "555-000-555"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:190
|
#: canaille/core/endpoints/forms.py:209
|
||||||
msgid "Address"
|
msgid "Address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:192
|
#: canaille/core/endpoints/forms.py:211
|
||||||
msgid "132, Foobar Street, Gotham City 12401, XX"
|
msgid "132, Foobar Street, Gotham City 12401, XX"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:196
|
#: canaille/core/endpoints/forms.py:215
|
||||||
msgid "Street"
|
msgid "Street"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:198
|
#: canaille/core/endpoints/forms.py:217
|
||||||
msgid "132, Foobar Street"
|
msgid "132, Foobar Street"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:202
|
#: canaille/core/endpoints/forms.py:221
|
||||||
msgid "Postal Code"
|
msgid "Postal Code"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:208
|
#: canaille/core/endpoints/forms.py:227
|
||||||
msgid "Locality"
|
msgid "Locality"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:210
|
#: canaille/core/endpoints/forms.py:229
|
||||||
msgid "Gotham City"
|
msgid "Gotham City"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:214
|
#: canaille/core/endpoints/forms.py:233
|
||||||
msgid "Region"
|
msgid "Region"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:216
|
#: canaille/core/endpoints/forms.py:235
|
||||||
msgid "North Pole"
|
msgid "North Pole"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:220
|
#: canaille/core/endpoints/forms.py:239
|
||||||
msgid "Photo"
|
msgid "Photo"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:224
|
#: canaille/core/endpoints/forms.py:243
|
||||||
#: canaille/core/templates/profile_add.html:56
|
#: canaille/core/templates/profile_add.html:56
|
||||||
#: canaille/core/templates/profile_edit.html:64
|
#: canaille/core/templates/profile_edit.html:64
|
||||||
msgid "Delete the photo"
|
msgid "Delete the photo"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:247
|
#: canaille/core/endpoints/forms.py:266
|
||||||
msgid "User number"
|
msgid "User number"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:249 canaille/core/endpoints/forms.py:255
|
#: canaille/core/endpoints/forms.py:268 canaille/core/endpoints/forms.py:274
|
||||||
msgid "1234"
|
msgid "1234"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:253
|
#: canaille/core/endpoints/forms.py:272
|
||||||
msgid "Department"
|
msgid "Department"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:259
|
#: canaille/core/endpoints/forms.py:278
|
||||||
msgid "Organization"
|
msgid "Organization"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:261
|
#: canaille/core/endpoints/forms.py:280
|
||||||
msgid "Cogip LTD."
|
msgid "Cogip LTD."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:265
|
#: canaille/core/endpoints/forms.py:284
|
||||||
msgid "Website"
|
msgid "Website"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:267
|
#: canaille/core/endpoints/forms.py:286
|
||||||
msgid "https://mywebsite.tld"
|
msgid "https://mywebsite.tld"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:272
|
#: canaille/core/endpoints/forms.py:291
|
||||||
msgid "Preferred language"
|
msgid "Preferred language"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:279
|
#: canaille/core/endpoints/forms.py:298
|
||||||
msgid "users, admins …"
|
msgid "users, admins …"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:303
|
#: canaille/core/endpoints/forms.py:323
|
||||||
msgid "Account expiration"
|
msgid "Account expiration"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:327
|
#: canaille/core/endpoints/forms.py:347
|
||||||
msgid "group"
|
msgid "group"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:331 canaille/core/endpoints/forms.py:348
|
#: canaille/core/endpoints/forms.py:351 canaille/core/endpoints/forms.py:368
|
||||||
#: canaille/core/templates/partial/groups.html:7
|
#: canaille/core/templates/partial/groups.html:7
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:355 canaille/core/endpoints/forms.py:380
|
#: canaille/core/endpoints/forms.py:375 canaille/core/endpoints/forms.py:400
|
||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:374
|
#: canaille/core/endpoints/forms.py:394
|
||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:378
|
#: canaille/core/endpoints/forms.py:398
|
||||||
msgid "Username editable by the invitee"
|
msgid "Username editable by the invitee"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: canaille/core/endpoints/forms.py:417
|
#: canaille/core/endpoints/forms.py:437
|
||||||
msgid "New email address"
|
msgid "New email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ def test_edition(testclient, logged_user, admin, foo_group, bar_group, backend):
|
||||||
|
|
||||||
|
|
||||||
def test_group_removal(testclient, logged_admin, user, foo_group, backend):
|
def test_group_removal(testclient, logged_admin, user, foo_group, backend):
|
||||||
|
"""Tests that one can remove a group from a user."""
|
||||||
foo_group.members = [user, logged_admin]
|
foo_group.members = [user, logged_admin]
|
||||||
foo_group.save()
|
foo_group.save()
|
||||||
user.reload()
|
user.reload()
|
||||||
|
@ -52,9 +53,33 @@ def test_group_removal(testclient, logged_admin, user, foo_group, backend):
|
||||||
assert foo_group not in user.groups
|
assert foo_group not in user.groups
|
||||||
|
|
||||||
foo_group.reload()
|
foo_group.reload()
|
||||||
|
logged_admin.reload()
|
||||||
assert foo_group.members == [logged_admin]
|
assert foo_group.members == [logged_admin]
|
||||||
|
|
||||||
|
|
||||||
|
def test_empty_group_removal(testclient, logged_admin, user, foo_group, backend):
|
||||||
|
"""Tests that one cannot remove a group from a user, when was the last
|
||||||
|
person in the group.
|
||||||
|
|
||||||
|
This is because LDAP groups cannot be empty because
|
||||||
|
groupOfNames.member is a MUST attribute.
|
||||||
|
https://www.rfc-editor.org/rfc/rfc2256.html#section-7.10
|
||||||
|
"""
|
||||||
|
assert foo_group in user.groups
|
||||||
|
|
||||||
|
res = testclient.get("/profile/user/settings", status=200)
|
||||||
|
res.form["groups"] = []
|
||||||
|
res = res.form.submit(name="action", value="edit-settings")
|
||||||
|
assert res.flashes == [("error", "Profile edition failed.")]
|
||||||
|
|
||||||
|
res.mustcontain(
|
||||||
|
"The group 'foo' cannot be removed, because it must have at least one user left."
|
||||||
|
)
|
||||||
|
|
||||||
|
user.reload()
|
||||||
|
assert foo_group in user.groups
|
||||||
|
|
||||||
|
|
||||||
def test_profile_settings_edition_dynamic_validation(testclient, logged_admin):
|
def test_profile_settings_edition_dynamic_validation(testclient, logged_admin):
|
||||||
res = testclient.get("/profile/admin/settings")
|
res = testclient.get("/profile/admin/settings")
|
||||||
res = testclient.post(
|
res = testclient.post(
|
||||||
|
|
Loading…
Reference in a new issue