Mercurial > prosody-modules
annotate mod_storage_ldap/mod_storage_ldap.lua @ 5668:ecfd7aece33b
mod_measure_modules: Report module statuses via OpenMetrics
Someone in the chat asked about a health check endpoint, which reminded
me of mod_http_status, which provides access to module statuses with
full details. After that, this idea came about, which seems natural.
As noted in the README, it could be used to monitor that critical
modules are in fact loaded correctly.
As more modules use the status API, the more useful this module and
mod_http_status becomes.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 06 Oct 2023 18:34:39 +0200 |
parents | e099586f9de5 |
children |
rev | line source |
---|---|
809 | 1 -- vim:sts=4 sw=4 |
2 | |
3 -- Prosody IM | |
4 -- Copyright (C) 2008-2010 Matthew Wild | |
5 -- Copyright (C) 2008-2010 Waqas Hussain | |
6 -- Copyright (C) 2012 Rob Hoelz | |
7 -- | |
8 -- This project is MIT/X11 licensed. Please see the | |
9 -- COPYING file in the source package for more information. | |
10 -- | |
11 | |
12 ---------------------------------------- | |
13 -- Constants and such -- | |
14 ---------------------------------------- | |
15 | |
16 local setmetatable = setmetatable; | |
17 local ldap = module:require 'ldap'; | |
18 local vcardlib = module:require 'ldap/vcard'; | |
19 local st = require 'util.stanza'; | |
20 local gettime = require 'socket'.gettime; | |
21 | |
22 if not ldap then | |
23 return; | |
24 end | |
25 | |
26 local CACHE_EXPIRY = 300; | |
27 local params = module:get_option('ldap'); | |
28 | |
29 ---------------------------------------- | |
30 -- Utility Functions -- | |
31 ---------------------------------------- | |
32 | |
33 local function ldap_record_to_vcard(record) | |
34 return vcardlib.create { | |
35 record = record, | |
36 format = params.vcard_format, | |
37 } | |
38 end | |
39 | |
40 local get_alias_for_user; | |
41 | |
42 do | |
43 local user_cache; | |
44 local last_fetch_time; | |
45 | |
46 local function populate_user_cache() | |
47 local ld = ldap.getconnection(); | |
48 | |
49 local usernamefield = params.user.usernamefield; | |
50 local namefield = params.user.namefield; | |
51 | |
52 user_cache = {}; | |
53 | |
54 for _, attrs in ld:search { base = params.user.basedn, scope = 'onelevel', filter = params.user.filter } do | |
55 user_cache[attrs[usernamefield]] = attrs[namefield]; | |
56 end | |
57 last_fetch_time = gettime(); | |
58 end | |
59 | |
60 function get_alias_for_user(user) | |
61 if last_fetch_time and last_fetch_time + CACHE_EXPIRY < gettime() then | |
62 user_cache = nil; | |
63 end | |
64 if not user_cache then | |
65 populate_user_cache(); | |
66 end | |
67 return user_cache[user]; | |
68 end | |
69 end | |
70 | |
71 ---------------------------------------- | |
72 -- General Setup -- | |
73 ---------------------------------------- | |
74 | |
75 local ldap_store = {}; | |
76 ldap_store.__index = ldap_store; | |
77 | |
78 local adapters = { | |
79 roster = {}, | |
80 vcard = {}, | |
81 } | |
82 | |
83 for k, v in pairs(adapters) do | |
84 setmetatable(v, ldap_store); | |
85 v.__index = v; | |
86 v.name = k; | |
87 end | |
88 | |
89 function ldap_store:get(username) | |
90 return nil, "get method unimplemented on store '" .. tostring(self.name) .. "'" | |
91 end | |
92 | |
93 function ldap_store:set(username, data) | |
94 return nil, "LDAP storage is currently read-only"; | |
95 end | |
96 | |
97 ---------------------------------------- | |
98 -- Roster Storage Implementation -- | |
99 ---------------------------------------- | |
100 | |
101 function adapters.roster:get(username) | |
102 local ld = ldap.getconnection(); | |
103 local contacts = {}; | |
104 | |
105 local memberfield = params.groups.memberfield; | |
106 local namefield = params.groups.namefield; | |
107 local filter = memberfield .. '=' .. tostring(username); | |
108 | |
109 local groups = {}; | |
110 for _, config in ipairs(params.groups) do | |
111 groups[ config[namefield] ] = config.name; | |
112 end | |
113 | |
114 -- XXX this kind of relies on the way we do groups at INOC | |
115 for _, attrs in ld:search { base = params.groups.basedn, scope = 'onelevel', filter = filter } do | |
116 if groups[ attrs[namefield] ] then | |
117 local members = attrs[memberfield]; | |
118 | |
119 for _, user in ipairs(members) do | |
120 if user ~= username then | |
121 local jid = user .. '@' .. module.host; | |
122 local record = contacts[jid]; | |
123 | |
124 if not record then | |
125 record = { | |
126 subscription = 'both', | |
127 groups = {}, | |
128 name = get_alias_for_user(user), | |
129 }; | |
130 contacts[jid] = record; | |
131 end | |
132 | |
133 record.groups[ groups[ attrs[namefield] ] ] = true; | |
134 end | |
135 end | |
136 end | |
137 end | |
138 | |
139 return contacts; | |
140 end | |
141 | |
142 ---------------------------------------- | |
143 -- vCard Storage Implementation -- | |
144 ---------------------------------------- | |
145 | |
146 function adapters.vcard:get(username) | |
147 if not params.vcard_format then | |
148 return nil, ''; | |
149 end | |
150 | |
151 local ld = ldap.getconnection(); | |
152 local filter = params.user.usernamefield .. '=' .. tostring(username); | |
153 | |
154 local match = ldap.singlematch { | |
155 base = params.user.basedn, | |
156 filter = filter, | |
157 }; | |
158 if match then | |
159 match.jid = username .. '@' .. module.host | |
160 return st.preserialize(ldap_record_to_vcard(match)); | |
161 else | |
162 return nil, 'not found'; | |
163 end | |
164 end | |
165 | |
166 ---------------------------------------- | |
167 -- Driver Definition -- | |
168 ---------------------------------------- | |
169 | |
813
2469f779b3f7
mod_storage_*: Update to use module:provides().
Waqas Hussain <waqas20@gmail.com>
parents:
809
diff
changeset
|
170 local driver = {}; |
809 | 171 |
172 function driver:open(store, typ) | |
173 local adapter = adapters[store]; | |
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 | 176 return adapter; |
177 end | |
178 return nil, "unsupported-store"; | |
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); |