16 affiliations = {}; |
16 affiliations = {}; |
17 nodes = {}; |
17 nodes = {}; |
18 }, service_mt); |
18 }, service_mt); |
19 end |
19 end |
20 |
20 |
21 function service:add_subscription(node, actor, jid) |
21 function service:may(node, actor, action) |
22 local node_obj = self.nodes[node]; |
22 if actor == true then return true; end |
23 if not node_obj then |
23 |
24 return false, "item-not-found"; |
24 |
25 end |
25 local node_obj = self.nodes[node]; |
26 node_obj.subscribers[jid] = true; |
26 local node_aff = node_obj and node_obj.affiliations[actor]; |
|
27 local service_aff = self.affiliations[actor] |
|
28 or self.config.get_affiliation(actor, node, action) |
|
29 or "none"; |
|
30 |
|
31 local node_capabilities = node_obj and node_obj.capabilities; |
|
32 local service_capabilities = self.config.capabilities; |
|
33 |
|
34 -- Check if node allows/forbids it |
|
35 if node_capabilities then |
|
36 local caps = node_capabilities[node_aff or service_aff]; |
|
37 if caps then |
|
38 local can = caps[action]; |
|
39 if can ~= nil then |
|
40 return can; |
|
41 end |
|
42 end |
|
43 end |
|
44 -- Check service-wide capabilities instead |
|
45 local caps = service_capabilities[node_aff or service_aff]; |
|
46 if caps then |
|
47 local can = caps[action]; |
|
48 if can ~= nil then |
|
49 return can; |
|
50 end |
|
51 end |
|
52 |
|
53 return false; |
|
54 end |
|
55 |
|
56 function service:set_affiliation(node, actor, jid, affiliation) |
|
57 -- Access checking |
|
58 if not self:may(node, actor, "set_affiliation") then |
|
59 return false, "forbidden"; |
|
60 end |
|
61 -- |
|
62 local node_obj = self.nodes[node]; |
|
63 if not node_obj then |
|
64 return false, "item-not-found"; |
|
65 end |
|
66 node_obj.affiliations[jid] = affiliation; |
|
67 local _, jid_sub = self:get_subscription(node, nil, jid); |
|
68 if not jid_sub and not self:may(node, jid, "be_unsubscribed") then |
|
69 local ok, err = self:add_subscription(node, nil, jid); |
|
70 if not ok then |
|
71 return ok, err; |
|
72 end |
|
73 elseif jid_sub and not self:may(node, jid, "be_subscribed") then |
|
74 local ok, err = self:add_subscription(node, nil, jid); |
|
75 if not ok then |
|
76 return ok, err; |
|
77 end |
|
78 end |
|
79 return true; |
|
80 end |
|
81 |
|
82 function service:add_subscription(node, actor, jid, options) |
|
83 -- Access checking |
|
84 local cap; |
|
85 if jid == actor or self.config.jids_equal(actor, jid) then |
|
86 cap = "subscribe"; |
|
87 else |
|
88 cap = "subscribe_other"; |
|
89 end |
|
90 if not self:may(node, actor, cap) then |
|
91 return false, "forbidden"; |
|
92 end |
|
93 if not self:may(node, jid, "be_subscribed") then |
|
94 return false, "forbidden"; |
|
95 end |
|
96 -- |
|
97 local node_obj = self.nodes[node]; |
|
98 if not node_obj then |
|
99 if not self.config.autocreate_on_subscribe then |
|
100 return false, "item-not-found"; |
|
101 else |
|
102 local ok, err = self:create(node, actor); |
|
103 if not ok then |
|
104 return ok, err; |
|
105 end |
|
106 end |
|
107 end |
|
108 node_obj.subscribers[jid] = options or true; |
27 return true; |
109 return true; |
28 end |
110 end |
29 |
111 |
30 function service:remove_subscription(node, actor, jid) |
112 function service:remove_subscription(node, actor, jid) |
|
113 -- Access checking |
|
114 local cap; |
|
115 if jid == actor or self.config.jids_equal(actor, jid) then |
|
116 cap = "unsubscribe"; |
|
117 else |
|
118 cap = "unsubscribe_other"; |
|
119 end |
|
120 if not self:may(node, actor, cap) then |
|
121 return false, "forbidden"; |
|
122 end |
|
123 if not self:may(node, jid, "be_unsubscribed") then |
|
124 return false, "forbidden"; |
|
125 end |
|
126 -- |
31 local node_obj = self.nodes[node]; |
127 local node_obj = self.nodes[node]; |
32 if not node_obj then |
128 if not node_obj then |
33 return false, "item-not-found"; |
129 return false, "item-not-found"; |
34 end |
130 end |
35 if not node_obj.subscribers[jid] then |
131 if not node_obj.subscribers[jid] then |
38 node_obj.subscribers[jid] = nil; |
134 node_obj.subscribers[jid] = nil; |
39 return true; |
135 return true; |
40 end |
136 end |
41 |
137 |
42 function service:get_subscription(node, actor, jid) |
138 function service:get_subscription(node, actor, jid) |
|
139 -- Access checking |
|
140 local cap; |
|
141 if jid == actor or self.config.jids_equal(actor, jid) then |
|
142 cap = "get_subscription"; |
|
143 else |
|
144 cap = "get_subscription_other"; |
|
145 end |
|
146 if not self:may(node, actor, cap) then |
|
147 return false, "forbidden"; |
|
148 end |
|
149 -- |
43 local node_obj = self.nodes[node]; |
150 local node_obj = self.nodes[node]; |
44 if node_obj then |
151 if node_obj then |
45 return node_obj.subscribers[jid]; |
152 return true, node_obj.subscribers[jid]; |
46 end |
153 end |
47 end |
154 end |
48 |
155 |
49 function service:create(node, actor) |
156 function service:create(node, actor) |
50 if not self.nodes[node] then |
157 -- Access checking |
51 self.nodes[node] = { name = node, subscribers = {}, config = {}, data = {} }; |
158 if not self:may(node, actor, "create") then |
52 return true; |
159 return false, "forbidden"; |
53 end |
160 end |
54 return false, "conflict"; |
161 -- |
|
162 if self.nodes[node] then |
|
163 return false, "conflict"; |
|
164 end |
|
165 |
|
166 self.nodes[node] = { |
|
167 name = node; |
|
168 subscribers = {}; |
|
169 config = {}; |
|
170 data = {}; |
|
171 affiliations = {}; |
|
172 }; |
|
173 local ok, err = self:set_affiliation(node, true, actor, "owner"); |
|
174 if not ok then |
|
175 self.nodes[node] = nil; |
|
176 end |
|
177 return ok, err; |
55 end |
178 end |
56 |
179 |
57 function service:publish(node, actor, id, item) |
180 function service:publish(node, actor, id, item) |
58 local node_obj = self.nodes[node]; |
181 -- Access checking |
59 if not node_obj then |
182 if not self:may(node, actor, "publish") then |
60 node_obj = { name = node, subscribers = {}, config = {}, data = {} }; |
183 return false, "forbidden"; |
61 self.nodes[node] = node_obj; |
184 end |
|
185 -- |
|
186 local node_obj = self.nodes[node]; |
|
187 if not node_obj then |
|
188 if not self.config.autocreate_on_publish then |
|
189 return false, "item-not-found"; |
|
190 end |
|
191 local ok, err = self:create(node, actor); |
|
192 if not ok then |
|
193 return ok, err; |
|
194 end |
|
195 node_obj = self.nodes[node]; |
62 end |
196 end |
63 node_obj.data[id] = item; |
197 node_obj.data[id] = item; |
64 self.cb.broadcaster(node, node_obj.subscribers, item); |
198 self.config.broadcaster(node, node_obj.subscribers, item); |
65 return true; |
199 return true; |
66 end |
200 end |
67 |
201 |
68 function service:retract(node, actor, id, retract) |
202 function service:retract(node, actor, id, retract) |
|
203 -- Access checking |
|
204 if not self:may(node, actor, "retract") then |
|
205 return false, "forbidden"; |
|
206 end |
|
207 -- |
69 local node_obj = self.nodes[node]; |
208 local node_obj = self.nodes[node]; |
70 if (not node_obj) or (not node_obj.data[id]) then |
209 if (not node_obj) or (not node_obj.data[id]) then |
71 return false, "item-not-found"; |
210 return false, "item-not-found"; |
72 end |
211 end |
73 node_obj.data[id] = nil; |
212 node_obj.data[id] = nil; |
74 if retract then |
213 if retract then |
75 self.cb.broadcaster(node, node_obj.subscribers, retract); |
214 self.config.broadcaster(node, node_obj.subscribers, retract); |
76 end |
215 end |
77 return true |
216 return true |
78 end |
217 end |
79 |
218 |
80 function service:get(node, actor, id) |
219 function service:get_items(node, actor, id) |
81 local node_obj = self.nodes[node]; |
220 -- Access checking |
82 if node_obj then |
221 if not self:may(node, actor, "get_items") then |
83 if id then |
222 return false, "forbidden"; |
84 return { node_obj.data[id] }; |
223 end |
85 else |
224 -- |
86 return node_obj.data; |
225 local node_obj = self.nodes[node]; |
87 end |
226 if not node_obj then |
|
227 return false, "item-not-found"; |
|
228 end |
|
229 if id then -- Restrict results to a single specific item |
|
230 return true, { node_obj.data[id] }; |
|
231 else |
|
232 return true, node_obj.data; |
88 end |
233 end |
89 end |
234 end |
90 |
235 |
91 function service:get_nodes(actor) |
236 function service:get_nodes(actor) |
|
237 -- Access checking |
|
238 if not self:may(node, actor, "get_nodes") then |
|
239 return false, "forbidden"; |
|
240 end |
|
241 -- |
92 return true, self.nodes; |
242 return true, self.nodes; |
93 end |
243 end |
94 |
244 |
95 return _M; |
245 return _M; |