annotate mod_storage_ldap/mod_storage_ldap.lua @ 5551:8bfcedd93a72

mod_rest: List all error conditions in OpenAPI spec These are not handled by datamanager but by util.stanza and util.error, so they are not represented in the JSON schema file.
author Kim Alvefur <zash@zash.se>
date Sat, 17 Jun 2023 16:26:33 +0200
parents e099586f9de5
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
809
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
1 -- vim:sts=4 sw=4
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
2
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
3 -- Prosody IM
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
4 -- Copyright (C) 2008-2010 Matthew Wild
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
5 -- Copyright (C) 2008-2010 Waqas Hussain
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
6 -- Copyright (C) 2012 Rob Hoelz
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
7 --
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
8 -- This project is MIT/X11 licensed. Please see the
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
9 -- COPYING file in the source package for more information.
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
10 --
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
11
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
12 ----------------------------------------
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
13 -- Constants and such --
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
14 ----------------------------------------
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
15
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
16 local setmetatable = setmetatable;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
17 local ldap = module:require 'ldap';
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
18 local vcardlib = module:require 'ldap/vcard';
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
19 local st = require 'util.stanza';
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
20 local gettime = require 'socket'.gettime;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
21
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
22 if not ldap then
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
23 return;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
24 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
25
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
26 local CACHE_EXPIRY = 300;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
27 local params = module:get_option('ldap');
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
28
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
29 ----------------------------------------
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
30 -- Utility Functions --
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
31 ----------------------------------------
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
32
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
33 local function ldap_record_to_vcard(record)
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
34 return vcardlib.create {
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
35 record = record,
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
36 format = params.vcard_format,
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
37 }
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
38 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
39
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
40 local get_alias_for_user;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
41
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
42 do
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
43 local user_cache;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
44 local last_fetch_time;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
45
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
46 local function populate_user_cache()
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
47 local ld = ldap.getconnection();
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
48
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
49 local usernamefield = params.user.usernamefield;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
50 local namefield = params.user.namefield;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
51
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
52 user_cache = {};
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
53
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
54 for _, attrs in ld:search { base = params.user.basedn, scope = 'onelevel', filter = params.user.filter } do
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
55 user_cache[attrs[usernamefield]] = attrs[namefield];
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
56 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
57 last_fetch_time = gettime();
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
58 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
59
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
60 function get_alias_for_user(user)
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
61 if last_fetch_time and last_fetch_time + CACHE_EXPIRY < gettime() then
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
62 user_cache = nil;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
63 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
64 if not user_cache then
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
65 populate_user_cache();
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
66 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
67 return user_cache[user];
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
68 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
69 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
70
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
71 ----------------------------------------
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
72 -- General Setup --
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
73 ----------------------------------------
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
74
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
75 local ldap_store = {};
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
76 ldap_store.__index = ldap_store;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
77
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
78 local adapters = {
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
79 roster = {},
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
80 vcard = {},
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
81 }
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
82
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
83 for k, v in pairs(adapters) do
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
84 setmetatable(v, ldap_store);
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
85 v.__index = v;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
86 v.name = k;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
87 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
88
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
89 function ldap_store:get(username)
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
90 return nil, "get method unimplemented on store '" .. tostring(self.name) .. "'"
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
91 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
92
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
93 function ldap_store:set(username, data)
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
94 return nil, "LDAP storage is currently read-only";
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
95 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
96
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
97 ----------------------------------------
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
98 -- Roster Storage Implementation --
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
99 ----------------------------------------
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
100
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
101 function adapters.roster:get(username)
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
102 local ld = ldap.getconnection();
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
103 local contacts = {};
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
104
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
105 local memberfield = params.groups.memberfield;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
106 local namefield = params.groups.namefield;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
107 local filter = memberfield .. '=' .. tostring(username);
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
108
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
109 local groups = {};
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
110 for _, config in ipairs(params.groups) do
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
111 groups[ config[namefield] ] = config.name;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
112 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
113
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
114 -- XXX this kind of relies on the way we do groups at INOC
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
115 for _, attrs in ld:search { base = params.groups.basedn, scope = 'onelevel', filter = filter } do
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
116 if groups[ attrs[namefield] ] then
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
117 local members = attrs[memberfield];
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
118
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
119 for _, user in ipairs(members) do
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
120 if user ~= username then
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
121 local jid = user .. '@' .. module.host;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
122 local record = contacts[jid];
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
123
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
124 if not record then
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
125 record = {
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
126 subscription = 'both',
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
127 groups = {},
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
128 name = get_alias_for_user(user),
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
129 };
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
130 contacts[jid] = record;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
131 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
132
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
133 record.groups[ groups[ attrs[namefield] ] ] = true;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
134 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
135 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
136 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
137 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
138
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
139 return contacts;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
140 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
141
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
142 ----------------------------------------
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
143 -- vCard Storage Implementation --
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
144 ----------------------------------------
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
145
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
146 function adapters.vcard:get(username)
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
147 if not params.vcard_format then
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
148 return nil, '';
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
149 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
150
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
151 local ld = ldap.getconnection();
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
152 local filter = params.user.usernamefield .. '=' .. tostring(username);
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
153
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
154 local match = ldap.singlematch {
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
155 base = params.user.basedn,
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
156 filter = filter,
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
157 };
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
158 if match then
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
159 match.jid = username .. '@' .. module.host
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
160 return st.preserialize(ldap_record_to_vcard(match));
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
161 else
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
162 return nil, 'not found';
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
163 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
164 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
165
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
166 ----------------------------------------
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
167 -- Driver Definition --
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
168 ----------------------------------------
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
169
813
2469f779b3f7 mod_storage_*: Update to use module:provides().
Waqas Hussain <waqas20@gmail.com>
parents: 809
diff changeset
170 local driver = {};
809
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
171
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
172 function driver:open(store, typ)
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
173 local adapter = adapters[store];
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
174
2299
e099586f9de5 mod_storage_ldap: Handle being passed an explicit storage "type" (fixes #654)
Kim Alvefur <zash@zash.se>
parents: 813
diff changeset
175 if adapter and typ == nil or typ == "keyval" then
809
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
176 return adapter;
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
177 end
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
178 return nil, "unsupported-store";
1d51c5e38faa Add LDAP plugin suite
rob@hoelz.ro
parents:
diff changeset
179 end
813
2469f779b3f7 mod_storage_*: Update to use module:provides().
Waqas Hussain <waqas20@gmail.com>
parents: 809
diff changeset
180 module:provides("storage", driver);