diff --git a/changelog.html b/changelog.html index e4902ac8b..717de8854 100644 --- a/changelog.html +++ b/changelog.html @@ -44,10 +44,12 @@
1.11.1 (tbd)
+1.12.0 (tbd)
Copy restAPI.jar into the plugins directory of your Openfire server. The plugin will be automatically deployed. To upgrade to a newer version, overwrite the restAPI.jar file with the new one.
- -
- Important Step: To enable the plugin make sure to set the system property adminConsole.access.allow-wildcards-in-excludes to true.
- Without the above step the REST API plugin always redirects to login
- This was done in response to a security issue
-
Important Step: To enable the plugin make sure to set the system property adminConsole.access.allow-wildcards-in-excludes to true
Without the above step the REST API plugin always redirects to login.
+ This was done in response to a security issue.
To provide a standard way of accessing the data the plugin is using REST.
@@ -287,7 +286,8 @@GET http://example.org:9090/plugins/restapi/v1/users?propertyKey=keyname&propertyValue=keyvalue
If you want to get a JSON format result, please add “Accept: application/json” to the Header.
-Endpoint to get information over a specific user
@@ -333,33 +333,31 @@GET /users/{username}
Payload Example 1 (required parameters):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<user>
- <username>test3</username> <password>p4ssword</password></user>
+<user>
+ <username>test3</username> <password>p4ssword</password></user>
Payload Example 2 (available parameters):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<user>
- <username>testuser</username> <password>p4ssword</password> <name>Test User</name> <email>test@localhost.de</email> <properties> <property key="keyname" value="value"/> <property key="anotherkey" value="value"/> </properties></user>
+<user>
+ <username>testuser</username> <password>p4ssword</password> <name>Test User</name> <email>test@localhost.de</email> <properties> <property key="keyname" value="value"/> <property key="anotherkey" value="value"/> </properties></user>
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type: application/json
-
- POST http://example.org:9090/plugins/restapi/v1/usersHeader: Content-Type: application/json
+
Payload Example 1 (required parameters):
{
- "username": "admin", "password": "p4ssword"}
+ "username": "admin", "password": "p4ssword"}
Payload Example 2 (available parameters):
{
- "username": "admin", "password": "p4ssword", "name": "Administrator", "email": "admin@example.com", "properties": { "property": [ { "@key": "console.rows_per_page", "@value": "user-summary=8" }, { "@key": "console.order", "@value": "session-summary=1" } ] }}
+ "username": "admin", "password": "p4ssword", "name": "Administrator", "email": "admin@example.com", "properties": { "property": [ { "@key": "console.rows_per_page", "@value": "user-summary=8" }, { "@key": "console.order", "@value": "session-summary=1" } ] }}
REST API Version 1.3.0 and later - Payload Example 3 (available parameters):
{
- "users": [ { "username": "admin", "name": "Administrator", "email": "admin@example.com", "password": "p4ssword", "properties": [ { "key": "console.order", "value": "session-summary=0" } ] }, { "username": "test", "name": "Test", "password": "p4ssword" } ]}
+ "users": [ { "username": "admin", "name": "Administrator", "email": "admin@example.com", "password": "p4ssword", "properties": [ { "key": "console.order", "value": "session-summary=0" } ] }, { "username": "test", "name": "Test", "password": "p4ssword" } ]}
Endpoint to delete a user
@@ -390,9 +388,7 @@Header: Authorization: Basic YWRtaW46MTIzNDU=
--+DELETE http://example.org:9090/plugins/restapi/v1/users/testuser
-DELETE http://example.org:9090/plugins/restapi/v1/users/testuser
Endpoint to update / rename a user
@@ -424,46 +420,41 @@Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type application/xml
-
- PUT http://example.org:9090/plugins/restapi/v1/users/testuserHeader: Content-Type application/xml
+PUT http://example.org:9090/plugins/restapi/v1/users/testuser
Payload:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<user>
- <username>testuser</username> <name>Test User edit</name> <email>test@edit.de</email> <properties> <property key="keyname" value="value"/> </properties></user>
+<user>
+ <username>testuser</username> <name>Test User edit</name> <email>test@edit.de</email> <properties> <property key="keyname" value="value"/> </properties></user>
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type application/xml
-
- PUT http://example.org:9090/plugins/restapi/v1/users/oldUsernameHeader: Content-Type application/xml
+PUT http://example.org:9090/plugins/restapi/v1/users/oldUsername
Payload:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<user>
- <username>newUsername</username> <name>Test User edit</name> <email>test@edit.de</email> <properties> <property key="keyname" value="value"/> </properties></user>
+<user>
+ <username>newUsername</username> <name>Test User edit</name> <email>test@edit.de</email> <properties> <property key="keyname" value="value"/> </properties></user>
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type application/json
-
- PUT http://example.org:9090/plugins/restapi/v1/users/testuserHeader: Content-Type application/json
+PUT http://example.org:9090/plugins/restapi/v1/users/testuser
Payload:
{
- "username": "testuser", "name": "Test User edit", "email": "test@edit.de", "properties": { "property": { "@key": "keyname", "@value": "value" } }}
+ "username": "testuser", "name": "Test User edit", "email": "test@edit.de", "properties": { "property": { "@key": "keyname", "@value": "value" } }}
REST API Version 1.3.0 and later - Payload Example 2 (available parameters):
{
- "username": "testuser", "name": "Test User edit", "email": "test@edit.de", "properties": [ { "key": "keyname", "value": "value" } ]}
+ "username": "testuser", "name": "Test User edit", "email": "test@edit.de", "properties": [ { "key": "keyname", "value": "value" } ]}
- Endpoint to get group names of a specific user
@@ -491,9 +482,7 @@GET /users/{username}/groups
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+GET http://example.org:9090/plugins/restapi/v1/users/testuser/groups
-GET http://example.org:9090/plugins/restapi/v1/users/testuser/groups
Endpoint to add user to a groups
@@ -524,15 +513,13 @@Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type application/xml
-
- POST http://example.org:9090/plugins/restapi/v1/users/testuser/groupsHeader: Content-Type application/xml
+POST http://example.org:9090/plugins/restapi/v1/users/testuser/groups
Payload:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<groups>
- <groupname>Admins</groupname> <groupname>Support</groupname></groups>
+<groups>
+ <groupname>Admins</groupname> <groupname>Support</groupname></groups>
Endpoint to add user to a group
@@ -569,10 +556,8 @@Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type application/xml
-
- POST http://example.org:9090/plugins/restapi/v1/users/testuser/groups/testGroupHeader: Content-Type application/xml
+POST http://example.org:9090/plugins/restapi/v1/users/testuser/groups/testGroup
Endpoint to remove a user from a groups
@@ -603,15 +588,13 @@Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type application/xml
-
- DELETE http://example.org:9090/plugins/restapi/v1/users/testuser/groupsHeader: Content-Type application/xml
+DELETE http://example.org:9090/plugins/restapi/v1/users/testuser/groups
Payload:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<groups>
- <groupname>Admins</groupname> <groupname>Support</groupname></groups>
+<groups>
+ <groupname>Admins</groupname> <groupname>Support</groupname></groups>
Endpoint to remove a user from a group
@@ -648,10 +631,8 @@Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type application/xml
-
- DELETE http://example.org:9090/plugins/restapi/v1/users/testuser/groups/testGroupHeader: Content-Type application/xml
+DELETE http://example.org:9090/plugins/restapi/v1/users/testuser/groups/testGroup
Endpoint to lockout / ban the user from the chat server. The user will be kicked if the user is online.
@@ -682,11 +663,10 @@-Header: Authorization: Basic YWRtaW46MTIzNDU=
--+POST http://example.org:9090/plugins/restapi/v1/lockouts/testuser
-POST http://example.org:9090/plugins/restapi/v1/lockouts/testuser
Endpoint to unlock / unban the user
@@ -714,11 +694,10 @@DELETE /lockouts/{username}
-Header: Authorization: Basic YWRtaW46MTIzNDU=
--+DELETE http://example.org:9090/plugins/restapi/v1/lockouts/testuser
-DELETE http://example.org:9090/plugins/restapi/v1/lockouts/testuser
Endpoint to get roster entries (buddies) from a specific user
@@ -746,11 +725,10 @@GET /users/{username}/roster
-Header: Authorization: Basic YWRtaW46MTIzNDU=
--+GET http://example.org:9090/plugins/restapi/v1/users/testuser/roster
-GET http://example.org:9090/plugins/restapi/v1/users/testuser/roster
Endpoint to add a new roster entry to a user
@@ -778,23 +756,22 @@POST /users/{username}/roster
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type application/xml
-
- POST http://example.org:9090/plugins/restapi/v1/users/testuser/rosterHeader: Content-Type application/xml
+POST http://example.org:9090/plugins/restapi/v1/users/testuser/roster
Payload:
Payload Example 1 (required parameters):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<rosterItem>
- <jid>peter@pan.de</jid></rosterItem>
+<rosterItem>
+ <jid>peter@pan.de</jid></rosterItem>
Payload Example 2 (available parameters):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<rosterItem>
- <jid>peter@pan1.de</jid> <nickname>Peter1</nickname> <subscriptionType>3</subscriptionType> <groups> <group>Friends</group> </groups></rosterItem>
+<rosterItem>
+ <jid>peter@pan1.de</jid> <nickname>Peter1</nickname> <subscriptionType>3</subscriptionType> <groups> <group>Friends</group> </groups></rosterItem>
- Endpoint to remove a roster entry from a user
@@ -828,11 +805,10 @@DELETE /users/{username}/roster/{jid}
-Header: Authorization: Basic YWRtaW46MTIzNDU=
--+DELETE http://example.org:9090/plugins/restapi/v1/users/testuser/roster/peter@pan.de
-DELETE http://example.org:9090/plugins/restapi/v1/users/testuser/roster/peter@pan.de
Endpoint to update a roster entry
@@ -866,16 +842,113 @@PUT /users/{username}/roster/{jid}
+Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type application/xml
-
- PUT http://example.org:9090/plugins/restapi/v1/users/testuser/roster/peter@pan.deHeader: Content-Type application/xml
+PUT http://example.org:9090/plugins/restapi/v1/users/testuser/roster/peter@pan.de
+
Payload:
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<rosterItem>
+ <jid>peter@pan.de</jid> <nickname>Peter Pan</nickname> <subscriptionType>0</subscriptionType> <groups> <group>Support</group> </groups></rosterItem>
+
+ Endpoint to get the vCard of a particular user
+++GET /users/{username}/vcard
+
Payload: none
+Return value: vCard XML data
+| Parameter | +Parameter Type | +Description | +Default value | +
|---|---|---|---|
| username | +@Path | +Exact username | ++ |
++Header: Authorization: Basic YWRtaW46MTIzNDU=
+GET http://example.org:9090/plugins/restapi/v1/users/testuser/vcard
+
Endpoint to add or replace a vCard of a particular user.
+++PUT /users/{username}/vcard
+
Payload: vCard XML data
+Return value: HTTP status 200 (Created)
+| Parameter | +Parameter Type | +Description | +Default value | +
|---|---|---|---|
| username | +@Path | +Exact username | ++ |
+Header: Authorization: Basic YWRtaW46MTIzNDU=
+Header: Content-Type application/xml
+POST http://example.org:9090/plugins/restapi/v1/users/testuser/vcard
Payload:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<rosterItem>
- <jid>peter@pan.de</jid> <nickname>Peter Pan</nickname> <subscriptionType>0</subscriptionType> <groups> <group>Support</group> </groups></rosterItem>
+<vCard xmlns="vcard-temp">
+ <N> <FAMILY>Doe</FAMILY> <GIVEN>Janice</GIVEN> <MIDDLE>Francis</MIDDLE> </N> <ORG> <ORGNAME/> <ORGUNIT/> </ORG> <NICKNAME>Jane</NICKNAME> <FN>Janice Francis Doe</FN> <TITLE/> <URL/> <EMAIL> <HOME/> <INTERNET/> <PREF/> <USERID>j.doe@example.org</USERID> </EMAIL> <TEL> <WORK/> <VOICE/> <NUMBER/> </TEL> <TEL> <WORK/> <PAGER/> <NUMBER/> </TEL> <TEL> <WORK/> <FAX/> <NUMBER/> </TEL> <TEL> <WORK/> <CELL/> <NUMBER/> </TEL> <TEL> <HOME/> <VOICE/> <NUMBER/> </TEL> <TEL> <HOME/> <PAGER/> <NUMBER/> </TEL> <TEL> <HOME/> <FAX/> <NUMBER/> </TEL> <TEL> <HOME/> <CELL/> <NUMBER/> </TEL> <ADR> <WORK/> <LOCALITY/> <CTRY/> <STREET/> <PCODE/> <REGION/> </ADR> <ADR> <HOME/> <LOCALITY/> <CTRY/> <STREET/> <PCODE/> <REGION/> </ADR></vCard>
+ Endpoint to remove the vCard of a particular user
+++DELETE /users/{username}/vcard
+
Payload: none
+Return value: none
+| Parameter | +Parameter Type | +Description | +Default value | +
|---|---|---|---|
| username | +@Path | +Exact username | ++ |
+Header: Authorization: Basic YWRtaW46MTIzNDU=
+DELETE http://example.org:9090/plugins/restapi/v1/users/testuser/vcard
+
Endpoint to get all chat services
@@ -885,7 +958,7 @@Payload: none
Return value: Chat services
Possible parameters: none
-Header: Authorization: Basic YWRtaW46MTIzNDU=
GET http://example.org:9090/plugins/restapi/v1/chatservices
@@ -906,8 +979,8 @@XML Examples
Payload Example (available parameters):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<chatService>
- <serviceName>new-chat-service-name</serviceName> <description>A mightily fine service</description> <hidden>false</hidden></chatService>
+<chatService>
+ <serviceName>new-chat-service-name</serviceName> <description>A mightily fine service</description> <hidden>false</hidden></chatService>
@@ -917,15 +990,16 @@JSON Examples
Payload Example (available parameters):
{
- "serviceName": "new-chat-service-name", "description": "A mightily fine service", "hidden": false}
+ "serviceName": "new-chat-service-name", "description": "A mightily fine service", "hidden": false}
- Endpoint to get all chat rooms
GET /chatrooms
Payload: none
Return value: Chatrooms
-| - |
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+GET http://example.org:9090/plugins/restapi/v1/chatrooms
-
- GET http://example.org:9090/plugins/restapi/v1/chatrooms?type=all
- GET http://example.org:9090/plugins/restapi/v1/chatrooms?type=all&servicename=privateconf
- GET http://example.org:9090/plugins/restapi/v1/chatrooms?search=testGET http://example.org:9090/plugins/restapi/v1/chatrooms
+GET http://example.org:9090/plugins/restapi/v1/chatrooms?type=all
+GET http://example.org:9090/plugins/restapi/v1/chatrooms?type=all&servicename=privateconf
+GET http://example.org:9090/plugins/restapi/v1/chatrooms?search=test
Endpoint to get information over specific chat room
@@ -973,7 +1045,7 @@Payload: none
Return value: Chatroom
-| conference | -
-Header: Authorization: Basic YWRtaW46MTIzNDU=
--+GET http://example.org:9090/plugins/restapi/v1/chatrooms/test
-
- GET http://example.org:9090/plugins/restapi/v1/chatrooms/test?servicename=privateconfGET http://example.org:9090/plugins/restapi/v1/chatrooms/test
+GET http://example.org:9090/plugins/restapi/v1/chatrooms/test?servicename=privateconf
Endpoint to get all participants with a role of specified room.
GET /chatrooms/{roomName}/participants
Payload: none
Return value: Participants
-| conference | -
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+GET http://example.org:9090/plugins/restapi/v1/chatrooms/room1/participants
-GET http://example.org:9090/plugins/restapi/v1/chatrooms/room1/participants
Endpoint to get all occupants (all roles / affiliations) of a specified room.
@@ -1051,7 +1120,7 @@Payload: none
Return value: Occupants
-| conference | -
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+GET http://example.org:9090/plugins/restapi/v1/chatrooms/room1/occupants
-GET http://example.org:9090/plugins/restapi/v1/chatrooms/room1/occupants
Endpoint to get the chat message history of a specified room.
@@ -1090,7 +1157,7 @@Payload: none
Return value: Chat History
-Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type: application/xml
-
- POST http://example.org:9090/plugins/restapi/v1/chatroomsHeader: Content-Type: application/xml
+
Payload Example 1 (required parameters):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<chatRoom>
- <naturalName>global-1</naturalName> <roomName>global</roomName> <description>Global Chat Room</description></chatRoom>
+<chatRoom>
+ <naturalName>global-1</naturalName> <roomName>global</roomName> <description>Global Chat Room</description></chatRoom>
Payload Example 2 (available parameters):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<chatRoom>
- <roomName>global</roomName> <naturalName>global-2</naturalName> <description>Global Chat Room</description> <subject>global-2 Subject</subject> <creationDate>2014-02-12T15:52:37.592+01:00</creationDate> <modificationDate>2014-09-12T15:35:54.702+02:00</modificationDate> <maxUsers>0</maxUsers> <persistent>true</persistent> <publicRoom>true</publicRoom> <registrationEnabled>false</registrationEnabled> <canAnyoneDiscoverJID>false</canAnyoneDiscoverJID> <canOccupantsChangeSubject>false</canOccupantsChangeSubject> <canOccupantsInvite>false</canOccupantsInvite> <canChangeNickname>false</canChangeNickname> <logEnabled>true</logEnabled> <loginRestrictedToNickname>false</loginRestrictedToNickname> <membersOnly>false</membersOnly> <moderated>false</moderated> <allowPM>anyone</allowPM> <broadcastPresenceRoles> <broadcastPresenceRole>moderator</broadcastPresenceRole> <broadcastPresenceRole>participant</broadcastPresenceRole> <broadcastPresenceRole>visitor</broadcastPresenceRole> </broadcastPresenceRoles> <owners> <owner>owner@localhost</owner> </owners> <admins> <admin>admin@localhost</admin> </admins> <members> <member>member2@localhost</member> <member>member1@localhost</member> </members> <outcasts> <outcast>outcast1@localhost</outcast> </outcasts></chatRoom>
+<chatRoom>
+ <roomName>global</roomName> <naturalName>global-2</naturalName> <description>Global Chat Room</description> <subject>global-2 Subject</subject> <creationDate>2014-02-12T15:52:37.592+01:00</creationDate> <modificationDate>2014-09-12T15:35:54.702+02:00</modificationDate> <maxUsers>0</maxUsers> <persistent>true</persistent> <publicRoom>true</publicRoom> <registrationEnabled>false</registrationEnabled> <canAnyoneDiscoverJID>false</canAnyoneDiscoverJID> <canOccupantsChangeSubject>false</canOccupantsChangeSubject> <canOccupantsInvite>false</canOccupantsInvite> <canChangeNickname>false</canChangeNickname> <logEnabled>true</logEnabled> <loginRestrictedToNickname>false</loginRestrictedToNickname> <membersOnly>false</membersOnly> <moderated>false</moderated> <allowPM>anyone</allowPM> <broadcastPresenceRoles> <broadcastPresenceRole>moderator</broadcastPresenceRole> <broadcastPresenceRole>participant</broadcastPresenceRole> <broadcastPresenceRole>visitor</broadcastPresenceRole> </broadcastPresenceRoles> <owners> <owner>owner@localhost</owner> </owners> <admins> <admin>admin@localhost</admin> </admins> <members> <member>member2@localhost</member> <member>member1@localhost</member> </members> <outcasts> <outcast>outcast1@localhost</outcast> </outcasts></chatRoom>
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type: application/json
-
- POST http://example.org:9090/plugins/restapi/v1/chatroomsHeader: Content-Type: application/json
+
Payload Example 1 (required parameters):
{
- "roomName": "global", "naturalName": "global-2", "description": "Global chat room"}
+ "roomName": "global", "naturalName": "global-2", "description": "Global chat room"}
Payload Example 2 (available parameters):
{
- "roomName": "global-1", "naturalName": "global-1_test_hello", "description": "Global chat room", "subject": "Global chat room subject", "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", "allowPM": "anyone", "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" ] }}
+ "roomName": "global-1", "naturalName": "global-1_test_hello", "description": "Global chat room", "subject": "Global chat room subject", "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", "allowPM": "anyone", "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" ] }}
REST API Version 1.3.0 and later - Payload Example 2 (available parameters):
{
- "roomName": "global-1", "naturalName": "global-1_test_hello", "description": "Global chat room", "subject": "Global chat room subject", "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", "allowPM": "anyone", "broadcastPresenceRoles": [ "moderator", "participant", "visitor" ], "owners": [ "owner@localhost" ], "admins": [ "admin@localhost" ], "members": [ "member@localhost" ], "outcasts": [ "outcast@localhost" ]}
+ "roomName": "global-1", "naturalName": "global-1_test_hello", "description": "Global chat room", "subject": "Global chat room subject", "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", "allowPM": "anyone", "broadcastPresenceRoles": [ "moderator", "participant", "visitor" ], "owners": [ "owner@localhost" ], "admins": [ "admin@localhost" ], "members": [ "member@localhost" ], "outcasts": [ "outcast@localhost" ]}
Endpoint to create multiple new chat rooms at once.
@@ -1193,13 +1256,13 @@Payload: Chatrooms
Return value: Result list, ordered by successes and failures
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<results>
- <success> <result> <roomName>room1</roomName> <resultType>Success</resultType> <message>Room was successfully created</message> </result> <result> <roomName>room2</roomName> <resultType>Success</resultType> <message>Room was successfully created</message> </result> </success> <failure/> <other/></results>
+<results>
+ <success> <result> <roomName>room1</roomName> <resultType>Success</resultType> <message>Room was successfully created</message> </result> <result> <roomName>room2</roomName> <resultType>Success</resultType> <message>Room was successfully created</message> </result> </success> <failure/> <other/></results>
{
- "success": [ { "roomName": "room1", "resultType": "Success", "message": "Room was successfully created" }, { "roomName": "room2", "resultType": "Success", "message": "Room was successfully created" } ], "failure": [], "other": []}
+ "success": [ { "roomName": "room1", "resultType": "Success", "message": "Room was successfully created" }, { "roomName": "room2", "resultType": "Success", "message": "Room was successfully created" } ], "failure": [], "other": []}
- | conference | -
-Header: Authorization: Basic YWRtaW46MTIzNDU=
--+DELETE http://example.org:9090/plugins/restapi/v1/chatrooms/testroom
-
- DELETE http://example.org:9090/plugins/restapi/v1/chatrooms/testroom?servicename=privateconfDELETE http://example.org:9090/plugins/restapi/v1/chatrooms/testroom
+DELETE http://example.org:9090/plugins/restapi/v1/chatrooms/testroom?servicename=privateconf
Endpoint to update a chat room.
PUT /chatrooms/{roomName}
Payload: Chatroom
Return value: HTTP status 200 (OK)
-| false | -
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type application/xml
-
- PUT http://example.org:9090/plugins/restapi/v1/chatrooms/globalHeader: Content-Type application/xml
+PUT http://example.org:9090/plugins/restapi/v1/chatrooms/global
Payload:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<chatRoom>
- <roomName>global</roomName> <naturalName>global-2</naturalName> <description>Global Chat Room edit</description> <subject>New subject</subject> <password>test</password> <creationDate>2014-02-12T15:52:37.592+01:00</creationDate> <modificationDate>2014-09-12T14:20:56.286+02:00</modificationDate> <maxUsers>0</maxUsers> <persistent>true</persistent> <publicRoom>true</publicRoom> <registrationEnabled>false</registrationEnabled> <canAnyoneDiscoverJID>false</canAnyoneDiscoverJID> <canOccupantsChangeSubject>false</canOccupantsChangeSubject> <canOccupantsInvite>false</canOccupantsInvite> <canChangeNickname>false</canChangeNickname> <logEnabled>true</logEnabled> <loginRestrictedToNickname>false</loginRestrictedToNickname> <membersOnly>false</membersOnly> <moderated>false</moderated> <allowPM>anyone</allowPM> <broadcastPresenceRoles/> <owners> <owner>owner@localhost</owner> </owners> <admins> <admin>admin@localhost</admin> </admins> <members> <member>member2@localhost</member> <member>member1@localhost</member> </members> <outcasts> <outcast>outcast1@localhost</outcast> </outcasts></chatRoom>
+<chatRoom>
+ <roomName>global</roomName> <naturalName>global-2</naturalName> <description>Global Chat Room edit</description> <subject>New subject</subject> <password>test</password> <creationDate>2014-02-12T15:52:37.592+01:00</creationDate> <modificationDate>2014-09-12T14:20:56.286+02:00</modificationDate> <maxUsers>0</maxUsers> <persistent>true</persistent> <publicRoom>true</publicRoom> <registrationEnabled>false</registrationEnabled> <canAnyoneDiscoverJID>false</canAnyoneDiscoverJID> <canOccupantsChangeSubject>false</canOccupantsChangeSubject> <canOccupantsInvite>false</canOccupantsInvite> <canChangeNickname>false</canChangeNickname> <logEnabled>true</logEnabled> <loginRestrictedToNickname>false</loginRestrictedToNickname> <membersOnly>false</membersOnly> <moderated>false</moderated> <allowPM>anyone</allowPM> <broadcastPresenceRoles/> <owners> <owner>owner@localhost</owner> </owners> <admins> <admin>admin@localhost</admin> </admins> <members> <member>member2@localhost</member> <member>member1@localhost</member> </members> <outcasts> <outcast>outcast1@localhost</outcast> </outcasts></chatRoom>
Endpoint to invite a user or a user group to a room.
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type: application/xml
-
- POST http://localhost:9090/plugins/restapi/v1/chatrooms/{roomName}/invite/{name}Header: Content-Type: application/xml
+POST http://localhost:9090/plugins/restapi/v1/chatrooms/{roomName}/invite/{name}
Payload Example:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<mucInvitation>
- <reason>Hello, come to this room, it is nice</reason></mucInvitation>
+<mucInvitation>
+ <reason>Hello, come to this room, it is nice</reason></mucInvitation>
Return value: HTTP status 200 (OK)
-| conference | -
Header: Authorization: Basic YWRtaW46MTIzNDU=
Header: Content-Type application/xml
@@ -1454,8 +1513,8 @@Possible parameters
Return payload:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<members>
- <member>member2@localhost</member> <member>member1@localhost</member></members>
+<members>
+ <member>member2@localhost</member> <member>member1@localhost</member></members>
Endpoint to add a new user with affiliation to a room.
@@ -1464,7 +1523,7 @@Payload: none
Return value: HTTP status 201 (Created)
-| false | -
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type application/xml
-
- POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser
- POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser@openfire.com
- POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/admins/testUser
- POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/members/testUser?sendInvitations=true
- POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/outcasts/testUser
- POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser?servicename=privateconfHeader: Content-Type application/xml
+POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser
+POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser@openfire.com
+POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/admins/testUser
+POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/members/testUser?sendInvitations=true
+POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/outcasts/testUser
+POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser?servicename=privateconf
Endpoint to replace all users with a particular affiliation in a multi-user chat room. Note that a user can only have one type of affiliation with a room. By adding a user using a particular affiliation, any other pre-existing affiliation is removed.
@@ -1527,7 +1584,7 @@Payload: list of affiliations
Return value: HTTP status 201 (Created)
-| false | -
Header: Authorization: Basic YWRtaW46MTIzNDU=
Header: Content-Type application/xml
@@ -1572,8 +1629,8 @@Possible parameters
Request Payload:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<members>
- <member>member2@localhost</member> <member>member1@localhost</member></members>
+<members>
+ <member>member2@localhost</member> <member>member1@localhost</member></members>
Endpoint to add multiple users with an affiliation to a multi-user chat room. Note that a user can only have one type of affiliation with a room. By adding a user using a particular affiliation, any other pre-existing affiliation is removed.
@@ -1582,7 +1639,7 @@Payload: list of affiliations
Return value: HTTP status 201 (Created)
-| false | -
Header: Authorization: Basic YWRtaW46MTIzNDU=
Header: Content-Type application/xml
@@ -1627,8 +1684,8 @@Possible parameters
Request Payload:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<members>
- <member>member2@localhost</member> <member>member1@localhost</member></members>
+<members>
+ <member>member2@localhost</member> <member>member1@localhost</member></members>
Endpoint to add a new group with affiliation to a room.
@@ -1637,7 +1694,7 @@Payload: none
Return value: HTTP status 201 (Created)
-| false | -
-Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type application/xml
-Header: Content-Type application/xml
POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/group/testGroup
--+POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/admins/group/testGroup
-
- POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/members/group/testGroup
- POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/outcasts/group/testGroup
- POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/group/testUser?servicename=privateconfPOST http://example.org:9090/plugins/restapi/v1/chatrooms/global/admins/group/testGroup
+POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/members/group/testGroup
+POST http://example.org:9090/plugins/restapi/v1/chatrooms/global/outcasts/group/testGroup
+
Endpoint to remove a room user affiliation.
DELETE /chatrooms/{roomName}/{affiliations}/{name}
Payload: none
Return value: HTTP status 200 (OK)
-| conference | -
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type application/xml
-
- DELETE http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser
- DELETE http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser@openfire.com
- DELETE http://example.org:9090/plugins/restapi/v1/chatrooms/global/admins/testUser
- DELETE http://example.org:9090/plugins/restapi/v1/chatrooms/global/members/testUser
- DELETE http://example.org:9090/plugins/restapi/v1/chatrooms/global/outcasts/testUser
- DELETE http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser?servicename=privateconfHeader: Content-Type application/xml
+DELETE http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser
+DELETE http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser@openfire.com
+DELETE http://example.org:9090/plugins/restapi/v1/chatrooms/global/admins/testUser
+DELETE http://example.org:9090/plugins/restapi/v1/chatrooms/global/members/testUser
+DELETE http://example.org:9090/plugins/restapi/v1/chatrooms/global/outcasts/testUser
+DELETE http://example.org:9090/plugins/restapi/v1/chatrooms/global/owners/testUser?servicename=privateconf
Endpoint to get all system properties
GET /system/properties
Payload: none
Return value: System properties
--Header: Authorization: Basic YWRtaW46MTIzNDU=
--+GET http://example.org:9090/plugins/restapi/v1/system/properties
-GET http://example.org:9090/plugins/restapi/v1/system/properties
Endpoint to get information over specific system property
GET /system/properties/{propertyName}
Payload: none
Return value: System property
-| - |
-Header: Authorization: Basic YWRtaW46MTIzNDU=
GET http://example.org:9090/plugins/restapi/v1/system/properties/xmpp.domain
Endpoint to create a system property
POST system/properties
Payload: System Property
Return value: HTTP status 201 (Created)
-Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type: application/xml
-
- POST http://example.org:9090/plugins/restapi/v1/system/propertiesHeader: Content-Type: application/xml
+POST http://example.org:9090/plugins/restapi/v1/system/properties
Payload Example:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<property key="propertyName" value="propertyValue"/>
+<property key="propertyName" value="propertyValue"/>
Endpoint to delete a system property
@@ -1819,7 +1870,7 @@Payload: none
Return value: HTTP status 200 (OK)
-| - |
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+DELETE http://example.org:9090/plugins/restapi/v1/system/properties/propertyName
-DELETE http://example.org:9090/plugins/restapi/v1/system/properties/propertyName
Endpoint to update / overwrite a system property
@@ -1852,7 +1901,7 @@Payload: System property
Return value: HTTP status 200 (OK)
-| - |
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type application/xml
-
- PUT http://example.org:9090/plugins/restapi/v1/system/properties/propertyNameHeader: Content-Type application/xml
+PUT http://example.org:9090/plugins/restapi/v1/system/properties/propertyName
Payload:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<property key="propertyName" value="anotherValue"/>
+<property key="propertyName" value="anotherValue"/>
Endpoint to get count of concurrent sessions
@@ -1890,7 +1937,7 @@Payload: none
Return value: Sessions count
-Header: Authorization: Basic YWRtaW46MTIzNDU=
GET http://example.org:9090/plugins/restapi/v1/system/statistics/sessions
@@ -1951,7 +1998,7 @@Perform ‘connections’ readiness
Payload: none
Return value: HTTP status 200 (OK). Any HTTP status outside the range 200-399 indicates failure.
-Endpoint to get all groups
GET /groups
Payload: none
Return value: Groups
--Header: Authorization: Basic YWRtaW46MTIzNDU=
-- -+
Endpoint to get information over specific group
GET /groups/{groupName}
Payload: none
Return value: Group
-| - |
-Header: Authorization: Basic YWRtaW46MTIzNDU=
GET http://example.org:9090/plugins/restapi/v1/groups/moderators
Endpoint to create a new group
POST /groups
Payload: Group
Return value: HTTP status 201 (Created)
-Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type: application/xml
-
- POST http://example.org:9090/plugins/restapi/v1/groupsHeader: Content-Type: application/xml
+
Payload Example:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<group>
- <name>GroupName</name> <description>Some description</description> <isshared>false</isshared></group>
+<group>
+ <name>GroupName</name> <description>Some description</description> <isshared>false</isshared></group>
Endpoint to delete a group
@@ -2046,7 +2092,7 @@Payload: none
Return value: HTTP status 200 (OK)
-| - |
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+DELETE http://example.org:9090/plugins/restapi/v1/groups/groupToDelete
-DELETE http://example.org:9090/plugins/restapi/v1/groups/groupToDelete
Endpoint to update / overwrite a group
@@ -2079,7 +2123,7 @@Payload: Group
Return value: HTTP status 200 (OK)
-| - |
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+Header: Content-Type application/xml
-
- PUT http://example.org:9090/plugins/restapi/v1/groups/groupNameToUpdateHeader: Content-Type application/xml
+PUT http://example.org:9090/plugins/restapi/v1/groups/groupNameToUpdate
Payload:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<group>
- <name>groupNameToUpdate</name> <description>New description</description> <isshared>false</isshared></group>
+<group>
+ <name>groupNameToUpdate</name> <description>New description</description> <isshared>false</isshared></group>
Payload: none
Return value: Sessions
-Header: Authorization: Basic YWRtaW46MTIzNDU=
-- -+
Endpoint to get sessions from a user
@@ -2133,7 +2173,7 @@Payload: none
Return value: Sessions
-| - |
Header: Authorization: Basic YWRtaW46MTIzNDU=
GET http://example.org:9090/plugins/restapi/v1/sessions/testuser
@@ -2164,7 +2204,7 @@Close all user sessions
Payload: none
Return value: HTTP status 200 (OK)
-| - |
Header: Authorization: Basic YWRtaW46MTIzNDU=
DELETE http://example.org:9090/plugins/restapi/v1/sessions/testuser
@@ -2196,17 +2236,15 @@Send a broadcast message
Payload: Message
Return value: HTTP status 201 (Created)
-Header: Authorization: Basic YWRtaW46MTIzNDU=
--+POST http://example.org:9090/plugins/restapi/v1/messages/users
-POST http://example.org:9090/plugins/restapi/v1/messages/users
Payload:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<message>
- <body>Your message</body></message>
+<message>
+ <body>Your message</body></message>
Payload: none
Return value: Security Audit Logs
-| - |
Header: Authorization: Basic YWRtaW46MTIzNDU=
--+GET http://example.org:9090/plugins/restapi/v1/logs/security
-GET http://example.org:9090/plugins/restapi/v1/logs/security
Payload: none
Return value: ClusterNodes
-Header: Authorization: Basic YWRtaW46MTIzNDU=
GET http://example.org:9090/plugins/restapi/v1/clustering/nodes
@@ -2288,7 +2324,7 @@Retrieve information
Payload: none
Return value: ClusterNode
-| - |
Header: Authorization: Basic YWRtaW46MTIzNDU=
GET http://example.org:9090/plugins/restapi/v1/clustering/nodes/52a89928-66f7-45fd-9bb8-096de07400ac
@@ -2319,7 +2355,7 @@Retrieve the Clustering status
Payload: none
Return value: String describing the clustering status of this Openfire instance
-Header: Authorization: Basic YWRtaW46MTIzNDU=
GET http://example.org:9090/plugins/restapi/v1/clustering/status
@@ -2827,15 +2863,15 @@Configuration
Using the Plugin
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 http://example.com/plugins/restapi/userservice
The following parameters can be passed into the request:
-| Name | | Description | |--------------|--------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
- | type | Required | The admin service required. Possible values are ‘add’, ‘delete’, ‘update’, ‘enable’, ‘disable’, ‘add_roster’, ‘update_roster’, ‘delete_roster’, ‘grouplist’, ‘usergrouplist’. |
- | secret | Required | The secret key that allows access to the User Service. |
- | username | Required | The username of the user to ‘add’, ‘delete’, ‘update’, ‘enable’, ‘disable’, ‘add_roster’, ‘update_roster’, ‘delete_roster’. ie the part before the @ symbol. |
- | password | Required for ‘add’ operation | The password of the new user or the user being updated. |
- | name | Optional | 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. |
- | email | Optional | The email address of the new user or the user being updated. |
- | groups | Optional | 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. |
- | item_jid | Required for ‘add_roster’, ‘update_roster’, ‘delete_roster’ operations. | The JID of the roster item |
+| Name | | Description | |--------------|--------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+ | type | Required | The admin service required. Possible values are ‘add’, ‘delete’, ‘update’, ‘enable’, ‘disable’, ‘add_roster’, ‘update_roster’, ‘delete_roster’, ‘grouplist’, ‘usergrouplist’. |
+ | secret | Required | The secret key that allows access to the User Service. |
+ | username | Required | The username of the user to ‘add’, ‘delete’, ‘update’, ‘enable’, ‘disable’, ‘add_roster’, ‘update_roster’, ‘delete_roster’. ie the part before the @ symbol. |
+ | password | Required for ‘add’ operation | The password of the new user or the user being updated. |
+ | name | Optional | 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. |
+ | email | Optional | The email address of the new user or the user being updated. |
+ | groups | Optional | 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. |
+ | item_jid | Required for ‘add_roster’, ‘update_roster’, ‘delete_roster’ operations. | The JID of the roster item |
| subscription | Optional | Type of subscription for ‘add_roster’, ‘update_roster’ operations. Possible numeric values are: -1(remove), 0(none), 1(to), 2(from), 3(both). |Sample HTML
The following example adds a user
@@ -2862,13 +2898,13 @@Sample HTML
http://example.com:9090/plugins/restapi/userservice?type=grouplist&secret=bigsecret
Which replies an XML group list formatted like this:<result> - <groupname>group1</groupname> <groupname>group2</groupname></result> + <groupname>group1</groupname> <groupname>group2</groupname></result>The following example gets all groups for a specific user
http://example.com:9090/plugins/restapi/userservice?type=usergrouplist&secret=bigsecret&username=kafka
Which replies an XML group list formatted like this:<result> - <groupname>usergroup1</groupname> <groupname>usergroup2</groupname></result> + <groupname>usergroup1</groupname> <groupname>usergroup2</groupname></result>When sending double characters (Chinese/Japanese/Korean etc.) you should URLEncode the string as utf8.
diff --git a/readme.md b/readme.md index a07b0e832..a2d8e9447 100644 --- a/readme.md +++ b/readme.md @@ -626,6 +626,148 @@ Endpoint to update a roster entry ``` +## Retrieve user's vcard +Endpoint to get the vCard of a particular user +> **GET** /users/{username}/vcard + +**Payload:** none + +**Return value:** vCard XML data + +### Possible parameters + +| Parameter | Parameter Type | Description | Default value | +|-----------|-----------------|----------------|---------------| +| username | @Path | Exact username | | + +### Examples +>**Header:** Authorization: Basic YWRtaW46MTIzNDU= +> +>**GET** http://example.org:9090/plugins/restapi/v1/users/testuser/vcard + +## Add or update user's vCard +Endpoint to add or replace a vCard of a particular user. +> **PUT** /users/{username}/vcard + +**Payload:** vCard XML data + +**Return value:** HTTP status 200 (Created) + +### Possible parameters + + +| Parameter | Parameter Type | Description | Default value | +|-----------|-----------------|----------------|---------------| +| username | @Path | Exact username | | + +### Examples +>**Header:** Authorization: Basic YWRtaW46MTIzNDU= +> +>**Header:** Content-Type application/xml +> +>**POST** http://example.org:9090/plugins/restapi/v1/users/testuser/vcard + +**Payload:** +```xml + +
In Java this is done like this+ +``` + +## Delete user's vcard +Endpoint to remove the vCard of a particular user +> **DELETE** /users/{username}/vcard + +**Payload:** none + +**Return value:** none + +### Possible parameters + +| Parameter | Parameter Type | Description | Default value | +|-----------|-----------------|----------------|---------------| +| username | @Path | Exact username | | + +### Examples +>**Header:** Authorization: Basic YWRtaW46MTIzNDU= +> +>**DELETE** http://example.org:9090/plugins/restapi/v1/users/testuser/vcard + # Chat room related REST Endpoints ## Retrieve all chat services diff --git a/src/java/org/jivesoftware/openfire/plugin/rest/controller/UserServiceController.java b/src/java/org/jivesoftware/openfire/plugin/rest/controller/UserServiceController.java index c7bde3825..54fd6a239 100644 --- a/src/java/org/jivesoftware/openfire/plugin/rest/controller/UserServiceController.java +++ b/src/java/org/jivesoftware/openfire/plugin/rest/controller/UserServiceController.java @@ -16,6 +16,10 @@ package org.jivesoftware.openfire.plugin.rest.controller; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.DocumentHelper; +import org.dom4j.Element; import org.jivesoftware.openfire.SessionManager; import org.jivesoftware.openfire.SharedGroupException; import org.jivesoftware.openfire.XMPPServer; @@ -37,6 +41,7 @@ import org.jivesoftware.openfire.user.UserAlreadyExistsException; import org.jivesoftware.openfire.user.UserManager; import org.jivesoftware.openfire.user.UserNotFoundException; +import org.jivesoftware.openfire.vcard.VCardManager; import org.jivesoftware.util.JiveGlobals; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,6 +74,8 @@ public class UserServiceController { /** The lock out manager. */ private final LockOutManager lockOutManager; + private final VCardManager vcardManager; + /** * Gets the single instance of UserServiceController. * @@ -98,6 +105,7 @@ private UserServiceController() { userManager = server.getUserManager(); rosterManager = server.getRosterManager(); lockOutManager = server.getLockOutManager(); + vcardManager = server.getVCardManager(); } public static void log(String logMessage) { @@ -611,4 +619,82 @@ private Roster getUserRoster(String username) throws ServiceException { Response.Status.NOT_FOUND, e); } } + + /** + * Retrieves a vCard for a user. + * + * @param username The username for which to return a vcard + * @return A vCard (or null) + */ + public Element getUserVCard(String username) throws ServiceException + { + log("Get user vCard for user: " + username); + if (username.contains("@")) { + final JID jid = new JID(username); + if (jid.getDomain().equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { + username = jid.getNode(); + } else { + // Implementing this would require us to iterate over all groups, which is a performance nightmare. + throw new ServiceException("This service cannot be used for non-local users.", username, ExceptionType.USER_NOT_FOUND_EXCEPTION, Response.Status.INTERNAL_SERVER_ERROR); + } + } + + return vcardManager.getVCard(username); + } + + /** + * Adds or updates a vCard for a user. + * + * @param username The username for which to return a vcard + * @param data The raw XML vCard data + */ + public void setUserVCard(String username, String data) throws ServiceException + { + log("Set user vCard for user: " + username); + if (username.contains("@")) { + final JID jid = new JID(username); + if (jid.getDomain().equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { + username = jid.getNode(); + } else { + // Implementing this would require us to iterate over all groups, which is a performance nightmare. + throw new ServiceException("This service cannot be used for non-local users.", username, ExceptionType.USER_NOT_FOUND_EXCEPTION, Response.Status.INTERNAL_SERVER_ERROR); + } + } + + try { + final Document document = DocumentHelper.parseText(data); + vcardManager.setVCard(username, document.getRootElement()); + } catch (DocumentException e) { + throw new ServiceException("Could not parse the provided data as a vCard", username, ExceptionType.ILLEGAL_ARGUMENT_EXCEPTION, Response.Status.BAD_REQUEST); + } catch (UnsupportedOperationException e) { + throw new ServiceException("Cannot update vCards in the system, as the vCard system is configured to be read-only.", username, ExceptionType.ILLEGAL_ARGUMENT_EXCEPTION, Response.Status.CONFLICT); + } catch (Exception e) { + throw new ServiceException("Unexpected problem while trying to update vCard.", username, ExceptionType.ILLEGAL_ARGUMENT_EXCEPTION, Response.Status.INTERNAL_SERVER_ERROR); + } + } + + /** + * Removes a vCard for a user. + * + * @param username The username for which to return a vcard + */ + public void deleteUserVCard(String username) throws ServiceException + { + log("Get user vCard for user: " + username); + if (username.contains("@")) { + final JID jid = new JID(username); + if (jid.getDomain().equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { + username = jid.getNode(); + } else { + // Implementing this would require us to iterate over all groups, which is a performance nightmare. + throw new ServiceException("This service cannot be used for non-local users.", username, ExceptionType.USER_NOT_FOUND_EXCEPTION, Response.Status.INTERNAL_SERVER_ERROR); + } + } + + try { + vcardManager.deleteVCard(username); + } catch (UnsupportedOperationException e) { + throw new ServiceException("Cannot update vCards in the system, as the vCard system is configured to be read-only.", username, ExceptionType.ILLEGAL_ARGUMENT_EXCEPTION, Response.Status.CONFLICT); + } + } } diff --git a/src/java/org/jivesoftware/openfire/plugin/rest/service/JerseyWrapper.java b/src/java/org/jivesoftware/openfire/plugin/rest/service/JerseyWrapper.java index c61174eb3..1fa6a3314 100644 --- a/src/java/org/jivesoftware/openfire/plugin/rest/service/JerseyWrapper.java +++ b/src/java/org/jivesoftware/openfire/plugin/rest/service/JerseyWrapper.java @@ -115,7 +115,8 @@ public JerseyWrapper(@Context ServletConfig servletConfig) { UserLockoutService.class, UserRosterService.class, UserService.class, - UserServiceLegacy.class + UserServiceLegacy.class, + UserVCardService.class ); // Exception mapper diff --git a/src/java/org/jivesoftware/openfire/plugin/rest/service/UserVCardService.java b/src/java/org/jivesoftware/openfire/plugin/rest/service/UserVCardService.java new file mode 100644 index 000000000..c3ca53926 --- /dev/null +++ b/src/java/org/jivesoftware/openfire/plugin/rest/service/UserVCardService.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2025 Ignite Realtime Foundation + * + * 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.service; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.dom4j.Element; +import org.jivesoftware.openfire.SharedGroupException; +import org.jivesoftware.openfire.plugin.rest.controller.UserServiceController; +import org.jivesoftware.openfire.plugin.rest.entity.RosterItemEntity; +import org.jivesoftware.openfire.plugin.rest.entity.UserGroupsEntity; +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; + +import javax.annotation.PostConstruct; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@Path("restapi/v1/users/{username}/vcard") +@Tag(name = "Users", description = "Managing vCards of Openfire users.") +public class UserVCardService +{ + private UserServiceController plugin; + + @PostConstruct + public void init() { + plugin = UserServiceController.getInstance(); + } + + @GET + @Operation( summary = "Get user's vCard", + description = "Retrieves the vCard for a particular user.", + responses = { + @ApiResponse(responseCode = "200", description = "The vCard of the user"), + @ApiResponse(responseCode = "204", description = "No vCard found.") + }) + @Produces({MediaType.APPLICATION_XML}) + public String getUserVcard( + @Parameter(description = "The username for user for which to return the vcard.", required = true) @PathParam("username") String username) + throws ServiceException + { + final Element el = plugin.getUserVCard(username); + if (el == null) { + return null; + } + return el.asXML(); + } + + @PUT + @Operation( summary = "Update vCard", + description = "Creates or changes a vCard of a particular user.", + responses = { + @ApiResponse(responseCode = "200", description = "The vCard was updated/created."), + @ApiResponse(responseCode = "400", description = "Provided data could not be parsed."), + @ApiResponse(responseCode = "409", description = "Cannot change vCard, as Openfire is configured to have read-only vCards.") + }) + @Consumes({MediaType.APPLICATION_XML}) + public Response setUserVcard( + @Parameter(description = "The username of the user for which the update a roster entry.", required = true) @PathParam("username") String username, + @RequestBody(description = "The updated definition of the vCard.", required = true) String vCard) + throws ServiceException + { + plugin.setUserVCard(username, vCard); + return Response.status(Response.Status.OK).build(); + } + + @DELETE + @Operation( summary = "Delete vCard", + description = "Removes a vCard of a particular user.", + responses = { + @ApiResponse(responseCode = "200", description = "The vCard was deleted."), + @ApiResponse(responseCode = "409", description = "Cannot delete vCard, as Openfire is configured to have read-only vCards.") + }) + public Response deleteUserVcard( + @Parameter(description = "The username of the user for which the update a roster entry.", required = true) @PathParam("username") String username) + throws ServiceException + { + plugin.deleteUserVCard(username); + return Response.status(Response.Status.OK).build(); + } +}+ +Doe +Janice +Francis ++ ++ + Jane +Janice Francis Doe ++ + + ++ + + j.doe@example.org ++ ++ + + + ++ + + + ++ + + + ++ + | + + ++ + + + ++ + + + ++ + + + ++ + | + + ++ + + + + + + ++ + + + + +