# HG changeset patch # User bsw # Date 1632733094 -7200 # Node ID 5eb8b596f7d48d9f0d62f5a46ddaf301a81fe1d9 # Parent 4ddc5841e136f07da218d2f9c821b5d61c104001 Added OAuth2 client code diff -r 4ddc5841e136 -r 5eb8b596f7d4 app/main/_filter/21_auth.lua --- a/app/main/_filter/21_auth.lua Mon Sep 27 10:57:00 2021 +0200 +++ b/app/main/_filter/21_auth.lua Mon Sep 27 10:58:14 2021 +0200 @@ -137,14 +137,22 @@ error("array type params not implemented") end end - request.redirect{ - module = 'index', view = 'login', params = { - redirect_module = module, - redirect_view = view, - redirect_id = param.get_id(), - redirect_params = params + if config.login and config.login.method == "oauth2" then + request.redirect{ + module = "oauth2_client", + view = "redirect", + params = { provider = config.login.provider } } - } + else + request.redirect{ + module = 'index', view = 'login', params = { + redirect_module = module, + redirect_view = view, + redirect_id = param.get_id(), + redirect_params = params + } + } + end elseif auth_needed and app.session.member.locked then trace.debug("Member locked.") request.redirect{ module = 'index', view = 'login' } diff -r 4ddc5841e136 -r 5eb8b596f7d4 app/main/oauth2_client/callback.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/oauth2_client/callback.lua Mon Sep 27 10:58:14 2021 +0200 @@ -0,0 +1,88 @@ +local provider = param.get("provider") +local provider_config = config.oauth2_providers[provider] +if not provider_config then + return +end + + +local error = param.get("error") + +if error then + ui.heading{ content = "OAuth error" } + ui.container{ content = error } + return +end + +local state = param.get("state") + +if state ~= app.session:additional_secret_for("oauth") then + ui.heading{ content = "OAuth error" } + ui.container{ content = "state invalid" } + return +end + +local code = param.get("code") + +local params = { + code = code, + client_id = provider_config.client_id, + client_secret = provider_config.client_secret, + redirect_uri = request.get_absolute_baseurl() .. "oauth2_client/callback.html?provider=" .. provider, + grant_type = "authorization_code" +} + +local params_list = {} +for key, val in pairs(params) do + table.insert(params_list, encode.url_part(key) .. "=" .. encode.url_part(val)) +end + +local r = table.concat(params_list, "&") + +local output, err, status = extos.pfilter(nil, "curl", "-X", "POST", "-d", r, provider_config.token_url) + +local result = json.import(output) + +local url = provider_config.id_url .. "?access_token=" .. encode.url_part(result.access_token) + +local output, err, status = extos.pfilter(nil, "curl", url) + +local id_result = json.import(output) + +local id = id_result[provider_config.id_field] +local email = id_result[provider_config.email_field] + +if id then + local member = Member:new_selector() + :add_where{ "authority = ?", "oauth2_" .. provider } + :add_where{ "authority_uid = ?", id } + :optional_object_mode() + :exec() + + if not member then + member = Member:new() + member.authority = "oauth2_" .. provider + member.authority_uid = id + member.notify_email = email + member.name = "Member " .. id + member.identification = "Member " .. id + member.activated = "now" + member:save() + for i, unit_id in ipairs(provider_config.unit_ids) do + local privilege = Privilege:new() + privilege.member_id = member.id + privilege.unit_id = unit_id + privilege.initiative_right = true + privilege.voting_right = true + privilege:save() + end + end + member.last_login = "now" + member.last_activity = "now" + member.active = true + member:save() + app.session.member = member + app.session:save() + request.redirect{ external = request.get_absolute_baseurl() } + +end + diff -r 4ddc5841e136 -r 5eb8b596f7d4 app/main/oauth2_client/redirect.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/oauth2_client/redirect.lua Mon Sep 27 10:58:14 2021 +0200 @@ -0,0 +1,29 @@ +local provider = param.get("provider") +local provider_config = config.oauth2_providers[provider] +if not provider_config then + return +end + +local params = { + response_type = "code", + redirect_uri = request.get_absolute_baseurl() .. "oauth2_client/callback.html?provider=" .. provider, + client_id = provider_config.client_id, + --scope = provider_config.scope, + state = app.session:additional_secret_for("oauth"), +} + +if provider_config.additional_auth_params then + for key, val in pairs(provider_config.additional_auth_params) do + params[key] = val + end +end + +local params_list = {} +for key, val in pairs(params) do + table.insert(params_list, encode.url_part(key) .. "=" .. encode.url_part(val)) +end + +local url = provider_config.auth_url .. "?" .. table.concat(params_list, "&") + +request.redirect{ external = url } +