Skip to content

Commit

Permalink
fixes #67, fixes #1: Migrate to Jersey 2 and Swagger (#70)
Browse files Browse the repository at this point in the history
* fixes #67: Migrate to Jersey 2

This updates the Jersey dependency from 1.x to 2.x.

This commit requires OF-2352 / igniterealtime/Openfire#1945 which means that this PR will _not_ work with 4.7.0 beta (but hopefully will with 4.7.0 non-beta).

* fixes #1: Migrate to Swagger

This commit introduces an automatically generated Swagger-based REST client on /plugins/restapi/docs/index.html
Note that this can't be used 'offline'. We still need to replace the static documentation (in readme.html) with something that's generated during compilation/packaging (issue #71)

* Add Swagger annotations to document endpoints

By adding certain annotations, the documentation as generated by Swagger becomes enriched.

* Add JsonProperty matching XmlElementWrapper name
* Add JsonProperty annotation for a user's groupnames

Co-authored-by: Dan Caseley <[email protected]>
  • Loading branch information
guusdk and Fishbowler authored Jan 16, 2022
1 parent eeae470 commit 5ced36b
Show file tree
Hide file tree
Showing 55 changed files with 1,246 additions and 454 deletions.
4 changes: 3 additions & 1 deletion changelog.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ <h1>

<p><b>1.7.0</b> (tbd)</p>
<ul>
<li>This plugin now requires Openfire 4.7.0-beta or later</li>
<li>Requires Openfire 4.7.0</li>
<li>[<a href='https://github.com/igniterealtime/openfire-restAPI-plugin/issues/1'>#1</a>] - Migrate to Swagger.</li>
<li>[<a href='https://github.com/igniterealtime/openfire-restAPI-plugin/issues/25'>#25</a>] - Java 11 Jaxb issue</li>
<li>[<a href='https://github.com/igniterealtime/openfire-restAPI-plugin/issues/39'>#39</a>] - Requests fail when using XML as accept type on Openfire servers running java 11</li>
<li>[<a href='https://github.com/igniterealtime/openfire-restAPI-plugin/issues/67'>#67</a>] - Updated Jersey dependency to 2.35.</li>
<li>[<a href='https://github.com/igniterealtime/openfire-restAPI-plugin/issues/68'>#68</a>] - Fix for incompatibility with Openfire v4.7.0-beta and later</li>
<li>[<a href='https://github.com/igniterealtime/openfire-restAPI-plugin/issues/77'>#77</a>] - Add dependency checking</li>
</ul>
Expand Down
2 changes: 1 addition & 1 deletion plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<description>Allows administration over a RESTful API.</description>
<author>Roman Soldatow</author>
<version>${project.version}</version>
<date>12/17/2021</date>
<date>01/07/2022</date>
<minServerVersion>4.7.0</minServerVersion>
<adminconsole>
<tab id="tab-server">
Expand Down
70 changes: 32 additions & 38 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
<description>Allows administration over a RESTful API.</description>

<properties>
<jackson.version>2.12.1</jackson.version>
<jersey.version>1.19.4</jersey.version>
<jersey.version>2.35</jersey.version>
</properties>

<developers>
Expand All @@ -38,45 +37,40 @@

<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>${jackson.version}</version>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-jetty-http</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>${jackson.version}</version>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-jetty-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-jaxb</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-jaxrs2</artifactId>
<version>2.1.11</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-jaxrs2-servlet-initializer-v2</artifactId>
<version>2.1.11</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>

<profiles>
Expand Down
33 changes: 18 additions & 15 deletions src/java/org/jivesoftware/openfire/plugin/rest/AuthFilter.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package org.jivesoftware.openfire.plugin.rest;

import javax.annotation.Priority;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Priorities;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response.Status;

Expand All @@ -14,12 +19,13 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerRequestFilter;
import java.io.IOException;

/**
* The Class AuthFilter.
*/
@PreMatching
@Priority(Priorities.AUTHORIZATION)
public class AuthFilter implements ContainerRequestFilter {

/** The log. */
Expand All @@ -33,15 +39,13 @@ public class AuthFilter implements ContainerRequestFilter {
private RESTServicePlugin plugin = (RESTServicePlugin) XMPPServer.getInstance().getPluginManager()
.getPlugin("restapi");

/*
* (non-Javadoc)
*
* @see
* com.sun.jersey.spi.container.ContainerRequestFilter#filter(com.sun.jersey
* .spi.container.ContainerRequest)
*/
@Override
public ContainerRequest filter(ContainerRequest containerRequest) throws WebApplicationException {
public void filter(ContainerRequestContext containerRequest) throws IOException {
if (containerRequest.getUriInfo().getRequestUri().getPath().equals("/plugins/restapi/v1/openapi.yaml")) {
LOG.debug("Authentication was bypassed for openapi.yaml file (documentation)");
return;
}

if (!plugin.isEnabled()) {
LOG.debug("REST API Plugin is not enabled");
throw new WebApplicationException(Status.FORBIDDEN);
Expand All @@ -50,13 +54,13 @@ public ContainerRequest filter(ContainerRequest containerRequest) throws WebAppl
// Let the preflight request through the authentication
if ("OPTIONS".equals(containerRequest.getMethod())) {
LOG.debug("Authentication was bypassed because of OPTIONS request");
return containerRequest;
return;
}

// To be backwards compatible to userservice 1.*
if ("restapi/v1/userservice".equals(containerRequest.getPath())) {
if (containerRequest.getUriInfo().getRequestUri().getPath().contains("restapi/v1/userservice")) {
LOG.info("Deprecated 'userservice' endpoint was used. Please switch to the new endpoints");
return containerRequest;
return;
}

if (!plugin.getAllowedIPs().isEmpty()) {
Expand All @@ -78,7 +82,7 @@ public ContainerRequest filter(ContainerRequest containerRequest) throws WebAppl
}

// Get the authentication passed in HTTP headers parameters
String auth = containerRequest.getHeaderValue("authorization");
String auth = containerRequest.getHeaderString("authorization");

if (auth == null) {
throw new WebApplicationException(Status.UNAUTHORIZED);
Expand Down Expand Up @@ -119,6 +123,5 @@ public ContainerRequest filter(ContainerRequest containerRequest) throws WebAppl
throw new WebApplicationException(Status.UNAUTHORIZED);
}
}
return containerRequest;
}
}
27 changes: 12 additions & 15 deletions src/java/org/jivesoftware/openfire/plugin/rest/CORSFilter.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
package org.jivesoftware.openfire.plugin.rest;

import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;
import javax.annotation.Priority;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import java.io.IOException;

/**
* The Class CORSFilter.
*/
@Priority(Priorities.HEADER_DECORATOR)
public class CORSFilter implements ContainerResponseFilter {

/* (non-Javadoc)
* @see com.sun.jersey.spi.container.ContainerResponseFilter#filter(com.sun.jersey.spi.container.ContainerRequest, com.sun.jersey.spi.container.ContainerResponse)
*/
@Override
public ContainerResponse filter(ContainerRequest request, ContainerResponse response) {
response.getHttpHeaders().add("Access-Control-Allow-Origin", "*");
response.getHttpHeaders().add("Access-Control-Allow-Headers",
"origin, content-type, accept, authorization");
response.getHttpHeaders().add("Access-Control-Allow-Credentials", "true");
response.getHttpHeaders().add("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS, HEAD");

return response;
public void filter(ContainerRequestContext requestContext, ContainerResponseContext response) throws IOException {
response.getHeaders().add("Access-Control-Allow-Origin", "*");
response.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
response.getHeaders().add("Access-Control-Allow-Credentials", "true");
response.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import javax.ws.rs.core.Response;

import org.jivesoftware.admin.AuthCheckFilter;
import org.jivesoftware.openfire.container.Plugin;
import org.jivesoftware.openfire.container.PluginManager;
import org.jivesoftware.openfire.plugin.rest.entity.SystemProperties;
Expand Down Expand Up @@ -112,12 +113,17 @@ public void initializePlugin(PluginManager manager, File pluginDirectory) {
setServiceLoggingEnabled(JiveGlobals.getBooleanProperty(SERVICE_LOGGING_ENABLED, false));
// Listen to system property events
PropertyEventDispatcher.addListener(this);

// Exclude this servlet from requering the user to login
AuthCheckFilter.addExclude(JerseyWrapper.SERVLET_URL);
}

/* (non-Javadoc)
* @see org.jivesoftware.openfire.container.Plugin#destroyPlugin()
*/
public void destroyPlugin() {
// Release the excluded URL
AuthCheckFilter.removeExclude(JerseyWrapper.SERVLET_URL);
// Stop listening to system property events
PropertyEventDispatcher.removeListener(this);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package org.jivesoftware.openfire.plugin.rest.entity;

import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.List;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import org.codehaus.jackson.annotate.JsonProperty;

/**
* The Class GroupEntities.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jivesoftware.openfire.plugin.rest.entity;

import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.List;

import javax.xml.bind.annotation.XmlElement;
Expand Down Expand Up @@ -92,6 +94,7 @@ public void setDescription(String description) {
*/
@XmlElementWrapper(name = "admins")
@XmlElement(name = "admin")
@JsonProperty(value = "admins")
public List<String> getAdmins() {
return admins;
}
Expand All @@ -103,6 +106,7 @@ public List<String> getAdmins() {
*/
@XmlElementWrapper(name = "members")
@XmlElement(name = "member")
@JsonProperty(value = "members")
public List<String> getMembers() {
return members;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package org.jivesoftware.openfire.plugin.rest.entity;

import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.List;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import org.codehaus.jackson.annotate.JsonProperty;

@XmlRootElement(name = "chatRooms")
public class MUCRoomEntities {
List<MUCRoomEntity> mucRooms;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jivesoftware.openfire.plugin.rest.entity;

import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.Date;
import java.util.List;

Expand Down Expand Up @@ -239,18 +241,21 @@ public void setModerated(boolean moderated) {

@XmlElement(name = "broadcastPresenceRole")
@XmlElementWrapper(name = "broadcastPresenceRoles")
@JsonProperty(value = "broadcastPresenceRoles")
public List<String> getBroadcastPresenceRoles() {
return broadcastPresenceRoles;
}

@XmlElementWrapper(name = "owners")
@XmlElement(name = "owner")
@JsonProperty(value = "owners")
public List<String> getOwners() {
return owners;
}

@XmlElementWrapper(name = "ownerGroups")
@XmlElement(name = "ownerGroup")
@JsonProperty(value = "ownerGroups")
public List<String> getOwnerGroups() {
return ownerGroups;
}
Expand All @@ -265,12 +270,14 @@ public void setOwnerGroups(List<String> ownerGroups) {

@XmlElementWrapper(name = "members")
@XmlElement(name = "member")
@JsonProperty(value = "members")
public List<String> getMembers() {
return members;
}

@XmlElementWrapper(name = "memberGroups")
@XmlElement(name = "memberGroup")
@JsonProperty(value = "memberGroups")
public List<String> getmemberGroups() {
return memberGroups;
}
Expand All @@ -285,12 +292,14 @@ public void setMemberGroups(List<String> memberGroups) {

@XmlElementWrapper(name = "outcasts")
@XmlElement(name = "outcast")
@JsonProperty(value = "outcasts")
public List<String> getOutcasts() {
return outcasts;
}

@XmlElementWrapper(name = "outcastGroups")
@XmlElement(name = "outcastGroup")
@JsonProperty(value = "outcastGroups")
public List<String> getoutcastGroups() {
return outcastGroups;
}
Expand All @@ -305,12 +314,14 @@ public void setOutcastGroups(List<String> outcastGroups) {

@XmlElementWrapper(name = "admins")
@XmlElement(name = "admin")
@JsonProperty(value = "admins")
public List<String> getAdmins() {
return admins;
}

@XmlElementWrapper(name = "adminGroups")
@XmlElement(name = "adminGroup")
@JsonProperty(value = "adminGroups")
public List<String> getadminGroups() {
return adminGroups;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package org.jivesoftware.openfire.plugin.rest.entity;

import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import org.codehaus.jackson.annotate.JsonProperty;
import java.util.List;

@XmlRootElement(name = "occupants")
public class OccupantEntities {
Expand Down
Loading

0 comments on commit 5ced36b

Please sign in to comment.