Mercurial > prosody-modules
comparison mod_password_policy/mod_password_policy.lua @ 4832:bfd4af4caddc
mod_password_policy: Support for additional policies provided by other modules
E.g. check a password contains an uppercase character:
module:provides("password-policy", {
name = "contains_uppercase";
check_password = function (password, policy)
return (policy ~= true) or (not not password:match("%u"));
end;
})
Config:
password_policy = {
contains_uppercase = true;
}
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Wed, 22 Dec 2021 14:48:46 +0000 |
parents | 5a42cb84c8ee |
children | d3b69859553a |
comparison
equal
deleted
inserted
replaced
4831:5a42cb84c8ee | 4832:bfd4af4caddc |
---|---|
7 -- password_policy = { | 7 -- password_policy = { |
8 -- length = 8; | 8 -- length = 8; |
9 -- } | 9 -- } |
10 | 10 |
11 | 11 |
12 local it = require "util.iterators"; | |
13 local set = require "util.set"; | |
14 local st = require "util.stanza"; | |
15 | |
12 local options = module:get_option("password_policy"); | 16 local options = module:get_option("password_policy"); |
13 | 17 |
14 options = options or {}; | 18 options = options or {}; |
15 options.length = options.length or 8; | 19 options.length = options.length or 8; |
16 if options.exclude_username == nil then | 20 if options.exclude_username == nil then |
17 options.exclude_username = true; | 21 options.exclude_username = true; |
18 end | 22 end |
19 | 23 |
20 local st = require "util.stanza"; | 24 local builtin_policies = set.new({ "length", "exclude_username" }); |
25 local extra_policies = set.new(it.to_array(it.keys(options))) - builtin_policies; | |
26 | |
27 local extra_policy_handlers = {}; | |
28 | |
29 module:handle_items("password-policy-provider", function (event) | |
30 -- Password policy handler added | |
31 local item = event.item; | |
32 module:log("error", "Adding password policy handler '%s'", item.name); | |
33 extra_policy_handlers[item.name] = item.check_password; | |
34 end, function (event) | |
35 -- Password policy handler removed | |
36 local item = event.item; | |
37 extra_policy_handlers[item.name] = nil; | |
38 end); | |
21 | 39 |
22 function check_password(password, additional_info) | 40 function check_password(password, additional_info) |
23 if not password or password == "" then | 41 if not password or password == "" then |
24 return nil, "No password provided", "no-password"; | 42 return nil, "No password provided", "no-password"; |
25 end | 43 end |
32 local username = additional_info.username; | 50 local username = additional_info.username; |
33 if username and password:lower():find(username:lower(), 1, true) then | 51 if username and password:lower():find(username:lower(), 1, true) then |
34 return nil, "Password must not include your username", "username"; | 52 return nil, "Password must not include your username", "username"; |
35 end | 53 end |
36 end | 54 end |
55 | |
56 for policy in extra_policies do | |
57 local handler = extra_policy_handlers[policy]; | |
58 if not handler then | |
59 module:log("error", "No policy handler found for '%s' (typo, or module not loaded?)", policy); | |
60 return nil, "Internal error while verifying password", "internal"; | |
61 end | |
62 local ok, reason_text, reason_name = handler(password, options[policy], additional_info); | |
63 if ok ~= true then | |
64 return nil, reason_text or ("Password failed %s check"):format(policy), reason_name or policy; | |
65 end | |
66 end | |
67 | |
37 return true; | 68 return true; |
38 end | 69 end |
39 | 70 |
40 function get_policy() --luacheck: ignore 131/get_policy | 71 function get_policy() --luacheck: ignore 131/get_policy |
41 return options; | 72 return options; |