Mercurial > prosody-modules
annotate mod_storage_ldap/mod_storage_ldap.lua @ 5935:46394b327d17
mod_http_oauth2: Guard against malformed authorization header
Prevent error on calling :lower() afterwards
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Mon, 15 Jul 2024 20:02:25 +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); |