igniterealtime / openfire-restAPI-plugin

Allows Openfire administration over a RESTful API.
http://www.igniterealtime.org/projects/openfire/plugin-archive.jsp?plugin=restAPI
Apache License 2.0
19 stars 53 forks source link

Backwards compatibility breakage in release 1.7.0 #88

Closed guusdk closed 2 years ago

guusdk commented 2 years ago

PUT restapi/v1/chatrooms/lobby?servicename=conference unrecognized field "broadcastPresenceRoles"

It now seems to want the singular broadcastPresenceRole instead of the plural broadcastPresenceRoles

hassanrazakhalid commented 2 years ago

Yes same api but different error. Current docs and api are not compatible with new version of openfire 4.7.0. I get following exception. This used to work And my request body

{"model":{"RoomBasicInfo":{"roomName":"Sypore Chat","naturalName":"Sypore Chat","description":"Sypore","persistent":true,"moderated":true,"maxUsers":30,"publicRoom":false,"membersOnly":true,"loginRestrictedToNickname":false,"logEnabled":true,"canChangeNickname":true,"subject":"Sypore","owners":["bbf3ef52-c6d3-4b0a-a4a0-f3cd1aaf3f78@hardstoneenterprises.com"],"admins":null,"members":["a3f1a10d-3f9d-4972-8414-222f6b756e65@hardstoneenterprises.com"]}}}

System.Exception: Unrecognized field "owners" (class org.jivesoftware.openfire.plugin.rest.entity.MUCRoomEntity), not marked as ignorable (28 known properties: "moderated", "maxUsers", "memberGroup", "roomName", "registrationEnabled", "ownerGroup", "loginRestrictedToNickname", "canOccupantsInvite", "canAnyoneDiscoverJID", "naturalName", "canOccupantsChangeSubject", "persistent", "member", "password", "logEnabled", "publicRoom", "membersOnly", "modificationDate", "subject", "creationDate", "canChangeNickname", "adminGroup", "broadcastPresenceRole", "owner", "description", "outcast", "admin", "outcastGroup"])
       at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 296] (through reference chain: org.jivesoftware.openfire.plugin.rest.entity.MUCRoomEntity["owners"])
guusdk commented 2 years ago

An effort to create tests that verify backwards compatibility has been started in https://github.com/igniterealtime/openfire-restAPI-plugin/pull/89

To write those tests, I have compared the behavior of various services between several versions of this plugin. I've consistently found that v1.4.0 and v1.6.0 behave the same, while v1.7.0 behaves different. I will include the details of each test in new comments to this issue.

guusdk commented 2 years ago

I've executed these tests to verify what the response is of retrieving all MUC rooms, using the GET /restapi/v1/chatrooms on various combinations of the plugin on Openfire.

First, I created one room, with these settings (using the demoboot server startup):

Room ID: lobby Room name: Lobby Description: Welcome in our lobby! Topic: Introduction to XMPP permissions - owners: admin@example.org permissions - admins: jane@example.org, john@example.org

I've used these commands to get the XML and JSON representation from the service:

curl -X GET --header "Authorization: test" --header "Accept: application/xml"  http://localhost:9090/plugins/restapi/v1/chatrooms
curl -X GET --header "Authorization: test" --header "Accept: application/json"  http://localhost:9090/plugins/restapi/v1/chatrooms

These server/plugin combinations all had the same responses (disregarding the timestamps):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><chatRooms><chatRoom><roomName>lobby</roomName><naturalName>Lobby</naturalName><description>Welcome in our lobby!</description><subject>Introduction to XMPP</subject><creationDate>2022-02-07T18:59:03.309+01:00</creationDate><modificationDate>2022-02-07T18:59:03.314+01:00</modificationDate><maxUsers>30</maxUsers><persistent>true</persistent><publicRoom>true</publicRoom><registrationEnabled>true</registrationEnabled><canAnyoneDiscoverJID>true</canAnyoneDiscoverJID><canOccupantsChangeSubject>false</canOccupantsChangeSubject><canOccupantsInvite>false</canOccupantsInvite><canChangeNickname>true</canChangeNickname><logEnabled>true</logEnabled><loginRestrictedToNickname>false</loginRestrictedToNickname><membersOnly>false</membersOnly><moderated>false</moderated><broadcastPresenceRoles><broadcastPresenceRole>moderator</broadcastPresenceRole><broadcastPresenceRole>participant</broadcastPresenceRole><broadcastPresenceRole>visitor</broadcastPresenceRole></broadcastPresenceRoles><owners><owner>admin@example.org</owner></owners><admins><admin>john@example.org</admin><admin>jane@example.org</admin></admins><members/><outcasts/><ownerGroups/><adminGroups/><memberGroups/><outcastGroups/></chatRoom></chatRooms>
{"chatRooms":[{"roomName":"lobby","naturalName":"Lobby","description":"Welcome in our lobby!","subject":"Introduction to XMPP","creationDate":1644256743309,"modificationDate":1644256743314,"maxUsers":30,"persistent":true,"publicRoom":true,"registrationEnabled":true,"canAnyoneDiscoverJID":true,"canOccupantsChangeSubject":false,"canOccupantsInvite":false,"canChangeNickname":true,"logEnabled":true,"loginRestrictedToNickname":false,"membersOnly":false,"moderated":false,"broadcastPresenceRoles":["moderator","participant","visitor"],"owners":["admin@example.org"],"admins":["john@example.org","jane@example.org"],"members":[],"outcasts":[],"ownerGroups":[],"adminGroups":[],"memberGroups":[],"outcastGroups":[]}]}

Openfire 4.7.0 - rest API 1.7.0 had a different response, but only for the JSON output:


{"chatRoom":[{"roomName":"lobby","naturalName":"Lobby","description":"Welcome in our lobby!","password":null,"subject":"Introduction to XMPP","creationDate":1644257026325,"modificationDate":1644257026349,"maxUsers":30,"persistent":true,"publicRoom":true,"registrationEnabled":true,"canAnyoneDiscoverJID":true,"canOccupantsChangeSubject":false,"canOccupantsInvite":false,"canChangeNickname":true,"logEnabled":true,"loginRestrictedToNickname":false,"membersOnly":false,"moderated":false,"broadcastPresenceRole":["moderator","participant","visitor"],"owner":["admin@example.org"],"admin":["john@example.org","jane@example.org"],"member":[],"outcast":[],"ownerGroup":[],"adminGroup":[],"memberGroup":[],"outcastGroup":[]}]}
guusdk commented 2 years ago

I've executed these tests to verify what the response is of retrieving a specifi MUC room, using GET /restapi/v1/chatrooms/{roomname} on various combinations of the plugin on Openfire.

First, I created one room, with these settings (using the demoboot server startup):

Room ID: lobby Room name: Lobby Description: Welcome in our lobby! Topic: Introduction to XMPP permissions - owners: admin@example.org permissions - admins: jane@example.org, john@example.org

I've used these commands to get the XML and JSON representation from the service:

curl -v -X GET --header "Authorization: test" \
 --header "Accept: application/xml" \
 http://localhost:9090/plugins/restapi/v1/chatrooms/lobby
curl -v -X GET --header "Authorization: test" \
 --header "Accept: application/json" \
 http://localhost:9090/plugins/restapi/v1/chatrooms/lobby 

These server/plugin combinations all had the same responses (disregarding the timestamps):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><chatRoom><roomName>lobby</roomName><naturalName>Lobby</naturalName><description>Welcome in our lobby!</description><subject>Introduction to XMPP</subject><creationDate>2022-02-07T15:38:48.925+01:00</creationDate><modificationDate>2022-02-07T15:38:48.930+01:00</modificationDate><maxUsers>30</maxUsers><persistent>true</persistent><publicRoom>true</publicRoom><registrationEnabled>true</registrationEnabled><canAnyoneDiscoverJID>true</canAnyoneDiscoverJID><canOccupantsChangeSubject>false</canOccupantsChangeSubject><canOccupantsInvite>false</canOccupantsInvite><canChangeNickname>true</canChangeNickname><logEnabled>true</logEnabled><loginRestrictedToNickname>false</loginRestrictedToNickname><membersOnly>false</membersOnly><moderated>false</moderated><broadcastPresenceRoles><broadcastPresenceRole>moderator</broadcastPresenceRole><broadcastPresenceRole>participant</broadcastPresenceRole><broadcastPresenceRole>visitor</broadcastPresenceRole></broadcastPresenceRoles><owners><owner>admin@example.org</owner></owners><admins><admin>john@example.org</admin><admin>jane@example.org</admin></admins><members/><outcasts/><ownerGroups/><adminGroups/><memberGroups/><outcastGroups/></chatRoom>
{"roomName":"lobby","naturalName":"Lobby","description":"Welcome in our lobby!","subject":"Introduction to XMPP","creationDate":1644244728925,"modificationDate":1644244728930,"maxUsers":30,"persistent":true,"publicRoom":true,"registrationEnabled":true,"canAnyoneDiscoverJID":true,"canOccupantsChangeSubject":false,"canOccupantsInvite":false,"canChangeNickname":true,"logEnabled":true,"loginRestrictedToNickname":false,"membersOnly":false,"moderated":false,"broadcastPresenceRoles":["moderator","participant","visitor"],"owners":["admin@example.org"],"admins":["john@example.org","jane@example.org"],"members":[],"outcasts":[],"ownerGroups":[],"adminGroups":[],"memberGroups":[],"outcastGroups":[]}

Openfire 4.7.0 - rest API 1.7.0 had a different response, but only for the JSON output:

{"roomName":"lobby","naturalName":"Lobby","description":"Welcome in our lobby!","password":null,"subject":"Introduction to XMPP","creationDate":1644246591517,"modificationDate":1644246591538,"maxUsers":30,"persistent":true,"publicRoom":true,"registrationEnabled":true,"canAnyoneDiscoverJID":true,"canOccupantsChangeSubject":false,"canOccupantsInvite":false,"canChangeNickname":true,"logEnabled":true,"loginRestrictedToNickname":false,"membersOnly":false,"moderated":false,"broadcastPresenceRole":["moderator","participant","visitor"],"owner":["admin@example.org"],"admin":["john@example.org","jane@example.org"],"member":[],"outcast":[],"ownerGroup":[],"adminGroup":[],"memberGroup":[],"outcastGroup":[]}
guusdk commented 2 years ago

I've executed these tests to verify what the response is of retrieving a user roster, using GET /restapi/v1/users/{username}/roster on various combinations of the plugin on Openfire.

The roster definition is based on the 'jane' user as populated in a 'demoboot' server. It contains exactly one roster item, "John" (john@example.org) without groups, in a two-way subscription state.

I've used these commands to get the XML and JSON representation from the service:

curl -X GET --header "Authorization: test" --header "Accept: application/xml"  http://localhost:9090/plugins/restapi/v1/users/jane/roster
curl -X GET --header "Authorization: test" --header "Accept: application/json"  http://localhost:9090/plugins/restapi/v1/users/jane/roster

These server/plugin combinations all had the same responses:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><roster><rosterItem><jid>john@example.org</jid><nickname>John</nickname><subscriptionType>3</subscriptionType><groups/></rosterItem></roster>
{"rosterItem":[{"jid":"john@example.org","nickname":"John","subscriptionType":3,"groups":[]}]}

Openfire 4.7.0 - rest API 1.7.0 had a different response, but only for the JSON output:

{"rosterItem":[{"jid":"john@example.org","nickname":"John","subscriptionType":3,"group":[]}]}
guusdk commented 2 years ago

I've executed these tests to verify if creating a new chat room, using POST /restapi/v1/chatrooms/ on various combinations of the plugin on Openfire is possible, using the same input.

I've used these commands to send the XML and JSON representation to the service:

curl -v --header "Authorization: test" --header "Accept: application/xml" --header "Content-Type: application/xml" \
  -d '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><chatRoom><roomName>lobby</roomName><naturalName>Lobby</naturalName><description>Welcome in our lobby!</description><subject>Introduction to XMPP</subject><maxUsers>30</maxUsers><persistent>true</persistent><publicRoom>true</publicRoom><registrationEnabled>true</registrationEnabled><canAnyoneDiscoverJID>true</canAnyoneDiscoverJID><canOccupantsChangeSubject>false</canOccupantsChangeSubject><canOccupantsInvite>false</canOccupantsInvite><canChangeNickname>true</canChangeNickname><logEnabled>true</logEnabled><loginRestrictedToNickname>false</loginRestrictedToNickname><membersOnly>false</membersOnly><moderated>false</moderated><broadcastPresenceRoles><broadcastPresenceRole>moderator</broadcastPresenceRole><broadcastPresenceRole>participant</broadcastPresenceRole><broadcastPresenceRole>visitor</broadcastPresenceRole></broadcastPresenceRoles><owners><owner>admin@example.org</owner></owners><admins><admin>john@example.org</admin><admin>jane@example.org</admin></admins><members/><outcasts/><ownerGroups/><adminGroups/><memberGroups/><outcastGroups/></chatRoom>' \
  -X POST http://localhost:9090/plugins/restapi/v1/chatrooms/

curl -v --header "Authorization: test" --header "Accept: application/json" --header "Content-Type: application/json" \
  -d '{"roomName":"lobby","naturalName":"Lobby","description":"Welcome in our lobby!","subject":"Introduction to XMPP","maxUsers":30,"persistent":true,"publicRoom":true,"registrationEnabled":true,"canAnyoneDiscoverJID":true,"canOccupantsChangeSubject":false,"canOccupantsInvite":false,"canChangeNickname":true,"logEnabled":true,"loginRestrictedToNickname":false,"membersOnly":false,"moderated":false,"broadcastPresenceRoles":["moderator","participant","visitor"],"owners":["admin@example.org"],"admins":["john@example.org","jane@example.org"],"members":[],"outcasts":[],"ownerGroups":[],"adminGroups":[],"memberGroups":[],"outcastGroups":[]}' \
  -X POST http://localhost:9090/plugins/restapi/v1/chatrooms/

These server/plugin combinations all had the same responses, which is a empty response, using the 201 CREATED HTTP response status code.

Openfire 4.7.0 - rest API 1.7.0 had a different response, but only for the JSON variant of the request:


JSON: HTTP/1.1 400 Bad Request
Unrecognized field "broadcastPresenceRoles" (class org.jivesoftware.openfire.plugin.rest.entity.MUCRoomEntity), not marked as ignorable (28 known properties: "moderated", "maxUsers", "memberGroup", "roomName", "registrationEnabled", "ownerGroup", "loginRestrictedToNickname", "canOccupantsInvite", "canAnyoneDiscoverJID", "naturalName", "canOccupantsChangeSubject", "persistent", "member", "password", "logEnabled", "publicRoom", "membersOnly", "modificationDate", "subject", "creationDate", "canChangeNickname", "adminGroup", "broadcastPresenceRole", "owner", "description", "outcast", "admin", "outcastGroup"])
* Connection #0 to host localhost left intact
 at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 421] (through reference chain: org.jivesoftware.openfire.plugin.rest.entity.MUCRoomEntity["broadcastPresenceRoles"])```
guusdk commented 2 years ago

I've executed these tests to verify if updating an existing chat room, using PUT /restapi/v1/chatrooms/{roomName} on various combinations of the plugin on Openfire is possible, using the same input.

Before each test, I reset the server to have only one chat room, with these settings (using the demoboot server startup):

Room ID: lobby Room name: Lobby Description: This will be changed!

I've used these commands to update the XML and JSON representation using the service:

curl -v --header "Authorization: test" --header "Accept: application/xml" --header "Content-Type: application/xml" \
  -d '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><chatRoom><roomName>lobby</roomName><naturalName>Lobby</naturalName><description>Welcome in our lobby!</description><subject>Introduction to XMPP</subject><maxUsers>30</maxUsers><persistent>true</persistent><publicRoom>true</publicRoom><registrationEnabled>true</registrationEnabled><canAnyoneDiscoverJID>true</canAnyoneDiscoverJID><canOccupantsChangeSubject>false</canOccupantsChangeSubject><canOccupantsInvite>false</canOccupantsInvite><canChangeNickname>true</canChangeNickname><logEnabled>true</logEnabled><loginRestrictedToNickname>false</loginRestrictedToNickname><membersOnly>false</membersOnly><moderated>false</moderated><broadcastPresenceRoles><broadcastPresenceRole>moderator</broadcastPresenceRole><broadcastPresenceRole>participant</broadcastPresenceRole><broadcastPresenceRole>visitor</broadcastPresenceRole></broadcastPresenceRoles><owners><owner>admin@example.org</owner></owners><admins><admin>john@example.org</admin><admin>jane@example.org</admin></admins><members/><outcasts/><ownerGroups/><adminGroups/><memberGroups/><outcastGroups/></chatRoom>' \
  -X PUT http://localhost:9090/plugins/restapi/v1/chatrooms/lobby

curl -v --header "Authorization: test" --header "Accept: application/json" --header "Content-Type: application/json" \
  -d '{"roomName":"lobby","naturalName":"Lobby","description":"Welcome in our lobby!","subject":"Introduction to XMPP","maxUsers":30,"persistent":true,"publicRoom":true,"registrationEnabled":true,"canAnyoneDiscoverJID":true,"canOccupantsChangeSubject":false,"canOccupantsInvite":false,"canChangeNickname":true,"logEnabled":true,"loginRestrictedToNickname":false,"membersOnly":false,"moderated":false,"broadcastPresenceRoles":["moderator","participant","visitor"],"owners":["admin@example.org"],"admins":["john@example.org","jane@example.org"],"members":[],"outcasts":[],"ownerGroups":[],"adminGroups":[],"memberGroups":[],"outcastGroups":[]}' \
  -X PUT http://localhost:9090/plugins/restapi/v1/chatrooms/lobby

These server/plugin combinations all had the same responses, which is a empty response, using the 200 OK HTTP response status code.

Openfire 4.7.0 - rest API 1.7.0 had a different response, but only for the JSON variant of the request:


HTTP/1.1 400 Bad Request
Unrecognized field "broadcastPresenceRoles" (class org.jivesoftware.openfire.plugin.rest.entity.MUCRoomEntity), not marked as ignorable (28 known properties: "moderated", "maxUsers", "memberGroup", "roomName", "registrationEnabled", "ownerGroup", "loginRestrictedToNickname", "canOccupantsInvite", "canAnyoneDiscoverJID", "naturalName", "canOccupantsChangeSubject", "persistent", "member", "password", "logEnabled", "publicRoom", "membersOnly", "modificationDate", "subject", "creationDate", "canChangeNickname", "adminGroup", "broadcastPresenceRole", "owner", "description", "outcast", "admin", "outcastGroup"])
* Connection #0 to host localhost left intact
 at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 421] (through reference chain: org.jivesoftware.openfire.plugin.rest.entity.MUCRoomEntity["broadcastPresenceRoles"])```
guusdk commented 2 years ago

I've executed these tests to verify if adding a member to an existing chat room, using POST /restapi/v1/chatrooms/{roomName}/members/{user} on various combinations of the plugin on Openfire is possible, using the same input.

Before each test, I reset the server to have only one chat room, with these settings (using the demoboot server startup):

Room ID: lobby Room name: Lobby Description: Welcome to our lobby!

I've used these commands to add a member, using XML and JSON variants of the service (note that no content is sent - this service works using URL parts solely:

curl -v --header "Authorization: test" --header "Accept: application/xml" --header "Content-Type: application/xml" -X POST http://localhost:9090/plugins/restapi/v1/chatrooms/lobby/members/jane
curl -v --header "Authorization: test" --header "Accept: application/xml" --header "Content-Type: application/xml" -X POST http://localhost:9090/plugins/restapi/v1/chatrooms/lobby/members/jane@example.org

curl -v --header "Authorization: test" --header "Accept: application/json" --header "Content-Type: application/json" -X POST http://localhost:9090/plugins/restapi/v1/chatrooms/lobby/members/jane
curl -v --header "Authorization: test" --header "Accept: application/json" --header "Content-Type: application/json" -X POST http://localhost:9090/plugins/restapi/v1/chatrooms/lobby/members/jane@example.org

All server/plugin combinations had the same responses, which is a empty response, using the 201 CREATED HTTP response status code. I tried these combinations:

guusdk commented 2 years ago
curl -v --header "Authorization: test" --header "Accept: application/xml" -X GET http://localhost:9090/plugins/restapi/v1/chatrooms/lobby/occupants
curl -v --header "Authorization: test" --header "Accept: application/json" -X GET http://localhost:9090/plugins/restapi/v1/chatrooms/lobby/occupants

The XML output is similar in versions 1.4.0 and 1.7.0.

The JSON output differs in two ways:

guusdk commented 2 years ago

I've executed these tests to verify if removing a member to an existing chat room, using DELETE /restapi/v1/chatrooms/{roomName}/members/{user} on various combinations of the plugin on Openfire is possible, using the same input.

Before each test, I reset the server to have only one chat room, with these settings (using the demoboot server startup):

Room ID: lobby Room name: Lobby Description: Welcome to our lobby! Member: jane@example.org

I've used these commands to remove the 'jane' member, using XML and JSON variants of the service:

curl -v --header "Authorization: test" --header "Accept: application/xml" -X DELETE http://localhost:9090/plugins/restapi/v1/chatrooms/lobby/members/jane
curl -v --header "Authorization: test" --header "Accept: application/xml" -X DELETE http://localhost:9090/plugins/restapi/v1/chatrooms/lobby/members/jane@example.org
curl -v --header "Authorization: test" --header "Accept: application/json" -X DELETE http://localhost:9090/plugins/restapi/v1/chatrooms/lobby/members/jane
curl -v --header "Authorization: test" --header "Accept: application/json" -X DELETE http://localhost:9090/plugins/restapi/v1/chatrooms/lobby/members/jane@example.org

All server/plugin combinations had the same responses, which is a empty response, using the 200 OK HTTP response status code. I tried these combinations:

guusdk commented 2 years ago

I've executed these tests to verify if adding a member group to an existing chat room, using POST /restapi/v1/chatrooms/{roomName}/members/group/{groupName} on various combinations of the plugin on Openfire is possible, using the same input.

Before each test, I reset the server to have only one chat room, with these settings (using the demoboot server startup):

Room ID: lobby Room name: Lobby Description: Welcome to our lobby!

I've also created a group named "test group", that contains two users: "john@example.org" and "john@example.org."

I've used these commands to add a member, using XML and JSON variants of the service (note that no content is sent - this service works using URL parts solely:

curl -v --header "Authorization: test" --header "Accept: application/xml" --header "Content-Type: application/xml" -X POST http://localhost:9090/plugins/restapi/v1/chatrooms/lobby/members/group/test%20group
curl -v --header "Authorization: test" --header "Accept: application/json" --header "Content-Type: application/json" -X POST http://localhost:9090/plugins/restapi/v1/chatrooms/lobby/members/group/test%20group

All server/plugin combinations had the same responses, which is a empty response, using the 201 CREATED HTTP response status code. I tried these combinations:

guusdk commented 2 years ago

I've executed these tests to verify if removing a member group from an existing chat room, using DELETE /restapi/v1/chatrooms/{roomName}/members/group/{groupName} on various combinations of the plugin on Openfire is possible, using the same input.

Before each test, I reset the server to have only one chat room, with these settings (using the demoboot server startup):

Room ID: lobby Room name: Lobby Description: Welcome to our lobby! Members: "test group@example.org"

I've also created a group named "test group", that contains two users: "john@example.org" and "john@example.org."

I've used these commands to add a member, using XML and JSON variants of the service (note that no content is sent - this service works using URL parts solely:

curl -v --header "Authorization: test" --header "Accept: application/xml" -X DELETE http://localhost:9090/plugins/restapi/v1/chatrooms/lobby/members/group/test%20group
curl -v --header "Authorization: test" --header "Accept: application/json" -X DELETE http://localhost:9090/plugins/restapi/v1/chatrooms/lobby/members/group/test%20group

All server/plugin combinations had the same responses, which is a empty response, using the 200 OK HTTP response status code. I tried these combinations: