plugins/mod_tokenauth.lua
author Jonas Schäfer <jonas@wielicki.name>
Mon, 03 Oct 2022 12:55:11 +0200
changeset 12743 0dc80024fdd2
parent 12666 07424992d7fc
child 12746 126aefd2c4c6
permissions -rw-r--r--
Backed out changeset 1bc2220cd6ec The use of the error helpers creates an `<error/>` child element containing the error condition. This is however not allowed as per XEP-0198, which specifies that the error condition is to be a direct child of the `<failed/>` stream management element. This has triggered a fun reconnect loop in aioxmpp where it was reported by a user [1]. [1]: https://github.com/horazont/aioxmpp/issues/382
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10672
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
local id = require "util.id";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     2
local jid = require "util.jid";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     3
local base64 = require "util.encodings".base64;
12653
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
     4
local usermanager = require "core.usermanager";
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
     5
local generate_identifier = require "util.id".short;
10672
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     6
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     7
local token_store = module:open_store("auth_tokens", "map");
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
12653
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
     9
local function select_role(username, host, role)
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    10
	if role then
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    11
		return prosody.hosts[host].authz.get_role_by_name(role);
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    12
	end
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12653
diff changeset
    13
	return usermanager.get_user_role(username, host);
12653
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    14
end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    15
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    16
function create_jid_token(actor_jid, token_jid, token_role, token_ttl)
10672
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
	token_jid = jid.prep(token_jid);
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
	if not actor_jid or token_jid ~= actor_jid and not jid.compare(token_jid, actor_jid) then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
		return nil, "not-authorized";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
	end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    22
	local token_username, token_host, token_resource = jid.split(token_jid);
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
	if token_host ~= module.host then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
		return nil, "invalid-host";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
	end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
	local token_info = {
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    29
		owner = actor_jid;
10679
5efd6865486c mod_tokenauth: Track creation time of tokens
Matthew Wild <mwild1@gmail.com>
parents: 10678
diff changeset
    30
		created = os.time();
10672
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
		expires = token_ttl and (os.time() + token_ttl) or nil;
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
		jid = token_jid;
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    33
12653
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    34
		resource = token_resource;
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    35
		role = token_role;
10672
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
	};
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    38
	local token_id = id.long();
10678
4459afac4d13 mod_tokenauth: Handle tokens issued to bare hosts (eg components)
Kim Alvefur <zash@zash.se>
parents: 10673
diff changeset
    39
	local token = base64.encode("1;"..jid.join(token_username, token_host)..";"..token_id);
10672
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    40
	token_store:set(token_username, token_id, token_info);
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    42
	return token, token_info;
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
local function parse_token(encoded_token)
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
	local token = base64.decode(encoded_token);
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
	if not token then return nil; end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
	local token_jid, token_id = token:match("^1;([^;]+);(.+)$");
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
	if not token_jid then return nil; end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
	local token_user, token_host = jid.split(token_jid);
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    51
	return token_id, token_user, token_host;
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    53
12653
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    54
local function _get_parsed_token_info(token_id, token_user, token_host)
10672
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    55
	if token_host ~= module.host then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    56
		return nil, "invalid-host";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    57
	end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
	local token_info, err = token_store:get(token_user, token_id);
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
	if not token_info then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    61
		if err then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    62
			return nil, "internal-error";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
		end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
		return nil, "not-authorized";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    65
	end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    66
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    67
	if token_info.expires and token_info.expires < os.time() then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    68
		return nil, "not-authorized";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    69
	end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    70
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
	return token_info
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    72
end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
12653
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    74
function get_token_info(token)
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    75
	local token_id, token_user, token_host = parse_token(token);
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    76
	if not token_id then
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    77
		return nil, "invalid-token-format";
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    78
	end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    79
	return _get_parsed_token_info(token_id, token_user, token_host);
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    80
end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    81
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    82
function get_token_session(token, resource)
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    83
	local token_id, token_user, token_host = parse_token(token);
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    84
	if not token_id then
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    85
		return nil, "invalid-token-format";
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    86
	end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    87
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    88
	local token_info, err = _get_parsed_token_info(token_id, token_user, token_host);
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    89
	if not token_info then return nil, err; end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    90
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    91
	return {
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    92
		username = token_user;
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    93
		host = token_host;
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    94
		resource = token_info.resource or resource or generate_identifier();
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    95
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    96
		role = select_role(token_user, token_host, token_info.role);
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    97
	};
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    98
end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
    99
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10679
diff changeset
   100
10672
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   101
function revoke_token(token)
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   102
	local token_id, token_user, token_host = parse_token(token);
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   103
	if not token_id then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   104
		return nil, "invalid-token-format";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   105
	end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   106
	if token_host ~= module.host then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   107
		return nil, "invalid-host";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   108
	end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   109
	return token_store:set(token_user, token_id, nil);
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   110
end