Created
December 5, 2016 00:46
-
-
Save bangarangadang/4c4d50192ec2984cc6341664f5665f7b to your computer and use it in GitHub Desktop.
Discourse Authentication Module for Prosody
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Discourse Authentication Module for Prosody | |
-- https://meta.discourse.org/t/use-discourse-for-sso-in-a-non-web-app/40584/9 | |
-- | |
local new_sasl = require "util.sasl".new; | |
local http = require "net.http"; | |
local json = require "util.json"; | |
local log = module._log; | |
local host = module.host; | |
local discourse_url = module:get_option_string("discourse_url", ""):gsub("$host", host); | |
if discourse_url == "" then error("discourse_url required") end | |
local function discourse(username, password) | |
module:log("debug", "fetching token for user %s", username); | |
local url = discourse_url:gsub("$user", username); | |
local credentials = { | |
{ name = "login", value = username }; | |
{ name = "password", value = password }; | |
} | |
local function discourse_verify(response, code) | |
module:log("debug", "response: %s", response); | |
if string.match(response, '"username":"(.-)"') == username:gsub("^%l", string.upper) then | |
module:log("debug", "login successful for user: %s", username) | |
else | |
module:log("debug", "login failed for user: %s", username) | |
end | |
end | |
local function discourse_login(response, code, request) | |
csrf = string.match(response, '"csrf":"(.-)"'); | |
cookie = string.match(request.responseheaders["set-cookie"], '(.-);'); | |
module:log("debug", "csrf: %s", csrf); | |
module:log("debug", "cookie: %s", cookie); | |
if csrf == nil or cookie == nil then | |
module:log("debug", "no csrf or cookie fetched for user %s. abort login", username); | |
else | |
module:log("debug", "trying to login with fetched csrf and cookie for user %s", username); | |
local ex = { | |
headers = { | |
["Origin"] = url, | |
["X-CSRF-Token"] = csrf, | |
["Cookie"] = cookie, | |
["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8", | |
["Referer"] = url, | |
["X-Requested-With"] = "XMLHttpRequest" | |
}; | |
body = http.formencode(credentials); | |
} | |
http.request (url .. "session", ex, discourse_verify) | |
end | |
end | |
local ex = { | |
headers = { | |
["X-CSRF-Token"] = "undefined", | |
["Referer"] = url, | |
["X-Requested-With"] = "XMLHttpRequest" | |
}; | |
} | |
http.request(url .. "session/csrf", ex, discourse_login); | |
end | |
local provider = {}; | |
function provider.test_password(username, password) | |
return nil, "Not supported" | |
end | |
function provider.get_password(username) | |
return nil, "Not supported" | |
end | |
function provider.set_password(username, password) | |
return nil, "Not supported" | |
end | |
function provider.user_exists(username) | |
return true; | |
end | |
function provider.create_user(username, password) | |
return nil, "Not supported" | |
end | |
function provider.delete_user(username) | |
return nil, "Not supported" | |
end | |
function provider.get_sasl_handler() | |
return new_sasl(host, { | |
plain_test = function(sasl, username, password, realm) | |
return discourse(username, password), true; | |
end | |
}); | |
end | |
module:provides("auth", provider); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment