mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-24 17:29:28 +01:00
Added node creation with configure form
Added deletion Better behavior in case of a crash (returns 500)
This commit is contained in:
parent
cd923838c3
commit
bf98fa0c01
@ -13,33 +13,67 @@ Also, in the ejabberd_http handler configuration, add the identified line.
|
||||
{request_handlers, [{["pshb"], pshb_http}]} % this should be added
|
||||
]}
|
||||
|
||||
## Important notice ##
|
||||
|
||||
In the current version of the code, some security checks are not done :
|
||||
|
||||
* read operations can all be done without authentication
|
||||
|
||||
* node creation uses the default `all` access_createnode acl, not checking for the actual configuration.
|
||||
|
||||
## Usage example with cURL ##
|
||||
|
||||
### Getting the service document ###
|
||||
|
||||
No authentication necessary. All nodes are listed.
|
||||
|
||||
curl -i http://<host>:<port>/pshb/<domain>/
|
||||
curl -i http://host:port/pshb/domain/
|
||||
|
||||
### Getting items from a node ###
|
||||
|
||||
No authentication done, and all nodes are accessible.
|
||||
|
||||
curl -i http://<host>:<port>/pshb/<domain>/<node>/
|
||||
curl -i http://host:port/pshb/domain/node/
|
||||
|
||||
|
||||
### Posting a new item ###
|
||||
|
||||
curl -u <jid>:<password> -i -X POST -d @entry.atom http://<host>:<port>/pshb/<domain>/<node>
|
||||
curl -u jid:password -i -X POST -d @entry.atom http://post:port/pshb/domain/node
|
||||
|
||||
User ability to post is based on node configuration.
|
||||
|
||||
|
||||
### Creating a new node ###
|
||||
|
||||
An instant node can be created :
|
||||
An instant node can be created if server configuration allows:
|
||||
|
||||
curl -X POST -u cstar@localhost:encore -d "" http://localhost:5280/pshb/localhost
|
||||
|
||||
or
|
||||
|
||||
curl -X POST -u cstar@localhost:encore -d "<pubsub><create node='princely_musings'/></pubsub>" http://localhost:5280/pshb/localhost
|
||||
|
||||
configure element (as per XEP-60) can be passed in the pubsub body.
|
||||
|
||||
$ cat createnode.xml
|
||||
<pubsub><create node='princely_musings' type='flat'/>
|
||||
<x xmlns='jabber:x:data' type='submit'>
|
||||
<field var='FORM_TYPE' type='hidden'>
|
||||
<value>http://jabber.org/protocol/pubsub#node_config</value>
|
||||
</field>
|
||||
<field var='pubsub#title'><value>Princely Musings (Atom)</value></field>
|
||||
<field var='pubsub#max_payload_size'><value>1028</value></field>
|
||||
<field var='pubsub#type'><value>Atom</value></field>
|
||||
</x>
|
||||
</pubsub>
|
||||
|
||||
$ curl -X POST -u cstar@localhost:encore -d @createnode.xml http://localhost:5280/pshb/localhost
|
||||
|
||||
### Deleting a node ###
|
||||
|
||||
A node is deleted by:
|
||||
|
||||
curl -X DELETE -u cstar@localhost:encore http://localhost:5280/pshb/localhost/princely_musings
|
||||
|
||||
|
||||
|
||||
|
@ -78,6 +78,7 @@
|
||||
|
||||
%% exports for console debug manual use
|
||||
-export([create_node/5,
|
||||
create_node/7,
|
||||
delete_node/3,
|
||||
subscribe_node/5,
|
||||
unsubscribe_node/5,
|
||||
|
@ -48,35 +48,36 @@
|
||||
|
||||
process(LocalPath, #request{auth = Auth} = Request)->
|
||||
?DEBUG("LocalPath = ~p", [LocalPath]),
|
||||
case get_auth(Auth) of
|
||||
%%make sure user belongs to pubsub domain
|
||||
{User, Domain} ->
|
||||
out(Request, Request#request.method, LocalPath,{User, Domain});
|
||||
_ ->
|
||||
out(Request, Request#request.method, LocalPath, undefined)
|
||||
end.
|
||||
UD = get_auth(Auth),
|
||||
case catch out(Request, Request#request.method, LocalPath,UD) of
|
||||
{'EXIT', Error} ->
|
||||
?ERROR_MSG("Error while processing ~p : ~n~p", [LocalPath, Error]),
|
||||
error(500);
|
||||
Result ->
|
||||
Result
|
||||
end.
|
||||
|
||||
get_auth(Auth) ->
|
||||
case Auth of
|
||||
{SJID, P} ->
|
||||
case jlib:string_to_jid(SJID) of
|
||||
error ->
|
||||
unauthorized;
|
||||
undefined;
|
||||
#jid{user = U, server = S} ->
|
||||
case ejabberd_auth:check_password(U, S, P) of
|
||||
true ->
|
||||
{U, S};
|
||||
false ->
|
||||
unauthorized
|
||||
undefined
|
||||
end
|
||||
end;
|
||||
_ ->
|
||||
unauthorized
|
||||
undefined
|
||||
end.
|
||||
|
||||
out(Args, 'GET', [Domain,Node]=Uri, _User) ->
|
||||
case mod_pubsub:tree_action(get_host(Uri), get_node, [get_host(Uri),get_collection(Uri)]) of
|
||||
{error, _} -> error(404);
|
||||
{error, Error} -> error(Error);
|
||||
_ ->
|
||||
Items = lists:sort(fun(X,Y)->
|
||||
{DateX, _} = X#pubsub_item.modification,
|
||||
@ -135,7 +136,7 @@ out(Args, 'GET', [Domain]=Uri, From)->
|
||||
case mod_pubsub:tree_action(Host, get_subnodes, [Host, <<>>, From ]) of
|
||||
[] ->
|
||||
?DEBUG("Error getting URI ~p : ~p",[Uri, From]),
|
||||
error(404);
|
||||
error(?ERR_ITEM_NOT_FOUND);
|
||||
Collections ->
|
||||
{200, [{"Content-Type", "application/atomsvc+xml"}], "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
|
||||
++ xml:element_to_string(service(Args,Domain, Collections))}
|
||||
@ -143,18 +144,37 @@ out(Args, 'GET', [Domain]=Uri, From)->
|
||||
|
||||
out(Args, 'POST', [Domain]=Uri, {User, UDomain})->
|
||||
Host = get_host(Uri),
|
||||
case mod_pubsub:create_node(Host, Domain, <<>>, {User, UDomain}, "default") of
|
||||
Payload = xml_stream:parse_element(Args#request.data),
|
||||
{Node, Type} = case xml:get_subtag(Payload, "create") of
|
||||
false -> {<<>>,"flat"};
|
||||
E ->
|
||||
{list_to_binary(get_tag_attr_or_default("node", E,"")),
|
||||
get_tag_attr_or_default("type", E,"flat")}
|
||||
|
||||
end,
|
||||
ConfigureElement = case xml:get_subtag(Payload, "configure") of
|
||||
false ->[];
|
||||
{xmlelement, _, _, SubEls}->SubEls
|
||||
end,
|
||||
Jid = jlib:make_jid({User, UDomain, ""}),
|
||||
case mod_pubsub:create_node(Host, Domain, Node, Jid, Type, all, ConfigureElement) of
|
||||
{error, Error} ->
|
||||
?ERROR_MSG("Error create node via HTTP : ~p",[Error]),
|
||||
|
||||
error(Error); % will probably detail more
|
||||
{result, [Node]} ->
|
||||
{result, [Result]} ->
|
||||
{200, [{"Content-Type", "application/xml"}], "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
|
||||
++ xml:element_to_string(Node)}
|
||||
++ xml:element_to_string(Result)}
|
||||
end;
|
||||
|
||||
out(Args, 'DELETE', [Domain, Node] = Uri, {User, UDomain})->
|
||||
Host = get_host(Uri),
|
||||
Jid = jlib:make_jid({User, UDomain, ""}),
|
||||
BinNode = list_to_binary(Node),
|
||||
case mod_pubsub:delete_node(Host, BinNode, Jid) of
|
||||
{error, Error} -> error(Error);
|
||||
{result, []} ->
|
||||
{200, [],[]}
|
||||
end;
|
||||
|
||||
out(Args, 'POST', [Domain]=Uri, undefined) ->
|
||||
error(403);
|
||||
|
||||
|
||||
|
||||
@ -178,7 +198,7 @@ out(Args, 'GET', [Domain, Node, _Item]=URI, _) ->
|
||||
|
||||
out(_,Method,Uri,undefined) ->
|
||||
?DEBUG("Error, ~p not authorized for ~p : ~p",[ Method,Uri]),
|
||||
error(403).
|
||||
error(?ERR_FORBIDDEN).
|
||||
|
||||
get_item(Uri, Failure, Success)->
|
||||
?DEBUG(" mod_pubsub:get_item(~p, ~p,~p)", [get_host(Uri), get_collection(Uri), get_member(Uri)]),
|
||||
@ -341,4 +361,10 @@ i2l(I) when is_integer(I) -> integer_to_list(I);
|
||||
i2l(L) when is_list(L) -> L.
|
||||
|
||||
b2l(B) when is_binary(B) -> binary_to_list(B);
|
||||
b2l(L) when is_list(L) -> L.
|
||||
b2l(L) when is_list(L) -> L.
|
||||
|
||||
get_tag_attr_or_default(AttrName, Element, Default)->
|
||||
case xml:get_tag_attr_s(AttrName, Element) of
|
||||
"" -> Default;
|
||||
Val -> Val
|
||||
end.
|
Loading…
Reference in New Issue
Block a user