Mercurial > prosody-modules
annotate mod_protect_last_admin/mod_protect_last_admin.lua @ 6326:2623515d8507
mod_protect_last_admin: New module to ensure the last admin account on a server cannot be demoted or removed
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Thu, 25 Sep 2025 18:21:27 +0100 |
| parents | |
| children | 4f6fb56572f7 |
| 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 |
|
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
|
9 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
|
10 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
|
11 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
|
12 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
|
13 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
|
14 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
|
15 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
|
16 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
|
17 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
|
18 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
|
19 |
|
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
|
20 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
|
21 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
|
22 |
|
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 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
|
24 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
|
25 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
|
26 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
|
27 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
|
28 |
|
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 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
|
30 |
|
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 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
|
32 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
|
33 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
|
34 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
|
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 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
|
37 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
|
38 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
|
39 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
|
40 |
|
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 if not other_protected_users(username, host) 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
|
42 event.reason = "Cannot remove the only administrator"; |
|
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 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
|
44 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
|
45 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
|
46 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
|
47 |
|
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 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
|
49 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
|
50 module:hook("pre-user-role-change", check_last_admin); |
