/ucengine/src/core/uce_ctl.erl
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.