1 |
|
%%% ==================================================================== |
2 |
|
%%% ``The contents of this file are subject to the Erlang Public License, |
3 |
|
%%% Version 1.1, (the "License"); you may not use this file except in |
4 |
|
%%% compliance with the License. You should have received a copy of the |
5 |
|
%%% Erlang Public License along with this software. If not, it can be |
6 |
|
%%% retrieved via the world wide web at http://www.erlang.org/. |
7 |
|
%%% |
8 |
|
%%% |
9 |
|
%%% Software distributed under the License is distributed on an "AS IS" |
10 |
|
%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See |
11 |
|
%%% the License for the specific language governing rights and limitations |
12 |
|
%%% under the License. |
13 |
|
%%% |
14 |
|
%%% |
15 |
|
%%% The Initial Developer of the Original Code is ProcessOne. |
16 |
|
%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne |
17 |
|
%%% All Rights Reserved.'' |
18 |
|
%%% This software is copyright 2006-2015, ProcessOne. |
19 |
|
%%% |
20 |
|
%%% @copyright 2006-2015 ProcessOne |
21 |
|
%%% @author Christophe Romain <christophe.romain@process-one.net> |
22 |
|
%%% [http://www.process-one.net/] |
23 |
|
%%% @end |
24 |
|
%%% ==================================================================== |
25 |
|
|
26 |
|
|
27 |
|
-module(node_hometree). |
28 |
|
-behaviour(gen_pubsub_node). |
29 |
|
-author('christophe.romain@process-one.net'). |
30 |
|
-include("mongoose.hrl"). |
31 |
|
-include("pubsub.hrl"). |
32 |
|
-include("jlib.hrl"). |
33 |
|
|
34 |
|
-export([based_on/0, init/3, terminate/2, options/0, features/0, |
35 |
|
create_node_permission/6, node_to_path/1, |
36 |
|
path_to_node/1]). |
37 |
|
|
38 |
947 |
based_on() -> node_flat. |
39 |
|
|
40 |
|
init(Host, ServerHost, Opts) -> |
41 |
1 |
node_flat:init(Host, ServerHost, Opts), |
42 |
1 |
Owner = mod_pubsub:service_jid(Host), |
43 |
1 |
spawn(fun() -> continue_init(Host, ServerHost, Owner) end), |
44 |
1 |
ok. |
45 |
|
|
46 |
|
terminate(Host, ServerHost) -> |
47 |
1 |
node_flat:terminate(Host, ServerHost). |
48 |
|
|
49 |
|
options() -> |
50 |
97 |
node_flat:options(). |
51 |
|
|
52 |
|
features() -> |
53 |
479 |
node_flat:features(). |
54 |
|
|
55 |
|
%% @doc Checks if the current user has the permission to create the requested node |
56 |
|
%% <p>In hometree node, the permission is decided by the place in the |
57 |
|
%% hierarchy where the user is creating the node. The access parameter is also |
58 |
|
%% checked. This parameter depends on the value of the |
59 |
|
%% <tt>access_createnode</tt> ACL value in ejabberd config file.</p> |
60 |
|
%% <p>This function also check that node can be created as a children of its |
61 |
|
%% parent node</p> |
62 |
|
create_node_permission(Host, _ServerHost, _Node, _ParentNode, |
63 |
|
#jid{ luser = <<>>, lserver = Host, lresource = <<>> }, _Access) -> |
64 |
2 |
{result, true}; % pubsub service always allowed |
65 |
|
create_node_permission(_Host, ServerHost, Node, _ParentNode, |
66 |
|
#jid{ luser = LUser, lserver = LServer } = Owner, Access) -> |
67 |
7 |
{ok, HostType} = mongoose_domain_api:get_domain_host_type(ServerHost), |
68 |
7 |
case acl:match_rule(HostType, ServerHost, Access, Owner) of |
69 |
|
allow -> |
70 |
7 |
case node_to_path(Node) of |
71 |
7 |
[<<"home">>, LServer, LUser | _] -> {result, true}; |
72 |
:-( |
_ -> {result, false} |
73 |
|
end; |
74 |
:-( |
_ -> {result, false} |
75 |
|
end. |
76 |
|
|
77 |
|
%% @doc <p>Return the path of the node.</p> |
78 |
|
node_to_path(Node) -> |
79 |
102 |
mongoose_bin:tokens(Node, <<"/">>). |
80 |
|
|
81 |
1 |
path_to_node([]) -> <<>>; |
82 |
9 |
path_to_node(Path) -> mongoose_bin:join([<<"">> | Path], <<"/">>). |
83 |
|
|
84 |
|
continue_init(Host, ServerHost, Owner) -> |
85 |
|
% we have to wait for mod_pubsub to be up and running before we try to use it |
86 |
1 |
Proc = gen_mod:get_module_proc(ServerHost, ?PROCNAME), |
87 |
1 |
case wait_for(Proc, 5) of |
88 |
|
{ok, _} -> |
89 |
1 |
mod_pubsub:create_node(Host, ServerHost, <<"/home">>, Owner, <<"hometree">>), |
90 |
1 |
mod_pubsub:create_node(Host, ServerHost, <<"/home/", ServerHost/binary>>, Owner, <<"hometree">>); |
91 |
|
{error, E} -> |
92 |
:-( |
error(E) |
93 |
|
end. |
94 |
|
|
95 |
|
wait_for(_Proc, 0) -> |
96 |
:-( |
?LOG_ERROR(#{what => plugin_init_failed, plugin => ?MODULE}), |
97 |
:-( |
{error, no_pubsub_proc}; |
98 |
|
wait_for(Proc, Retries) -> |
99 |
1 |
case whereis(Proc) of |
100 |
|
undefined -> |
101 |
:-( |
timer:sleep(timer:seconds(1)), |
102 |
:-( |
wait_for(Proc, Retries - 1); |
103 |
|
P -> |
104 |
1 |
{ok, P} |
105 |
|
end. |