Mercurial > prosody-modules
annotate mod_protect_last_admin/mod_protect_last_admin.lua @ 6398:9c9889ad4302
mod_unsubscriber: Add MUC support
This catches XEP-0045 Join stanzas and replies with an error telling the
prospective participant that the supposed MUC is gone. The user or their
client can then take action to remove any bookmark or at least disable
autojoin.
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sat, 07 Feb 2026 12:25:52 +0100 |
| parents | 187b957dc528 |
| children | d1f64ffca879 |
| rev | line source |
|---|---|
|
6326
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
1 module:set_global(); |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
2 |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
3 local um = require "prosody.core.usermanager"; |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
4 |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
5 local set = require "prosody.util.set"; |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
6 |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
7 local protected_roles = module:get_option_set("protect_last_admin_roles", { "prosody:admin", "prosody:operator" }); |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 |
|
6327
4f6fb56572f7
mod_protect_last_admin: Return util.error object to provide more information
Matthew Wild <mwild1@gmail.com>
parents:
6326
diff
changeset
|
9 local errors = require "prosody.util.error".init(module.name, { |
|
4f6fb56572f7
mod_protect_last_admin: Return util.error object to provide more information
Matthew Wild <mwild1@gmail.com>
parents:
6326
diff
changeset
|
10 ["cannot-remove-only-admin"] = { |
|
4f6fb56572f7
mod_protect_last_admin: Return util.error object to provide more information
Matthew Wild <mwild1@gmail.com>
parents:
6326
diff
changeset
|
11 code = 400; |
|
4f6fb56572f7
mod_protect_last_admin: Return util.error object to provide more information
Matthew Wild <mwild1@gmail.com>
parents:
6326
diff
changeset
|
12 type = "cancel"; |
|
6328
187b957dc528
mod_protect_last_admin: Switch to service-unavailable rather than policy-violation
Matthew Wild <mwild1@gmail.com>
parents:
6327
diff
changeset
|
13 condition = "service-unavailable"; |
|
6327
4f6fb56572f7
mod_protect_last_admin: Return util.error object to provide more information
Matthew Wild <mwild1@gmail.com>
parents:
6326
diff
changeset
|
14 text = "Cannot remove the only administrator"; |
|
4f6fb56572f7
mod_protect_last_admin: Return util.error object to provide more information
Matthew Wild <mwild1@gmail.com>
parents:
6326
diff
changeset
|
15 extra = { |
|
4f6fb56572f7
mod_protect_last_admin: Return util.error object to provide more information
Matthew Wild <mwild1@gmail.com>
parents:
6326
diff
changeset
|
16 namespace = "https://prosody.im/protocol/errors"; |
|
4f6fb56572f7
mod_protect_last_admin: Return util.error object to provide more information
Matthew Wild <mwild1@gmail.com>
parents:
6326
diff
changeset
|
17 condition = "cannot-remove-only-admin"; |
|
4f6fb56572f7
mod_protect_last_admin: Return util.error object to provide more information
Matthew Wild <mwild1@gmail.com>
parents:
6326
diff
changeset
|
18 }; |
|
4f6fb56572f7
mod_protect_last_admin: Return util.error object to provide more information
Matthew Wild <mwild1@gmail.com>
parents:
6326
diff
changeset
|
19 }; |
|
4f6fb56572f7
mod_protect_last_admin: Return util.error object to provide more information
Matthew Wild <mwild1@gmail.com>
parents:
6326
diff
changeset
|
20 }); |
|
4f6fb56572f7
mod_protect_last_admin: Return util.error object to provide more information
Matthew Wild <mwild1@gmail.com>
parents:
6326
diff
changeset
|
21 |
|
6326
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
22 local function other_protected_users(username, host) |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
23 local protected_users = set.new(); |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
24 for protected_role in protected_roles do |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
25 local users = um.get_users_with_role(protected_role, host); |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
26 module:log("debug", "Role %s: %s", protected_role, require "util.serialization".serialize(users, "debug")); |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
27 protected_users:add_list(um.get_users_with_role(protected_role, host)); |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
28 end |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
29 protected_users:remove(username); |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
30 return not protected_users:empty(); |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
31 end |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
32 |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 function check_last_admin(event) |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
34 local username, host = event.username, event.host; |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
35 |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
36 local current_role = um.get_user_role(username, host); |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
37 if not current_role then |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
38 module:log("warn", "Couldn't detect role for %s@%s", username, host); |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
39 return; |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
40 end |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
41 |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 module:log("debug", "Checking whether to allow this event..."); |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
43 |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
44 if event.role_name and protected_roles:contains(event.role_name) then |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
45 module:log("debug", "Permitting role change to %s", event.role_name); |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
46 return; -- Switching to another protected role is fine |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
47 end |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
48 |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
49 if not protected_roles:contains(current_role.name) then |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
50 module:log("debug", "Permitting event, role %s is not protected", current_role.name); |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
51 return; -- This is not a protected user |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
52 end |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
53 |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
54 if not other_protected_users(username, host) then |
|
6327
4f6fb56572f7
mod_protect_last_admin: Return util.error object to provide more information
Matthew Wild <mwild1@gmail.com>
parents:
6326
diff
changeset
|
55 event.reason = errors.new("cannot-remove-only-admin"); |
|
6326
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
56 return false; |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
57 end |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
58 module:log("debug", "Permitting event, no reason not to!"); |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
59 end |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
60 |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
61 module:hook("pre-delete-user", check_last_admin); |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
62 module:hook("pre-disable-user", check_last_admin); |
|
2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
63 module:hook("pre-user-role-change", check_last_admin); |
