PageRenderTime 56ms CodeModel.GetById 21ms 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. -export([start/0, stop/0, cmd/2]).
  20. -export([meeting/3, meeting/4, user/3, user/4, user/5, user/6, role/4, role/7, time/2]).
  21. -include("uce.hrl").
  22. get_node() ->
  23. Command = init:get_arguments(),
  24. case utils:get(Command, ['-node']) of
  25. [none] ->
  26. NodeDomain =
  27. case re:run(atom_to_list(node()), "@(.*)", [{capture, all, list}]) of
  28. {match, [_, Domain]} ->
  29. Domain;
  30. _ ->
  31. "localhost"
  32. end,
  33. list_to_atom("ucengine@" ++ NodeDomain);
  34. [[Node]] ->
  35. list_to_atom(Node)
  36. end.
  37. args_to_dictionary([]) ->
  38. [];
  39. args_to_dictionary([{Key, Value}|Tail]) when is_atom(Key) ->
  40. args_to_dictionary([{atom_to_list(Key), Value}] ++ Tail);
  41. args_to_dictionary([{"-" ++ Key, Value} | Tail]) ->
  42. [{Key, string:join(Value, " ")}] ++ args_to_dictionary(Tail);
  43. args_to_dictionary([_|Tail]) ->
  44. [] ++ args_to_dictionary(Tail).
  45. filter_node({"node", _Value}) ->
  46. false;
  47. filter_node({_Name, _Value}) ->
  48. true.
  49. get_user_uid(Domain, Name) ->
  50. {ok, #uce_user{id=Uid}} = call(user, get_by_name, [Domain, Name]),
  51. {ok, Uid}.
  52. success(Result) when is_list(Result) ->
  53. io:format("Success: ~s", [Result]),
  54. ok;
  55. success(Result) ->
  56. io:format("Success: ~p", [Result]),
  57. ok.
  58. start() ->
  59. Command = init:get_arguments(),
  60. Args = lists:filter(fun filter_node/1, args_to_dictionary(Command)),
  61. try cmd(proplists:lookup(dummy, Command), Args) of
  62. ok ->
  63. io:format("~n"),
  64. init:stop(0);
  65. error ->
  66. io:format("~n"),
  67. init:stop(2);
  68. {ok, nothing} ->
  69. init:stop(0);
  70. {ok, Result} ->
  71. io:format(Result, []),
  72. init:stop(0)
  73. catch
  74. error:_Reason ->
  75. usage();
  76. {error, nodedown} ->
  77. io:format("Fatal: U.C.Engine node is not running, call 'ucengine start' to start it.~n");
  78. Exception ->
  79. io:format("Fatal: ~p~n", [Exception]),
  80. init:stop(2)
  81. end,
  82. halt().
  83. cmd({dummy, [Domain, Object, Action|Other]}, Args) ->
  84. Fun = list_to_atom(Object),
  85. apply(?MODULE, Fun, [Domain, Action]++Other ++ [Args]);
  86. cmd({dummy, [Object, Action]}, Args) ->
  87. Fun = list_to_atom(Object),
  88. ?MODULE:Fun(Action, Args).
  89. stop() ->
  90. ok.
  91. usage() ->
  92. io:format("Usage:~n"),
  93. io:format("ucengine-admin <domain> <object> <action> [--<parameter> <value>]~n~n"),
  94. io:format("Meetings:~n"),
  95. io:format("\tmeeting add <name> [--<metadata> <value>]~n"),
  96. io:format("\tmeeting update <name> [--<metadata> <value>]~n"),
  97. io:format("\tmeeting get <name>~n"),
  98. io:format("\tmeeting delete <name>~n"),
  99. io:format("\tmeeting list~n~n"),
  100. io:format("Users:~n"),
  101. io:format("\tuser add <name> <auth> <credential> [--<metadata> <value>]~n"),
  102. io:format("\tuser update <name> <auth> <credential> [--<metadata> <value>]~n"),
  103. io:format("\tuser get <name>~n"),
  104. io:format("\tuser delete <name>~n"),
  105. io:format("\tuser list~n"),
  106. io:format("\tuser role add <name> <role> [--location <location>]~n"),
  107. io:format("\tuser role delete <name> <role> [--location <location>]~n~n"),
  108. io:format("Roles:~n"),
  109. io:format("\trole add <name>~n"),
  110. io:format("\trole delete <name>~n"),
  111. io:format("\trole access add <name> <action> <object> [--<condition> <value>]~n"),
  112. io:format("\trole access delete <name> <action> <object> [--<condition> <value>]~n"),
  113. io:format("\trole access check <name> <action> <object> [--<condition> <value>]~n~n"),
  114. io:format("ucengine-admin time get~n~n"),
  115. io:format("U.C.Engine (c) AF83 - http://ucengine.org~n"),
  116. {ok, nothing}.
  117. call(Object, Action, Args) ->
  118. Module = list_to_atom("uce_" ++ atom_to_list(Object)),
  119. case catch rpc:call(get_node(), Module, Action, Args) of
  120. {badrpc, Reason} ->
  121. throw({error, Reason});
  122. {error, Reason} ->
  123. throw({error, Reason});
  124. Result ->
  125. Result
  126. end.
  127. %%
  128. %% Meeting add
  129. %%
  130. meeting(Domain, "add", Name, Metadata) ->
  131. {ok, created} = call(meeting, add, [Domain,
  132. #uce_meeting{id=Name,
  133. metadata={struct, Metadata}}]),
  134. success(created);
  135. %%
  136. %% Meeting update
  137. %%
  138. meeting(Domain, "update", Name, Metadata) ->
  139. {ok, updated} = call(meeting, update, [Domain,
  140. #uce_meeting{id=Name,
  141. metadata={struct, Metadata}}]),
  142. success(updated);
  143. %%
  144. %% Meeting delete
  145. %%
  146. meeting(Domain, "delete", Name, []) ->
  147. {ok, deleted} = call(meeting, delete, [Domain, Name]),
  148. success(deleted);
  149. %%
  150. %% Meeting get
  151. %%
  152. meeting(Domain, "get", Name, []) ->
  153. {ok, Record} = call(meeting, get, [Domain, Name]),
  154. {ok, pretty_print:print(Record, flat)}.
  155. %%
  156. %% Meeting list
  157. %%
  158. meeting(Domain, "list", []) ->
  159. {ok, Records} = call(meeting, list, [Domain]),
  160. {ok, pretty_print:print(Records, flat)}.
  161. %%
  162. %% Users
  163. %%
  164. user(Domain, "add", Name, Auth, Credential, Metadata) ->
  165. {ok, Uid} = call(user, add, [Domain,
  166. #uce_user{id=none,
  167. name=Name,
  168. auth=Auth,
  169. credential=Credential,
  170. metadata={struct, Metadata}}]),
  171. success(Uid);
  172. %%
  173. %% User update
  174. %%
  175. user(Domain, "update", Name, Auth, Credential, Metadata) ->
  176. {ok, Uid} = get_user_uid(Domain, Name),
  177. {ok, updated} = call(user, update, [Domain,
  178. #uce_user{id=Uid,
  179. name=Name,
  180. auth=Auth,
  181. credential=Credential,
  182. metadata={struct, Metadata}}]),
  183. success(updated);
  184. %%
  185. %% User add role
  186. %%
  187. user(Domain, "role", "add", Name, Role, Args) ->
  188. {ok, Uid} = get_user_uid(Domain, Name),
  189. Location = proplists:get_value("location", Args, ""),
  190. {ok, updated} = call(user, add_role, [Domain,
  191. Uid,
  192. {Role, Location}]),
  193. success(updated);
  194. %%
  195. %% User delete role
  196. %%
  197. user(Domain, "role", "delete", Name, Role, Args) ->
  198. {ok, Uid} = get_user_uid(Domain, Name),
  199. Location = proplists:get_value("location", Args, ""),
  200. {ok, updated} = call(user, delete_role, [Domain,
  201. Uid,
  202. {Role, Location}]),
  203. success(Uid).
  204. %%
  205. %% Anonymous user add
  206. %%
  207. user(Domain, "add", Name, Auth, Metadata) ->
  208. {ok, Uid} = call(user, add, [Domain,
  209. #uce_user{id=none,
  210. name=Name,
  211. auth=Auth,
  212. metadata=json_helpers:to_struct(Metadata)}]),
  213. success(Uid).
  214. %%
  215. %% User delete
  216. %%
  217. user(Domain, "delete", Name, []) ->
  218. {ok, #uce_user{id=Uid}} = call(user, get, [Domain, Name]),
  219. {ok, deleted} = call(user, delete, [Domain, Uid]),
  220. success(deleted);
  221. %%
  222. %% User get
  223. %%
  224. user(Domain, "get", Name, []) ->
  225. {ok, Record} = call(user, get, [Domain, Name]),
  226. {ok, pretty_print:print(Record, flat)}.
  227. %%
  228. %% User list
  229. %%
  230. user(Domain, "list", []) ->
  231. {ok, Records} = call(user, list, [Domain]),
  232. {ok, pretty_print:print(Records, flat)}.
  233. %%
  234. %% Role add
  235. %%
  236. role(Domain, "add", Name, []) ->
  237. {ok, created} = call(role, add, [Domain, #uce_role{id=Name}]),
  238. success(created);
  239. %%
  240. %% Role delete
  241. %%
  242. role(Domain, "delete", Name, []) ->
  243. {ok, deleted} = call(role, delete, [Domain, Name]),
  244. success(deleted).
  245. %%
  246. %% Role access add
  247. %%
  248. role(Domain, "access", "add", Name, Action, Object, Conditions) ->
  249. {ok, updated} = call(role, add_access, [Domain, Name,
  250. #uce_access{action=Action,
  251. object=Object,
  252. conditions=Conditions}]),
  253. success(updated);
  254. %%
  255. %% Role access delete
  256. %%
  257. role(Domain, "access", "delete", Name, Action, Object, Conditions) ->
  258. {ok, updated} = call(role, delete_access, [Domain, Name,
  259. #uce_access{action=Action,
  260. object=Object,
  261. conditions=Conditions}]),
  262. success(updated);
  263. %%
  264. %% Role access check
  265. %%
  266. role(Domain, "access", "check", Name, Action, Object, Args) ->
  267. {ok, Uid} = get_user_uid(Domain, Name),
  268. Location = proplists:get_value("location", Args, ""),
  269. {_, Conditions} = proplists:split(Args, ["location"]),
  270. {ok, Result} = call(access, check, [Domain,
  271. Uid,
  272. Location,
  273. Object,
  274. Action,
  275. Conditions]),
  276. success(Result).
  277. %%
  278. %% Time
  279. %%
  280. time("get", []) ->
  281. io:format("Server time: ~p", [utils:now()]),
  282. ok.
  283. -ifdef(TEST).
  284. -include_lib("eunit/include/eunit.hrl").
  285. parse_arguments_test() ->
  286. ?assertEqual([], args_to_dictionary([])),
  287. ?assertEqual([{"node", "plop"}], args_to_dictionary([{'-node', ["plop"]}])),
  288. ?assertEqual([{"node", "plop plip"}], args_to_dictionary([{'-node', ["plop", "plip"]}])),
  289. ?assertEqual([{"node", "plop plip"}, {"name", "chuck"}], args_to_dictionary([{'-node', ["plop", "plip"]}, {'-name', ["chuck"]}])),
  290. ?assertEqual([{"node", "plop"}], args_to_dictionary([{'-node', ["plop"]}, {hello, "plop"}])).
  291. -endif.