Mercurial > prosody-modules
view mod_auth_ha1/mod_auth_ha1.lua @ 5255:001c8fdc91a4
mod_http_oauth2: Add support for the "openid" scope
This "openid" scope is there to signal access to the userinfo endpoint,
which is needed for OIDC support.
We don't actually check this later because the userinfo endpoint only
returns info embedded in the token itself, but in the future we may want
to check this more carefully.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Thu, 16 Mar 2023 17:06:35 +0100 |
parents | 31c4d92a81e5 |
children |
line wrap: on
line source
-- Prosody IM -- Copyright (C) 2014 Matthew Wild -- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. -- local usermanager = require "core.usermanager"; local new_sasl = require "util.sasl".new; local nodeprep = require "util.encodings".stringprep.nodeprep; local nameprep = require "util.encodings".stringprep.nameprep; local md5 = require "util.hashes".md5; local host = module.host; local auth_filename = module:get_option_string("auth_ha1_file", "auth.txt"); local auth_data = {}; function reload_auth_data() local f, err = io.open(auth_filename); if not f then module:log("error", "Failed to read from auth file: %s", err); return; end auth_data = {}; local line_number, imported_count, not_authorized_count = 0, 0, 0; for line in f:lines() do line_number = line_number + 1; local username, hash, realm, state = line:match("^([^:]+):(%x+):([^:]+):(.+)$"); if not username then if line:sub(1,1) ~= "#" then module:log("error", "Unable to parse line %d of auth file, skipping", line_number); end else username, realm = nodeprep(username), nameprep(realm); if not username then module:log("error", "Invalid username on line %d of auth file, skipping", line_number); elseif not realm then module:log("error", "Invalid hostname/realm on line %d of auth file, skipping", line_number); elseif state ~= "authorized" then not_authorized_count = not_authorized_count + 1; elseif realm == host then auth_data[username] = hash; imported_count = imported_count + 1; end end end f:close(); module:log("debug", "Loaded %d accounts from auth file (%d authorized)", imported_count, imported_count-not_authorized_count); end function module.load() reload_auth_data(); end module:hook_global("config-reloaded", reload_auth_data); -- define auth provider local provider = {}; function provider.test_password(username, password) module:log("debug", "test password for user %s at host %s, %s", username, host, password); local test_hash = md5(username..":"..host..":"..password, true); if test_hash == auth_data[username] then return true; else return nil, "Auth failed. Invalid username or password."; end end function provider.set_password(username, password) return nil, "Changing passwords not supported"; end function provider.user_exists(username) if not auth_data[username] then module:log("debug", "account not found for username '%s' at host '%s'", username, host); return nil, "Auth failed. Invalid username"; end return true; end function provider.create_user(username, password) return nil, "User creation not supported"; end function provider.delete_user(username) return nil , "User deletion not supported"; end function provider.get_sasl_handler() return new_sasl(host, { plain_test = function(sasl, username, password, realm) return usermanager.test_password(username, realm, password), true; end }); end module:provides("auth", provider);