From 363711a37055459388ef15bef32ff11dcada4910 Mon Sep 17 00:00:00 2001 From: Eric Cestari Date: Tue, 7 Sep 2010 16:22:57 +0200 Subject: [PATCH] New features : - edit an item - edit node configuration --- doc/http_post.md | 72 ++++++++++++++++++++++++++++++++++++++----- src/web/pshb_http.erl | 65 +++++++++++++++++++++++--------------- 2 files changed, 106 insertions(+), 31 deletions(-) diff --git a/doc/http_post.md b/doc/http_post.md index cbddb4d5c..97cec2a07 100644 --- a/doc/http_post.md +++ b/doc/http_post.md @@ -23,22 +23,50 @@ In the current version of the code, some security checks are not done : ## Usage example with cURL ## +### Errors ### + +HTTP status codes are used as intended. Additionally, the XMPP error stanza can also be set in the body : + + $ curl -i -X POST -u cstar@localhost:encore -d @createnode.xml http://localhost:5280/pshb/localhost + HTTP/1.1 409 Conflict + Content-Type: text/html; charset=utf-8 + Content-Length: 95 + Content-type: application/xml + + + +or + + $ curl -i -X DELETE -u cstar@localhost:encore http://localhost:5280/pshb/localhost/princely_musings + HTTP/1.1 404 Not Found + Content-Type: text/html; charset=utf-8 + Content-Length: 101 + Content-type: application/xml + + + ### 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://post: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. + +### Editing a new item ### + + $ curl -u jid:password -i -X POST -d @entry.atom http://post:port/pshb/domain/node/itemid User ability to post is based on node configuration. @@ -47,11 +75,11 @@ User ability to post is based on node configuration. An instant node can be created if server configuration allows: - curl -X POST -u cstar@localhost:encore -d "" http://localhost:5280/pshb/localhost + $ curl -X POST -u cstar@localhost:encore -d "" http://localhost:5280/pshb/localhost or - curl -X POST -u cstar@localhost:encore -d "" http://localhost:5280/pshb/localhost + $ curl -X POST -u cstar@localhost:encore -d "" http://localhost:5280/pshb/localhost configure element (as per XEP-60) can be passed in the pubsub body. @@ -67,13 +95,43 @@ configure element (as per XEP-60) can be passed in the pubsub body. - $ curl -X POST -u cstar@localhost:encore -d @createnode.xml http://localhost:5280/pshb/localhost + $ curl -i -X POST -u cstar@localhost:encore -d @createnode.xml http://localhost:5280/pshb/localhost + HTTP/1.1 200 OK + Content-Length: 130 + Content-Type: application/xml + + + +### Editing a node configuration ### + + $ cat editnode.xml + + + + + http://jabber.org/protocol/pubsub#node_config + + Princely Musings (Atom) + 1 + 1 + 1 + 10 + 604800 + roster + + + + + + $ curl -i -X PUT -u cstar@localhost:encore -d @createnode.xml http://localhost:5280/pshb/localhost/princely_musings + + ### Deleting a node ### A node is deleted by: - curl -X DELETE -u cstar@localhost:encore http://localhost:5280/pshb/localhost/princely_musings + $ curl -X DELETE -u cstar@localhost:encore http://localhost:5280/pshb/localhost/princely_musings diff --git a/src/web/pshb_http.erl b/src/web/pshb_http.erl index 89eea479e..0b48b378d 100644 --- a/src/web/pshb_http.erl +++ b/src/web/pshb_http.erl @@ -49,7 +49,7 @@ process(LocalPath, #request{auth = Auth} = Request)-> ?DEBUG("LocalPath = ~p", [LocalPath]), UD = get_auth(Auth), - case catch out(Request, Request#request.method, LocalPath,UD) of + case out(Request, Request#request.method, LocalPath,UD) of {'EXIT', Error} -> ?ERROR_MSG("Error while processing ~p : ~n~p", [LocalPath, Error]), error(500); @@ -110,26 +110,26 @@ out(Args, 'GET', [Domain,Node]=Uri, _User) -> end end; -out(Args, 'POST', [Domain, Node]=Uri, {User, _Domain}) -> - Slug = uniqid(false), - Payload = xml_stream:parse_element(Args#request.data), - [FilteredPayload]=xml:remove_cdata([Payload]), +out(Args, 'POST', [_D, _Node]=Uri, {_User, _Domain} = UD) -> + publish_item(Args, Uri, uniqid(false), UD); - %FilteredPayload2 = case xml:get_subtag(FilteredPayload, "app:edited") -> - % {xmlelement, Name, Attrs, [{cdata, }]} - case mod_pubsub:publish_item(get_host(Uri), - Domain, - get_collection(Uri), - jlib:make_jid(User,Domain, ""), - Slug, - [FilteredPayload]) of - {result, [_]} -> - ?DEBUG("Publishing to ~p~n",[entry_uri(Args, Domain, Node,Slug)]), - {201, [{"location", entry_uri(Args, Domain,Node,Slug)}], Payload}; - {error, Error} -> - error(Error) - end; - +out(Args, 'PUT', [_D, _Node, Slug]=Uri, {_User, _Domain} = UD) -> + publish_item(Args, Uri, Slug, UD); + + +out(Args, 'PUT', [_Domain, Node]= Uri, {User, UDomain}) -> + Host = get_host(Uri), + Jid = jlib:make_jid({User, UDomain, ""}), + Payload = xml_stream:parse_element(Args#request.data), + ConfigureElement = case xml:get_subtag(Payload, "configure") of + false ->[]; + {xmlelement, _, _, SubEls}->SubEls + end, + case mod_pubsub:set_configure(Host, list_to_binary(Node), Jid, ConfigureElement, Args#request.lang) of + {result, []} -> success(200); + {error, Error} -> error(Error) + end; + out(Args, 'GET', [Domain]=Uri, From)-> Host = get_host(Uri), ?DEBUG("Host = ~p", [Host]), @@ -150,7 +150,6 @@ out(Args, 'POST', [Domain]=Uri, {User, UDomain})-> 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 ->[]; @@ -166,7 +165,7 @@ out(Args, 'POST', [Domain]=Uri, {User, UDomain})-> ++ xml:element_to_string(Result)} end; -out(Args, 'DELETE', [Domain, Node] = Uri, {User, UDomain})-> +out(_Args, 'DELETE', [_Domain, Node] = Uri, {User, UDomain})-> Host = get_host(Uri), Jid = jlib:make_jid({User, UDomain, ""}), BinNode = list_to_binary(Node), @@ -208,6 +207,26 @@ get_item(Uri, Failure, Success)-> #pubsub_item{}=Item -> Success(Item) end. + +publish_item(Args, [Domain, Node | _R] = Uri, Slug, {User, Domain})-> + + Payload = xml_stream:parse_element(Args#request.data), + [FilteredPayload]=xml:remove_cdata([Payload]), + + %FilteredPayload2 = case xml:get_subtag(FilteredPayload, "app:edited") -> + % {xmlelement, Name, Attrs, [{cdata, }]} + case mod_pubsub:publish_item(get_host(Uri), + Domain, + get_collection(Uri), + jlib:make_jid(User,Domain, ""), + Slug, + [FilteredPayload]) of + {result, [_]} -> + ?DEBUG("Publishing to ~p~n",[entry_uri(Args, Domain, Node,Slug)]), + {201, [{"location", entry_uri(Args, Domain,Node,Slug)}], Payload}; + {error, Error} -> + error(Error) + end. generate_etag(#pubsub_item{modification={{_, D2, D3}, _JID}})->integer_to_list(D3+D2). get_host([Domain|_Rest])-> "pubsub."++Domain. @@ -284,8 +303,6 @@ error(401)-> {401, [{"WWW-Authenticate", "basic realm=\"ejabberd\""}],"Unauthorized"}; error(Code)-> {Code, [], ""}. -error(Code, Error) when is_list(Error) -> {Code, [], Error}; -error(Code, _Error) -> {Code, [], "Bad request"}. success(200)-> {200, [], ""}; success(Code)->