Software /
code /
prosody-modules
Annotate
mod_storage_ldap/mod_storage_ldap.lua @ 1268:854a3933cfcd
mod_muc_log_http: URL-encode room names. This allows special characters in room names to work. Ideally this escaping shouldn’t be done in the user visible content, but the module’s template system doesn’t currently allow that.
author | Waqas Hussain <waqas20@gmail.com> |
---|---|
date | Sat, 04 Jan 2014 16:50:57 -0500 |
parent | 813:2469f779b3f7 |
child | 2299:e099586f9de5 |
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 | |
175 if adapter and not typ then | |
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); |