Mercurial > prosody-modules
view mod_password_policy/mod_password_policy.lua @ 5265:f845c218e52c
mod_http_oauth2: Allow revoking a token without OAuth client credentials
If you have a valid token, and you're not supposed to have it, revoking
it seems the most responsible thing to do with it, so it should be
allowed, while if you are supposed to have it, you should also be
allowed to revoke it.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Tue, 21 Mar 2023 22:02:38 +0100 |
parents | bfd4af4caddc |
children | d3b69859553a |
line wrap: on
line source
-- Password policy enforcement for Prosody -- -- Copyright (C) 2012 Waqas Hussain -- -- -- Configuration: -- password_policy = { -- length = 8; -- } local it = require "util.iterators"; local set = require "util.set"; local st = require "util.stanza"; local options = module:get_option("password_policy"); options = options or {}; options.length = options.length or 8; if options.exclude_username == nil then options.exclude_username = true; end local builtin_policies = set.new({ "length", "exclude_username" }); local extra_policies = set.new(it.to_array(it.keys(options))) - builtin_policies; local extra_policy_handlers = {}; module:handle_items("password-policy-provider", function (event) -- Password policy handler added local item = event.item; module:log("error", "Adding password policy handler '%s'", item.name); extra_policy_handlers[item.name] = item.check_password; end, function (event) -- Password policy handler removed local item = event.item; extra_policy_handlers[item.name] = nil; end); function check_password(password, additional_info) if not password or password == "" then return nil, "No password provided", "no-password"; end if #password < options.length then return nil, ("Password is too short (minimum %d characters)"):format(options.length), "length"; end if additional_info then local username = additional_info.username; if username and password:lower():find(username:lower(), 1, true) then return nil, "Password must not include your username", "username"; end end for policy in extra_policies do local handler = extra_policy_handlers[policy]; if not handler then module:log("error", "No policy handler found for '%s' (typo, or module not loaded?)", policy); return nil, "Internal error while verifying password", "internal"; end local ok, reason_text, reason_name = handler(password, options[policy], additional_info); if ok ~= true then return nil, reason_text or ("Password failed %s check"):format(policy), reason_name or policy; end end return true; end function get_policy() --luacheck: ignore 131/get_policy return options; end function handler(event) local origin, stanza = event.origin, event.stanza; if stanza.attr.type == "set" then local query = stanza.tags[1]; local passwords = {}; local dataform = query:get_child("x", "jabber:x:data"); if dataform then for _,tag in ipairs(dataform.tags) do if tag.attr.var == "password" then table.insert(passwords, tag:get_child_text("value")); end end end table.insert(passwords, query:get_child_text("password")); local additional_info = { username = origin.username; }; for _,password in ipairs(passwords) do if password then local pw_ok, pw_err, pw_failed_policy = check_password(password, additional_info); if not pw_ok then module:log("debug", "Password failed check against '%s' policy", pw_failed_policy); origin.send(st.error_reply(stanza, "cancel", "not-acceptable", pw_err)); return true; end end end end end module:hook("iq/self/jabber:iq:register:query", handler, 10); module:hook("iq/host/jabber:iq:register:query", handler, 10); module:hook("stanza/iq/jabber:iq:register:query", handler, 10);