PageRenderTime 29ms CodeModel.GetById 9ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

/ucengine/src/core/uce_ctl.erl

http://github.com/AF83/ucengine
Erlang | 332 lines | 217 code | 41 blank | 74 comment | 0 complexity | 8d021ffbecece0826d387ac3fc60fc86 MD5 | raw file
  1%%
  2%%  U.C.Engine - Unified Collaboration Engine
  3%%  Copyright (C) 2011 af83
  4%%
  5%%  This program is free software: you can redistribute it and/or modify
  6%%  it under the terms of the GNU Affero General Public License as published by
  7%%  the Free Software Foundation, either version 3 of the License, or
  8%%  (at your option) any later version.
  9%%
 10%%  This program is distributed in the hope that it will be useful,
 11%%  but WITHOUT ANY WARRANTY; without even the implied warranty of
 12%%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13%%  GNU Affero General Public License for more details.
 14%%
 15%%  You should have received a copy of the GNU Affero General Public License
 16%%  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 17%%
 18-module(uce_ctl).
 19
 20-export([start/0, stop/0, cmd/2]).
 21
 22-export([meeting/3, meeting/4, user/3, user/4, user/5, user/6, role/4, role/7, time/2]).
 23
 24-include("uce.hrl").
 25
 26get_node() ->
 27    Command = init:get_arguments(),
 28    case utils:get(Command, ['-node']) of
 29        [none] ->
 30            NodeDomain =
 31                case re:run(atom_to_list(node()), "@(.*)", [{capture, all, list}]) of
 32                    {match, [_, Domain]} ->
 33                        Domain;
 34                    _ ->
 35                        "localhost"
 36                end,
 37            list_to_atom("ucengine@" ++ NodeDomain);
 38        [[Node]] ->
 39            list_to_atom(Node)
 40    end.
 41
 42args_to_dictionary([]) ->
 43    [];
 44args_to_dictionary([{Key, Value}|Tail]) when is_atom(Key) ->
 45    args_to_dictionary([{atom_to_list(Key), Value}] ++ Tail);
 46args_to_dictionary([{"-" ++ Key, Value} | Tail]) ->
 47    [{Key, string:join(Value, " ")}] ++ args_to_dictionary(Tail);
 48args_to_dictionary([_|Tail]) ->
 49    [] ++ args_to_dictionary(Tail).
 50
 51filter_node({"node", _Value}) ->
 52    false;
 53filter_node({_Name, _Value}) ->
 54    true.
 55
 56get_user_uid(Domain, Name) ->
 57    {ok, #uce_user{id=Uid}} = call(user, get_by_name, [Domain, Name]),
 58    {ok, Uid}.
 59
 60success(Result) when is_list(Result) ->
 61    io:format("Success: ~s", [Result]),
 62    ok;
 63success(Result) ->
 64    io:format("Success: ~p", [Result]),
 65    ok.
 66
 67start() ->
 68    Command = init:get_arguments(),
 69    Args = lists:filter(fun filter_node/1, args_to_dictionary(Command)),
 70    try cmd(proplists:lookup(dummy, Command), Args) of
 71        ok ->
 72            io:format("~n"),
 73            init:stop(0);
 74        error ->
 75            io:format("~n"),
 76            init:stop(2);
 77        {ok, nothing} ->
 78            init:stop(0);
 79        {ok, Result} ->
 80            io:format(Result, []),
 81            init:stop(0)
 82    catch
 83        error:_Reason ->
 84            usage();
 85        {error, nodedown} ->
 86            io:format("Fatal: U.C.Engine node is not running, call 'ucengine start' to start it.~n");
 87        Exception ->
 88            io:format("Fatal: ~p~n", [Exception]),
 89            init:stop(2)
 90    end,
 91    halt().
 92
 93cmd({dummy, [Domain, Object, Action|Other]}, Args) ->
 94    Fun = list_to_atom(Object),
 95    apply(?MODULE, Fun, [Domain, Action]++Other ++ [Args]);
 96cmd({dummy, [Object, Action]}, Args) ->
 97    Fun = list_to_atom(Object),
 98    ?MODULE:Fun(Action, Args).
 99
100stop() ->
101    ok.
102
103usage() ->
104    io:format("Usage:~n"),
105    io:format("ucengine-admin <domain> <object> <action> [--<parameter> <value>]~n~n"),
106
107    io:format("Meetings:~n"),
108    io:format("\tmeeting add <name> [--<metadata> <value>]~n"),
109    io:format("\tmeeting update <name> [--<metadata> <value>]~n"),
110    io:format("\tmeeting get <name>~n"),
111    io:format("\tmeeting delete <name>~n"),
112    io:format("\tmeeting list~n~n"),
113
114    io:format("Users:~n"),
115    io:format("\tuser add <name> <auth> <credential> [--<metadata> <value>]~n"),
116    io:format("\tuser update <name> <auth> <credential> [--<metadata> <value>]~n"),
117    io:format("\tuser get <name>~n"),
118    io:format("\tuser delete <name>~n"),
119    io:format("\tuser list~n"),
120    io:format("\tuser role add <name> <role> [--location <location>]~n"),
121    io:format("\tuser role delete <name> <role> [--location <location>]~n~n"),
122
123    io:format("Roles:~n"),
124    io:format("\trole add <name>~n"),
125    io:format("\trole delete <name>~n"),
126    io:format("\trole access add <name> <action> <object> [--<condition> <value>]~n"),
127    io:format("\trole access delete <name> <action> <object> [--<condition> <value>]~n"),
128    io:format("\trole access check <name> <action> <object> [--<condition> <value>]~n~n"),
129
130    io:format("ucengine-admin time get~n~n"),
131
132    io:format("U.C.Engine (c) AF83 - http://ucengine.org~n"),
133    {ok, nothing}.
134
135call(Object, Action, Args) ->
136    Module = list_to_atom("uce_" ++ atom_to_list(Object)),
137    case catch rpc:call(get_node(), Module, Action, Args) of
138        {badrpc, Reason} ->
139            throw({error, Reason});
140        {error, Reason} ->
141            throw({error, Reason});
142        Result ->
143            Result
144    end.
145
146%%
147%% Meeting add
148%%
149meeting(Domain, "add", Name, Metadata) ->
150    {ok, created} = call(meeting, add, [Domain,
151                                        #uce_meeting{id=Name,
152                                                     metadata={struct, Metadata}}]),
153    success(created);
154
155%%
156%% Meeting update
157%%
158meeting(Domain, "update", Name, Metadata) ->
159    {ok, updated} = call(meeting, update, [Domain,
160                                           #uce_meeting{id=Name,
161                                                        metadata={struct, Metadata}}]),
162    success(updated);
163
164%%
165%% Meeting delete
166%%
167meeting(Domain, "delete", Name, []) ->
168    {ok, deleted} = call(meeting, delete, [Domain, Name]),
169    success(deleted);
170
171%%
172%% Meeting get
173%%
174meeting(Domain, "get", Name, []) ->
175    {ok, Record} = call(meeting, get, [Domain, Name]),
176    {ok, pretty_print:print(Record, flat)}.
177
178%%
179%% Meeting list
180%%
181meeting(Domain, "list", []) ->
182    {ok, Records} = call(meeting, list, [Domain]),
183    {ok, pretty_print:print(Records, flat)}.
184
185%%
186%% Users
187%%
188user(Domain, "add", Name, Auth, Credential, Metadata) ->
189    {ok, Uid} = call(user, add, [Domain,
190                                 #uce_user{id=none,
191                                           name=Name,
192                                           auth=Auth,
193                                           credential=Credential,
194                                           metadata={struct, Metadata}}]),
195    success(Uid);
196
197%%
198%% User update
199%%
200user(Domain, "update", Name, Auth, Credential, Metadata) ->
201    {ok, Uid} = get_user_uid(Domain, Name),
202    {ok, updated} = call(user, update, [Domain,
203                                        #uce_user{id=Uid,
204                                                  name=Name,
205                                                  auth=Auth,
206                                                  credential=Credential,
207                                                  metadata={struct, Metadata}}]),
208    success(updated);
209
210%%
211%% User add role
212%%
213user(Domain, "role", "add", Name, Role, Args) ->
214    {ok, Uid} = get_user_uid(Domain, Name),
215    Location = proplists:get_value("location", Args, ""),
216    {ok, updated} = call(user, add_role, [Domain,
217                                          Uid,
218                                          {Role, Location}]),
219    success(updated);
220
221%%
222%% User delete role
223%%
224user(Domain, "role", "delete", Name, Role, Args) ->
225    {ok, Uid} = get_user_uid(Domain, Name),
226    Location = proplists:get_value("location", Args, ""),
227    {ok, updated} = call(user, delete_role, [Domain,
228                                             Uid,
229                                             {Role, Location}]),
230    success(Uid).
231
232%%
233%% Anonymous user add
234%%
235user(Domain, "add", Name, Auth, Metadata) ->
236    {ok, Uid} = call(user, add, [Domain,
237                                 #uce_user{id=none,
238                                           name=Name,
239                                           auth=Auth,
240                                           metadata=json_helpers:to_struct(Metadata)}]),
241    success(Uid).
242
243%%
244%% User delete
245%%
246user(Domain, "delete", Name, []) ->
247    {ok, #uce_user{id=Uid}} = call(user, get, [Domain, Name]),
248    {ok, deleted} = call(user, delete, [Domain, Uid]),
249    success(deleted);
250
251%%
252%% User get
253%%
254user(Domain, "get", Name, []) ->
255    {ok, Record} = call(user, get, [Domain, Name]),
256    {ok, pretty_print:print(Record, flat)}.
257
258%%
259%% User list
260%%
261user(Domain, "list", []) ->
262    {ok, Records} = call(user, list, [Domain]),
263    {ok, pretty_print:print(Records, flat)}.
264
265%%
266%% Role add
267%%
268role(Domain, "add", Name, []) ->
269    {ok, created} = call(role, add, [Domain, #uce_role{id=Name}]),
270    success(created);
271
272%%
273%% Role delete
274%%
275role(Domain, "delete", Name, []) ->
276    {ok, deleted} = call(role, delete, [Domain, Name]),
277    success(deleted).
278
279%%
280%% Role access add
281%%
282role(Domain, "access", "add", Name, Action, Object, Conditions) ->
283    {ok, updated} = call(role, add_access, [Domain, Name,
284                                            #uce_access{action=Action,
285                                                        object=Object,
286                                                        conditions=Conditions}]),
287    success(updated);
288
289%%
290%% Role access delete
291%%
292role(Domain, "access", "delete", Name, Action, Object, Conditions) ->
293    {ok, updated} = call(role, delete_access, [Domain, Name,
294                                               #uce_access{action=Action,
295                                                           object=Object,
296                                                           conditions=Conditions}]),
297    success(updated);
298
299%%
300%% Role access check
301%%
302role(Domain, "access", "check", Name, Action, Object, Args) ->
303    {ok, Uid} = get_user_uid(Domain, Name),
304    Location = proplists:get_value("location", Args, ""),
305
306    {_, Conditions} = proplists:split(Args, ["location"]),
307    {ok, Result} = call(access, check, [Domain,
308                                        Uid,
309                                        Location,
310                                        Object,
311                                        Action,
312                                        Conditions]),
313    success(Result).
314
315%%
316%% Time
317%%
318time("get", []) ->
319    io:format("Server time: ~p", [utils:now()]),
320    ok.
321
322-ifdef(TEST).
323-include_lib("eunit/include/eunit.hrl").
324
325parse_arguments_test() ->
326    ?assertEqual([], args_to_dictionary([])),
327    ?assertEqual([{"node", "plop"}], args_to_dictionary([{'-node', ["plop"]}])),
328    ?assertEqual([{"node", "plop plip"}], args_to_dictionary([{'-node', ["plop", "plip"]}])),
329    ?assertEqual([{"node", "plop plip"}, {"name", "chuck"}], args_to_dictionary([{'-node', ["plop", "plip"]}, {'-name', ["chuck"]}])),
330    ?assertEqual([{"node", "plop"}], args_to_dictionary([{'-node', ["plop"]}, {hello, "plop"}])).
331
332-endif.