Commit 90501d8a authored by daryl herzmann's avatar daryl herzmann

Merge pull request #171 from Redor/openfire

REST API plugin version 1.0.0
parents 9c69db39 4c2804b6
...@@ -44,6 +44,12 @@ ...@@ -44,6 +44,12 @@
REST API Plugin Changelog REST API Plugin Changelog
</h1> </h1>
<p><b>1.0.0</b> -- February 3rd, 2015</p>
<ul>
<li>UserService plugin and MUC Service plugin are merged to the REST API plugin.</li>
<li>Extended REST API with JSON data format.</li>
</ul>
<p><b>0.1.0</b> -- November 14th, 2014</p> <p><b>0.1.0</b> -- November 14th, 2014</p>
<ul> <ul>
<li>Initial release of REST API Plugin with possibility to manage system properties.</li> <li>Initial release of REST API Plugin with possibility to manage system properties.</li>
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
<name>REST API</name> <name>REST API</name>
<description>Allows administration over a RESTful API.</description> <description>Allows administration over a RESTful API.</description>
<author>Roman Soldatow</author> <author>Roman Soldatow</author>
<version>0.1.0</version> <version>1.0.0</version>
<date>11/14/2014</date> <date>02/03/2015</date>
<minServerVersion>3.9.0</minServerVersion> <minServerVersion>3.9.0</minServerVersion>
<adminconsole> <adminconsole>
......
...@@ -1225,7 +1225,7 @@ body.pdf{font-family:"DejaVu Sans"}body.pdf code,body.pdf pre{font-family:"DejaV ...@@ -1225,7 +1225,7 @@ body.pdf{font-family:"DejaVu Sans"}body.pdf code,body.pdf pre{font-family:"DejaV
</head> </head>
<body><div class="container"><h1 id="rest-api-plugin-readme">REST API Plugin Readme</h1> <body><div class="container"><h1 id="rest-api-plugin-readme">REST API Plugin Readme</h1>
<p>The REST API Plugin provides the ability to manage system properties by sending an HTTP request to the server. This plugin’s functionality is useful for applications that need to administer Openfire outside of the Openfire admin console.</p> <p>The REST API Plugin provides the ability to manage Openfire by sending an REST/HTTP request to the server. This plugin’s functionality is useful for applications that need to administer Openfire outside of the Openfire admin console.</p>
<hr> <hr>
...@@ -1240,52 +1240,200 @@ body.pdf{font-family:"DejaVu Sans"}body.pdf code,body.pdf pre{font-family:"DejaV ...@@ -1240,52 +1240,200 @@ body.pdf{font-family:"DejaVu Sans"}body.pdf code,body.pdf pre{font-family:"DejaV
<li><a href="#shared-secret-key">Shared secret key</a></li> <li><a href="#shared-secret-key">Shared secret key</a></li>
</ul> </ul>
</li> </li>
<li><a href="#data-format">Data format</a></li>
<li><a href="#data-types">Data types</a><ul> <li><a href="#data-types">Data types</a><ul>
<li><a href="#user">User</a></li>
<li><a href="#rosteritem">RosterItem</a></li>
<li><a href="#chatroom">Chatroom</a></li>
<li><a href="#system-property">System Property</a></li> <li><a href="#system-property">System Property</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
</li> </li>
<li><a href="#system-related-rest-endpoints">System related REST Endpoints</a><ul> <li><a href="#user-related-rest-endpoints">User related REST Endpoints</a><ul>
<li><a href="#get-restapisystemproperties">GET /restapi/system/properties</a><ul> <li><a href="#retrieve-users">Retrieve users</a><ul>
<li><a href="#possible-parameters">Possible parameters</a></li>
<li><a href="#examples">Examples</a></li> <li><a href="#examples">Examples</a></li>
</ul> </ul>
</li> </li>
<li><a href="#get-restapisystempropertiespropertyname">GET /restapi/system/properties/{propertyName}</a><ul> <li><a href="#retrieve-a-user">Retrieve a user</a><ul>
<li><a href="#possible-parameters">Possible parameters</a></li> <li><a href="#possible-parameters-1">Possible parameters</a></li>
<li><a href="#examples-1">Examples</a></li> <li><a href="#examples-1">Examples</a></li>
</ul> </ul>
</li> </li>
<li><a href="#post-restapisystemproperties">POST /restapi/system/properties</a><ul> <li><a href="#create-a-user">Create a user</a><ul>
<li><a href="#examples-2">Examples</a></li> <li><a href="#examples-2">Examples</a><ul>
<li><a href="#xml-examples">XML Examples</a></li>
<li><a href="#json-examples">JSON Examples</a></li>
</ul> </ul>
</li> </li>
<li><a href="#delete-restapisystempropertiespropertyname">DELETE /restapi/system/properties/{propertyName}</a><ul>
<li><a href="#possible-parameters-1">Possible parameters</a></li>
<li><a href="#examples-3">Examples</a></li>
</ul> </ul>
</li> </li>
<li><a href="#put-restapisystempropertiespropertyname">PUT /restapi/system/properties/{propertyName}</a><ul> <li><a href="#delete-a-user">Delete a user</a><ul>
<li><a href="#possible-parameters-2">Possible parameters</a></li> <li><a href="#possible-parameters-2">Possible parameters</a></li>
<li><a href="#examples-4">Examples</a></li> <li><a href="#examples-3">Examples</a></li>
</ul>
</li>
<li><a href="#update-a-user">Update a user</a><ul>
<li><a href="#possible-parameters-3">Possible parameters</a></li>
<li><a href="#examples-4">Examples</a><ul>
<li><a href="#xml-example">XML Example</a></li>
<li><a href="#json-example">JSON Example</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#retrieve-all-user-groups">Retrieve all user groups</a><ul>
<li><a href="#possible-parameters-4">Possible parameters</a></li>
<li><a href="#examples-5">Examples</a></li>
</ul>
</li>
<li><a href="#add-user-to-group">Add user to group</a><ul>
<li><a href="#possible-parameters-5">Possible parameters</a></li>
<li><a href="#examples-6">Examples</a></li>
</ul>
</li>
<li><a href="#delete-a-user-from-a-group">Delete a user from a group</a><ul>
<li><a href="#possible-parameters-6">Possible parameters</a></li>
<li><a href="#examples-7">Examples</a></li>
</ul>
</li>
<li><a href="#lockout-a-user">Lockout a user</a><ul>
<li><a href="#possible-parameters-7">Possible parameters</a></li>
<li><a href="#examples-8">Examples</a></li>
</ul>
</li>
<li><a href="#unlock-a-user">Unlock a user</a><ul>
<li><a href="#possible-parameters-8">Possible parameters</a></li>
<li><a href="#examples-9">Examples</a></li>
</ul>
</li>
<li><a href="#retrieve-user-roster">Retrieve user roster</a><ul>
<li><a href="#possible-parameters-9">Possible parameters</a></li>
<li><a href="#examples-10">Examples</a></li>
</ul>
</li>
<li><a href="#create-a-user-roster-entry">Create a user roster entry</a><ul>
<li><a href="#possible-parameters-10">Possible parameters</a></li>
<li><a href="#examples-11">Examples</a></li>
</ul>
</li>
<li><a href="#delete-a-user-roster-entry">Delete a user roster entry</a><ul>
<li><a href="#possible-parameters-11">Possible parameters</a></li>
<li><a href="#examples-12">Examples</a></li>
</ul>
</li>
<li><a href="#update-a-user-roster-entry">Update a user roster entry</a><ul>
<li><a href="#possible-parameters-12">Possible parameters</a></li>
<li><a href="#examples-13">Examples</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#chat-room-related-rest-endpoints">Chat room related REST Endpoints</a><ul>
<li><a href="#retrieve-all-chat-rooms">Retrieve all chat rooms</a><ul>
<li><a href="#possible-parameters-13">Possible parameters</a></li>
<li><a href="#examples-14">Examples</a></li>
</ul>
</li>
<li><a href="#retrieve-a-chat-room">Retrieve a chat room</a><ul>
<li><a href="#possible-parameters-14">Possible parameters</a></li>
<li><a href="#examples-15">Examples</a></li>
</ul>
</li>
<li><a href="#retrieve-chat-room-participants">Retrieve chat room participants</a><ul>
<li><a href="#possible-parameters-15">Possible parameters</a></li>
<li><a href="#examples-16">Examples</a></li>
</ul>
</li>
<li><a href="#create-a-chat-room">Create a chat room</a><ul>
<li><a href="#possible-parameters-16">Possible parameters</a></li>
<li><a href="#xml-examples-1">XML Examples</a></li>
<li><a href="#json-examples-1">JSON Examples</a></li>
</ul>
</li>
<li><a href="#delete-a-chat-room">Delete a chat room</a><ul>
<li><a href="#possible-parameters-17">Possible parameters</a></li>
<li><a href="#examples-17">Examples</a></li>
</ul>
</li>
<li><a href="#update-a-chat-room">Update a chat room</a><ul>
<li><a href="#possible-parameters-18">Possible parameters</a></li>
<li><a href="#examples-18">Examples</a></li>
</ul>
</li>
<li><a href="#add-user-with-role-to-chat-room">Add user with role to chat room</a><ul>
<li><a href="#possible-parameters-19">Possible parameters</a></li>
<li><a href="#examples-19">Examples</a></li>
</ul>
</li>
<li><a href="#delete-a-user-from-a-chat-room">Delete a user from a chat room</a><ul>
<li><a href="#possible-parameters-20">Possible parameters</a></li>
<li><a href="#examples-20">Examples</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#system-related-rest-endpoints">System related REST Endpoints</a><ul>
<li><a href="#retrieve-all-system-properties">Retrieve all system properties</a><ul>
<li><a href="#examples-21">Examples</a></li>
</ul>
</li>
<li><a href="#retrieve-system-property">Retrieve system property</a><ul>
<li><a href="#possible-parameters-21">Possible parameters</a></li>
<li><a href="#examples-22">Examples</a></li>
</ul>
</li>
<li><a href="#create-a-system-property">Create a system property</a><ul>
<li><a href="#examples-23">Examples</a></li>
</ul> </ul>
</li> </li>
<li><a href="#delete-a-system-property">Delete a system property</a><ul>
<li><a href="#possible-parameters-22">Possible parameters</a></li>
<li><a href="#examples-24">Examples</a></li>
</ul>
</li>
<li><a href="#update-a-system-property">Update a system property</a><ul>
<li><a href="#possible-parameters-23">Possible parameters</a></li>
<li><a href="#examples-25">Examples</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#deprecated-user-service-plugin-readme">(Deprecated) User Service Plugin Readme</a><ul>
<li><a href="#overview">Overview</a></li>
<li><a href="#installation-1">Installation</a></li>
<li><a href="#configuration">Configuration</a></li>
<li><a href="#using-the-plugin">Using the Plugin</a></li>
<li><a href="#sample-html">Sample HTML</a></li>
<li><a href="#server-reply">Server Reply</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
</div> </div>
</p> </p>
<h2 id="feature-list">Feature list</h2> <h2 id="feature-list">Feature list</h2>
<ul> <ul>
<li>Get overview over all or specific user and to create, update or delete a user</li>
<li>Get overview over all user roster entries and to add, update or delete a roster entry</li>
<li>Add user to a group and remove a user from a group</li>
<li>Lockout or unlock the user (enable / disable)</li>
<li>Get overview over all or specific system properties and to create, update or delete system property</li> <li>Get overview over all or specific system properties and to create, update or delete system property</li>
<li>Get overview over all or specific chat room and to create, update or delete a chat room</li>
</ul> </ul>
<h2 id="installation">Installation</h2> <h2 id="installation">Installation</h2>
<p>Copy restAPI.jar into the plugins directory of your Openfire server. The plugin will then be automatically deployed. To upgrade to a new version, copy the new restAPI.jar file over the existing file.</p> <p>Copy restAPI.jar into the plugins directory of your Openfire server. The plugin will then be automatically deployed. To upgrade to a new version, copy the new restAPI.jar file over the existing file.</p>
<h2 id="explanation-of-rest">Explanation of REST</h2> <h2 id="explanation-of-rest">Explanation of REST</h2>
<p>To provide a standard way of accessing the data the plugin is using REST.</p> <p>To provide a standard way of accessing the data the plugin is using REST.</p>
...@@ -1316,22 +1464,27 @@ body.pdf{font-family:"DejaVu Sans"}body.pdf code,body.pdf pre{font-family:"DejaV ...@@ -1316,22 +1464,27 @@ body.pdf{font-family:"DejaVu Sans"}body.pdf code,body.pdf pre{font-family:"DejaV
</tbody></table> </tbody></table>
<h2 id="authentication">Authentication</h2> <h2 id="authentication">Authentication</h2>
<p>All REST Endpoint are secured by <a href="http://en.wikipedia.org/wiki/Basic_access_authentication">Basic HTTP Authentication</a> or by shared secret key. The configuration can be done in Openfire Admin console under Server &gt; Server Settings &gt; REST API.</p> <p>All REST Endpoint are secured and must be authenticated. There are two ways to authenticate: </p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Basic_access_authentication">Basic HTTP Authentication</a></li>
<li>Shared secret key</li>
</ul>
<p>The configuration can be done in Openfire Admin console under Server &gt; Server Settings &gt; REST API.</p>
<h3 id="basic-http-authentication">Basic HTTP Authentication</h3> <h3 id="basic-http-authentication">Basic HTTP Authentication</h3>
<p>To access the endpoints is that required to send the Username and Password of a Openfire Admin account in your header request.</p> <p>To access the endpoints is that required to send the Username and Password of a Openfire Admin account in your HTTP header request.</p>
<p>E.g. <strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= (username: admin / password: 12345)</p> <p>E.g. <strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= (username: admin / password: 12345)</p>
<p>Example for Jersey Client <br>
<code> <br>
Client c = Client.create(); <br>
c.addFilter(new HTTPBasicAuthFilter(user, password)); <br>
</code></p>
<h3 id="shared-secret-key">Shared secret key</h3> <h3 id="shared-secret-key">Shared secret key</h3>
...@@ -1340,11 +1493,21 @@ body.pdf{font-family:"DejaVu Sans"}body.pdf code,body.pdf pre{font-family:"DejaV ...@@ -1340,11 +1493,21 @@ body.pdf{font-family:"DejaVu Sans"}body.pdf code,body.pdf pre{font-family:"DejaV
<p>E.g. <strong>Header:</strong> Authorization: s3cretKey</p> <p>E.g. <strong>Header:</strong> Authorization: s3cretKey</p>
<h2 id="data-format">Data format</h2>
<p>Openfire REST API provides XML and JSON as data format. The default data format is XML. <br>
To get a JSON result, please add “<strong>Accept application/json</strong>” to the request header. <br>
If you want to create a resource with JSON data format, please add “<strong>Content-Type: application/json</strong>“.</p>
<h2 id="data-types">Data types</h2> <h2 id="data-types">Data types</h2>
<h3 id="system-property">System Property</h3> <h3 id="user">User</h3>
<table> <table>
<thead> <thead>
...@@ -1355,95 +1518,243 @@ body.pdf{font-family:"DejaVu Sans"}body.pdf code,body.pdf pre{font-family:"DejaV ...@@ -1355,95 +1518,243 @@ body.pdf{font-family:"DejaVu Sans"}body.pdf code,body.pdf pre{font-family:"DejaV
</tr> </tr>
</thead> </thead>
<tbody><tr> <tbody><tr>
<td>key</td> <td>username</td>
<td>No</td> <td>No</td>
<td>The name of the system property</td> <td>The username of the user</td>
</tr> </tr>
<tr> <tr>
<td>value</td> <td>name</td>
<td>Yes</td>
<td>The name of the user</td>
</tr>
<tr>
<td>email</td>
<td>Yes</td>
<td>The email of the user</td>
</tr>
<tr>
<td>password</td>
<td>No</td> <td>No</td>
<td>The value of the system property</td> <td>The password of the user</td>
</tr>
<tr>
<td>properties</td>
<td>Yes</td>
<td>List of properties. Property is a key / value object. The key must to be per user unique</td>
</tr> </tr>
</tbody></table> </tbody></table>
<h1 id="system-related-rest-endpoints">System related REST Endpoints</h1>
<h2 id="get-restapisystemproperties">GET /restapi/system/properties</h2>
<p>Endpoint to get all system properties</p> <h3 id="rosteritem">RosterItem</h3>
<p><strong>Payload:</strong> none <br> <table>
<strong>Return value:</strong> System properties</p> <thead>
<tr>
<th>Parameter</th>
<th>Optional</th>
<th>Description</th>
</tr>
</thead>
<tbody><tr>
<td>jid</td>
<td>No</td>
<td>The JID of the roster item</td>
</tr>
<tr>
<td>nickname</td>
<td>Yes</td>
<td>The nickname for the user when used in this roster</td>
</tr>
<tr>
<td>subscriptionType</td>
<td>Yes</td>
<td>The subscription type <br> Possible numeric values are: -1 (remove), 0 (none), 1 (to), 2 (from), 3 (both)</td>
</tr>
<tr>
<td>groups</td>
<td>No</td>
<td>A list of groups to organize roster entries under (e.g. friends, co-workers, etc.)</td>
</tr>
</tbody></table>
<h3 id="examples">Examples</h3>
<p><strong>Header</strong>: Authorization: Basic YWRtaW46MTIzNDU=</p>
<p><strong>GET</strong> <a href="http://example.org:9090/plugins/restapi/system/properties">http://example.org:9090/plugins/restapi/system/properties</a></p>
<h2 id="get-restapisystempropertiespropertyname">GET /restapi/system/properties/{propertyName}</h2> <h3 id="chatroom">Chatroom</h3>
<p>Endpoint to get information over specific system property</p> <table>
<thead>
<tr>
<th>Parameter</th>
<th>Optional</th>
<th>Description</th>
</tr>
</thead>
<tbody><tr>
<td>roomName</td>
<td>No</td>
<td>The name/id of the room. Can only contains lowercase and alphanumeric characters.</td>
</tr>
<tr>
<td>naturalName</td>
<td>No</td>
<td>Also the name of the room, but can contains non alphanumeric characters. It’s mainly used for users while discovering rooms hosted by the Multi-User Chat service.</td>
</tr>
<tr>
<td>description</td>
<td>No</td>
<td>Description text of the room.</td>
</tr>
<tr>
<td>password</td>
<td>Yes</td>
<td>The password that the user must provide to enter the room</td>
</tr>
<tr>
<td>creationDate</td>
<td>Yes</td>
<td>The date when the room was created. Will be automatically set by creation. Example: 2014-07-10T09:49:12.411+02:00</td>
</tr>
<tr>
<td>modificationDate</td>
<td>Yes</td>
<td>The last date when the room’s configuration was modified. If the room’s configuration was never modified then the initial value will be the same as the creation date. Will be automatically set by update. Example: 2014-07-10T09:49:12.411+02:00</td>
</tr>
<tr>
<td>maxUsers</td>
<td>Yes</td>
<td>the maximum number of occupants that can be simultaneously in the room. 0 means unlimited number of occupants.</td>
</tr>
<tr>
<td>persistent</td>
<td>Yes</td>
<td>Can be “true” or “false”. Persistent rooms are saved to the database to make their configurations persistent together with the affiliation of the users. Otherwise the room will be destroyed if the last occupant leave the room.</td>
</tr>
<tr>
<td>publicRoom</td>
<td>Yes</td>
<td>Can be “true” or “false”. True if the room is searchable and visible through service discovery.</td>
</tr>
<tr>
<td>registrationEnabled</td>
<td>Yes</td>
<td>Can be “true” or “false”. True if users are allowed to register with the room. By default, room registration is enabled.</td>
</tr>
<tr>
<td>canAnyoneDiscoverJID</td>
<td>Yes</td>
<td>Can be “true” or “false”. True if every presence packet will include the JID of every occupant.</td>
</tr>
<tr>
<td>canOccupantsChangeSubject</td>
<td>Yes</td>
<td>Can be “true” or “false”. True if participants are allowed to change the room’s subject.</td>
</tr>
<tr>
<td>canOccupantsInvite</td>
<td>Yes</td>
<td>Can be “true” or “false”. True if occupants can invite other users to the room. If the room does not require an invitation to enter (i.e. is not members-only) then any occupant can send invitations. On the other hand, if the room is members-only and occupants cannot send invitation then only the room owners and admins are allowed to send invitations.</td>
</tr>
<tr>
<td>canChangeNickname</td>
<td>Yes</td>
<td>Can be “true” or “false”. True if room occupants are allowed to change their nicknames in the room. By default, occupants are allowed to change their nicknames.</td>
</tr>
<tr>
<td>logEnabled</td>
<td>Yes</td>
<td>Can be “true” or “false”. True if the room’s conversation is being logged. If logging is activated the room conversation will be saved to the database every couple of minutes. The saving frequency is the same for all the rooms and can be configured by changing the property “xmpp.muc.tasks.log.timeout”.</td>
</tr>
<tr>
<td>loginRestrictedToNickname</td>
<td>Yes</td>
<td>Can be “true” or “false”. True if registered users can only join the room using their registered nickname. By default, registered users can join the room using any nickname.</td>
</tr>
<tr>
<td>membersOnly</td>
<td>Yes</td>
<td>Can be “true” or “false”. True if the room requires an invitation to enter. That is if the room is members-only.</td>
</tr>
<tr>
<td>moderated</td>
<td>Yes</td>
<td>Can be “true” or “false”. True if the room in which only those with “voice” may send messages to all occupants.</td>
</tr>
<tr>
<td>broadcastPresenceRoles</td>
<td>Yes</td>
<td>The list of roles of which presence will be broadcasted to the rest of the occupants.</td>
</tr>
<tr>
<td>owners</td>
<td>Yes</td>
<td>A collection with the current list of owners. The collection contains the bareJID of the users with owner affiliation.</td>
</tr>
<tr>
<td>admins</td>
<td>Yes</td>
<td>A collection with the current list of admins. The collection contains the bareJID of the users with admin affiliation.</td>
</tr>
<tr>
<td>members</td>
<td>Yes</td>
<td>A collection with the current list of room members. The collection contains the bareJID of the users with member affiliation. If the room is not members-only then the list will contain the users that registered with the room and therefore they may have reserved a nickname.</td>
</tr>
<tr>
<td>outcasts</td>
<td>Yes</td>
<td>A collection with the current list of outcast users. An outcast user is not allowed to join the room again. The collection contains the bareJID of the users with outcast affiliation.</td>
</tr>
</tbody></table>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> System property</p>
<h3 id="possible-parameters">Possible parameters</h3> <h3 id="system-property">System Property</h3>
<table> <table>
<thead> <thead>
<tr> <tr>
<th>Parameter</th> <th>Parameter</th>
<th>Parameter Type</th> <th>Optional</th>
<th>Description</th> <th>Description</th>
<th>Default value</th>
</tr> </tr>
</thead> </thead>
<tbody><tr> <tbody><tr>
<td>propertyName</td> <td>key</td>
<td>@Path</td> <td>No</td>
<td>The name of system property</td> <td>The name of the system property</td>
<td></td> </tr>
<tr>
<td>value</td>
<td>No</td>
<td>The value of the system property</td>
</tr> </tr>
</tbody></table> </tbody></table>
<h3 id="examples-1">Examples</h3>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU=</p>
<p><strong>GET</strong> <a href="http://example.org:9090/plugins//restapi/system/properties/xmpp.domain">http://example.org:9090/plugins/restapi/system/properties/xmpp.domain</a></p>
<h2 id="post-restapisystemproperties">POST /restapi/system/properties</h2>
<p>Endpoint to create a system property</p>
<p><strong>Payload:</strong> System Property <br> <h1 id="user-related-rest-endpoints">User related REST Endpoints</h1>
<strong>Return value:</strong> HTTP status 201 (Created)</p>
<h3 id="examples-2">Examples</h3>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>Header:</strong> Content-Type: application/xml</p>
<p><strong>POST</strong> <a href="http://example.org:9090/plugins/restapi/system/properties">http://example.org:9090/plugins/restapi/system/properties</a></p> <h2 id="retrieve-users">Retrieve users</h2>
<p><strong>Payload Example:</strong></p> <p>Endpoint to get all or filtered users</p>
<pre class="prettyprint prettyprinted"><code><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"UTF-8"</span><span class="pln"> standalone</span><span class="pun">=</span><span class="str">"yes"</span><span class="pun">?&gt;</span><span class="pln"> <blockquote>
</span><span class="tag">&lt;property</span><span class="pln"> </span><span class="atn">key</span><span class="pun">=</span><span class="atv">"propertyName"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"propertyValue"</span><span class="tag">/&gt;</span></code></pre> <p><strong>GET</strong> /users</p>
</blockquote>
<h2 id="delete-restapisystempropertiespropertyname">DELETE /restapi/system/properties/{propertyName}</h2> <p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> Users</p>
<p>Endpoint to delete a system property</p>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> HTTP status 200 (OK)</p>
<h3 id="possible-parameters-1">Possible parameters</h3> <h3 id="possible-parameters">Possible parameters</h3>
<table> <table>
<thead> <thead>
...@@ -1455,28 +1766,57 @@ body.pdf{font-family:"DejaVu Sans"}body.pdf code,body.pdf pre{font-family:"DejaV ...@@ -1455,28 +1766,57 @@ body.pdf{font-family:"DejaVu Sans"}body.pdf code,body.pdf pre{font-family:"DejaV
</tr> </tr>
</thead> </thead>
<tbody><tr> <tbody><tr>
<td>propertyName</td> <td>search</td>
<td>@Path</td> <td>@QueryParam</td>
<td>The name of system property</td> <td>Search/Filter by username. <br> This act like the wildcard search %String%</td>
<td></td>
</tr>
<tr>
<td>propertyKey</td>
<td>@QueryParam</td>
<td>Filter by user propertyKey.</td>
<td></td>
</tr>
<tr>
<td>propertyValue</td>
<td>@QueryParam</td>
<td>Filter by user propertyKey and propertyValue. <br><strong>Note:</strong> It can only be used within propertyKey parameter</td>
<td></td> <td></td>
</tr> </tr>
</tbody></table> </tbody></table>
<h3 id="examples-3">Examples</h3>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU=</p>
<p><strong>DELETE</strong> <a href="http://example.org:9090/plugins/restapi/system/properties/propertyName">http://example.org:9090/plugins/restapi/system/properties/propertyName</a></p> <h3 id="examples">Examples</h3>
<h2 id="put-restapisystempropertiespropertyname">PUT /restapi/system/properties/{propertyName}</h2> <blockquote>
<p><strong>Header</strong>: Authorization: Basic YWRtaW46MTIzNDU=</p>
<p>Endpoint to update / overwrite a system property</p> <p><strong>GET</strong> <a href="http://example.org:9090/plugins/restapi/v1/users">http://example.org:9090/plugins/restapi/v1/users</a> <br>
<strong>GET</strong> <a href="http://example.org:9090/plugins/restapi/v1/users?search=testuser">http://example.org:9090/plugins/restapi/v1/users?search=testuser</a> <br>
<strong>GET</strong> <a href="http://example.org:9090/plugins/restapi/v1/users?propertyKey=keyname">http://example.org:9090/plugins/restapi/v1/users?propertyKey=keyname</a> <br>
<strong>GET</strong> <a href="http://example.org:9090/plugins/restapi/v1/users?propertyKey=keyname&amp;propertyValue=keyvalue">http://example.org:9090/plugins/restapi/v1/users?propertyKey=keyname&amp;propertyValue=keyvalue</a></p>
</blockquote>
<p><strong>Payload:</strong> System property <br> <p>If you want to get a JSON format result, please add “<strong>Accept: application/json</strong>” to the <strong>Header</strong>.</p>
<strong>Return value:</strong> HTTP status 200 (OK)</p>
<h3 id="possible-parameters-2">Possible parameters</h3>
<h2 id="retrieve-a-user">Retrieve a user</h2>
<p>Endpoint to get information over a specific user</p>
<blockquote>
<p><strong>GET</strong> /users/{username}</p>
</blockquote>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> User</p>
<h3 id="possible-parameters-1">Possible parameters</h3>
<table> <table>
<thead> <thead>
...@@ -1488,25 +1828,1819 @@ body.pdf{font-family:"DejaVu Sans"}body.pdf code,body.pdf pre{font-family:"DejaV ...@@ -1488,25 +1828,1819 @@ body.pdf{font-family:"DejaVu Sans"}body.pdf code,body.pdf pre{font-family:"DejaV
</tr> </tr>
</thead> </thead>
<tbody><tr> <tbody><tr>
<td>propertyName</td> <td>username</td>
<td>@Path</td> <td>@Path</td>
<td>The name of system property</td> <td>Exact username</td>
<td></td> <td></td>
</tr> </tr>
</tbody></table> </tbody></table>
<h3 id="examples-4">Examples</h3>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>Header:</strong> Content-Type application/xml</p>
<p><strong>PUT</strong> <a href="http://example.org:9090/plugins/restapi/system/properties/propertyName">http://example.org:9090/plugins/restapi/system/properties/propertyName</a></p> <h3 id="examples-1">Examples</h3>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU=</p>
<p><strong>GET</strong> <a href="http://example.org:9090/plugins/restapi/v1/users/testuser">http://example.org:9090/plugins/restapi/v1/users/testuser</a></p>
<h2 id="create-a-user">Create a user</h2>
<p>Endpoint to create a new user</p>
<blockquote>
<p><strong>POST</strong> /users</p>
</blockquote>
<p><strong>Payload:</strong> User <br>
<strong>Return value:</strong> HTTP status 201 (Created)</p>
<h3 id="examples-2">Examples</h3>
<h4 id="xml-examples">XML Examples</h4>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>Header:</strong> Content-Type: application/<strong>xml</strong></p>
<p><strong>POST</strong> <a href="http://example.org:9090/plugins/restapi/v1/users">http://example.org:9090/plugins/restapi/v1/users</a></p>
</blockquote>
<p><strong>Payload Example 1 (required parameters):</strong></p>
<pre class="prettyprint prettyprinted"><code><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"UTF-8"</span><span class="pln"> standalone</span><span class="pun">=</span><span class="str">"yes"</span><span class="pun">?&gt;</span><span class="pln">
</span><span class="tag">&lt;user&gt;</span><span class="pln">
</span><span class="tag">&lt;username&gt;</span><span class="pln">test3</span><span class="tag">&lt;/username&gt;</span><span class="pln">
</span><span class="tag">&lt;password&gt;</span><span class="pln">p4ssword</span><span class="tag">&lt;/password&gt;</span><span class="pln">
</span><span class="tag">&lt;/user&gt;</span></code></pre>
<p><strong>Payload Example 2 (available parameters):</strong></p>
<pre class="prettyprint prettyprinted"><code><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"UTF-8"</span><span class="pln"> standalone</span><span class="pun">=</span><span class="str">"yes"</span><span class="pun">?&gt;</span><span class="pln">
</span><span class="tag">&lt;user&gt;</span><span class="pln">
</span><span class="tag">&lt;username&gt;</span><span class="pln">testuser</span><span class="tag">&lt;/username&gt;</span><span class="pln">
</span><span class="tag">&lt;password&gt;</span><span class="pln">p4ssword</span><span class="tag">&lt;/password&gt;</span><span class="pln">
</span><span class="tag">&lt;name&gt;</span><span class="pln">Test User</span><span class="tag">&lt;/name&gt;</span><span class="pln">
</span><span class="tag">&lt;email&gt;</span><span class="pln">test@localhost.de</span><span class="tag">&lt;/email&gt;</span><span class="pln">
</span><span class="tag">&lt;properties&gt;</span><span class="pln">
</span><span class="tag">&lt;property</span><span class="pln"> </span><span class="atn">key</span><span class="pun">=</span><span class="atv">"keyname"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"value"</span><span class="tag">/&gt;</span><span class="pln">
</span><span class="tag">&lt;property</span><span class="pln"> </span><span class="atn">key</span><span class="pun">=</span><span class="atv">"anotherkey"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"value"</span><span class="tag">/&gt;</span><span class="pln">
</span><span class="tag">&lt;/properties&gt;</span><span class="pln">
</span><span class="tag">&lt;/user&gt;</span></code></pre>
<h4 id="json-examples">JSON Examples</h4>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>Header:</strong> Content-Type: application/<strong>json</strong></p>
<p><strong>POST</strong> <a href="http://example.org:9090/plugins/restapi/v1/users">http://example.org:9090/plugins/restapi/v1/users</a></p>
</blockquote>
<p><strong>Payload Example 1 (required parameters):</strong></p>
<pre class="prettyprint prettyprinted"><code><span class="pun">{</span><span class="pln">
</span><span class="str">"username"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"admin"</span><span class="pun">,</span><span class="pln">
</span><span class="str">"password"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"p4ssword"</span><span class="pln">
</span><span class="pun">}</span></code></pre>
<p><strong>Payload Example 2 (available parameters):</strong></p>
<pre class="prettyprint prettyprinted"><code><span class="pun">{</span><span class="pln">
</span><span class="str">"username"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"admin"</span><span class="pun">,</span><span class="pln">
</span><span class="str">"password"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"p4ssword"</span><span class="pun">,</span><span class="pln">
</span><span class="str">"name"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"Administrator"</span><span class="pun">,</span><span class="pln">
</span><span class="str">"email"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"admin@example.com"</span><span class="pun">,</span><span class="pln">
</span><span class="str">"properties"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="str">"property"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
</span><span class="str">"@key"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"console.rows_per_page"</span><span class="pun">,</span><span class="pln">
</span><span class="str">"@value"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"user-summary=8"</span><span class="pln">
</span><span class="pun">},</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
</span><span class="str">"@key"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"console.order"</span><span class="pun">,</span><span class="pln">
</span><span class="str">"@value"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"session-summary=1"</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">]</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code></pre>
<h2 id="delete-a-user">Delete a user</h2>
<p>Endpoint to delete a user</p>
<blockquote>
<p><strong>DELETE</strong> /users/{username}</p>
</blockquote>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> HTTP status 200 (OK)</p>
<h3 id="possible-parameters-2">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>username</td>
<td>@Path</td>
<td>Exact username</td>
<td></td>
</tr>
</tbody></table>
<h3 id="examples-3">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>DELETE</strong> <a href="http://example.org:9090/plugins/restapi/v1/users/testuser">http://example.org:9090/plugins/restapi/v1/users/testuser</a></p>
</blockquote>
<h2 id="update-a-user">Update a user</h2>
<p>Endpoint to update / overwrite a user</p>
<blockquote>
<p><strong>PUT</strong> /users/{username}</p>
</blockquote>
<p><strong>Payload:</strong> User <br>
<strong>Return value:</strong> HTTP status 200 (OK)</p>
<h3 id="possible-parameters-3">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>username</td>
<td>@Path</td>
<td>Exact username</td>
<td></td>
</tr>
</tbody></table>
<h3 id="examples-4">Examples</h3>
<h4 id="xml-example">XML Example</h4>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>Header:</strong> Content-Type application/xml</p>
<p><strong>PUT</strong> <a href="http://example.org:9090/plugins/restapi/v1/users/testuser">http://example.org:9090/plugins/restapi/v1/users/testuser</a></p>
</blockquote>
<p><strong>Payload:</strong></p>
<pre class="prettyprint prettyprinted"><code><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"UTF-8"</span><span class="pln"> standalone</span><span class="pun">=</span><span class="str">"yes"</span><span class="pun">?&gt;</span><span class="pln">
</span><span class="tag">&lt;user&gt;</span><span class="pln">
</span><span class="tag">&lt;username&gt;</span><span class="pln">testuser</span><span class="tag">&lt;/username&gt;</span><span class="pln">
</span><span class="tag">&lt;name&gt;</span><span class="pln">Test User edit</span><span class="tag">&lt;/name&gt;</span><span class="pln">
</span><span class="tag">&lt;email&gt;</span><span class="pln">test@edit.de</span><span class="tag">&lt;/email&gt;</span><span class="pln">
</span><span class="tag">&lt;properties&gt;</span><span class="pln">
</span><span class="tag">&lt;property</span><span class="pln"> </span><span class="atn">key</span><span class="pun">=</span><span class="atv">"keyname"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"value"</span><span class="tag">/&gt;</span><span class="pln">
</span><span class="tag">&lt;/properties&gt;</span><span class="pln">
</span><span class="tag">&lt;/user&gt;</span></code></pre>
<h4 id="json-example">JSON Example</h4>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>Header:</strong> Content-Type application/json</p>
<p><strong>PUT</strong> <a href="http://example.org:9090/plugins/restapi/v1/users/testuser">http://example.org:9090/plugins/restapi/v1/users/testuser</a></p>
</blockquote>
<p><strong>Payload:</strong></p>
<pre class="prettyprint prettyprinted"><code><span class="pun">{</span><span class="pln">
</span><span class="str">"username"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"testuser"</span><span class="pun">,</span><span class="pln">
</span><span class="str">"name"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"Test User edit"</span><span class="pun">,</span><span class="pln">
</span><span class="str">"email"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"test@edit.de"</span><span class="pun">,</span><span class="pln">
</span><span class="str">"properties"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="str">"property"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="str">"@key"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"keyname"</span><span class="pun">,</span><span class="pln">
</span><span class="str">"@value"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"value"</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code></pre>
<h2 id="retrieve-all-user-groups">Retrieve all user groups</h2>
<p>Endpoint to get group names of a specific user</p>
<blockquote>
<p><strong>GET</strong> /users/{username}/groups</p>
</blockquote>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> Groups</p>
<h3 id="possible-parameters-4">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>username</td>
<td>@Path</td>
<td>Exact username</td>
<td></td>
</tr>
</tbody></table>
<h3 id="examples-5">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU=</p>
<p><strong>GET </strong> <a href="http://example.org:9090/plugins/restapi/v1/users/testuser/groups">http://example.org:9090/plugins/restapi/v1/users/testuser/groups</a></p>
</blockquote>
<h2 id="add-user-to-group">Add user to group</h2>
<p>Endpoint to add user to a group(s)</p>
<blockquote>
<p><strong>POST</strong> /users/{username}/groups</p>
</blockquote>
<p><strong>Payload:</strong> Groups <br>
<strong>Return value:</strong> HTTP status 201 (Created)</p>
<h3 id="possible-parameters-5">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>username</td>
<td>@Path</td>
<td>Exact username</td>
<td></td>
</tr>
</tbody></table>
<h3 id="examples-6">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>Header:</strong> Content-Type application/xml</p>
<p><strong>POST</strong> <a href="http://example.org:9090/plugins/restapi/v1/users/testuser/groups">http://example.org:9090/plugins/restapi/v1/users/testuser/groups</a></p>
</blockquote>
<p><strong>Payload:</strong></p>
<pre class="prettyprint prettyprinted"><code><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"UTF-8"</span><span class="pln"> standalone</span><span class="pun">=</span><span class="str">"yes"</span><span class="pun">?&gt;</span><span class="pln">
</span><span class="tag">&lt;groups&gt;</span><span class="pln">
</span><span class="tag">&lt;groupname&gt;</span><span class="pln">Admins</span><span class="tag">&lt;/groupname&gt;</span><span class="pln">
</span><span class="tag">&lt;groupname&gt;</span><span class="pln">Support</span><span class="tag">&lt;/groupname&gt;</span><span class="pln">
</span><span class="tag">&lt;/groups&gt;</span></code></pre>
<h2 id="delete-a-user-from-a-group">Delete a user from a group</h2>
<p>Endpoint to remove a user from a group(s)</p>
<blockquote>
<p><strong>DELETE</strong> /users/{username}/groups</p>
</blockquote>
<p><strong>Payload:</strong> Groups <br>
<strong>Return value:</strong> HTTP status 200 (OK)</p>
<h3 id="possible-parameters-6">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>username</td>
<td>@Path</td>
<td>Exact username</td>
<td></td>
</tr>
</tbody></table>
<h3 id="examples-7">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>Header:</strong> Content-Type application/xml</p>
<p><strong>DELETE</strong> <a href="http://example.org:9090/plugins/restapi/v1/users/testuser/groups">http://example.org:9090/plugins/restapi/v1/users/testuser/groups</a></p>
</blockquote>
<p><strong>Payload:</strong></p>
<pre class="prettyprint prettyprinted"><code><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"UTF-8"</span><span class="pln"> standalone</span><span class="pun">=</span><span class="str">"yes"</span><span class="pun">?&gt;</span><span class="pln">
</span><span class="tag">&lt;groups&gt;</span><span class="pln">
</span><span class="tag">&lt;groupname&gt;</span><span class="pln">Admins</span><span class="tag">&lt;/groupname&gt;</span><span class="pln">
</span><span class="tag">&lt;groupname&gt;</span><span class="pln">Support</span><span class="tag">&lt;/groupname&gt;</span><span class="pln">
</span><span class="tag">&lt;/groups&gt;</span></code></pre>
<h2 id="lockout-a-user">Lockout a user</h2>
<p>Endpoint to lockout / ban the user from the chat server</p>
<blockquote>
<p><strong>POST</strong> /lockouts/{username}</p>
</blockquote>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> HTTP status 201 (Created)</p>
<h3 id="possible-parameters-7">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>username</td>
<td>@Path</td>
<td>Exact username</td>
<td></td>
</tr>
</tbody></table>
<h3 id="examples-8">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU=</p>
<p><strong>POST</strong> <a href="http://example.org:9090/plugins/restapi/v1/lockouts/testuser">http://example.org:9090/plugins/restapi/v1/lockouts/testuser</a></p>
</blockquote>
<h2 id="unlock-a-user">Unlock a user</h2>
<p>Endpoint to unlock / unban the user</p>
<blockquote>
<p><strong>DELETE</strong> /lockouts/{username}</p>
</blockquote>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> HTTP status 200 (OK)</p>
<h3 id="possible-parameters-8">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>username</td>
<td>@Path</td>
<td>Exact username</td>
<td></td>
</tr>
</tbody></table>
<h3 id="examples-9">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU=</p>
<p><strong>DELETE</strong> <a href="http://example.org:9090/plugins/restapi/v1/lockouts/testuser">http://example.org:9090/plugins/restapi/v1/lockouts/testuser</a></p>
</blockquote>
<h2 id="retrieve-user-roster">Retrieve user roster</h2>
<p>Endpoint to get roster entries (buddies) from a specific user</p>
<blockquote>
<p><strong>GET</strong> /users/{username}/roster</p>
</blockquote>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> Roster</p>
<h3 id="possible-parameters-9">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>username</td>
<td>@Path</td>
<td>Exact username</td>
<td></td>
</tr>
</tbody></table>
<h3 id="examples-10">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU=</p>
<p><strong>GET </strong> <a href="http://example.org:9090/plugins/restapi/v1/users/testuser/roster">http://example.org:9090/plugins/restapi/v1/users/testuser/roster</a></p>
</blockquote>
<h2 id="create-a-user-roster-entry">Create a user roster entry</h2>
<p>Endpoint to add a new roster entry to a user</p>
<blockquote>
<p><strong>POST</strong> /users/{username}/roster</p>
</blockquote>
<p><strong>Payload:</strong> RosterItem <br>
<strong>Return value:</strong> HTTP status 201 (Created)</p>
<h3 id="possible-parameters-10">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>username</td>
<td>@Path</td>
<td>Exact username</td>
<td></td>
</tr>
</tbody></table>
<h3 id="examples-11">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>Header:</strong> Content-Type application/xml</p>
<p><strong>POST</strong> <a href="http://example.org:9090/plugins/restapi/v1/users/testuser/roster">http://example.org:9090/plugins/restapi/v1/users/testuser/roster</a></p>
</blockquote>
<p><strong>Payload:</strong> <br>
Payload Example 1 (required parameters):</p>
<pre class="prettyprint prettyprinted"><code><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"UTF-8"</span><span class="pln"> standalone</span><span class="pun">=</span><span class="str">"yes"</span><span class="pun">?&gt;</span><span class="pln">
</span><span class="tag">&lt;rosterItem&gt;</span><span class="pln">
</span><span class="tag">&lt;jid&gt;</span><span class="pln">peter@pan.de</span><span class="tag">&lt;/jid&gt;</span><span class="pln">
</span><span class="tag">&lt;/rosterItem&gt;</span></code></pre>
<p>Payload Example 2 (available parameters):</p>
<pre class="prettyprint prettyprinted"><code><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"UTF-8"</span><span class="pln"> standalone</span><span class="pun">=</span><span class="str">"yes"</span><span class="pun">?&gt;</span><span class="pln">
</span><span class="tag">&lt;rosterItem&gt;</span><span class="pln">
</span><span class="tag">&lt;jid&gt;</span><span class="pln">peter@pan1.de</span><span class="tag">&lt;/jid&gt;</span><span class="pln">
</span><span class="tag">&lt;nickname&gt;</span><span class="pln">Peter1</span><span class="tag">&lt;/nickname&gt;</span><span class="pln">
</span><span class="tag">&lt;subscriptionType&gt;</span><span class="pln">3</span><span class="tag">&lt;/subscriptionType&gt;</span><span class="pln">
</span><span class="tag">&lt;groups&gt;</span><span class="pln">
</span><span class="tag">&lt;group&gt;</span><span class="pln">Friends</span><span class="tag">&lt;/group&gt;</span><span class="pln">
</span><span class="tag">&lt;/groups&gt;</span><span class="pln">
</span><span class="tag">&lt;/rosterItem&gt;</span></code></pre>
<h2 id="delete-a-user-roster-entry">Delete a user roster entry</h2>
<p>Endpoint to remove a roster entry from a user</p>
<blockquote>
<p><strong>DELETE</strong> /users/{username}/roster/{jid}</p>
</blockquote>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> HTTP status 200 (OK)</p>
<h3 id="possible-parameters-11">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>username</td>
<td>@Path</td>
<td>Exact username</td>
<td></td>
</tr>
<tr>
<td>jid</td>
<td>@Path</td>
<td>JID of the roster item</td>
<td></td>
</tr>
</tbody></table>
<h3 id="examples-12">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU=</p>
<p><strong>DELETE</strong> <a href="http://example.org:9090/plugins/restapi/v1/users/testuser/roster/peter@pan.de">http://example.org:9090/plugins/restapi/v1/users/testuser/roster/peter@pan.de</a></p>
</blockquote>
<h2 id="update-a-user-roster-entry">Update a user roster entry</h2>
<p>Endpoint to update a roster entry</p>
<blockquote>
<p><strong>PUT</strong> /users/{username}/roster/{jid}</p>
</blockquote>
<p><strong>Payload:</strong> RosterItem <br>
<strong>Return value:</strong> HTTP status 200 (OK)</p>
<h3 id="possible-parameters-12">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>username</td>
<td>@Path</td>
<td>Exact username</td>
<td></td>
</tr>
<tr>
<td>jid</td>
<td>@Path</td>
<td>JID of the roster item</td>
<td></td>
</tr>
</tbody></table>
<h3 id="examples-13">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>Header:</strong> Content-Type application/xml</p>
<p><strong>PUT</strong> <a href="http://example.org:9090/plugins/restapi/v1/users/testuser/roster/peter@pan.de">http://example.org:9090/plugins/restapi/v1/users/testuser/roster/peter@pan.de</a></p>
</blockquote>
<p><strong>Payload:</strong></p>
<pre class="prettyprint prettyprinted"><code><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"UTF-8"</span><span class="pln"> standalone</span><span class="pun">=</span><span class="str">"yes"</span><span class="pun">?&gt;</span><span class="pln">
</span><span class="tag">&lt;rosterItem&gt;</span><span class="pln">
</span><span class="tag">&lt;jid&gt;</span><span class="pln">peter@pan.de</span><span class="tag">&lt;/jid&gt;</span><span class="pln">
</span><span class="tag">&lt;nickname&gt;</span><span class="pln">Peter Pan</span><span class="tag">&lt;/nickname&gt;</span><span class="pln">
</span><span class="tag">&lt;subscriptionType&gt;</span><span class="pln">0</span><span class="tag">&lt;/subscriptionType&gt;</span><span class="pln">
</span><span class="tag">&lt;groups&gt;</span><span class="pln">
</span><span class="tag">&lt;group&gt;</span><span class="pln">Support</span><span class="tag">&lt;/group&gt;</span><span class="pln">
</span><span class="tag">&lt;/groups&gt;</span><span class="pln">
</span><span class="tag">&lt;/rosterItem&gt;</span></code></pre>
<h1 id="chat-room-related-rest-endpoints">Chat room related REST Endpoints</h1>
<h2 id="retrieve-all-chat-rooms">Retrieve all chat rooms</h2>
<p>Endpoint to get all chat rooms</p>
<blockquote>
<p><strong>GET</strong> /chatrooms</p>
</blockquote>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> Chatrooms</p>
<h3 id="possible-parameters-13">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>servicename</td>
<td>@QueryParam</td>
<td>The name of the Group Chat Service</td>
<td>conference</td>
</tr>
<tr>
<td>type</td>
<td>@QueryParam</td>
<td><strong>public:</strong> Only as List Room in Directory set rooms <br> <strong>all:</strong> All rooms.</td>
<td>public</td>
</tr>
<tr>
<td>search</td>
<td>@QueryParam</td>
<td>Search/Filter by room name. <br> This act like the wildcard search %String%</td>
<td></td>
</tr>
</tbody></table>
<h3 id="examples-14">Examples</h3>
<blockquote>
<p><strong>Header</strong>: Authorization: Basic YWRtaW46MTIzNDU=</p>
<p><strong>GET</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms">http://example.org:9090/plugins/restapi/v1/chatrooms</a> <br>
<strong>GET</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms?type=all">http://example.org:9090/plugins/restapi/v1/chatrooms?type=all</a> <br>
<strong>GET</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms?type=all&amp;servicename=privateconf">http://example.org:9090/plugins/restapi/v1/chatrooms?type=all&amp;servicename=privateconf</a> <br>
<strong>GET</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms?search=test">http://example.org:9090/plugins/restapi/v1/chatrooms?search=test</a></p>
</blockquote>
<h2 id="retrieve-a-chat-room">Retrieve a chat room</h2>
<p>Endpoint to get information over specific chat room</p>
<blockquote>
<p><strong>GET</strong> /chatrooms<span>/{roomName}</span></p>
</blockquote>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> Chatroom</p>
<h3 id="possible-parameters-14">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>roomname</td>
<td>@Path</td>
<td>Exact room name</td>
<td></td>
</tr>
<tr>
<td>servicename</td>
<td>@QueryParam</td>
<td>The name of the Group Chat Service</td>
<td>conference</td>
</tr>
</tbody></table>
<h3 id="examples-15">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU=</p>
<p><strong>GET</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/test">http://example.org:9090/plugins/restapi/v1/chatrooms/test</a> <br>
<strong>GET</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/test?servicename=privateconf">http://example.org:9090/plugins/restapi/v1/chatrooms/test?servicename=privateconf</a></p>
</blockquote>
<h2 id="retrieve-chat-room-participants">Retrieve chat room participants</h2>
<p>Endpoint to get all participants with a role of specified room.</p>
<blockquote>
<p><strong>GET</strong> /chatrooms/{roomName}/participants</p>
</blockquote>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> Participants</p>
<h3 id="possible-parameters-15">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>roomname</td>
<td>@Path</td>
<td>Exact room name</td>
<td></td>
</tr>
<tr>
<td>servicename</td>
<td>@QueryParam</td>
<td>The name of the Group Chat Service</td>
<td>conference</td>
</tr>
</tbody></table>
<h3 id="examples-16">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU=</p>
<p><strong>GET</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/room1/participants">http://example.org:9090/plugins/restapi/v1/chatrooms/room1/participants</a></p>
</blockquote>
<h2 id="create-a-chat-room">Create a chat room</h2>
<p>Endpoint to create a new chat room.</p>
<blockquote>
<p><strong>POST</strong> /chatrooms</p>
</blockquote>
<p><strong>Payload:</strong> Chatroom <br>
<strong>Return value:</strong> HTTP status 201 (Created)</p>
<h3 id="possible-parameters-16">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>servicename</td>
<td>@QueryParam</td>
<td>The name of the Group Chat Service</td>
<td>conference</td>
</tr>
</tbody></table>
<h3 id="xml-examples-1">XML Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>Header:</strong> Content-Type: application/xml</p>
<p><strong>POST</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms">http://example.org:9090/plugins/restapi/v1/chatrooms</a></p>
</blockquote>
<p><strong>Payload Example 1 (required parameters):</strong></p>
<pre class="prettyprint prettyprinted"><code><span class="tag">&lt;chatRoom&gt;</span><span class="pln">
</span><span class="tag">&lt;naturalName&gt;</span><span class="pln">global-1</span><span class="tag">&lt;/naturalName&gt;</span><span class="pln">
</span><span class="tag">&lt;roomName&gt;</span><span class="pln">global</span><span class="tag">&lt;/roomName&gt;</span><span class="pln">
</span><span class="tag">&lt;description&gt;</span><span class="pln">Global Chat Room</span><span class="tag">&lt;/description&gt;</span><span class="pln">
</span><span class="tag">&lt;/chatRoom&gt;</span></code></pre>
<p><strong>Payload Example 2 (available parameters):</strong></p>
<pre class="prettyprint prettyprinted"><code><span class="tag">&lt;chatRoom&gt;</span><span class="pln">
</span><span class="tag">&lt;roomName&gt;</span><span class="pln">global</span><span class="tag">&lt;/roomName&gt;</span><span class="pln">
</span><span class="tag">&lt;naturalName&gt;</span><span class="pln">global-2</span><span class="tag">&lt;/naturalName&gt;</span><span class="pln">
</span><span class="tag">&lt;description&gt;</span><span class="pln">Global Chat Room</span><span class="tag">&lt;/description&gt;</span><span class="pln">
</span><span class="tag">&lt;creationDate&gt;</span><span class="pln">2014-02-12T15:52:37.592+01:00</span><span class="tag">&lt;/creationDate&gt;</span><span class="pln">
</span><span class="tag">&lt;modificationDate&gt;</span><span class="pln">2014-09-12T15:35:54.702+02:00</span><span class="tag">&lt;/modificationDate&gt;</span><span class="pln">
</span><span class="tag">&lt;maxUsers&gt;</span><span class="pln">0</span><span class="tag">&lt;/maxUsers&gt;</span><span class="pln">
</span><span class="tag">&lt;persistent&gt;</span><span class="pln">true</span><span class="tag">&lt;/persistent&gt;</span><span class="pln">
</span><span class="tag">&lt;publicRoom&gt;</span><span class="pln">true</span><span class="tag">&lt;/publicRoom&gt;</span><span class="pln">
</span><span class="tag">&lt;registrationEnabled&gt;</span><span class="pln">false</span><span class="tag">&lt;/registrationEnabled&gt;</span><span class="pln">
</span><span class="tag">&lt;canAnyoneDiscoverJID&gt;</span><span class="pln">false</span><span class="tag">&lt;/canAnyoneDiscoverJID&gt;</span><span class="pln">
</span><span class="tag">&lt;canOccupantsChangeSubject&gt;</span><span class="pln">false</span><span class="tag">&lt;/canOccupantsChangeSubject&gt;</span><span class="pln">
</span><span class="tag">&lt;canOccupantsInvite&gt;</span><span class="pln">false</span><span class="tag">&lt;/canOccupantsInvite&gt;</span><span class="pln">
</span><span class="tag">&lt;canChangeNickname&gt;</span><span class="pln">false</span><span class="tag">&lt;/canChangeNickname&gt;</span><span class="pln">
</span><span class="tag">&lt;logEnabled&gt;</span><span class="pln">true</span><span class="tag">&lt;/logEnabled&gt;</span><span class="pln">
</span><span class="tag">&lt;loginRestrictedToNickname&gt;</span><span class="pln">false</span><span class="tag">&lt;/loginRestrictedToNickname&gt;</span><span class="pln">
</span><span class="tag">&lt;membersOnly&gt;</span><span class="pln">false</span><span class="tag">&lt;/membersOnly&gt;</span><span class="pln">
</span><span class="tag">&lt;moderated&gt;</span><span class="pln">false</span><span class="tag">&lt;/moderated&gt;</span><span class="pln">
</span><span class="tag">&lt;broadcastPresenceRoles&gt;</span><span class="pln">
</span><span class="tag">&lt;broadcastPresenceRole&gt;</span><span class="pln">moderator</span><span class="tag">&lt;/broadcastPresenceRole&gt;</span><span class="pln">
</span><span class="tag">&lt;broadcastPresenceRole&gt;</span><span class="pln">participant</span><span class="tag">&lt;/broadcastPresenceRole&gt;</span><span class="pln">
</span><span class="tag">&lt;broadcastPresenceRole&gt;</span><span class="pln">visitor</span><span class="tag">&lt;/broadcastPresenceRole&gt;</span><span class="pln">
</span><span class="tag">&lt;/broadcastPresenceRoles&gt;</span><span class="pln">
</span><span class="tag">&lt;owners&gt;</span><span class="pln">
</span><span class="tag">&lt;owner&gt;</span><span class="pln">owner@localhost</span><span class="tag">&lt;/owner&gt;</span><span class="pln">
</span><span class="tag">&lt;/owners&gt;</span><span class="pln">
</span><span class="tag">&lt;admins&gt;</span><span class="pln">
</span><span class="tag">&lt;admin&gt;</span><span class="pln">admin@localhost</span><span class="tag">&lt;/admin&gt;</span><span class="pln">
</span><span class="tag">&lt;/admins&gt;</span><span class="pln">
</span><span class="tag">&lt;members&gt;</span><span class="pln">
</span><span class="tag">&lt;member&gt;</span><span class="pln">member2@localhost</span><span class="tag">&lt;/member&gt;</span><span class="pln">
</span><span class="tag">&lt;member&gt;</span><span class="pln">member1@localhost</span><span class="tag">&lt;/member&gt;</span><span class="pln">
</span><span class="tag">&lt;/members&gt;</span><span class="pln">
</span><span class="tag">&lt;outcasts&gt;</span><span class="pln">
</span><span class="tag">&lt;outcast&gt;</span><span class="pln">outcast1@localhost</span><span class="tag">&lt;/outcast&gt;</span><span class="pln">
</span><span class="tag">&lt;/outcasts&gt;</span><span class="pln">
</span><span class="tag">&lt;/chatRoom&gt;</span></code></pre>
<h3 id="json-examples-1">JSON Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>Header:</strong> Content-Type: application/json</p>
<p><strong>POST</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms">http://example.org:9090/plugins/restapi/v1/chatrooms</a></p>
</blockquote>
<p><strong>Payload Example 1 (required parameters):</strong></p>
<pre class="prettyprint prettyprinted"><code><span class="pun">{</span><span class="pln">
</span><span class="str">"roomName"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"global"</span><span class="pun">,</span><span class="pln">
</span><span class="str">"naturalName"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"global-2"</span><span class="pun">,</span><span class="pln">
</span><span class="str">"description"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"Global chat room"</span><span class="pln">
</span><span class="pun">}</span></code></pre>
<p><strong>Payload Example 2 (available parameters):</strong></p>
<pre class="prettyprint prettyprinted"><code><span class="str">```
{
"roomName": "global-1",
"naturalName": "global-1_test_hello",
"description": "Global chat room",
"creationDate": "2012-10-18T16:55:12.803+02:00",
"modificationDate": "2014-07-10T09:49:12.411+02:00",
"maxUsers": "0",
"persistent": "true",
"publicRoom": "true",
"registrationEnabled": "false",
"canAnyoneDiscoverJID": "true",
"canOccupantsChangeSubject": "false",
"canOccupantsInvite": "false",
"canChangeNickname": "false",
"logEnabled": "true",
"loginRestrictedToNickname": "true",
"membersOnly": "false",
"moderated": "false",
"broadcastPresenceRoles": {
"broadcastPresenceRole": [
"moderator",
"participant",
"visitor"
]
},
"owners": {
"owner": "owner@localhost"
},
"admins": {
"admin": [
"admin@localhost",
"admin2@localhost"
]
},
"members": {
"member": [
"member@localhost",
"member2@localhost"
]
},
"outcasts": {
"outcast": [
"outcast@localhost",
"outcast2@localhost"
]
}
}</span></code></pre>
<h2 id="delete-a-chat-room">Delete a chat room</h2>
<p>Endpoint to delete a chat room.</p>
<blockquote>
<p><strong>DELETE</strong> /chatrooms/{roomName}</p>
</blockquote>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> HTTP status 200 (OK)</p>
<h3 id="possible-parameters-17">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>roomname</td>
<td>@Path</td>
<td>Exact room name</td>
<td></td>
</tr>
<tr>
<td>servicename</td>
<td>@QueryParam</td>
<td>The name of the Group Chat Service</td>
<td>conference</td>
</tr>
</tbody></table>
<h3 id="examples-17">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU=</p>
<p><strong>DELETE</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/testroom">http://example.org:9090/plugins/restapi/v1/chatrooms/testroom</a> <br>
<strong>DELETE</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/testroom?servicename=privateconf">http://example.org:9090/plugins/restapi/v1/chatrooms/testroom?servicename=privateconf</a></p>
</blockquote>
<h2 id="update-a-chat-room">Update a chat room</h2>
<p>Endpoint to update a chat room.</p>
<blockquote>
<p><strong>PUT</strong> /chatrooms/{roomName}</p>
</blockquote>
<p><strong>Payload:</strong> Chatroom <br>
<strong>Return value:</strong> HTTP status 200 (OK)</p>
<h3 id="possible-parameters-18">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>roomname</td>
<td>@Path</td>
<td>Exact room name</td>
<td></td>
</tr>
<tr>
<td>servicename</td>
<td>@QueryParam</td>
<td>The name of the Group Chat Service</td>
<td>conference</td>
</tr>
</tbody></table>
<h3 id="examples-18">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>Header:</strong> Content-Type application/xml</p>
<p><strong>PUT</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/global">http://example.org:9090/plugins/restapi/v1/chatrooms/global</a></p>
</blockquote>
<p><strong>Payload:</strong></p>
<pre class="prettyprint prettyprinted"><code><span class="tag">&lt;chatRoom&gt;</span><span class="pln">
</span><span class="tag">&lt;roomName&gt;</span><span class="pln">global</span><span class="tag">&lt;/roomName&gt;</span><span class="pln">
</span><span class="tag">&lt;naturalName&gt;</span><span class="pln">global-2</span><span class="tag">&lt;/naturalName&gt;</span><span class="pln">
</span><span class="tag">&lt;description&gt;</span><span class="pln">Global Chat Room edit</span><span class="tag">&lt;/description&gt;</span><span class="pln">
</span><span class="tag">&lt;password&gt;</span><span class="pln">test</span><span class="tag">&lt;/password&gt;</span><span class="pln">
</span><span class="tag">&lt;creationDate&gt;</span><span class="pln">2014-02-12T15:52:37.592+01:00</span><span class="tag">&lt;/creationDate&gt;</span><span class="pln">
</span><span class="tag">&lt;modificationDate&gt;</span><span class="pln">2014-09-12T14:20:56.286+02:00</span><span class="tag">&lt;/modificationDate&gt;</span><span class="pln">
</span><span class="tag">&lt;maxUsers&gt;</span><span class="pln">0</span><span class="tag">&lt;/maxUsers&gt;</span><span class="pln">
</span><span class="tag">&lt;persistent&gt;</span><span class="pln">true</span><span class="tag">&lt;/persistent&gt;</span><span class="pln">
</span><span class="tag">&lt;publicRoom&gt;</span><span class="pln">true</span><span class="tag">&lt;/publicRoom&gt;</span><span class="pln">
</span><span class="tag">&lt;registrationEnabled&gt;</span><span class="pln">false</span><span class="tag">&lt;/registrationEnabled&gt;</span><span class="pln">
</span><span class="tag">&lt;canAnyoneDiscoverJID&gt;</span><span class="pln">false</span><span class="tag">&lt;/canAnyoneDiscoverJID&gt;</span><span class="pln">
</span><span class="tag">&lt;canOccupantsChangeSubject&gt;</span><span class="pln">false</span><span class="tag">&lt;/canOccupantsChangeSubject&gt;</span><span class="pln">
</span><span class="tag">&lt;canOccupantsInvite&gt;</span><span class="pln">false</span><span class="tag">&lt;/canOccupantsInvite&gt;</span><span class="pln">
</span><span class="tag">&lt;canChangeNickname&gt;</span><span class="pln">false</span><span class="tag">&lt;/canChangeNickname&gt;</span><span class="pln">
</span><span class="tag">&lt;logEnabled&gt;</span><span class="pln">true</span><span class="tag">&lt;/logEnabled&gt;</span><span class="pln">
</span><span class="tag">&lt;loginRestrictedToNickname&gt;</span><span class="pln">false</span><span class="tag">&lt;/loginRestrictedToNickname&gt;</span><span class="pln">
</span><span class="tag">&lt;membersOnly&gt;</span><span class="pln">false</span><span class="tag">&lt;/membersOnly&gt;</span><span class="pln">
</span><span class="tag">&lt;moderated&gt;</span><span class="pln">false</span><span class="tag">&lt;/moderated&gt;</span><span class="pln">
</span><span class="tag">&lt;broadcastPresenceRoles/&gt;</span><span class="pln">
</span><span class="tag">&lt;owners&gt;</span><span class="pln">
</span><span class="tag">&lt;owner&gt;</span><span class="pln">owner@localhost</span><span class="tag">&lt;/owner&gt;</span><span class="pln">
</span><span class="tag">&lt;/owners&gt;</span><span class="pln">
</span><span class="tag">&lt;admins&gt;</span><span class="pln">
</span><span class="tag">&lt;admin&gt;</span><span class="pln">admin@localhost</span><span class="tag">&lt;/admin&gt;</span><span class="pln">
</span><span class="tag">&lt;/admins&gt;</span><span class="pln">
</span><span class="tag">&lt;members&gt;</span><span class="pln">
</span><span class="tag">&lt;member&gt;</span><span class="pln">member2@localhost</span><span class="tag">&lt;/member&gt;</span><span class="pln">
</span><span class="tag">&lt;member&gt;</span><span class="pln">member1@localhost</span><span class="tag">&lt;/member&gt;</span><span class="pln">
</span><span class="tag">&lt;/members&gt;</span><span class="pln">
</span><span class="tag">&lt;outcasts&gt;</span><span class="pln">
</span><span class="tag">&lt;outcast&gt;</span><span class="pln">outcast1@localhost</span><span class="tag">&lt;/outcast&gt;</span><span class="pln">
</span><span class="tag">&lt;/outcasts&gt;</span><span class="pln">
</span><span class="tag">&lt;/chatRoom&gt;</span></code></pre>
<h2 id="add-user-with-role-to-chat-room">Add user with role to chat room</h2>
<p>Endpoint to add a new user with role to a room.</p>
<blockquote>
<p><strong>POST</strong> /chatrooms/{roomName}/{roles}/{name}</p>
</blockquote>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> HTTP status 201 (Created)</p>
<h3 id="possible-parameters-19">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>roomname</td>
<td>@Path</td>
<td>Exact room name</td>
<td></td>
</tr>
<tr>
<td>name</td>
<td>@Path</td>
<td>The local username or the user JID</td>
<td></td>
</tr>
<tr>
<td>roles</td>
<td>@Path</td>
<td>Available roles: <br><strong>owners</strong> <br> <strong>admins</strong> <br> <strong>members</strong> <br> <strong>outcasts</strong></td>
<td></td>
</tr>
<tr>
<td>servicename</td>
<td>@QueryParam</td>
<td>The name of the Group Chat Service</td>
<td>conference</td>
</tr>
</tbody></table>
<h3 id="examples-19">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>Header:</strong> Content-Type application/xml</p>
<p><strong>POST</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser">http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser</a> <br>
<strong>POST</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser@openfire.com">http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser@openfire.com</a> <br>
<strong>POST</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/global/admins/testUser">http://example.org:9090/plugins/restapi/v1/chatrooms/global/admins/testUser</a> <br>
<strong>POST</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/global/members/testUser">http://example.org:9090/plugins/restapi/v1/chatrooms/global/members/testUser</a> <br>
<strong>POST</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/global/outcasts/testUser">http://example.org:9090/plugins/restapi/v1/chatrooms/global/outcasts/testUser</a> <br>
<strong>POST</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser?servicename=privateconf">http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser?servicename=privateconf</a></p>
</blockquote>
<h2 id="delete-a-user-from-a-chat-room">Delete a user from a chat room</h2>
<p>Endpoint to remove a room user role. <br>
DELETE /chatrooms/{roomName}/{roles}/{name}</p>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> HTTP status 200 (OK)</p>
<h3 id="possible-parameters-20">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>roomname</td>
<td>@Path</td>
<td>Exact room name</td>
<td></td>
</tr>
<tr>
<td>name</td>
<td>@Path</td>
<td>The local username or the user JID</td>
<td></td>
</tr>
<tr>
<td>roles</td>
<td>@Path</td>
<td>Available roles: <br><strong>owners</strong> <br> <strong>admins</strong> <br> <strong>members</strong> <br> <strong>outcasts</strong></td>
<td></td>
</tr>
<tr>
<td>servicename</td>
<td>@QueryParam</td>
<td>The name of the Group Chat Service</td>
<td>conference</td>
</tr>
</tbody></table>
<h3 id="examples-20">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>Header:</strong> Content-Type application/xml</p>
<p><strong>DELETE</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser">http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser</a> <br>
<strong>DELETE</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser@openfire.com">http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser@openfire.com</a> <br>
<strong>DELETE</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/global/admins/testUser">http://example.org:9090/plugins/restapi/v1/chatrooms/global/admins/testUser</a> <br>
<strong>DELETE</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/global/members/testUser">http://example.org:9090/plugins/restapi/v1/chatrooms/global/members/testUser</a> <br>
<strong>DELETE</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/global/outcasts/testUser">http://example.org:9090/plugins/restapi/v1/chatrooms/global/outcasts/testUser</a> <br>
<strong>DELETE</strong> <a href="http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser?servicename=privateconf">http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser?servicename=privateconf</a></p>
</blockquote>
<h1 id="system-related-rest-endpoints">System related REST Endpoints</h1>
<h2 id="retrieve-all-system-properties">Retrieve all system properties</h2>
<p>Endpoint to get all system properties</p>
<blockquote>
<p><strong>GET</strong> /system/properties</p>
</blockquote>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> System properties</p>
<h3 id="examples-21">Examples</h3>
<blockquote>
<p><strong>Header</strong>: Authorization: Basic YWRtaW46MTIzNDU=</p>
<p><strong>GET</strong> <a href="http://example.org:9090/plugins/restapi/v1/system/properties">http://example.org:9090/plugins/restapi/v1/system/properties</a></p>
</blockquote>
<h2 id="retrieve-system-property">Retrieve system property</h2>
<p>Endpoint to get information over specific system property</p>
<blockquote>
<p><strong>GET</strong> /system/properties/{propertyName}</p>
</blockquote>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> System property</p>
<h3 id="possible-parameters-21">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>propertyName</td>
<td>@Path</td>
<td>The name of system property</td>
<td></td>
</tr>
</tbody></table>
<h3 id="examples-22">Examples</h3>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU=</p>
<p><strong>GET</strong> <a href="http://example.org:9090/plugins/restapi/v1/system/properties/xmpp.domain">http://example.org:9090/plugins/restapi/v1/system/properties/xmpp.domain</a></p>
<h2 id="create-a-system-property">Create a system property</h2>
<p>Endpoint to create a system property</p>
<blockquote>
<p><strong>POST</strong> system/properties</p>
</blockquote>
<p><strong>Payload:</strong> System Property <br>
<strong>Return value:</strong> HTTP status 201 (Created)</p>
<h3 id="examples-23">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>Header:</strong> Content-Type: application/xml</p>
<p><strong>POST</strong> <a href="http://example.org:9090/plugins/restapi/v1/system/properties">http://example.org:9090/plugins/restapi/v1/system/properties</a></p>
</blockquote>
<p><strong>Payload Example:</strong></p>
<pre class="prettyprint prettyprinted"><code><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"UTF-8"</span><span class="pln"> standalone</span><span class="pun">=</span><span class="str">"yes"</span><span class="pun">?&gt;</span><span class="pln">
</span><span class="tag">&lt;property</span><span class="pln"> </span><span class="atn">key</span><span class="pun">=</span><span class="atv">"propertyName"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"propertyValue"</span><span class="tag">/&gt;</span></code></pre>
<h2 id="delete-a-system-property">Delete a system property</h2>
<p>Endpoint to delete a system property</p>
<blockquote>
<p><strong>DELETE</strong> /system/properties/{propertyName}</p>
</blockquote>
<p><strong>Payload:</strong> none <br>
<strong>Return value:</strong> HTTP status 200 (OK)</p>
<h3 id="possible-parameters-22">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>propertyName</td>
<td>@Path</td>
<td>The name of system property</td>
<td></td>
</tr>
</tbody></table>
<h3 id="examples-24">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU=</p>
<p><strong>DELETE</strong> <a href="http://example.org:9090/plugins/restapi/v1/system/properties/propertyName">http://example.org:9090/plugins/restapi/v1/system/properties/propertyName</a></p>
</blockquote>
<h2 id="update-a-system-property">Update a system property</h2>
<p>Endpoint to update / overwrite a system property</p>
<blockquote>
<p><strong>PUT</strong> /system/properties/{propertyName}</p>
</blockquote>
<p><strong>Payload:</strong> System property <br>
<strong>Return value:</strong> HTTP status 200 (OK)</p>
<h3 id="possible-parameters-23">Possible parameters</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Parameter Type</th>
<th>Description</th>
<th>Default value</th>
</tr>
</thead>
<tbody><tr>
<td>propertyName</td>
<td>@Path</td>
<td>The name of system property</td>
<td></td>
</tr>
</tbody></table>
<h3 id="examples-25">Examples</h3>
<blockquote>
<p><strong>Header:</strong> Authorization: Basic YWRtaW46MTIzNDU= <br>
<strong>Header:</strong> Content-Type application/xml</p>
<p><strong>PUT</strong> <a href="http://example.org:9090/plugins/restapi/v1/system/properties/propertyName">http://example.org:9090/plugins/restapi/v1/system/properties/propertyName</a></p>
</blockquote>
<p><strong>Payload:</strong></p>
<pre class="prettyprint prettyprinted"><code><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"UTF-8"</span><span class="pln"> standalone</span><span class="pun">=</span><span class="str">"yes"</span><span class="pun">?&gt;</span><span class="pln">
</span><span class="tag">&lt;property</span><span class="pln"> </span><span class="atn">key</span><span class="pun">=</span><span class="atv">"propertyName"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"anotherValue"</span><span class="tag">/&gt;</span></code></pre>
<h1 id="deprecated-user-service-plugin-readme">(Deprecated) User Service Plugin Readme</h1>
<h2 id="overview">Overview</h2>
<p>The User Service Plugin provides the ability to add,edit,delete users and manage their rosters by sending an http request to the server. It is intended to be used by applications automating the user administration process. This plugin’s functionality is useful for applications that need to administer users outside of the Openfire admin console. An example of such an application might be a live sports reporting application that uses XMPP as its transport, and creates/deletes users according to the receipt, or non receipt, of a subscription fee.</p>
<h2 id="installation-1">Installation</h2>
<p>Copy userservice.jar into the plugins directory of your Openfire server. The plugin will then be automatically deployed. To upgrade to a new version, copy the new userservice.jar file over the existing file.</p>
<h2 id="configuration">Configuration</h2>
<p>Access to the service is restricted with a “secret” that can be viewed and set from the User Service page in the Openfire admin console. This page is located on the admin console under “Server” and then “Server Settings”. This should really only be considered weak security. The plugin was initially written with the assumption that http access to the Openfire service was only available to trusted machines. In the case of the plugin’s author, a web application running on the same server as Openfire makes the request.</p>
<h2 id="using-the-plugin">Using the Plugin</h2>
<p>To administer users, submit HTTP requests to the userservice service. The service address is [hostname]plugins/restapi/userservice. For example, if your server name is “example.com”, the URL is <a href="http://example.com/plugins/restapi/userservice">http://example.com/plugins/restapi/userservice</a></p>
<p>The following parameters can be passed into the request:</p>
<table>
<thead>
<tr>
<th>Name</th>
<th></th>
<th>Description</th>
</tr>
</thead>
<tbody><tr>
<td>type</td>
<td>Required</td>
<td>The admin service required. Possible values are ‘add’, ‘delete’, ‘update’, ‘enable’, ‘disable’, ‘add_roster’, ‘update_roster’, ‘delete_roster’, ‘grouplist’, ‘usergrouplist’.</td>
</tr>
<tr>
<td>secret</td>
<td>Required</td>
<td>The secret key that allows access to the User Service.</td>
</tr>
<tr>
<td>username</td>
<td>Required</td>
<td>The username of the user to ‘add’, ‘delete’, ‘update’, ‘enable’, ‘disable’, ‘add_roster’, ‘update_roster’, ‘delete_roster’. ie the part before the @ symbol.</td>
</tr>
<tr>
<td>password</td>
<td>Required for ‘add’ operation</td>
<td>The password of the new user or the user being updated.</td>
</tr>
<tr>
<td>name</td>
<td>Optional</td>
<td>The display name of the new user or the user being updated. For ‘add_roster’, ‘update_roster’ operations specifies the nickname of the roster item.</td>
</tr>
<tr>
<td>email</td>
<td>Optional</td>
<td>The email address of the new user or the user being updated.</td>
</tr>
<tr>
<td>groups</td>
<td>Optional</td>
<td>List of groups where the user is a member. Values are comma delimited. When used with types “add” or “update”, it adds the user to shared groups and auto-creates new groups. When used with ‘add_roster’ and ‘update_roster’, it adds the user to roster groups provided the group name does not clash with an existing shared group.</td>
</tr>
<tr>
<td>item_jid</td>
<td>Required for ‘add_roster’, ‘update_roster’, ‘delete_roster’ operations.</td>
<td>The JID of the roster item</td>
</tr>
<tr>
<td>subscription</td>
<td>Optional</td>
<td>Type of subscription for ‘add_roster’, ‘update_roster’ operations. Possible numeric values are: -1(remove), 0(none), 1(to), 2(from), 3(both).</td>
</tr>
</tbody></table>
<h2 id="sample-html">Sample HTML</h2>
<p>The following example adds a user</p>
<p><a href="http://example.com:9090/plugins/restapi/userservice?type=add&amp;secret=bigsecret&amp;username=kafka&amp;password=drowssap&amp;name=franz&amp;email=franz@kafka.com">http://example.com:9090/plugins/restapi/userservice?type=add&amp;secret=bigsecret&amp;username=kafka&amp;password=drowssap&amp;name=franz&amp;email=franz@kafka.com</a></p>
<p>The following example adds a user, adds two shared groups (if not existing) and adds the user to both groups.</p>
<p><a href="http://example.com:9090/plugins/restapi/userservice?type=add&amp;secret=bigsecret&amp;username=kafka&amp;password=drowssap&amp;name=franz&amp;email=franz@kafka.com&amp;groups=support,finance">http://example.com:9090/plugins/restapi/userservice?type=add&amp;secret=bigsecret&amp;username=kafka&amp;password=drowssap&amp;name=franz&amp;email=franz@kafka.com&amp;groups=support,finance</a></p>
<p>The following example deletes a user and all roster items of the user.</p>
<p><a href="http://example.com:9090/plugins/restapi/userservice?type=delete&amp;secret=bigsecret&amp;username=kafka">http://example.com:9090/plugins/restapi/userservice?type=delete&amp;secret=bigsecret&amp;username=kafka</a></p>
<p>The following example disables a user (lockout)</p>
<p><a href="http://example.com:9090/plugins/restapi/userservice?type=disable&amp;secret=bigsecret&amp;username=kafka">http://example.com:9090/plugins/restapi/userservice?type=disable&amp;secret=bigsecret&amp;username=kafka</a></p>
<p>The following example enables a user (removes lockout)</p>
<p><a href="http://example.com:9090/plugins/restapi/userservice?type=enable&amp;secret=bigsecret&amp;username=kafka">http://example.com:9090/plugins/restapi/userservice?type=enable&amp;secret=bigsecret&amp;username=kafka</a></p>
<p>The following example updates a user</p>
<p><a href="http://example.com:9090/plugins/restapi/userservice?type=update&amp;secret=bigsecret&amp;username=kafka&amp;password=drowssap&amp;name=franz&amp;email=beetle@kafka.com">http://example.com:9090/plugins/restapi/userservice?type=update&amp;secret=bigsecret&amp;username=kafka&amp;password=drowssap&amp;name=franz&amp;email=beetle@kafka.com</a></p>
<p>The following example adds new roster item with subscription ‘both’ for user ‘kafka’</p>
<p><a href="http://example.com:9090/plugins/restapi/userservice?type=add_roster&amp;secret=bigsecret&amp;username=kafka&amp;item_jid=franz@example.com&amp;name=franz&amp;subscription=3">http://example.com:9090/plugins/restapi/userservice?type=add_roster&amp;secret=bigsecret&amp;username=kafka&amp;item_jid=franz@example.com&amp;name=franz&amp;subscription=3</a></p>
<p>The following example adds new roster item with subscription ‘both’ for user ‘kafka’ and adds kafka to roster groups ‘family’ and ‘friends’</p>
<p><a href="http://example.com:9090/plugins/restapi/userservice?type=add_roster&amp;secret=bigsecret&amp;username=kafka&amp;item_jid=franz@example.com&amp;name=franz&amp;subscription=3&amp;groups=family,friends">http://example.com:9090/plugins/restapi/userservice?type=add_roster&amp;secret=bigsecret&amp;username=kafka&amp;item_jid=franz@example.com&amp;name=franz&amp;subscription=3&amp;groups=family,friends</a></p>
<p>The following example updates existing roster item to subscription ‘none’ for user ‘kafka’</p>
<p><a href="http://example.com:9090/plugins/restapi/userservice?type=update_roster&amp;secret=bigsecret&amp;username=kafka&amp;item_jid=franz@example.com&amp;name=franz&amp;subscription=0">http://example.com:9090/plugins/restapi/userservice?type=update_roster&amp;secret=bigsecret&amp;username=kafka&amp;item_jid=franz@example.com&amp;name=franz&amp;subscription=0</a></p>
<p>The following example deletes a specific roster item ‘franz@kafka.com’ for user ‘kafka’</p>
<p><a href="http://example.com:9090/plugins/restapi/userservice?type=delete_roster&amp;secret=bigsecret&amp;username=kafka&amp;item_jid=franz@example.com">http://example.com:9090/plugins/restapi/userservice?type=delete_roster&amp;secret=bigsecret&amp;username=kafka&amp;item_jid=franz@example.com</a></p>
<p>The following example gets all groups</p>
<p><a href="http://example.com:9090/plugins/restapi/userservice?type=grouplist&amp;secret=bigsecret">http://example.com:9090/plugins/restapi/userservice?type=grouplist&amp;secret=bigsecret</a> <br>
Which replies an XML group list formatted like this:</p>
<pre class="prettyprint prettyprinted"><code><span class="tag">&lt;result&gt;</span><span class="pln">
</span><span class="tag">&lt;groupname&gt;</span><span class="pln">group1</span><span class="tag">&lt;/groupname&gt;</span><span class="pln">
</span><span class="tag">&lt;groupname&gt;</span><span class="pln">group2</span><span class="tag">&lt;/groupname&gt;</span><span class="pln">
</span><span class="tag">&lt;/result&gt;</span></code></pre>
<p>The following example gets all groups for a specific user</p>
<p><a href="http://example.com:9090/plugins/restapi/userservice?type=usergrouplist&amp;secret=bigsecret&amp;username=kafka">http://example.com:9090/plugins/restapi/userservice?type=usergrouplist&amp;secret=bigsecret&amp;username=kafka</a> <br>
Which replies an XML group list formatted like this:</p>
<pre class="prettyprint prettyprinted"><code><span class="tag">&lt;result&gt;</span><span class="pln">
</span><span class="tag">&lt;groupname&gt;</span><span class="pln">usergroup1</span><span class="tag">&lt;/groupname&gt;</span><span class="pln">
</span><span class="tag">&lt;groupname&gt;</span><span class="pln">usergroup2</span><span class="tag">&lt;/groupname&gt;</span><span class="pln">
</span><span class="tag">&lt;/result&gt;</span></code></pre>
<p>* When sending double characters (Chinese/Japanese/Korean etc) you should URLEncode the string as utf8. <br>
In Java this is done like this <br>
URLEncoder.encode(username, “UTF-8”)); <br>
If the strings are encoded incorrectly, double byte characters will look garbeled in the Admin Console.</p>
<h2 id="server-reply">Server Reply</h2>
<p>The server will reply to all User Service requests with an XML result page. If the request was processed successfully the return will be a “result” element with a text body of “OK”, or an XML grouplist formatted like in the example for “grouplist” and “usergrouplist” above. If the request was unsuccessful, the return will be an “error” element with a text body of one of the following error strings.</p>
<table>
<thead>
<tr>
<th>Error String</th>
<th>Description</th>
</tr>
</thead>
<tbody><tr>
<td>IllegalArgumentException</td>
<td>One of the parameters passed in to the User Service was bad.</td>
</tr>
<tr>
<td>UserNotFoundException</td>
<td>No user of the name specified, for a delete or update operation, exists on this server. For ‘update_roster’ operation, roster item to be updated was not found.</td>
</tr>
<tr>
<td>UserAlreadyExistsException</td>
<td>A user with the same name as the user about to be added, already exists. For ‘add_roster’ operation, roster item with the same JID already exists.</td>
</tr>
<tr>
<td>RequestNotAuthorised</td>
<td>The supplied secret does not match the secret specified in the Admin Console or the requester is not a valid IP address.</td>
</tr>
<tr>
<td>UserServiceDisabled</td>
<td>The User Service is currently set to disabled in the Admin Console.</td>
</tr>
<tr>
<td>SharedGroupException</td>
<td>Roster item can not be added/deleted to/from a shared group for operations with roster.</td>
</tr>
</tbody></table>
<p><strong>Payload:</strong></p>
<pre class="prettyprint prettyprinted"><code><span class="pln">&lt;</span><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"UTF-8"</span><span class="pln"> standalone</span><span class="pun">=</span><span class="str">"yes"</span><span class="pun">?&gt;</span><span class="pln">
</span><span class="tag">&lt;property</span><span class="pln"> </span><span class="atn">key</span><span class="pun">=</span><span class="atv">"propertyName"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"anotherValue"</span><span class="tag">/&gt;</span></code></pre>
......
...@@ -46,6 +46,11 @@ public class AuthFilter implements ContainerRequestFilter { ...@@ -46,6 +46,11 @@ public class AuthFilter implements ContainerRequestFilter {
throw new WebApplicationException(Status.FORBIDDEN); throw new WebApplicationException(Status.FORBIDDEN);
} }
// To be backwards compatible to userservice 1.*
if ("restapi/v1/userservice".equals(containerRequest.getPath())) {
return containerRequest;
}
if (!plugin.getAllowedIPs().isEmpty()) { if (!plugin.getAllowedIPs().isEmpty()) {
// Get client's IP address // Get client's IP address
String ipAddress = httpRequest.getHeader("x-forwarded-for"); String ipAddress = httpRequest.getHeader("x-forwarded-for");
......
package org.jivesoftware.openfire.plugin.rest.controller;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.ws.rs.core.Response;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.plugin.rest.entity.MUCChannelType;
import org.jivesoftware.openfire.plugin.rest.entity.MUCRoomEntities;
import org.jivesoftware.openfire.plugin.rest.entity.MUCRoomEntity;
import org.jivesoftware.openfire.plugin.rest.entity.ParticipantEntities;
import org.jivesoftware.openfire.plugin.rest.entity.ParticipantEntity;
import org.jivesoftware.openfire.plugin.rest.exceptions.ExceptionType;
import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException;
import org.jivesoftware.openfire.muc.ConflictException;
import org.jivesoftware.openfire.muc.ForbiddenException;
import org.jivesoftware.openfire.muc.MUCRole;
import org.jivesoftware.openfire.muc.MUCRoom;
import org.jivesoftware.openfire.muc.NotAllowedException;
import org.jivesoftware.openfire.plugin.rest.utils.MUCRoomUtils;
import org.jivesoftware.openfire.plugin.rest.utils.UserUtils;
import org.xmpp.packet.JID;
/**
* The Class MUCRoomController.
*/
public class MUCRoomController {
/** The Constant INSTANCE. */
public static final MUCRoomController INSTANCE = new MUCRoomController();
/**
* Gets the single instance of MUCRoomController.
*
* @return single instance of MUCRoomController
*/
public static MUCRoomController getInstance() {
return INSTANCE;
}
/**
* Gets the chat rooms.
*
* @param serviceName
* the service name
* @param channelType
* the channel type
* @param roomSearch
* the room search
* @return the chat rooms
*/
public MUCRoomEntities getChatRooms(String serviceName, String channelType, String roomSearch) {
List<MUCRoom> rooms = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(serviceName)
.getChatRooms();
List<MUCRoomEntity> mucRoomEntities = new ArrayList<MUCRoomEntity>();
for (MUCRoom chatRoom : rooms) {
if (roomSearch != null) {
if (!chatRoom.getName().contains(roomSearch)) {
continue;
}
}
if (channelType.equals(MUCChannelType.ALL)) {
mucRoomEntities.add(convertToMUCRoomEntity(chatRoom));
} else if (channelType.equals(MUCChannelType.PUBLIC) && chatRoom.isPublicRoom()) {
mucRoomEntities.add(convertToMUCRoomEntity(chatRoom));
}
}
return new MUCRoomEntities(mucRoomEntities);
}
/**
* Gets the chat room.
*
* @param roomName
* the room name
* @param serviceName
* the service name
* @return the chat room
* @throws ServiceException
* the service exception
*/
public MUCRoomEntity getChatRoom(String roomName, String serviceName) throws ServiceException {
MUCRoom chatRoom = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(serviceName)
.getChatRoom(roomName);
if (chatRoom == null) {
throw new ServiceException("Could not find the chat room", roomName, ExceptionType.ROOM_NOT_FOUND, Response.Status.NOT_FOUND);
}
MUCRoomEntity mucRoomEntity = convertToMUCRoomEntity(chatRoom);
return mucRoomEntity;
}
/**
* Delete chat room.
*
* @param roomName
* the room name
* @param serviceName
* the service name
* @throws ServiceException
* the service exception
*/
public void deleteChatRoom(String roomName, String serviceName) throws ServiceException {
MUCRoom chatRoom = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(serviceName)
.getChatRoom(roomName.toLowerCase());
if (chatRoom != null) {
chatRoom.destroyRoom(null, null);
} else {
throw new ServiceException("Could not remove the channel", roomName, ExceptionType.ROOM_NOT_FOUND, Response.Status.NOT_FOUND);
}
}
/**
* Creates the chat room.
*
* @param serviceName
* the service name
* @param mucRoomEntity
* the MUC room entity
* @throws ServiceException
* the service exception
*/
public void createChatRoom(String serviceName, MUCRoomEntity mucRoomEntity) throws ServiceException {
try {
createRoom(mucRoomEntity, serviceName);
} catch (NotAllowedException e) {
throw new ServiceException("Could not create the channel", mucRoomEntity.getRoomName(),
ExceptionType.NOT_ALLOWED, Response.Status.FORBIDDEN, e);
} catch (ForbiddenException e) {
throw new ServiceException("Could not create the channel", mucRoomEntity.getRoomName(),
ExceptionType.NOT_ALLOWED, Response.Status.FORBIDDEN, e);
} catch (ConflictException e) {
throw new ServiceException("Could not create the channel", mucRoomEntity.getRoomName(),
ExceptionType.NOT_ALLOWED, Response.Status.FORBIDDEN, e);
}
}
/**
* Update chat room.
*
* @param roomName
* the room name
* @param serviceName
* the service name
* @param mucRoomEntity
* the MUC room entity
* @throws ServiceException
* the service exception
*/
public void updateChatRoom(String roomName, String serviceName, MUCRoomEntity mucRoomEntity)
throws ServiceException {
try {
// If the room name is different throw exception
if (!roomName.equals(mucRoomEntity.getRoomName())) {
throw new ServiceException(
"Could not update the channel. The room name is different to the entity room name.", roomName,
ExceptionType.ILLEGAL_ARGUMENT_EXCEPTION, Response.Status.BAD_REQUEST);
}
createRoom(mucRoomEntity, serviceName);
} catch (NotAllowedException e) {
throw new ServiceException("Could not update the channel", roomName, ExceptionType.NOT_ALLOWED, Response.Status.FORBIDDEN, e);
} catch (ForbiddenException e) {
throw new ServiceException("Could not update the channel", roomName, ExceptionType.NOT_ALLOWED, Response.Status.FORBIDDEN, e);
} catch (ConflictException e) {
throw new ServiceException("Could not update the channel", roomName, ExceptionType.NOT_ALLOWED, Response.Status.FORBIDDEN, e);
}
}
/**
* Creates the room.
*
* @param mucRoomEntity
* the MUC room entity
* @param serviceName
* the service name
* @throws NotAllowedException
* the not allowed exception
* @throws ForbiddenException
* the forbidden exception
* @throws ConflictException
* the conflict exception
*/
private void createRoom(MUCRoomEntity mucRoomEntity, String serviceName) throws NotAllowedException,
ForbiddenException, ConflictException {
// Set owner
JID owner = XMPPServer.getInstance().createJID("admin", null);
if (mucRoomEntity.getOwners() != null && mucRoomEntity.getOwners().size() > 0) {
owner = new JID(mucRoomEntity.getOwners().get(0));
} else {
List<String> owners = new ArrayList<String>();
owners.add(owner.toBareJID());
mucRoomEntity.setOwners(owners);
}
MUCRoom room = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(serviceName)
.getChatRoom(mucRoomEntity.getRoomName().toLowerCase(), owner);
// Set values
room.setNaturalLanguageName(mucRoomEntity.getNaturalName());
room.setSubject(mucRoomEntity.getSubject());
room.setDescription(mucRoomEntity.getDescription());
room.setPassword(mucRoomEntity.getPassword());
room.setPersistent(mucRoomEntity.isPersistent());
room.setPublicRoom(mucRoomEntity.isPublicRoom());
room.setRegistrationEnabled(mucRoomEntity.isRegistrationEnabled());
room.setCanAnyoneDiscoverJID(mucRoomEntity.isCanAnyoneDiscoverJID());
room.setCanOccupantsChangeSubject(mucRoomEntity.isCanOccupantsChangeSubject());
room.setCanOccupantsInvite(mucRoomEntity.isCanOccupantsInvite());
room.setChangeNickname(mucRoomEntity.isCanChangeNickname());
room.setModificationDate(mucRoomEntity.getModificationDate());
room.setLogEnabled(mucRoomEntity.isLogEnabled());
room.setLoginRestrictedToNickname(mucRoomEntity.isLoginRestrictedToNickname());
room.setMaxUsers(mucRoomEntity.getMaxUsers());
room.setMembersOnly(mucRoomEntity.isMembersOnly());
room.setModerated(mucRoomEntity.isModerated());
// Set broadcast presence roles
if (mucRoomEntity.getBroadcastPresenceRoles() != null) {
room.setRolesToBroadcastPresence(mucRoomEntity.getBroadcastPresenceRoles());
} else {
room.setRolesToBroadcastPresence(new ArrayList<String>());
}
// Set all roles
setRoles(room, mucRoomEntity);
// Set creation date
if (mucRoomEntity.getCreationDate() != null) {
room.setCreationDate(mucRoomEntity.getCreationDate());
} else {
room.setCreationDate(new Date());
}
// Set modification date
if (mucRoomEntity.getModificationDate() != null) {
room.setModificationDate(mucRoomEntity.getModificationDate());
} else {
room.setModificationDate(new Date());
}
// Unlock the room, because the default configuration lock the room.
room.unlock(room.getRole());
// Save the room to the DB if the room should be persistant
if (room.isPersistent()) {
room.saveToDB();
}
}
/**
* Gets the room participants.
*
* @param roomName
* the room name
* @param serviceName
* the service name
* @return the room participants
*/
public ParticipantEntities getRoomParticipants(String roomName, String serviceName) {
ParticipantEntities participantEntities = new ParticipantEntities();
List<ParticipantEntity> participants = new ArrayList<ParticipantEntity>();
Collection<MUCRole> serverParticipants = XMPPServer.getInstance().getMultiUserChatManager()
.getMultiUserChatService(serviceName).getChatRoom(roomName).getParticipants();
for (MUCRole role : serverParticipants) {
ParticipantEntity participantEntity = new ParticipantEntity();
participantEntity.setJid(role.getRoleAddress().toFullJID());
participantEntity.setRole(role.getRole().name());
participantEntity.setAffiliation(role.getAffiliation().name());
participants.add(participantEntity);
}
participantEntities.setParticipants(participants);
return participantEntities;
}
/**
* Convert to MUC room entity.
*
* @param room
* the room
* @return the MUC room entity
*/
public MUCRoomEntity convertToMUCRoomEntity(MUCRoom room) {
MUCRoomEntity mucRoomEntity = new MUCRoomEntity(room.getNaturalLanguageName(), room.getName(),
room.getDescription());
mucRoomEntity.setCanAnyoneDiscoverJID(room.canAnyoneDiscoverJID());
mucRoomEntity.setCanChangeNickname(room.canChangeNickname());
mucRoomEntity.setCanOccupantsChangeSubject(room.canOccupantsChangeSubject());
mucRoomEntity.setCanOccupantsInvite(room.canOccupantsInvite());
mucRoomEntity.setPublicRoom(room.isPublicRoom());
mucRoomEntity.setPassword(room.getPassword());
mucRoomEntity.setPersistent(room.isPersistent());
mucRoomEntity.setRegistrationEnabled(room.isRegistrationEnabled());
mucRoomEntity.setLogEnabled(room.isLogEnabled());
mucRoomEntity.setLoginRestrictedToNickname(room.isLoginRestrictedToNickname());
mucRoomEntity.setMaxUsers(room.getMaxUsers());
mucRoomEntity.setMembersOnly(room.isMembersOnly());
mucRoomEntity.setModerated(room.isModerated());
mucRoomEntity.setOwners(MUCRoomUtils.convertJIDsToStringList(room.getOwners()));
mucRoomEntity.setAdmins(MUCRoomUtils.convertJIDsToStringList(room.getAdmins()));
mucRoomEntity.setMembers(MUCRoomUtils.convertJIDsToStringList(room.getMembers()));
mucRoomEntity.setOutcasts(MUCRoomUtils.convertJIDsToStringList(room.getOutcasts()));
mucRoomEntity.setBroadcastPresenceRoles(room.getRolesToBroadcastPresence());
mucRoomEntity.setCreationDate(room.getCreationDate());
mucRoomEntity.setModificationDate(room.getModificationDate());
return mucRoomEntity;
}
/**
* Reset roles.
*
* @param room
* the room
* @param mucRoomEntity
* the muc room entity
* @throws ForbiddenException
* the forbidden exception
* @throws NotAllowedException
* the not allowed exception
* @throws ConflictException
* the conflict exception
*/
private void setRoles(MUCRoom room, MUCRoomEntity mucRoomEntity) throws ForbiddenException, NotAllowedException,
ConflictException {
List<JID> roles = new ArrayList<JID>();
Collection<JID> owners = new ArrayList<JID>();
Collection<JID> existingOwners = new ArrayList<JID>();
List<JID> mucRoomEntityOwners = MUCRoomUtils.convertStringsToJIDs(mucRoomEntity.getOwners());
owners.addAll(room.getOwners());
// Find same owners
for (JID jid : owners) {
if (mucRoomEntityOwners.contains(jid)) {
existingOwners.add(jid);
}
}
// Don't delete the same owners
owners.removeAll(existingOwners);
room.addOwners(MUCRoomUtils.convertStringsToJIDs(mucRoomEntity.getOwners()), room.getRole());
// Collect all roles to reset
roles.addAll(owners);
roles.addAll(room.getAdmins());
roles.addAll(room.getMembers());
roles.addAll(room.getOutcasts());
for (JID jid : roles) {
room.addNone(jid, room.getRole());
}
room.addOwners(MUCRoomUtils.convertStringsToJIDs(mucRoomEntity.getOwners()), room.getRole());
if (mucRoomEntity.getAdmins() != null) {
room.addAdmins(MUCRoomUtils.convertStringsToJIDs(mucRoomEntity.getAdmins()), room.getRole());
}
if (mucRoomEntity.getMembers() != null) {
for (String memberJid : mucRoomEntity.getMembers()) {
room.addMember(new JID(memberJid), null, room.getRole());
}
}
if (mucRoomEntity.getOutcasts() != null) {
for (String outcastJid : mucRoomEntity.getOutcasts()) {
room.addOutcast(new JID(outcastJid), null, room.getRole());
}
}
}
/**
* Adds the admin.
*
* @param serviceName
* the service name
* @param roomName
* the room name
* @param jid
* the jid
* @throws ServiceException
* the service exception
*/
public void addAdmin(String serviceName, String roomName, String jid) throws ServiceException {
MUCRoom room = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(serviceName)
.getChatRoom(roomName.toLowerCase());
try {
room.addAdmin(UserUtils.checkAndGetJID(jid), room.getRole());
} catch (ForbiddenException e) {
throw new ServiceException("Could not add admin", jid, ExceptionType.NOT_ALLOWED, Response.Status.FORBIDDEN, e);
} catch (ConflictException e) {
throw new ServiceException("Could not add admin", jid, ExceptionType.NOT_ALLOWED, Response.Status.FORBIDDEN, e);
}
}
/**
* Adds the owner.
*
* @param serviceName
* the service name
* @param roomName
* the room name
* @param jid
* the jid
* @throws ServiceException
* the service exception
*/
public void addOwner(String serviceName, String roomName, String jid) throws ServiceException {
MUCRoom room = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(serviceName)
.getChatRoom(roomName.toLowerCase());
try {
room.addOwner(UserUtils.checkAndGetJID(jid), room.getRole());
} catch (ForbiddenException e) {
throw new ServiceException("Could not add owner", jid, ExceptionType.NOT_ALLOWED, Response.Status.FORBIDDEN, e);
}
}
/**
* Adds the member.
*
* @param serviceName
* the service name
* @param roomName
* the room name
* @param jid
* the jid
* @throws ServiceException
* the service exception
*/
public void addMember(String serviceName, String roomName, String jid) throws ServiceException {
MUCRoom room = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(serviceName)
.getChatRoom(roomName.toLowerCase());
try {
room.addMember(UserUtils.checkAndGetJID(jid), null, room.getRole());
} catch (ForbiddenException e) {
throw new ServiceException("Could not add member", jid, ExceptionType.NOT_ALLOWED, Response.Status.FORBIDDEN, e);
} catch (ConflictException e) {
throw new ServiceException("Could not add member", jid, ExceptionType.NOT_ALLOWED, Response.Status.FORBIDDEN, e);
}
}
/**
* Adds the outcast.
*
* @param serviceName
* the service name
* @param roomName
* the room name
* @param jid
* the jid
* @throws ServiceException
* the service exception
*/
public void addOutcast(String serviceName, String roomName, String jid) throws ServiceException {
MUCRoom room = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(serviceName)
.getChatRoom(roomName.toLowerCase());
try {
room.addOutcast(UserUtils.checkAndGetJID(jid), null, room.getRole());
} catch (NotAllowedException e) {
throw new ServiceException("Could not add outcast", jid, ExceptionType.NOT_ALLOWED, Response.Status.FORBIDDEN, e);
} catch (ForbiddenException e) {
throw new ServiceException("Could not add outcast", jid, ExceptionType.NOT_ALLOWED, Response.Status.FORBIDDEN, e);
} catch (ConflictException e) {
throw new ServiceException("Could not add outcast", jid, ExceptionType.NOT_ALLOWED, Response.Status.FORBIDDEN, e);
}
}
/**
* Delete affiliation.
*
* @param serviceName
* the service name
* @param roomName
* the room name
* @param jid
* the jid
* @throws ServiceException
* the service exception
*/
public void deleteAffiliation(String serviceName, String roomName, String jid) throws ServiceException {
MUCRoom room = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(serviceName)
.getChatRoom(roomName.toLowerCase());
try {
room.addNone(UserUtils.checkAndGetJID(jid), room.getRole());
} catch (ForbiddenException e) {
throw new ServiceException("Could not delete affiliation", jid, ExceptionType.NOT_ALLOWED, Response.Status.FORBIDDEN, e);
} catch (ConflictException e) {
throw new ServiceException("Could not delete affiliation", jid, ExceptionType.NOT_ALLOWED, Response.Status.FORBIDDEN, e);
}
}
}
\ No newline at end of file
package org.jivesoftware.openfire.plugin.rest.controller;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.ws.rs.core.Response;
import org.jivesoftware.openfire.SharedGroupException;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.plugin.rest.entity.RosterEntities;
import org.jivesoftware.openfire.plugin.rest.entity.RosterItemEntity;
import org.jivesoftware.openfire.plugin.rest.entity.UserEntities;
import org.jivesoftware.openfire.plugin.rest.entity.UserEntity;
import org.jivesoftware.openfire.plugin.rest.entity.UserGroupsEntity;
import org.jivesoftware.openfire.plugin.rest.entity.UserProperty;
import org.jivesoftware.openfire.plugin.rest.exceptions.ExceptionType;
import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException;
import org.jivesoftware.openfire.group.Group;
import org.jivesoftware.openfire.group.GroupAlreadyExistsException;
import org.jivesoftware.openfire.group.GroupManager;
import org.jivesoftware.openfire.group.GroupNotFoundException;
import org.jivesoftware.openfire.lockout.LockOutManager;
import org.jivesoftware.openfire.plugin.rest.dao.PropertyDAO;
import org.jivesoftware.openfire.roster.Roster;
import org.jivesoftware.openfire.roster.RosterItem;
import org.jivesoftware.openfire.roster.RosterManager;
import org.jivesoftware.openfire.user.User;
import org.jivesoftware.openfire.user.UserAlreadyExistsException;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.openfire.plugin.rest.utils.UserUtils;
import org.xmpp.packet.JID;
/**
* The Class UserServiceController.
*/
public class UserServiceController {
/** The Constant INSTANCE. */
public static final UserServiceController INSTANCE = new UserServiceController();
/** The user manager. */
private UserManager userManager;
/** The roster manager. */
private RosterManager rosterManager;
/** The server. */
private XMPPServer server;
/**
* Gets the single instance of UserServiceController.
*
* @return single instance of UserServiceController
*/
public static UserServiceController getInstance() {
return INSTANCE;
}
/**
* Instantiates a new user service controller.
*/
private UserServiceController() {
server = XMPPServer.getInstance();
userManager = server.getUserManager();
rosterManager = server.getRosterManager();
}
/**
* Creates the user.
*
* @param userEntity
* the user entity
* @throws ServiceException
* the service exception
*/
public void createUser(UserEntity userEntity) throws ServiceException {
if (userEntity != null && !userEntity.getUsername().isEmpty()) {
if (userEntity.getPassword() == null) {
throw new ServiceException("Could not create new user, because password is null",
userEntity.getUsername(), "PasswordIsNull", Response.Status.BAD_REQUEST);
}
try {
userManager.createUser(userEntity.getUsername(), userEntity.getPassword(), userEntity.getName(),
userEntity.getEmail());
} catch (UserAlreadyExistsException e) {
throw new ServiceException("Could not create new user", userEntity.getUsername(),
ExceptionType.USER_ALREADY_EXISTS_EXCEPTION, Response.Status.BAD_REQUEST);
}
addProperties(userEntity);
}
}
/**
* Update user.
*
* @param username
* the username
* @param userEntity
* the user entity
* @throws ServiceException
* the service exception
*/
public void updateUser(String username, UserEntity userEntity) throws ServiceException {
if (userEntity != null && !username.isEmpty()) {
User user = getAndCheckUser(username);
if (userEntity.getPassword() != null) {
user.setPassword(userEntity.getPassword());
}
if (userEntity.getName() != null) {
user.setName(userEntity.getName());
}
if (userEntity.getEmail() != null) {
user.setEmail(userEntity.getEmail());
}
addProperties(userEntity);
}
}
/**
* Delete user.
*
* @param username
* the username
* @throws ServiceException
* the service exception
*/
public void deleteUser(String username) throws ServiceException {
User user = getAndCheckUser(username);
userManager.deleteUser(user);
rosterManager.deleteRoster(server.createJID(username, null));
}
/**
* Gets the user entities.
*
* @param userSearch
* the user search
* @param propertyValue
* @param propertyKey
* @return the user entities
* @throws ServiceException
*/
public UserEntities getUserEntities(String userSearch, String propertyKey, String propertyValue) throws ServiceException {
if(propertyKey != null) {
return getUserEntitiesByProperty(propertyKey, propertyValue);
}
UserEntities userEntities = new UserEntities();
userEntities.setUsers(UserUtils.convertUsersToUserEntities(userManager.getUsers(), userSearch));
return userEntities;
}
/**
* Gets the user entity.
*
* @param username
* the username
* @return the user entity
* @throws ServiceException
* the service exception
*/
public UserEntity getUserEntity(String username) throws ServiceException {
return UserUtils.convertUserToUserEntity(getAndCheckUser(username));
}
/**
* Enable user.
*
* @param username
* the username
* @throws ServiceException
* the service exception
*/
public void enableUser(String username) throws ServiceException {
getAndCheckUser(username);
LockOutManager.getInstance().enableAccount(username);
}
/**
* Disable user.
*
* @param username
* the username
* @throws ServiceException
* the service exception
*/
public void disableUser(String username) throws ServiceException {
getAndCheckUser(username);
LockOutManager.getInstance().disableAccount(username, null, null);
}
/**
* Gets the roster entities.
*
* @param username
* the username
* @return the roster entities
* @throws ServiceException
* the service exception
*/
public RosterEntities getRosterEntities(String username) throws ServiceException {
Roster roster = getUserRoster(username);
List<RosterItemEntity> rosterEntities = new ArrayList<RosterItemEntity>();
for (RosterItem rosterItem : roster.getRosterItems()) {
RosterItemEntity rosterItemEntity = new RosterItemEntity(rosterItem.getJid().toBareJID(),
rosterItem.getNickname(), rosterItem.getSubStatus().getValue());
rosterItemEntity.setGroups(rosterItem.getGroups());
rosterEntities.add(rosterItemEntity);
}
return new RosterEntities(rosterEntities);
}
/**
* Adds the roster item.
*
* @param username
* the username
* @param rosterItemEntity
* the roster item entity
* @throws ServiceException
* the service exception
* @throws UserAlreadyExistsException
* the user already exists exception
* @throws SharedGroupException
* the shared group exception
* @throws UserNotFoundException
* the user not found exception
*/
public void addRosterItem(String username, RosterItemEntity rosterItemEntity) throws ServiceException,
UserAlreadyExistsException, SharedGroupException, UserNotFoundException {
Roster roster = getUserRoster(username);
if (rosterItemEntity.getJid() == null) {
throw new ServiceException("JID is null", "JID", "IllegalArgumentException", Response.Status.BAD_REQUEST);
}
JID jid = new JID(rosterItemEntity.getJid());
try {
roster.getRosterItem(jid);
throw new UserAlreadyExistsException(jid.toBareJID());
} catch (UserNotFoundException e) {
// Roster item does not exist. Try to add it.
}
if (roster != null) {
RosterItem rosterItem = roster.createRosterItem(jid, rosterItemEntity.getNickname(),
rosterItemEntity.getGroups(), false, true);
UserUtils.checkSubType(rosterItemEntity.getSubscriptionType());
rosterItem.setSubStatus(RosterItem.SubType.getTypeFromInt(rosterItemEntity.getSubscriptionType()));
roster.updateRosterItem(rosterItem);
}
}
/**
* Update roster item.
*
* @param username
* the username
* @param rosterJid
* the roster jid
* @param rosterItemEntity
* the roster item entity
* @throws ServiceException
* the service exception
* @throws UserNotFoundException
* the user not found exception
* @throws UserAlreadyExistsException
* the user already exists exception
* @throws SharedGroupException
* the shared group exception
*/
public void updateRosterItem(String username, String rosterJid, RosterItemEntity rosterItemEntity)
throws ServiceException, UserNotFoundException, UserAlreadyExistsException, SharedGroupException {
getAndCheckUser(username);
Roster roster = getUserRoster(username);
JID jid = new JID(rosterJid);
RosterItem rosterItem = roster.getRosterItem(jid);
if (rosterItemEntity.getNickname() != null) {
rosterItem.setNickname(rosterItemEntity.getNickname());
}
if (rosterItemEntity.getGroups() != null) {
rosterItem.setGroups(rosterItemEntity.getGroups());
}
UserUtils.checkSubType(rosterItemEntity.getSubscriptionType());
rosterItem.setSubStatus(RosterItem.SubType.getTypeFromInt(rosterItemEntity.getSubscriptionType()));
roster.updateRosterItem(rosterItem);
}
/**
* Delete roster item.
*
* @param username
* the username
* @param rosterJid
* the roster jid
* @throws SharedGroupException
* the shared group exception
* @throws ServiceException
* the service exception
*/
public void deleteRosterItem(String username, String rosterJid) throws SharedGroupException, ServiceException {
getAndCheckUser(username);
Roster roster = getUserRoster(username);
JID jid = new JID(rosterJid);
if (roster.deleteRosterItem(jid, true) == null) {
throw new ServiceException("Roster Item could not deleted", jid.toBareJID(), "RosterItemNotFound",
Response.Status.NOT_FOUND);
}
}
/**
* Gets the user groups.
*
* @param username
* the username
* @return the user groups
* @throws ServiceException
* the service exception
*/
public List<String> getUserGroups(String username) throws ServiceException {
User user = getAndCheckUser(username);
Collection<Group> groups = GroupManager.getInstance().getGroups(user);
List<String> groupNames = new ArrayList<String>();
for (Group group : groups) {
groupNames.add(group.getName());
}
return groupNames;
}
/**
* Adds the user to group.
*
* @param username the username
* @param userGroupsEntity the user groups entity
* @throws ServiceException the service exception
*/
public void addUserToGroups(String username, UserGroupsEntity userGroupsEntity) throws ServiceException {
if (userGroupsEntity != null) {
Collection<Group> groups = new ArrayList<Group>();
for (String groupName : userGroupsEntity.getGroupNames()) {
Group group = null;
try {
group = GroupManager.getInstance().getGroup(groupName);
} catch (GroupNotFoundException e) {
// Create this group
group = createGroup(groupName);
}
groups.add(group);
}
for (Group group : groups) {
group.getMembers().add(server.createJID(username, null));
}
}
}
/**
* Delete user from groups.
*
* @param username
* the username
* @param userGroupsEntity
* the user groups entity
* @throws ServiceException
* the service exception
*/
public void deleteUserFromGroups(String username, UserGroupsEntity userGroupsEntity) throws ServiceException {
if (userGroupsEntity != null) {
for (String groupName : userGroupsEntity.getGroupNames()) {
Group group = null;
try {
group = GroupManager.getInstance().getGroup(groupName);
} catch (GroupNotFoundException e) {
throw new ServiceException("Could not find group", groupName, ExceptionType.GROUP_NOT_FOUND,
Response.Status.NOT_FOUND, e);
}
group.getMembers().remove(server.createJID(username, null));
}
}
}
/**
* Gets the user entities by property key and or value.
*
* @param propertyKey
* the property key
* @param propertyValue
* the property value (can be null)
* @return the user entities by property
* @throws ServiceException
* the service exception
*/
public UserEntities getUserEntitiesByProperty(String propertyKey, String propertyValue) throws ServiceException {
List<String> usernames = PropertyDAO.getUsernameByProperty(propertyKey, propertyValue);
List<UserEntity> users = new ArrayList<UserEntity>();
UserEntities userEntities = new UserEntities();
for (String username : usernames) {
users.add(getUserEntity(username));
}
userEntities.setUsers(users);
return userEntities;
}
/**
* Adds the properties.
*
* @param userEntity
* the user entity
* @throws ServiceException
* the service exception
*/
private void addProperties(UserEntity userEntity) throws ServiceException {
User user = getAndCheckUser(userEntity.getUsername());
user.getProperties().clear();
if (userEntity.getProperties() != null) {
for (UserProperty property : userEntity.getProperties()) {
user.getProperties().put(property.getKey(), property.getValue());
}
}
}
/**
* Creates the group.
*
* @param groupName the group name
* @return the group
* @throws ServiceException the service exception
*/
private Group createGroup(String groupName) throws ServiceException {
Group group = null;
try {
group = GroupManager.getInstance().createGroup(groupName);
group.getProperties().put("sharedRoster.showInRoster", "onlyGroup");
group.getProperties().put("sharedRoster.displayName", groupName);
group.getProperties().put("sharedRoster.groupList", "");
} catch (GroupAlreadyExistsException e) {
throw new ServiceException("Could not create group", groupName, ExceptionType.GROUP_ALREADY_EXISTS,
Response.Status.BAD_REQUEST, e);
}
return group;
}
/**
* Gets the and check user.
*
* @param username
* the username
* @return the and check user
* @throws ServiceException
* the service exception
*/
private User getAndCheckUser(String username) throws ServiceException {
JID targetJID = server.createJID(username, null);
if (targetJID.getNode() == null) {
throw new ServiceException("Could not get user", username, ExceptionType.USER_NOT_FOUND_EXCEPTION,
Response.Status.NOT_FOUND);
}
try {
return userManager.getUser(targetJID.getNode());
} catch (UserNotFoundException e) {
throw new ServiceException("Could not get user", username, ExceptionType.USER_NOT_FOUND_EXCEPTION,
Response.Status.NOT_FOUND, e);
}
}
/**
* Gets the user roster.
*
* @param username
* the username
* @return the user roster
* @throws ServiceException
* the service exception
*/
private Roster getUserRoster(String username) throws ServiceException {
try {
return rosterManager.getRoster(username);
} catch (UserNotFoundException e) {
throw new ServiceException("Could not get user roster", username, ExceptionType.USER_NOT_FOUND_EXCEPTION,
Response.Status.NOT_FOUND, e);
}
}
}
/**
* $Revision: 1722 $
* $Date: 2005-07-28 15:19:16 -0700 (Thu, 28 Jul 2005) $
*
* Copyright (C) 2005-2008 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.openfire.plugin.rest.controller;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.StringTokenizer;
import org.jivesoftware.openfire.SharedGroupException;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.group.Group;
import org.jivesoftware.openfire.group.GroupAlreadyExistsException;
import org.jivesoftware.openfire.group.GroupManager;
import org.jivesoftware.openfire.group.GroupNotFoundException;
import org.jivesoftware.openfire.lockout.LockOutManager;
import org.jivesoftware.openfire.roster.Roster;
import org.jivesoftware.openfire.roster.RosterItem;
import org.jivesoftware.openfire.roster.RosterManager;
import org.jivesoftware.openfire.user.User;
import org.jivesoftware.openfire.user.UserAlreadyExistsException;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.xmpp.packet.JID;
/**
* Plugin that allows the administration of users via HTTP requests.
*
* @author Justin Hunt
*/
public class UserServiceLegacyController {
/** The Constant INSTANCE. */
public static final UserServiceLegacyController INSTANCE = new UserServiceLegacyController();
/** The user manager. */
private UserManager userManager;
/** The roster manager. */
private RosterManager rosterManager;
/** The server. */
private XMPPServer server;
/**
* Gets the single instance of UserServiceLegacyController.
*
* @return single instance of UserServiceLegacyController
*/
public static UserServiceLegacyController getInstance() {
return INSTANCE;
}
/**
* Instantiates a new user service legacy controller.
*/
private UserServiceLegacyController() {
server = XMPPServer.getInstance();
userManager = server.getUserManager();
rosterManager = server.getRosterManager();
}
/**
* Creates the user.
*
* @param username the username
* @param password the password
* @param name the name
* @param email the email
* @param groupNames the group names
* @throws UserAlreadyExistsException the user already exists exception
* @throws GroupAlreadyExistsException the group already exists exception
* @throws UserNotFoundException the user not found exception
* @throws GroupNotFoundException the group not found exception
*/
public void createUser(String username, String password, String name, String email, String groupNames)
throws UserAlreadyExistsException, GroupAlreadyExistsException, UserNotFoundException,
GroupNotFoundException {
userManager.createUser(username, password, name, email);
userManager.getUser(username);
if (groupNames != null) {
Collection<Group> groups = new ArrayList<Group>();
StringTokenizer tkn = new StringTokenizer(groupNames, ",");
while (tkn.hasMoreTokens()) {
String groupName = tkn.nextToken();
Group group = null;
try {
group = GroupManager.getInstance().getGroup(groupName);
} catch (GroupNotFoundException e) {
// Create this group ;
group = GroupManager.getInstance().createGroup(groupName);
group.getProperties().put("sharedRoster.showInRoster", "onlyGroup");
group.getProperties().put("sharedRoster.displayName", groupName);
group.getProperties().put("sharedRoster.groupList", "");
}
groups.add(group);
}
for (Group group : groups) {
group.getMembers().add(server.createJID(username, null));
}
}
}
/**
* Delete user.
*
* @param username the username
* @throws UserNotFoundException the user not found exception
* @throws SharedGroupException the shared group exception
*/
public void deleteUser(String username) throws UserNotFoundException, SharedGroupException {
User user = getUser(username);
userManager.deleteUser(user);
rosterManager.deleteRoster(server.createJID(username, null));
}
/**
* Lock Out on a given username.
*
* @param username the username of the local user to disable.
* @throws UserNotFoundException if the requested user does not exist in the local server.
*/
public void disableUser(String username) throws UserNotFoundException {
getUser(username);
LockOutManager.getInstance().disableAccount(username, null, null);
}
/**
* Remove the lockout on a given username.
*
* @param username the username of the local user to enable.
* @throws UserNotFoundException if the requested user does not exist in the local server.
*/
public void enableUser(String username) throws UserNotFoundException {
getUser(username);
LockOutManager.getInstance().enableAccount(username);
}
/**
* Update user.
*
* @param username the username
* @param password the password
* @param name the name
* @param email the email
* @param groupNames the group names
* @throws UserNotFoundException the user not found exception
* @throws GroupAlreadyExistsException the group already exists exception
*/
public void updateUser(String username, String password, String name, String email, String groupNames)
throws UserNotFoundException, GroupAlreadyExistsException {
User user = getUser(username);
if (password != null)
user.setPassword(password);
if (name != null)
user.setName(name);
if (email != null)
user.setEmail(email);
if (groupNames != null) {
Collection<Group> newGroups = new ArrayList<Group>();
StringTokenizer tkn = new StringTokenizer(groupNames, ",");
while (tkn.hasMoreTokens()) {
String groupName = tkn.nextToken();
Group group = null;
try {
group = GroupManager.getInstance().getGroup(groupName);
} catch (GroupNotFoundException e) {
// Create this group ;
group = GroupManager.getInstance().createGroup(groupName);
group.getProperties().put("sharedRoster.showInRoster", "onlyGroup");
group.getProperties().put("sharedRoster.displayName", groupName);
group.getProperties().put("sharedRoster.groupList", "");
}
newGroups.add(group);
}
Collection<Group> existingGroups = GroupManager.getInstance().getGroups(user);
// Get the list of groups to add to the user
Collection<Group> groupsToAdd = new ArrayList<Group>(newGroups);
groupsToAdd.removeAll(existingGroups);
// Get the list of groups to remove from the user
Collection<Group> groupsToDelete = new ArrayList<Group>(existingGroups);
groupsToDelete.removeAll(newGroups);
// Add the user to the new groups
for (Group group : groupsToAdd) {
group.getMembers().add(server.createJID(username, null));
}
// Remove the user from the old groups
for (Group group : groupsToDelete) {
group.getMembers().remove(server.createJID(username, null));
}
}
}
/**
* Add new roster item for specified user.
*
* @param username the username of the local user to add roster item to.
* @param itemJID the JID of the roster item to be added.
* @param itemName the nickname of the roster item.
* @param subscription the type of subscription of the roster item. Possible values
* are: -1(remove), 0(none), 1(to), 2(from), 3(both).
* @param groupNames the name of a group to place contact into.
* @throws UserNotFoundException if the user does not exist in the local server.
* @throws UserAlreadyExistsException if roster item with the same JID already exists.
* @throws SharedGroupException if roster item cannot be added to a shared group.
*/
public void addRosterItem(String username, String itemJID, String itemName, String subscription, String groupNames)
throws UserNotFoundException, UserAlreadyExistsException, SharedGroupException {
getUser(username);
Roster r = rosterManager.getRoster(username);
JID j = new JID(itemJID);
try {
r.getRosterItem(j);
throw new UserAlreadyExistsException(j.toBareJID());
} catch (UserNotFoundException e) {
// Roster item does not exist. Try to add it.
}
if (r != null) {
List<String> groups = new ArrayList<String>();
if (groupNames != null) {
StringTokenizer tkn = new StringTokenizer(groupNames, ",");
while (tkn.hasMoreTokens()) {
groups.add(tkn.nextToken());
}
}
RosterItem ri = r.createRosterItem(j, itemName, groups, false, true);
if (subscription == null) {
subscription = "0";
}
ri.setSubStatus(RosterItem.SubType.getTypeFromInt(Integer.parseInt(subscription)));
r.updateRosterItem(ri);
}
}
/**
* Update roster item for specified user.
*
* @param username the username of the local user to update roster item for.
* @param itemJID the JID of the roster item to be updated.
* @param itemName the nickname of the roster item.
* @param subscription the type of subscription of the roster item. Possible values
* are: -1(remove), 0(none), 1(to), 2(from), 3(both).
* @param groupNames the name of a group.
* @throws UserNotFoundException if the user does not exist in the local server or roster item
* does not exist.
* @throws SharedGroupException if roster item cannot be added to a shared group.
*/
public void updateRosterItem(String username, String itemJID, String itemName, String subscription,
String groupNames) throws UserNotFoundException, SharedGroupException {
getUser(username);
Roster r = rosterManager.getRoster(username);
JID j = new JID(itemJID);
RosterItem ri = r.getRosterItem(j);
List<String> groups = new ArrayList<String>();
if (groupNames != null) {
StringTokenizer tkn = new StringTokenizer(groupNames, ",");
while (tkn.hasMoreTokens()) {
groups.add(tkn.nextToken());
}
}
ri.setGroups(groups);
ri.setNickname(itemName);
if (subscription == null) {
subscription = "0";
}
ri.setSubStatus(RosterItem.SubType.getTypeFromInt(Integer.parseInt(subscription)));
r.updateRosterItem(ri);
}
/**
* Delete roster item for specified user. No error returns if nothing to
* delete.
*
* @param username
* the username of the local user to add roster item to.
* @param itemJID
* the JID of the roster item to be deleted.
* @throws UserNotFoundException
* if the user does not exist in the local server.
* @throws SharedGroupException
* if roster item cannot be deleted from a shared group.
*/
public void deleteRosterItem(String username, String itemJID) throws UserNotFoundException, SharedGroupException {
getUser(username);
Roster r = rosterManager.getRoster(username);
JID j = new JID(itemJID);
// No roster item is found. Uncomment the following line to throw
// UserNotFoundException.
// r.getRosterItem(j);
r.deleteRosterItem(j, true);
}
/**
* Returns the the requested user or <tt>null</tt> if there are any problems
* that don't throw an error.
*
* @param username
* the username of the local user to retrieve.
* @return the requested user.
* @throws UserNotFoundException
* if the requested user does not exist in the local server.
*/
private User getUser(String username) throws UserNotFoundException {
JID targetJID = server.createJID(username, null);
// Check that the sender is not requesting information of a remote
// server entity
if (targetJID.getNode() == null) {
// Sender is requesting presence information of an anonymous user
throw new UserNotFoundException("Username is null");
}
return userManager.getUser(targetJID.getNode());
}
/**
* Returns all group names or an empty collection.
*
* @return the all groups
*/
public Collection<String> getAllGroups() {
Collection<Group> groups = GroupManager.getInstance().getGroups();
Collection<String> groupNames = new ArrayList<String>();
for (Group group : groups) {
groupNames.add(group.getName());
}
return groupNames;
}
/**
* Returns all group names or an empty collection for specific user.
*
* @param username the username
* @return the user groups
* @throws UserNotFoundException the user not found exception
*/
public Collection<String> getUserGroups(String username) throws UserNotFoundException {
User user = getUser(username);
Collection<Group> groups = GroupManager.getInstance().getGroups(user);
Collection<String> groupNames = new ArrayList<String>();
for (Group group : groups) {
groupNames.add(group.getName());
}
return groupNames;
}
}
package org.jivesoftware.openfire.plugin.rest.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.core.Response;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.openfire.plugin.rest.exceptions.ExceptionType;
import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException;
/**
* The Class PropertyDAO.
*/
public class PropertyDAO {
/** The Constant LOAD_PROPERTY. */
private final static String LOAD_PROPERTY = "SELECT username FROM ofUserProp WHERE name=? AND propValue=?";
/** The Constant LOAD_PROPERTY_BY_KEY. */
private final static String LOAD_PROPERTY_BY_KEY = "SELECT username FROM ofUserProp WHERE name=?";
/**
* Gets the username by property key and or value.
*
* @param propertyName
* the property name
* @param propertyValue
* the property value (can be null)
* @return the username by property
* @throws ServiceException
* the service exception
*/
public static List<String> getUsernameByProperty(String propertyName, String propertyValue) throws ServiceException {
List<String> usernames = new ArrayList<String>();
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = DbConnectionManager.getConnection();
// Load property by key and value
if (propertyValue != null) {
pstmt = con.prepareStatement(LOAD_PROPERTY);
pstmt.setString(1, propertyName);
pstmt.setString(2, propertyValue);
} else {
// Load property by key
pstmt = con.prepareStatement(LOAD_PROPERTY_BY_KEY);
pstmt.setString(1, propertyName);
}
rs = pstmt.executeQuery();
while (rs.next()) {
usernames.add(rs.getString(1));
}
} catch (SQLException sqle) {
throw new ServiceException("Could not get username by property", propertyName,
ExceptionType.PROPERTY_NOT_FOUND, Response.Status.NOT_FOUND, sqle);
} finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
return usernames;
}
}
package org.jivesoftware.openfire.plugin.rest.entity;
public final class MUCChannelType {
public static final String PUBLIC = "public";
public static final String ALL = "all";
private MUCChannelType() {
}
}
package org.jivesoftware.openfire.plugin.rest.entity;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "chatRooms")
public class MUCRoomEntities {
List<MUCRoomEntity> mucRooms;
public MUCRoomEntities() {
}
public MUCRoomEntities(List<MUCRoomEntity> mucRooms) {
this.mucRooms = mucRooms;
}
@XmlElement(name = "chatRoom")
public List<MUCRoomEntity> getMucRooms() {
return mucRooms;
}
public void setMucRooms(List<MUCRoomEntity> mucRooms) {
this.mucRooms = mucRooms;
}
}
package org.jivesoftware.openfire.plugin.rest.entity;
import java.util.Date;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlRootElement(name = "chatRoom")
@XmlType(propOrder = { "roomName", "naturalName", "description", "password", "subject", "creationDate",
"modificationDate", "maxUsers", "persistent", "publicRoom", "registrationEnabled", "canAnyoneDiscoverJID",
"canOccupantsChangeSubject", "canOccupantsInvite", "canChangeNickname", "logEnabled",
"loginRestrictedToNickname", "membersOnly", "moderated", "broadcastPresenceRoles", "owners", "admins",
"members", "outcasts" })
public class MUCRoomEntity {
private String roomName;
private String description;
private String password;
private String subject;
private String naturalName;
private int maxUsers;
private Date creationDate;
private Date modificationDate;
private boolean persistent;
private boolean publicRoom;
private boolean registrationEnabled;
private boolean canAnyoneDiscoverJID;
private boolean canOccupantsChangeSubject;
private boolean canOccupantsInvite;
private boolean canChangeNickname;
private boolean logEnabled;
private boolean loginRestrictedToNickname;
private boolean membersOnly;
private boolean moderated;
private List<String> broadcastPresenceRoles;
private List<String> owners;
private List<String> admins;
private List<String> members;
private List<String> outcasts;
public MUCRoomEntity() {
}
public MUCRoomEntity(String naturalName, String roomName, String description) {
this.naturalName = naturalName;
this.roomName = roomName;
this.description = description;
}
@XmlElement
public String getNaturalName() {
return naturalName;
}
public void setNaturalName(String naturalName) {
this.naturalName = naturalName;
}
@XmlElement
public String getRoomName() {
return roomName;
}
public void setRoomName(String roomName) {
this.roomName = roomName;
}
@XmlElement
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@XmlElement
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@XmlElement
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
@XmlElement
public int getMaxUsers() {
return maxUsers;
}
public void setMaxUsers(int maxUsers) {
this.maxUsers = maxUsers;
}
@XmlElement
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
@XmlElement
public Date getModificationDate() {
return modificationDate;
}
public void setModificationDate(Date modificationDate) {
this.modificationDate = modificationDate;
}
@XmlElement
public boolean isPersistent() {
return persistent;
}
public void setPersistent(boolean persistent) {
this.persistent = persistent;
}
@XmlElement
public boolean isPublicRoom() {
return publicRoom;
}
public void setPublicRoom(boolean publicRoom) {
this.publicRoom = publicRoom;
}
@XmlElement
public boolean isRegistrationEnabled() {
return registrationEnabled;
}
public void setRegistrationEnabled(boolean registrationEnabled) {
this.registrationEnabled = registrationEnabled;
}
@XmlElement
public boolean isCanAnyoneDiscoverJID() {
return canAnyoneDiscoverJID;
}
public void setCanAnyoneDiscoverJID(boolean canAnyoneDiscoverJID) {
this.canAnyoneDiscoverJID = canAnyoneDiscoverJID;
}
@XmlElement
public boolean isCanOccupantsChangeSubject() {
return canOccupantsChangeSubject;
}
public void setCanOccupantsChangeSubject(boolean canOccupantsChangeSubject) {
this.canOccupantsChangeSubject = canOccupantsChangeSubject;
}
@XmlElement
public boolean isCanOccupantsInvite() {
return canOccupantsInvite;
}
public void setCanOccupantsInvite(boolean canOccupantsInvite) {
this.canOccupantsInvite = canOccupantsInvite;
}
public void setBroadcastPresenceRoles(List<String> broadcastPresenceRoles) {
this.broadcastPresenceRoles = broadcastPresenceRoles;
}
@XmlElement
public boolean isCanChangeNickname() {
return canChangeNickname;
}
public void setCanChangeNickname(boolean canChangeNickname) {
this.canChangeNickname = canChangeNickname;
}
@XmlElement
public boolean isLogEnabled() {
return logEnabled;
}
public void setLogEnabled(boolean logEnabled) {
this.logEnabled = logEnabled;
}
@XmlElement
public boolean isLoginRestrictedToNickname() {
return loginRestrictedToNickname;
}
public void setLoginRestrictedToNickname(boolean loginRestrictedToNickname) {
this.loginRestrictedToNickname = loginRestrictedToNickname;
}
@XmlElement
public boolean isMembersOnly() {
return membersOnly;
}
public void setMembersOnly(boolean membersOnly) {
this.membersOnly = membersOnly;
}
@XmlElement
public boolean isModerated() {
return moderated;
}
public void setModerated(boolean moderated) {
this.moderated = moderated;
}
@XmlElement(name = "broadcastPresenceRole")
@XmlElementWrapper(name = "broadcastPresenceRoles")
public List<String> getBroadcastPresenceRoles() {
return broadcastPresenceRoles;
}
@XmlElementWrapper(name = "owners")
@XmlElement(name = "owner")
public List<String> getOwners() {
return owners;
}
public void setOwners(List<String> owners) {
this.owners = owners;
}
@XmlElementWrapper(name = "members")
@XmlElement(name = "member")
public List<String> getMembers() {
return members;
}
public void setMembers(List<String> members) {
this.members = members;
}
@XmlElementWrapper(name = "outcasts")
@XmlElement(name = "outcast")
public List<String> getOutcasts() {
return outcasts;
}
public void setOutcasts(List<String> outcasts) {
this.outcasts = outcasts;
}
@XmlElementWrapper(name = "admins")
@XmlElement(name = "admin")
public List<String> getAdmins() {
return admins;
}
public void setAdmins(List<String> admins) {
this.admins = admins;
}
}
\ No newline at end of file
package org.jivesoftware.openfire.plugin.rest.entity;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "participants")
public class ParticipantEntities {
List<ParticipantEntity> participants;
public ParticipantEntities() {
}
public ParticipantEntities(List<ParticipantEntity> participants) {
this.participants = participants;
}
@XmlElement(name = "participant")
public List<ParticipantEntity> getParticipants() {
return participants;
}
public void setParticipants(List<ParticipantEntity> participants) {
this.participants = participants;
}
}
package org.jivesoftware.openfire.plugin.rest.entity;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "participant")
public class ParticipantEntity {
private String jid;
private String role;
private String affiliation;
public ParticipantEntity() {
}
@XmlElement
public String getJid() {
return jid;
}
public void setJid(String jid) {
this.jid = jid;
}
@XmlElement
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
@XmlElement
public String getAffiliation() {
return affiliation;
}
public void setAffiliation(String affiliation) {
this.affiliation = affiliation;
}
}
\ No newline at end of file
package org.jivesoftware.openfire.plugin.rest.entity;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* The Class RosterEntities.
*/
@XmlRootElement(name = "roster")
public class RosterEntities {
/** The roster. */
List<RosterItemEntity> roster;
/**
* Instantiates a new roster entities.
*/
public RosterEntities() {
}
/**
* Instantiates a new roster entities.
*
* @param roster
* the roster
*/
public RosterEntities(List<RosterItemEntity> roster) {
this.roster = roster;
}
/**
* Gets the roster.
*
* @return the roster
*/
@XmlElement(name = "rosterItem")
public List<RosterItemEntity> getRoster() {
return roster;
}
/**
* Sets the roster.
*
* @param roster
* the new roster
*/
public void setRoster(List<RosterItemEntity> roster) {
this.roster = roster;
}
}
package org.jivesoftware.openfire.plugin.rest.entity;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* The Class RosterItemEntity.
*/
@XmlRootElement(name = "rosterItem")
@XmlType(propOrder = { "jid", "nickname", "subscriptionType", "groups" })
public class RosterItemEntity {
/** The jid. */
private String jid;
/** The nickname. */
private String nickname;
/** The subscription type. */
private int subscriptionType;
/** The groups. */
private List<String> groups;
/**
* Instantiates a new roster item entity.
*/
public RosterItemEntity() {
}
/**
* Instantiates a new roster item entity.
*
* @param jid
* the jid
* @param nickname
* the nickname
* @param subscriptionType
* the subscription type
*/
public RosterItemEntity(String jid, String nickname, int subscriptionType) {
this.jid = jid;
this.nickname = nickname;
this.subscriptionType = subscriptionType;
}
/**
* Gets the jid.
*
* @return the jid
*/
@XmlElement
public String getJid() {
return jid;
}
/**
* Sets the jid.
*
* @param jid
* the new jid
*/
public void setJid(String jid) {
this.jid = jid;
}
/**
* Gets the nickname.
*
* @return the nickname
*/
@XmlElement
public String getNickname() {
return nickname;
}
/**
* Sets the nickname.
*
* @param nickname
* the new nickname
*/
public void setNickname(String nickname) {
this.nickname = nickname;
}
/**
* Gets the subscription type.
*
* @return the subscription type
*/
@XmlElement
public int getSubscriptionType() {
return subscriptionType;
}
/**
* Sets the subscription type.
*
* @param subscriptionType
* the new subscription type
*/
public void setSubscriptionType(int subscriptionType) {
this.subscriptionType = subscriptionType;
}
/**
* Gets the groups.
*
* @return the groups
*/
@XmlElement(name = "group")
@XmlElementWrapper(name = "groups")
public List<String> getGroups() {
return groups;
}
/**
* Sets the groups.
*
* @param groups
* the new groups
*/
public void setGroups(List<String> groups) {
this.groups = groups;
}
}
package org.jivesoftware.openfire.plugin.rest.entity;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* The Class UserEntities.
*/
@XmlRootElement(name = "users")
public class UserEntities {
/** The users. */
List<UserEntity> users;
/**
* Instantiates a new user entities.
*/
public UserEntities() {
}
/**
* Instantiates a new user entities.
*
* @param users
* the users
*/
public UserEntities(List<UserEntity> users) {
this.users = users;
}
/**
* Gets the users.
*
* @return the users
*/
@XmlElement(name = "user")
public List<UserEntity> getUsers() {
return users;
}
/**
* Sets the users.
*
* @param users
* the new users
*/
public void setUsers(List<UserEntity> users) {
this.users = users;
}
}
package org.jivesoftware.openfire.plugin.rest.entity;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* The Class UserEntity.
*/
@XmlRootElement(name = "user")
@XmlType(propOrder = { "username", "name", "email", "password", "properties" })
public class UserEntity {
/** The username. */
private String username;
/** The name. */
private String name;
/** The email. */
private String email;
/** The password. */
private String password;
/** The properties. */
private List<UserProperty> properties;
/**
* Instantiates a new user entity.
*/
public UserEntity() {
}
/**
* Instantiates a new user entity.
*
* @param username
* the username
* @param name
* the name
* @param email
* the email
*/
public UserEntity(String username, String name, String email) {
this.username = username;
this.name = name;
this.email = email;
}
/**
* Gets the username.
*
* @return the username
*/
@XmlElement
public String getUsername() {
return username;
}
/**
* Sets the username.
*
* @param username
* the new username
*/
public void setUsername(String username) {
this.username = username;
}
/**
* Gets the name.
*
* @return the name
*/
@XmlElement
public String getName() {
return name;
}
/**
* Sets the name.
*
* @param name
* the new name
*/
public void setName(String name) {
this.name = name;
}
/**
* Gets the email.
*
* @return the email
*/
@XmlElement
public String getEmail() {
return email;
}
/**
* Sets the email.
*
* @param email
* the new email
*/
public void setEmail(String email) {
this.email = email;
}
/**
* Gets the password.
*
* @return the password
*/
public String getPassword() {
return password;
}
/**
* Sets the password.
*
* @param password
* the new password
*/
public void setPassword(String password) {
this.password = password;
}
/**
* Gets the properties.
*
* @return the properties
*/
@XmlElement(name = "property")
@XmlElementWrapper(name = "properties")
public List<UserProperty> getProperties() {
return properties;
}
/**
* Sets the properties.
*
* @param properties
* the new properties
*/
public void setProperties(List<UserProperty> properties) {
this.properties = properties;
}
}
package org.jivesoftware.openfire.plugin.rest.entity;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* The Class UserGroupsEntity.
*/
@XmlRootElement(name = "groups")
public class UserGroupsEntity {
/** The group names. */
private List<String> groupNames;
/**
* Instantiates a new user groups entity.
*/
public UserGroupsEntity() {
}
/**
* Instantiates a new user groups entity.
*
* @param groupNames
* the group names
*/
public UserGroupsEntity(List<String> groupNames) {
this.groupNames = groupNames;
}
/**
* Gets the group names.
*
* @return the group names
*/
@XmlElement(name = "groupname")
public List<String> getGroupNames() {
return groupNames;
}
/**
* Sets the group names.
*
* @param groupNames
* the new group names
*/
public void setGroupNames(List<String> groupNames) {
this.groupNames = groupNames;
}
}
package org.jivesoftware.openfire.plugin.rest.entity;
import javax.xml.bind.annotation.XmlAttribute;
/**
* The Class UserProperty.
*/
public class UserProperty {
/** The key. */
private String key;
/** The value. */
private String value;
/**
* Instantiates a new user property.
*/
public UserProperty() {
}
/**
* Instantiates a new user property.
*
* @param key
* the key
* @param value
* the value
*/
public UserProperty(String key, String value) {
this.key = key;
this.value = value;
}
/**
* Gets the key.
*
* @return the key
*/
@XmlAttribute
public String getKey() {
return key;
}
/**
* Sets the key.
*
* @param key
* the new key
*/
public void setKey(String key) {
this.key = key;
}
/**
* Gets the value.
*
* @return the value
*/
@XmlAttribute
public String getValue() {
return value;
}
/**
* Sets the value.
*
* @param value
* the new value
*/
public void setValue(String value) {
this.value = value;
}
}
...@@ -4,11 +4,32 @@ package org.jivesoftware.openfire.plugin.rest.exceptions; ...@@ -4,11 +4,32 @@ package org.jivesoftware.openfire.plugin.rest.exceptions;
* The Class ExceptionType. * The Class ExceptionType.
*/ */
public final class ExceptionType { public final class ExceptionType {
/** The Constant ILLEGAL_ARGUMENT_EXCEPTION. */
public static final String ILLEGAL_ARGUMENT_EXCEPTION = "IllegalArgumentException";
/** The Constant SHARED_GROUP_EXCEPTION. */
public static final String SHARED_GROUP_EXCEPTION = "SharedGroupException";
/** The Constant PROPERTY_NOT_FOUND. */ /** The Constant PROPERTY_NOT_FOUND. */
public static final String PROPERTY_NOT_FOUND = "PropertyNotFoundException"; public static final String PROPERTY_NOT_FOUND = "PropertyNotFoundException";
/** The Constant ILLEGAL_ARGUMENT_EXCEPTION. */ /** The Constant USER_ALREADY_EXISTS_EXCEPTION. */
public static final String ILLEGAL_ARGUMENT_EXCEPTION = "IllegalArgumentException"; public static final String USER_ALREADY_EXISTS_EXCEPTION = "UserAlreadyExistsException";
/** The Constant USER_NOT_FOUND_EXCEPTION. */
public static final String USER_NOT_FOUND_EXCEPTION = "UserNotFoundException";
/** The Constant GROUP_ALREADY_EXISTS. */
public static final String GROUP_ALREADY_EXISTS = "GroupAlreadyExistsException";
/** The Constant GROUP_NOT_FOUND. */
public static final String GROUP_NOT_FOUND = "GroupNotFoundException";
/** The Constant ROOM_NOT_FOUND. */
public static final String ROOM_NOT_FOUND = "RoomNotFoundException";
/** The Constant NOT_ALLOWED. */
public static final String NOT_ALLOWED = "NotAllowedException";
/** /**
* Instantiates a new exception type. * Instantiates a new exception type.
......
package org.jivesoftware.openfire.plugin.rest; package org.jivesoftware.openfire.plugin.rest.exceptions;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider; import javax.ws.rs.ext.Provider;
import org.jivesoftware.openfire.plugin.rest.exceptions.ErrorResponse;
import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
......
package org.jivesoftware.openfire.plugin.rest; package org.jivesoftware.openfire.plugin.rest.service;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -7,7 +7,7 @@ import javax.servlet.ServletConfig; ...@@ -7,7 +7,7 @@ import javax.servlet.ServletConfig;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import org.jivesoftware.admin.AuthCheckFilter; import org.jivesoftware.admin.AuthCheckFilter;
import org.jivesoftware.openfire.plugin.rest.service.RestAPIService; import org.jivesoftware.openfire.plugin.rest.exceptions.RESTExceptionMapper;
import com.sun.jersey.api.core.PackagesResourceConfig; import com.sun.jersey.api.core.PackagesResourceConfig;
import com.sun.jersey.spi.container.servlet.ServletContainer; import com.sun.jersey.spi.container.servlet.ServletContainer;
...@@ -53,6 +53,18 @@ public class JerseyWrapper extends ServletContainer { ...@@ -53,6 +53,18 @@ public class JerseyWrapper extends ServletContainer {
prc.getClasses().add(RestAPIService.class); prc.getClasses().add(RestAPIService.class);
prc.getClasses().add(MUCRoomService.class);
prc.getClasses().add(MUCRoomOwnersService.class);
prc.getClasses().add(MUCRoomAdminsService.class);
prc.getClasses().add(MUCRoomMembersService.class);
prc.getClasses().add(MUCRoomOutcastsService.class);
prc.getClasses().add(UserServiceLegacy.class);
prc.getClasses().add(UserService.class);
prc.getClasses().add(UserRosterService.class);
prc.getClasses().add(UserGroupService.class);
prc.getClasses().add(UserLockoutService.class);
prc.getClasses().add(RESTExceptionMapper.class); prc.getClasses().add(RESTExceptionMapper.class);
} }
......
package org.jivesoftware.openfire.plugin.rest.service;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException;
import org.jivesoftware.openfire.plugin.rest.controller.MUCRoomController;
@Path("restapi/v1/chatrooms/{roomName}/admins")
public class MUCRoomAdminsService {
@POST
@Path("/{jid}")
public Response addMUCRoomAdmin(@DefaultValue("conference") @QueryParam("servicename") String serviceName,
@PathParam("jid") String jid, @PathParam("roomName") String roomName) throws ServiceException {
MUCRoomController.getInstance().addAdmin(serviceName, roomName, jid);
return Response.status(Status.CREATED).build();
}
@DELETE
@Path("/{jid}")
public Response deleteMUCRoomAdmin(@PathParam("jid") String jid,
@DefaultValue("conference") @QueryParam("servicename") String serviceName,
@PathParam("roomName") String roomName) throws ServiceException {
MUCRoomController.getInstance().deleteAffiliation(serviceName, roomName, jid);
return Response.status(Status.OK).build();
}
}
package org.jivesoftware.openfire.plugin.rest.service;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException;
import org.jivesoftware.openfire.plugin.rest.controller.MUCRoomController;
@Path("restapi/v1/chatrooms/{roomName}/members")
public class MUCRoomMembersService {
@POST
@Path("/{jid}")
public Response addMUCRoomMember(@DefaultValue("conference") @QueryParam("servicename") String serviceName,
@PathParam("jid") String jid, @PathParam("roomName") String roomName) throws ServiceException {
MUCRoomController.getInstance().addMember(serviceName, roomName, jid);
return Response.status(Status.CREATED).build();
}
@DELETE
@Path("/{jid}")
public Response deleteMUCRoomMember(@PathParam("jid") String jid,
@DefaultValue("conference") @QueryParam("servicename") String serviceName,
@PathParam("roomName") String roomName) throws ServiceException {
MUCRoomController.getInstance().deleteAffiliation(serviceName, roomName, jid);
return Response.status(Status.OK).build();
}
}
package org.jivesoftware.openfire.plugin.rest.service;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException;
import org.jivesoftware.openfire.plugin.rest.controller.MUCRoomController;
@Path("restapi/v1/chatrooms/{roomName}/outcasts")
public class MUCRoomOutcastsService {
@POST
@Path("/{jid}")
public Response addMUCRoomOutcast(@DefaultValue("conference") @QueryParam("servicename") String serviceName,
@PathParam("jid") String jid, @PathParam("roomName") String roomName) throws ServiceException {
MUCRoomController.getInstance().addOutcast(serviceName, roomName, jid);
return Response.status(Status.CREATED).build();
}
@DELETE
@Path("/{jid}")
public Response deleteMUCRoomOutcast(@PathParam("jid") String jid,
@DefaultValue("conference") @QueryParam("servicename") String serviceName,
@PathParam("roomName") String roomName) throws ServiceException {
MUCRoomController.getInstance().deleteAffiliation(serviceName, roomName, jid);
return Response.status(Status.OK).build();
}
}
package org.jivesoftware.openfire.plugin.rest.service;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException;
import org.jivesoftware.openfire.plugin.rest.controller.MUCRoomController;
@Path("restapi/v1/chatrooms/{roomName}/owners")
public class MUCRoomOwnersService {
@POST
@Path("/{jid}")
public Response addMUCRoomOwner(@DefaultValue("conference") @QueryParam("servicename") String serviceName,
@PathParam("jid") String jid, @PathParam("roomName") String roomName) throws ServiceException {
MUCRoomController.getInstance().addOwner(serviceName, roomName, jid);
return Response.status(Status.CREATED).build();
}
@DELETE
@Path("/{jid}")
public Response deleteMUCRoomOwner(@PathParam("jid") String jid,
@DefaultValue("conference") @QueryParam("servicename") String serviceName,
@PathParam("roomName") String roomName) throws ServiceException {
MUCRoomController.getInstance().deleteAffiliation(serviceName, roomName, jid);
return Response.status(Status.OK).build();
}
}
package org.jivesoftware.openfire.plugin.rest.service;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.jivesoftware.openfire.plugin.rest.entity.MUCChannelType;
import org.jivesoftware.openfire.plugin.rest.entity.MUCRoomEntities;
import org.jivesoftware.openfire.plugin.rest.entity.MUCRoomEntity;
import org.jivesoftware.openfire.plugin.rest.entity.ParticipantEntities;
import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException;
import org.jivesoftware.openfire.plugin.rest.controller.MUCRoomController;
@Path("restapi/v1/chatrooms")
public class MUCRoomService {
@GET
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public MUCRoomEntities getMUCRooms(@DefaultValue("conference") @QueryParam("servicename") String serviceName,
@DefaultValue(MUCChannelType.PUBLIC) @QueryParam("type") String channelType,
@QueryParam("search") String roomSearch) {
return MUCRoomController.getInstance().getChatRooms(serviceName, channelType, roomSearch);
}
@GET
@Path("/{roomName}")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public MUCRoomEntity getMUCRoomJSON2(@PathParam("roomName") String roomName,
@DefaultValue("conference") @QueryParam("servicename") String serviceName) throws ServiceException {
return MUCRoomController.getInstance().getChatRoom(roomName, serviceName);
}
@DELETE
@Path("/{roomName}")
public Response deleteMUCRoom(@PathParam("roomName") String roomName,
@DefaultValue("conference") @QueryParam("servicename") String serviceName) throws ServiceException {
MUCRoomController.getInstance().deleteChatRoom(roomName, serviceName);
return Response.status(Status.OK).build();
}
@POST
public Response createMUCRoom(@DefaultValue("conference") @QueryParam("servicename") String serviceName,
MUCRoomEntity mucRoomEntity) throws ServiceException {
MUCRoomController.getInstance().createChatRoom(serviceName, mucRoomEntity);
return Response.status(Status.CREATED).build();
}
@PUT
@Path("/{roomName}")
public Response udpateMUCRoom(@PathParam("roomName") String roomName,
@DefaultValue("conference") @QueryParam("servicename") String serviceName, MUCRoomEntity mucRoomEntity)
throws ServiceException {
MUCRoomController.getInstance().updateChatRoom(roomName, serviceName, mucRoomEntity);
return Response.status(Status.OK).build();
}
@GET
@Path("/{roomName}/participants")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public ParticipantEntities getMUCRoomParticipants(@PathParam("roomName") String roomName,
@DefaultValue("conference") @QueryParam("servicename") String serviceName) {
return MUCRoomController.getInstance().getRoomParticipants(roomName, serviceName);
}
}
...@@ -16,7 +16,7 @@ import org.jivesoftware.openfire.plugin.rest.entity.SystemProperties; ...@@ -16,7 +16,7 @@ import org.jivesoftware.openfire.plugin.rest.entity.SystemProperties;
import org.jivesoftware.openfire.plugin.rest.entity.SystemProperty; import org.jivesoftware.openfire.plugin.rest.entity.SystemProperty;
import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException; import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException;
@Path("restapi/system/properties") @Path("restapi/v1/system/properties")
public class RestAPIService { public class RestAPIService {
private RESTServicePlugin plugin; private RESTServicePlugin plugin;
...@@ -27,14 +27,14 @@ public class RestAPIService { ...@@ -27,14 +27,14 @@ public class RestAPIService {
} }
@GET @GET
@Produces(MediaType.APPLICATION_XML) @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public SystemProperties getSystemProperties() { public SystemProperties getSystemProperties() {
return plugin.getSystemProperties(); return plugin.getSystemProperties();
} }
@GET @GET
@Path("/{propertyKey}") @Path("/{propertyKey}")
@Produces(MediaType.APPLICATION_XML) @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public SystemProperty getSystemProperty(@PathParam("propertyKey") String propertyKey) throws ServiceException { public SystemProperty getSystemProperty(@PathParam("propertyKey") String propertyKey) throws ServiceException {
return plugin.getSystemProperty(propertyKey); return plugin.getSystemProperty(propertyKey);
} }
......
package org.jivesoftware.openfire.plugin.rest.service;
import javax.annotation.PostConstruct;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.jivesoftware.openfire.plugin.rest.controller.UserServiceController;
import org.jivesoftware.openfire.plugin.rest.entity.UserGroupsEntity;
import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException;
@Path("restapi/v1/users/{username}/groups")
public class UserGroupService {
private UserServiceController plugin;
@PostConstruct
public void init() {
plugin = UserServiceController.getInstance();
}
@GET
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public UserGroupsEntity getUserGroups(@PathParam("username") String username) throws ServiceException {
return new UserGroupsEntity(plugin.getUserGroups(username));
}
@POST
public Response addUserToGroups(@PathParam("username") String username, UserGroupsEntity userGroupsEntity)
throws ServiceException {
plugin.addUserToGroups(username, userGroupsEntity);
return Response.status(Response.Status.CREATED).build();
}
@DELETE
public Response deleteUserFromGroups(@PathParam("username") String username, UserGroupsEntity userGroupsEntity)
throws ServiceException {
plugin.deleteUserFromGroups(username, userGroupsEntity);
return Response.status(Response.Status.OK).build();
}
}
package org.jivesoftware.openfire.plugin.rest.service;
import javax.annotation.PostConstruct;
import javax.ws.rs.DELETE;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
import org.jivesoftware.openfire.plugin.rest.controller.UserServiceController;
import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException;
@Path("restapi/v1/lockouts")
public class UserLockoutService {
private UserServiceController plugin;
@PostConstruct
public void init() {
plugin = UserServiceController.getInstance();
}
@POST
@Path("/{username}")
public Response disableUser(@PathParam("username") String username) throws ServiceException {
plugin.disableUser(username);
return Response.status(Response.Status.CREATED).build();
}
@DELETE
@Path("/{username}")
public Response enableUser(@PathParam("username") String username) throws ServiceException {
plugin.enableUser(username);
return Response.status(Response.Status.OK).build();
}
}
package org.jivesoftware.openfire.plugin.rest.service;
import javax.annotation.PostConstruct;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.jivesoftware.openfire.SharedGroupException;
import org.jivesoftware.openfire.plugin.rest.controller.UserServiceController;
import org.jivesoftware.openfire.plugin.rest.entity.RosterEntities;
import org.jivesoftware.openfire.plugin.rest.entity.RosterItemEntity;
import org.jivesoftware.openfire.plugin.rest.exceptions.ExceptionType;
import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException;
import org.jivesoftware.openfire.user.UserAlreadyExistsException;
import org.jivesoftware.openfire.user.UserNotFoundException;
@Path("restapi/v1/users/{username}/roster")
public class UserRosterService {
private static final String COULD_NOT_UPDATE_THE_ROSTER = "Could not update the roster";
private static final String COULD_NOT_CREATE_ROSTER_ITEM = "Could not create roster item";
private UserServiceController plugin;
@PostConstruct
public void init() {
plugin = UserServiceController.getInstance();
}
@GET
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public RosterEntities getUserRoster(@PathParam("username") String username) throws ServiceException {
return plugin.getRosterEntities(username);
}
@POST
public Response createRoster(@PathParam("username") String username, RosterItemEntity rosterItemEntity)
throws ServiceException {
try {
plugin.addRosterItem(username, rosterItemEntity);
} catch (UserNotFoundException e) {
throw new ServiceException(COULD_NOT_CREATE_ROSTER_ITEM, "", ExceptionType.USER_NOT_FOUND_EXCEPTION,
Response.Status.NOT_FOUND, e);
} catch (UserAlreadyExistsException e) {
throw new ServiceException(COULD_NOT_CREATE_ROSTER_ITEM, "", ExceptionType.USER_ALREADY_EXISTS_EXCEPTION,
Response.Status.BAD_REQUEST, e);
} catch (SharedGroupException e) {
throw new ServiceException(COULD_NOT_CREATE_ROSTER_ITEM, "", ExceptionType.SHARED_GROUP_EXCEPTION,
Response.Status.BAD_REQUEST, e);
}
return Response.status(Response.Status.CREATED).build();
}
@DELETE
@Path("/{rosterJid}")
public Response deleteRoster(@PathParam("username") String username, @PathParam("rosterJid") String rosterJid)
throws ServiceException {
try {
plugin.deleteRosterItem(username, rosterJid);
} catch (SharedGroupException e) {
throw new ServiceException("Could not delete the roster item", rosterJid,
ExceptionType.SHARED_GROUP_EXCEPTION, Response.Status.BAD_REQUEST, e);
}
return Response.status(Response.Status.OK).build();
}
@PUT
@Path("/{rosterJid}")
public Response updateRoster(@PathParam("username") String username, @PathParam("rosterJid") String rosterJid,
RosterItemEntity rosterItemEntity) throws ServiceException {
try {
plugin.updateRosterItem(username, rosterJid, rosterItemEntity);
} catch (UserNotFoundException e) {
throw new ServiceException(COULD_NOT_UPDATE_THE_ROSTER, rosterJid, ExceptionType.USER_NOT_FOUND_EXCEPTION,
Response.Status.NOT_FOUND, e);
} catch (SharedGroupException e) {
throw new ServiceException(COULD_NOT_UPDATE_THE_ROSTER, rosterJid, ExceptionType.SHARED_GROUP_EXCEPTION,
Response.Status.BAD_REQUEST, e);
} catch (UserAlreadyExistsException e) {
throw new ServiceException(COULD_NOT_UPDATE_THE_ROSTER, rosterJid,
ExceptionType.USER_ALREADY_EXISTS_EXCEPTION, Response.Status.BAD_REQUEST, e);
}
return Response.status(Response.Status.OK).build();
}
}
package org.jivesoftware.openfire.plugin.rest.service;
import javax.annotation.PostConstruct;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.jivesoftware.openfire.plugin.rest.controller.UserServiceController;
import org.jivesoftware.openfire.plugin.rest.entity.UserEntities;
import org.jivesoftware.openfire.plugin.rest.entity.UserEntity;
import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException;
@Path("restapi/v1/users")
public class UserService {
private UserServiceController plugin;
@PostConstruct
public void init() {
plugin = UserServiceController.getInstance();
}
@GET
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public UserEntities getUsers(@QueryParam("search") String userSearch,
@QueryParam("propertyKey") String propertyKey, @QueryParam("propertyValue") String propertyValue)
throws ServiceException {
return plugin.getUserEntities(userSearch, propertyKey, propertyValue);
}
@POST
public Response createUser(UserEntity userEntity) throws ServiceException {
plugin.createUser(userEntity);
return Response.status(Response.Status.CREATED).build();
}
@GET
@Path("/{username}")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public UserEntity getUser(@PathParam("username") String username) throws ServiceException {
return plugin.getUserEntity(username);
}
@PUT
@Path("/{username}")
public Response updateUser(@PathParam("username") String username, UserEntity userEntity) throws ServiceException {
plugin.updateUser(username, userEntity);
return Response.status(Response.Status.OK).build();
}
@DELETE
@Path("/{username}")
public Response deleteUser(@PathParam("username") String username) throws ServiceException {
plugin.deleteUser(username);
return Response.status(Response.Status.OK).build();
}
}
package org.jivesoftware.openfire.plugin.rest.service;
import gnu.inet.encoding.Stringprep;
import java.io.IOException;
import java.io.PrintWriter;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import org.apache.log4j.Logger;
import org.jivesoftware.openfire.SharedGroupException;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.plugin.rest.RESTServicePlugin;
import org.jivesoftware.openfire.plugin.rest.controller.UserServiceLegacyController;
import org.jivesoftware.openfire.user.UserAlreadyExistsException;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.xmpp.packet.JID;
@Path("restapi/v1")
public class UserServiceLegacy {
private static Logger Log = Logger.getLogger(UserServiceLegacy.class);
@Context
private HttpServletRequest request;
@Context
private HttpServletResponse response;
private RESTServicePlugin plugin;
private UserServiceLegacyController userServiceController;
@PostConstruct
public void init() {
plugin = (RESTServicePlugin) XMPPServer.getInstance().getPluginManager()
.getPlugin("restapi");
userServiceController = UserServiceLegacyController.getInstance();
}
@POST
@Path("/userservice")
public void userSerivcePostRequest() throws IOException {
userSerivceRequest();
}
@GET
@Path("/userservice")
public Response userSerivceRequest() throws IOException {
// Printwriter for writing out responses to browser
PrintWriter out = response.getWriter();
if (!plugin.getAllowedIPs().isEmpty()) {
// Get client's IP address
String ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null) {
ipAddress = request.getHeader("X_FORWARDED_FOR");
if (ipAddress == null) {
ipAddress = request.getHeader("X-Forward-For");
if (ipAddress == null) {
ipAddress = request.getRemoteAddr();
}
}
}
if (!plugin.getAllowedIPs().contains(ipAddress)) {
Log.warn("User service rejected service to IP address: " + ipAddress);
replyError("RequestNotAuthorised", response, out);
return Response.status(200).build();
}
}
String username = request.getParameter("username");
String password = request.getParameter("password");
String name = request.getParameter("name");
String email = request.getParameter("email");
String type = request.getParameter("type");
String secret = request.getParameter("secret");
String groupNames = request.getParameter("groups");
String item_jid = request.getParameter("item_jid");
String sub = request.getParameter("subscription");
// No defaults, add, delete, update only
// type = type == null ? "image" : type;
// Check that our plugin is enabled.
if (!plugin.isEnabled()) {
Log.warn("User service plugin is disabled: " + request.getQueryString());
replyError("UserServiceDisabled", response, out);
return Response.status(200).build();
}
// Check this request is authorised
if (secret == null || !secret.equals(plugin.getSecret())) {
Log.warn("An unauthorised user service request was received: " + request.getQueryString());
replyError("RequestNotAuthorised", response, out);
return Response.status(200).build();
}
// Some checking is required on the username
if (username == null && !"grouplist".equals(type)) {
replyError("IllegalArgumentException", response, out);
return Response.status(200).build();
}
if ((type.equals("add_roster") || type.equals("update_roster") || type.equals("delete_roster"))
&& (item_jid == null || !(sub == null || sub.equals("-1") || sub.equals("0") || sub.equals("1")
|| sub.equals("2") || sub.equals("3")))) {
replyError("IllegalArgumentException", response, out);
return Response.status(200).build();
}
// Check the request type and process accordingly
try {
if ("grouplist".equals(type)) {
String message = "";
for (String groupname : userServiceController.getAllGroups()) {
message += "<groupname>" + groupname + "</groupname>";
}
replyMessage(message, response, out);
} else {
username = username.trim().toLowerCase();
username = JID.escapeNode(username);
username = Stringprep.nodeprep(username);
if ("add".equals(type)) {
userServiceController.createUser(username, password, name, email, groupNames);
replyMessage("ok", response, out);
} else if ("delete".equals(type)) {
userServiceController.deleteUser(username);
replyMessage("ok", response, out);
} else if ("enable".equals(type)) {
userServiceController.enableUser(username);
replyMessage("ok", response, out);
} else if ("disable".equals(type)) {
userServiceController.disableUser(username);
replyMessage("ok", response, out);
} else if ("update".equals(type)) {
userServiceController.updateUser(username, password, name, email, groupNames);
replyMessage("ok", response, out);
} else if ("add_roster".equals(type)) {
userServiceController.addRosterItem(username, item_jid, name, sub, groupNames);
replyMessage("ok", response, out);
} else if ("update_roster".equals(type)) {
userServiceController.updateRosterItem(username, item_jid, name, sub, groupNames);
replyMessage("ok", response, out);
} else if ("delete_roster".equals(type)) {
userServiceController.deleteRosterItem(username, item_jid);
replyMessage("ok", response, out);
} else if ("usergrouplist".equals(type)) {
String message = "";
for (String groupname : userServiceController.getUserGroups(username)) {
message += "<groupname>" + groupname + "</groupname>";
}
replyMessage(message, response, out);
} else {
Log.warn("The userService servlet received an invalid request of type: " + type);
// TODO Do something
}
}
} catch (UserAlreadyExistsException e) {
replyError("UserAlreadyExistsException", response, out);
} catch (UserNotFoundException e) {
replyError("UserNotFoundException", response, out);
} catch (IllegalArgumentException e) {
replyError("IllegalArgumentException", response, out);
} catch (SharedGroupException e) {
replyError("SharedGroupException", response, out);
} catch (Exception e) {
Log.error("Error: ", e);
replyError(e.toString(), response, out);
}
return Response.status(200).build();
}
private void replyMessage(String message, HttpServletResponse response, PrintWriter out) {
response.setContentType("text/xml");
out.println("<result>" + message + "</result>");
out.flush();
}
private void replyError(String error, HttpServletResponse response, PrintWriter out) {
response.setContentType("text/xml");
out.println("<error>" + error + "</error>");
out.flush();
}
}
package org.jivesoftware.openfire.plugin.rest.utils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.xmpp.packet.JID;
/**
* The Class MUCRoomUtils.
*/
public class MUCRoomUtils {
/**
* Instantiates a new MUC room utils.
*/
private MUCRoomUtils() {
throw new AssertionError();
}
/**
* Convert jids to string list.
*
* @param jids
* the jids
* @return the array list< string>
*/
public static List<String> convertJIDsToStringList(Collection<JID> jids) {
List<String> result = new ArrayList<String>();
for (JID jid : jids) {
result.add(jid.toBareJID());
}
return result;
}
/**
* Convert strings to jids.
*
* @param jids
* the jids
* @return the list<jid>
*/
public static List<JID> convertStringsToJIDs(List<String> jids) {
List<JID> result = new ArrayList<JID>();
for (String jidString : jids) {
result.add(new JID(jidString));
}
return result;
}
}
package org.jivesoftware.openfire.plugin.rest.utils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.plugin.rest.entity.UserEntity;
import org.jivesoftware.openfire.plugin.rest.entity.UserProperty;
import org.jivesoftware.openfire.user.User;
import org.jivesoftware.openfire.user.UserAlreadyExistsException;
import org.xmpp.packet.JID;
// TODO: Auto-generated Javadoc
/**
* The Class UserUtils.
*/
public class UserUtils {
/**
* Instantiates a new user utils.
*/
private UserUtils() {
throw new AssertionError();
}
/**
* Convert users to user entities.
*
* @param users the users
* @param userSearch the user search
* @return the list
*/
public static List<UserEntity> convertUsersToUserEntities(Collection<User> users, String userSearch) {
List<UserEntity> result = new ArrayList<UserEntity>();
for (User user : users) {
if (userSearch != null) {
if (!user.getUsername().contains(userSearch)) {
continue;
}
}
result.add(convertUserToUserEntity(user));
}
return result;
}
/**
* Convert user to user entity.
*
* @param user
* the user
* @return the user entity
*/
public static UserEntity convertUserToUserEntity(User user) {
UserEntity userEntity = new UserEntity(user.getUsername(), user.getName(), user.getEmail());
List<UserProperty> userProperties = new ArrayList<UserProperty>();
for (Entry<String, String> property : user.getProperties().entrySet()) {
userProperties.add(new UserProperty(property.getKey(), property.getValue()));
}
userEntity.setProperties(userProperties);
return userEntity;
}
/**
* Checks if is valid sub type.
*
* @param subType the sub type
* @return true, if is valid sub type
* @throws UserAlreadyExistsException the user already exists exception
*/
public static void checkSubType(int subType) throws UserAlreadyExistsException {
if (!(subType >= -1 && subType <= 3)) {
throw new UserAlreadyExistsException();
}
}
/**
* Check and get jid.
*
* @param jid the jid
* @return the jid
*/
public static JID checkAndGetJID(String jid) {
if(isValidBareJid(jid)) {
return new JID(jid);
} else {
return XMPPServer.getInstance().createJID(jid, null);
}
}
/**
* Checks if is valid bare jid.
*
* @param jid the jid
* @return true, if is valid bare jid
*/
public static boolean isValidBareJid(String jid) {
final int index = jid.indexOf('@');
if (index == -1) {
return false;
} else if (jid.indexOf('@', index + 1) != -1) {
return false;
}
return true;
}
}
...@@ -4,12 +4,13 @@ ...@@ -4,12 +4,13 @@
<!-- Servlets --> <!-- Servlets -->
<servlet> <servlet>
<servlet-name>JerseyWrapper</servlet-name> <servlet-name>JerseyWrapper</servlet-name>
<servlet-class>org.jivesoftware.openfire.plugin.rest.JerseyWrapper</servlet-class> <servlet-class>org.jivesoftware.openfire.plugin.rest.service.JerseyWrapper</servlet-class>
</servlet> </servlet>
<!-- Servlet mappings --> <!-- Servlet mappings -->
<servlet-mapping> <servlet-mapping>
<servlet-name>JerseyWrapper</servlet-name> <servlet-name>JerseyWrapper</servlet-name>
<url-pattern>/system/*</url-pattern> <url-pattern>/v1/*</url-pattern>
</servlet-mapping> </servlet-mapping>
</web-app> </web-app>
<%@ page import="java.util.*, <%@ page
import="java.util.*,
org.jivesoftware.openfire.XMPPServer, org.jivesoftware.openfire.XMPPServer,
org.jivesoftware.util.*,org.jivesoftware.openfire.plugin.rest.RESTServicePlugin" org.jivesoftware.util.*,org.jivesoftware.openfire.plugin.rest.RESTServicePlugin"
errorPage="error.jsp" errorPage="error.jsp"%>
%>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %> <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %> <%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt"%>
<%-- Define Administration Bean --%> <%-- Define Administration Bean --%>
<jsp:useBean id="admin" class="org.jivesoftware.util.WebManager" /> <jsp:useBean id="admin" class="org.jivesoftware.util.WebManager" />
<c:set var="admin" value="${admin.manager}" /> <c:set var="admin" value="${admin.manager}" />
<% <%
admin.init(request, response, session, application, out ); admin.init(request, response, session, application, out);
%> %>
<% <%
...@@ -23,7 +23,8 @@ ...@@ -23,7 +23,8 @@
boolean httpBasicAuth = ParamUtils.getBooleanParameter(request, "authtype"); boolean httpBasicAuth = ParamUtils.getBooleanParameter(request, "authtype");
String allowedIPs = ParamUtils.getParameter(request, "allowedIPs"); String allowedIPs = ParamUtils.getParameter(request, "allowedIPs");
RESTServicePlugin plugin = (RESTServicePlugin) XMPPServer.getInstance().getPluginManager().getPlugin("restapi"); RESTServicePlugin plugin = (RESTServicePlugin) XMPPServer.getInstance().getPluginManager()
.getPlugin("restapi");
// Handle a save // Handle a save
Map errors = new HashMap(); Map errors = new HashMap();
...@@ -45,76 +46,92 @@ ...@@ -45,76 +46,92 @@
%> %>
<html> <html>
<head> <head>
<title>REST API Properties</title> <title>REST API Properties</title>
<meta name="pageID" content="rest-api"/> <meta name="pageID" content="rest-api" />
</head> </head>
<body> <body>
<p> <p>Use the form below to enable or disable the REST API and
Use the form below to enable or disable the REST API and configure the authentication. configure the authentication.</p>
</p>
<% if (success) { %> <%
if (success) {
%>
<div class="jive-success"> <div class="jive-success">
<table cellpadding="0" cellspacing="0" border="0"> <table cellpadding="0" cellspacing="0" border="0">
<tbody> <tbody>
<tr><td class="jive-icon"><img src="images/success-16x16.gif" width="16" height="16" border="0"></td> <tr>
<td class="jive-icon-label"> <td class="jive-icon"><img src="images/success-16x16.gif"
REST API properties edited successfully. width="16" height="16" border="0"></td>
</td></tr> <td class="jive-icon-label">REST API properties edited
successfully.</td>
</tr>
</tbody> </tbody>
</table> </table>
</div><br> </div>
<% } %> <br>
<%
}
%>
<form action="rest-api.jsp?save" method="post"> <form action="rest-api.jsp?save" method="post">
<fieldset> <fieldset>
<legend>REST API</legend> <legend>REST API</legend>
<div> <div>
<p> <p>
The addition, deletion and editing of Openfire system properties is not normally available outside of the admin console. The REST API can be secured with a shared secret key defined below
This service lets those administration tasks be performed HTTP requests to provide or a with HTTP basic authentication.<br />Moreover, for extra
simple integration with other applications.</p> security you can specify the list of IP addresses that are allowed
to use this service.<br />An empty list means that the service can
<p>The REST API can be secured with a shared secret key defined below or a with HTTP basic authentication. be accessed from any location. Addresses are delimited by commas.
Moreover, for extra security you can specify the list of IP addresses that are allowed to
use this service. An empty list means that the service can be accessed from any
location. Addresses are delimited by commas.
</p> </p>
<ul> <ul>
<input type="radio" name="enabled" value="true" id="rb01" <input type="radio" name="enabled" value="true" id="rb01"
<%= ((enabled) ? "checked" : "") %>> <%=((enabled) ? "checked" : "")%>>
<label for="rb01"><b>Enabled</b> - REST API requests will be processed.</label> <label for="rb01"><b>Enabled</b> - REST API requests will
be processed.</label>
<br> <br>
<input type="radio" name="enabled" value="false" id="rb02" <input type="radio" name="enabled" value="false" id="rb02"
<%= ((!enabled) ? "checked" : "") %>> <%=((!enabled) ? "checked" : "")%>>
<label for="rb02"><b>Disabled</b> - REST API requests will be ignored.</label> <label for="rb02"><b>Disabled</b> - REST API requests will
<br><br> be ignored.</label>
<br>
<br>
<input type="radio" name="authtype" value="true" id="http_basic_auth" <%= ((httpBasicAuth) ? "checked" : "") %>> <input type="radio" name="authtype" value="true"
<label for="http_basic_auth">HTTP basic auth - REST API authentication with Openfire admin account.</label> id="http_basic_auth" <%=((httpBasicAuth) ? "checked" : "")%>>
<label for="http_basic_auth">HTTP basic auth - REST API
authentication with Openfire admin account.</label>
<br>
<input type="radio" name="authtype" value="false"
id="secretKeyAuth" <%=((!httpBasicAuth) ? "checked" : "")%>>
<label for="secretKeyAuth">Secret key auth - REST API
authentication over specified secret key.</label>
<br>
<label style="padding-left: 25px" for="text_secret">Secret
key:</label>
<input type="text" name="secret" value="<%=secret%>"
id="text_secret">
<br> <br>
<input type="radio" name="authtype" value="false" id="secretKeyAuth" <%= ((!httpBasicAuth) ? "checked" : "") %>>
<label for="secretKeyAuth">Secret key auth - REST API authentication over specified secret key.</label>
<br> <br>
<label style="padding-left: 25px" for="text_secret">Secret key:</label>
<input type="text" name="secret" value="<%= secret %>" id="text_secret">
<br><br>
<label for="text_secret">Allowed IP Addresses:</label> <label for="allowedIPs">Allowed IP Addresses:</label>
<textarea name="allowedIPs" cols="40" rows="3" wrap="virtual"><%= ((allowedIPs != null) ? allowedIPs : "") %></textarea> <textarea name="allowedIPs" cols="40" rows="3" wrap="virtual"><%=((allowedIPs != null) ? allowedIPs : "")%></textarea>
</ul> </ul>
</div>
</fieldset>
<br><br> <p>You can find here detailed documentation over the Openfire REST API:
<a
href="/plugin-admin.jsp?plugin=restapi&showReadme=true&decorator=none">REST
API Documentation</a>
</p>
</div>
</fieldset>
<input type="submit" value="Save Settings"> <br> <br> <input type="submit" value="Save Settings">
</form> </form>
</body> </body>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment