mod_client_management/mod_client_management.lua
author Matthew Wild <mwild1@gmail.com>
Thu, 30 Mar 2023 11:32:50 +0100
changeset 5298 385346b6c81d
child 5305 8ef197cccd74
permissions -rw-r--r--
mod_client_management: New module for users to view/manage permitted clients This is just the data and API part.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5298
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
local modulemanager = require "core.modulemanager";
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     2
local usermanager = require "core.usermanager";
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     3
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
local id = require "util.id";
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     5
local jid = require "util.jid";
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     6
local st = require "util.stanza";
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     7
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
local strict = module:get_option_boolean("enforce_client_ids", false);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     9
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
local tokenauth = module:depends("tokenauth");
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    11
local mod_fast = module:depends("sasl2_fast");
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    12
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    13
local client_store = assert(module:open_store("clients", "keyval+"));
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    14
--[[{
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    15
	id = id;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    16
	first_seen =
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
	last_seen =
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
	user_agent = {
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
		name =
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
		os =
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
	}
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    22
--}]]
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
local xmlns_sasl2 = "urn:xmpp:sasl:2";
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
local function get_user_agent(sasl_handler, token_info)
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
	local sasl_agent = sasl_handler and sasl_handler.user_agent;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
	local token_agent = token_info and token_info.data and token_info.data.oauth2_client;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    29
	if not (sasl_agent or token_agent) then return; end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
	return {
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
		software = sasl_agent and sasl_agent.software or token_agent and token_agent.name or nil;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
		uri = token_agent and token_agent.uri or nil;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    33
		device = sasl_agent and sasl_agent.device or nil;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
	};
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
module:hook("sasl2/c2s/success", function (event)
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    38
	local session = event.session;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
	local username, client_id = session.username, session.client_id;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    40
	local mechanism = session.sasl_handler.selected;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
	local token_info = session.sasl_handler.token_info;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    42
	local token_id = token_info and token_info.id or nil;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
	local now = os.time();
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
	if client_id then -- SASL2, have client identifier
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
		local is_new_client;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
		local client_state = client_store:get_key(username, client_id);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
		if not client_state then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
			is_new_client = true;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    51
			client_state = {
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
				id = client_id;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    53
				first_seen = now;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    54
				user_agent = get_user_agent(session.sasl_handler, token_info);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    55
				full_jid = nil;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    56
				last_seen = nil;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    57
				mechanisms = {};
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
			};
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
		end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
		-- Update state
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    61
		client_state.full_jid = session.full_jid;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    62
		client_state.last_seen = now;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
		client_state.mechanisms[mechanism] = now;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
		if session.sasl_handler.fast_auth then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    65
			client_state.fast_auth = now;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    66
		end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    67
		if token_id then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    68
			client_state.auth_token_id = token_id;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    69
		end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    70
		-- Store updated state
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
		client_store:set_key(username, client_id, client_state);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    72
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
		if is_new_client then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    74
			module:fire_event("client_management/new-client", { client = client_state });
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    75
		end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    76
	end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    77
end);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    78
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    79
local function find_client_by_resource(username, resource)
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    80
	local full_jid = jid.join(username, module.host, resource);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    81
	local clients = client_store:get(username);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    82
	if not clients then return; end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    83
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    84
	for _, client_state in pairs(clients) do
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    85
		if client_state.full_jid == full_jid then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    86
			return client_state;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    87
		end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    88
	end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    89
end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    90
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    91
module:hook("resource-bind", function (event)
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    92
	local session = event.session;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    93
	if session.client_id then return; end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    94
	local is_new_client;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    95
	local client_state = find_client_by_resource(event.session.username, event.session.resource);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    96
	local now = os.time();
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    97
	if not client_state then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    98
		is_new_client = true;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    99
		client_state = {
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   100
			id = id.short();
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   101
			first_seen = now;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   102
			user_agent = nil;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   103
			full_jid = nil;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   104
			last_seen = nil;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   105
			mechanisms = {};
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   106
			legacy = true;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   107
		};
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   108
	end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   109
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   110
	-- Update state
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   111
	local legacy_info = session.client_management_info;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   112
	client_state.full_jid = session.full_jid;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   113
	client_state.last_seen = now;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   114
	client_state.mechanisms[legacy_info.mechanism] = now;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   115
	if legacy_info.fast_auth then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   116
		client_state.fast_auth = now;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   117
	end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   118
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   119
	local token_id = legacy_info.token_info and legacy_info.token_info.id;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   120
	if token_id then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   121
		client_state.auth_token_id = token_id;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   122
	end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   123
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   124
	-- Store updated state
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   125
	client_store:set_key(session.username, client_state.id, client_state);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   126
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   127
	if is_new_client then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   128
		module:fire_event("client_management/new-client", { client = client_state });
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   129
	end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   130
end);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   131
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   132
if strict then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   133
	module:hook_tag(xmlns_sasl2, "authenticate", function (session, auth)
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   134
		local user_agent = auth:get_child("user-agent");
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   135
		if not user_agent or not user_agent.attr.id then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   136
			local failure = st.stanza("failure", { xmlns = xmlns_sasl2 })
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   137
				:tag("malformed-request", { xmlns = "urn:ietf:params:xml:ns:xmpp-sasl" }):up()
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   138
				:text_tag("text", "Client identifier required but not supplied");
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   139
			session.send(failure);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   140
			return true;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   141
		end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   142
	end, 500);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   143
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   144
	if modulemanager.get_modules_for_host(module.host):contains("saslauth") then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   145
		module:log("error", "mod_saslauth is enabled, but enforce_client_ids is enabled and will prevent it from working");
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   146
	end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   147
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   148
	module:hook("stanza/urn:ietf:params:xml:ns:xmpp-sasl:auth", function (event)
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   149
		-- Block legacy SASL, if for some reason it is being used (either mod_saslauth is loaded,
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   150
		-- or clients try it without advertisement)
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   151
		module:log("warn", "Blocking legacy SASL authentication because enforce_client_ids is enabled");
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   152
		local failure = st.stanza("failure", { xmlns = xmlns_sasl2 })
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   153
			:tag("malformed-request", { xmlns = "urn:ietf:params:xml:ns:xmpp-sasl" }):up()
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   154
			:text_tag("text", "Legacy SASL authentication is not available on this server");
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   155
		event.session.send(failure);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   156
		return true;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   157
	end);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   158
else
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   159
	-- Legacy client compat code
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   160
	module:hook("authentication-success", function (event)
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   161
		local session = event.session;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   162
		if session.client_id then return; end -- SASL2 client
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   163
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   164
		local sasl_handler = session.sasl_handler;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   165
		session.client_management_info = {
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   166
			mechanism = sasl_handler.selected;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   167
			token_info = sasl_handler.token_info;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   168
			fast_auth = sasl_handler.fast_auth;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   169
		};
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   170
	end);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   171
end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   172
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   173
local function is_password_mechanism(mech_name)
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   174
	if mech_name == "OAUTHBEARER" then return false; end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   175
	if mech_name:match("^HT%-") then return false; end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   176
	return true;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   177
end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   178
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   179
local function is_client_active(client)
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   180
	local username, host = jid.split(client.full_jid);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   181
	local account_info = usermanager.get_account_info(username, host);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   182
	local last_password_change = account_info and account_info.password_updated;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   183
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   184
	local status = {};
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   185
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   186
	-- Check for an active token grant that has been previously used by this client
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   187
	if client.auth_token_id then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   188
		local grant = tokenauth.get_grant_info(client.auth_token_id);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   189
		if grant then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   190
			status.active_grant = grant;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   191
		end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   192
	end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   193
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   194
	-- Check for active FAST tokens
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   195
	if client.fast_auth then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   196
		if mod_fast.is_client_fast(username, client.id, last_password_change) then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   197
			status.active_fast = client.fast_auth;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   198
		end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   199
	end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   200
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   201
	-- Client has access if any password-based SASL mechanisms have been used since last password change
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   202
	for mech, mech_last_used in pairs(client.mechanisms) do
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   203
		if is_password_mechanism(mech) and mech_last_used >= last_password_change then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   204
			status.active_password = mech_last_used;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   205
		end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   206
	end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   207
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   208
	if prosody.full_sessions[client.full_jid] then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   209
		status.active_connected = true;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   210
	end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   211
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   212
	if next(status) == nil then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   213
		return nil;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   214
	end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   215
	return status;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   216
end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   217
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   218
-- Public API
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   219
--luacheck: ignore 131
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   220
function get_active_clients(username)
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   221
	local clients = client_store:get(username);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   222
	local active_clients = {};
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   223
	local used_grants = {};
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   224
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   225
	-- Go through known clients, check whether they could possibly log in
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   226
	for client_id, client in pairs(clients or {}) do --luacheck: ignore 213/client_id
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   227
		local active = is_client_active(client);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   228
		if active then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   229
			client.type = "session";
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   230
			client.active = active;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   231
			table.insert(active_clients, client);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   232
			if active.active_grant then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   233
				used_grants[active.active_grant.id] = true;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   234
			end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   235
		end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   236
	end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   237
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   238
	-- Next, account for any grants that have been issued, but never actually logged in
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   239
	for grant_id, grant in pairs(tokenauth.get_user_grants(username) or {}) do
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   240
		if not used_grants[grant_id] then -- exclude grants already accounted for
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   241
			table.insert(active_clients, {
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   242
				id = grant_id;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   243
				type = "access";
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   244
				first_seen = grant.created;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   245
				last_seen = grant.accessed;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   246
				active = {
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   247
					active_grant = grant;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   248
				};
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   249
				user_agent = get_user_agent(nil, grant);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   250
			});
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   251
		end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   252
	end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   253
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   254
	table.sort(active_clients, function (a, b)
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   255
		if a.last_seen and b.last_seen then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   256
			return a.last_seen < b.last_seen;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   257
		elseif not (a.last_seen or b.last_seen) then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   258
			if a.first_seen and b.first_seen then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   259
				return a.first_seen < b.first_seen;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   260
			end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   261
		elseif b.last_seen then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   262
			return true;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   263
		elseif a.last_seen then
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   264
			return false;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   265
		end
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   266
		return a.id < b.id;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   267
	end);
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   268
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   269
	return active_clients;
385346b6c81d mod_client_management: New module for users to view/manage permitted clients
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   270
end