mod_adhoc_oauth2_client/mod_adhoc_oauth2_client.lua
author Matthew Wild <mwild1@gmail.com>
Tue, 18 Jan 2022 17:01:18 +0000
changeset 4880 0f5f2d4475b9
parent 4272 871d140d61bb
child 5264 a9c1cc91d3d6
permissions -rw-r--r--
mod_http_xep227: Add support for import via APIs rather than direct store manipulation In particular this transitions PEP nodes and data to be imported via mod_pep's APIs, fixing issues with importing at runtime while PEP data may already be live in RAM. Next obvious candidate for this approach is rosters, so clients get immediate roster pushes and other special handling (such as emitting subscribes to reach the desired subscription state).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4265
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
local adhoc = require "util.adhoc";
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
local dataforms = require "util.dataforms";
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
local errors = require "util.error";
4267
d3af5f94d6df mod_http_oauth2: Improve storage of client secret
Kim Alvefur <zash@zash.se>
parents: 4266
diff changeset
     4
local hashes = require "util.hashes";
4265
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
local id = require "util.id";
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
local jid = require "util.jid";
4267
d3af5f94d6df mod_http_oauth2: Improve storage of client secret
Kim Alvefur <zash@zash.se>
parents: 4266
diff changeset
     7
local base64 = require"util.encodings".base64;
4265
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
local clients = module:open_store("oauth2_clients", "map");
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
4267
d3af5f94d6df mod_http_oauth2: Improve storage of client secret
Kim Alvefur <zash@zash.se>
parents: 4266
diff changeset
    11
local iteration_count = module:get_option_number("oauth2_client_iteration_count", 10000);
d3af5f94d6df mod_http_oauth2: Improve storage of client secret
Kim Alvefur <zash@zash.se>
parents: 4266
diff changeset
    12
local pepper = module:get_option_string("oauth2_client_pepper", "");
d3af5f94d6df mod_http_oauth2: Improve storage of client secret
Kim Alvefur <zash@zash.se>
parents: 4266
diff changeset
    13
4265
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
local new_client = dataforms.new({
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    15
	title = "Create OAuth2 client";
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    16
	{var = "FORM_TYPE"; type = "hidden"; value = "urn:uuid:ff0d55ed-2187-4ee0-820a-ab633a911c14#create"};
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    17
	{name = "name"; type = "text-single"; label = "Client name"; required = true};
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    18
	{name = "description"; type = "text-multi"; label = "Description"};
4271
43284437c5ed mod_adhoc_oauth2_client: Advertise URI fields with XEP-0122
Kim Alvefur <zash@zash.se>
parents: 4270
diff changeset
    19
	{name = "info_url"; type = "text-single"; label = "Informative URL"; desc = "Link to information about your client"; datatype = "xs:anyURI"};
43284437c5ed mod_adhoc_oauth2_client: Advertise URI fields with XEP-0122
Kim Alvefur <zash@zash.se>
parents: 4270
diff changeset
    20
	{
43284437c5ed mod_adhoc_oauth2_client: Advertise URI fields with XEP-0122
Kim Alvefur <zash@zash.se>
parents: 4270
diff changeset
    21
		name = "redirect_uri";
43284437c5ed mod_adhoc_oauth2_client: Advertise URI fields with XEP-0122
Kim Alvefur <zash@zash.se>
parents: 4270
diff changeset
    22
		type = "text-single";
43284437c5ed mod_adhoc_oauth2_client: Advertise URI fields with XEP-0122
Kim Alvefur <zash@zash.se>
parents: 4270
diff changeset
    23
		label = "Redirection URI";
43284437c5ed mod_adhoc_oauth2_client: Advertise URI fields with XEP-0122
Kim Alvefur <zash@zash.se>
parents: 4270
diff changeset
    24
		desc = "Where to redirect the user after authorizing.";
43284437c5ed mod_adhoc_oauth2_client: Advertise URI fields with XEP-0122
Kim Alvefur <zash@zash.se>
parents: 4270
diff changeset
    25
		datatype = "xs:anyURI";
43284437c5ed mod_adhoc_oauth2_client: Advertise URI fields with XEP-0122
Kim Alvefur <zash@zash.se>
parents: 4270
diff changeset
    26
		required = true;
43284437c5ed mod_adhoc_oauth2_client: Advertise URI fields with XEP-0122
Kim Alvefur <zash@zash.se>
parents: 4270
diff changeset
    27
	};
4265
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    28
})
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    29
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    30
local client_created = dataforms.new({
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    31
	title = "New OAuth2 client created";
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    32
	instructions = "Save these details, they will not be shown again";
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    33
	{var = "FORM_TYPE"; type = "hidden"; value = "urn:uuid:ff0d55ed-2187-4ee0-820a-ab633a911c14#created"};
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    34
	{name = "client_id"; type = "text-single"; label = "Client ID"};
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    35
	{name = "client_secret"; type = "text-single"; label = "Client secret"};
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    36
})
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    37
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    38
local function create_client(client, formerr, data)
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    39
	if formerr then
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    40
		local errmsg = {"Error in form:"};
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    41
		for field, err in pairs(formerr) do table.insert(errmsg, field .. ": " .. err); end
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    42
		return {status = "error"; error = {message = table.concat(errmsg, "\n")}};
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    43
	end
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    44
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    45
	local creator = jid.split(data.from);
4272
871d140d61bb mod_adhoc_oauth2_client: Fix including final client_id in result form
Kim Alvefur <zash@zash.se>
parents: 4271
diff changeset
    46
	local client_uid = id.short();
871d140d61bb mod_adhoc_oauth2_client: Fix including final client_id in result form
Kim Alvefur <zash@zash.se>
parents: 4271
diff changeset
    47
	local client_id = jid.join(creator, module.host, client_uid);
4267
d3af5f94d6df mod_http_oauth2: Improve storage of client secret
Kim Alvefur <zash@zash.se>
parents: 4266
diff changeset
    48
	local client_secret = id.long();
d3af5f94d6df mod_http_oauth2: Improve storage of client secret
Kim Alvefur <zash@zash.se>
parents: 4266
diff changeset
    49
	local salt = id.medium();
d3af5f94d6df mod_http_oauth2: Improve storage of client secret
Kim Alvefur <zash@zash.se>
parents: 4266
diff changeset
    50
	local i = iteration_count;
4265
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    51
4267
d3af5f94d6df mod_http_oauth2: Improve storage of client secret
Kim Alvefur <zash@zash.se>
parents: 4266
diff changeset
    52
	client.secret_hash = base64.encode(hashes.pbkdf2_hmac_sha256(client_secret, salt .. pepper, i));
d3af5f94d6df mod_http_oauth2: Improve storage of client secret
Kim Alvefur <zash@zash.se>
parents: 4266
diff changeset
    53
	client.iteration_count = i;
d3af5f94d6df mod_http_oauth2: Improve storage of client secret
Kim Alvefur <zash@zash.se>
parents: 4266
diff changeset
    54
	client.salt = salt;
4265
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    55
4272
871d140d61bb mod_adhoc_oauth2_client: Fix including final client_id in result form
Kim Alvefur <zash@zash.se>
parents: 4271
diff changeset
    56
	local ok, err = errors.coerce(clients:set(creator, client_uid, client));
4265
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    57
	module:log("info", "OAuth2 client %q created by %s", client_id, data.from);
4270
b43c6d614d22 mod_adhoc_oauth2_client: Fix adhoc status on error
Kim Alvefur <zash@zash.se>
parents: 4267
diff changeset
    58
	if not ok then return {status = "canceled"; error = {message = err}}; end
4265
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    59
4272
871d140d61bb mod_adhoc_oauth2_client: Fix including final client_id in result form
Kim Alvefur <zash@zash.se>
parents: 4271
diff changeset
    60
	return {status = "completed"; result = {layout = client_created; values = {client_id = client_id; client_secret = client_secret}}};
4265
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    61
end
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    62
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    63
local handler = adhoc.new_simple_form(new_client, create_client);
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    64
608be9a66876 mod_adhoc_oauth2_client: Allow creating OAuth2 clients via ad-hoc
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    65
module:provides("adhoc", module:require "adhoc".new(new_client.title, new_client[1].value, handler, "local_user"));
4266
6d7fb22c0440 mod_adhoc_oauth2_client: Note TODO
Kim Alvefur <zash@zash.se>
parents: 4265
diff changeset
    66
6d7fb22c0440 mod_adhoc_oauth2_client: Note TODO
Kim Alvefur <zash@zash.se>
parents: 4265
diff changeset
    67
-- TODO list/manage/revoke clients