Commit fada075d authored by Roman Soldatow's avatar Roman Soldatow Committed by daryl herzmann

Updating the REST API Plugin to 1.3.0 (#1039)

* Updating the REST API Plugin to 1.3.0

Added: Security Audit endpoint to get the security logs
Added: More details by error
Improvement: Better JSON mapping (e.g. single element in an array bug)

* Adding missing libs for the ANT job

* Fixing the date for the plugin

2018 instead if 2017
parent b35e03da
...@@ -44,6 +44,13 @@ ...@@ -44,6 +44,13 @@
REST API Plugin Changelog REST API Plugin Changelog
</h1> </h1>
<p><b>1.3.0</b> -- March 7th, 2018</p>
<ul>
<li>Added: Security Audit endpoint to get the security logs</li>
<li>Added: More details by error</li>
<li>Improvement: Better JSON mapping (e.g. single element in an array bug)</li>
</ul>
<p><b>1.2.6</b> -- May 31, 2017</p> <p><b>1.2.6</b> -- May 31, 2017</p>
<ul> <ul>
<li>Updated to match new API in Openfire 4.2.0</li> <li>Updated to match new API in Openfire 4.2.0</li>
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
<name>REST API</name> <name>REST API</name>
<description>Allows administration over a RESTful API.</description> <description>Allows administration over a RESTful API.</description>
<author>Roman Soldatow</author> <author>Roman Soldatow</author>
<version>1.2.6</version> <version>1.3.0</version>
<date>05/31/2017</date> <date>03/07/2018</date>
<minServerVersion>4.1.0</minServerVersion> <minServerVersion>4.1.0</minServerVersion>
<adminconsole> <adminconsole>
<tab id="tab-server"> <tab id="tab-server">
......
...@@ -8,9 +8,16 @@ ...@@ -8,9 +8,16 @@
</parent> </parent>
<groupId>org.igniterealtime.openfire.plugins</groupId> <groupId>org.igniterealtime.openfire.plugins</groupId>
<artifactId>restAPI</artifactId> <artifactId>restAPI</artifactId>
<version>1.2.6</version> <version>1.3.0</version>
<name>Rest API Plugin</name> <name>Rest API Plugin</name>
<description>Allows administration over a RESTful API.</description> <description>Allows administration over a RESTful API.</description>
<developers>
<developer>
<name>Roman Soldatow</name>
</developer>
</developers>
<build> <build>
<sourceDirectory>src/java</sourceDirectory> <sourceDirectory>src/java</sourceDirectory>
...@@ -18,15 +25,45 @@ ...@@ -18,15 +25,45 @@
<plugin> <plugin>
<artifactId>maven-assembly-plugin</artifactId> <artifactId>maven-assembly-plugin</artifactId>
</plugin> </plugin>
<!-- Compiles the Openfire Admin Console JSP pages. -->
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jspc-maven-plugin</artifactId>
</plugin>
</plugins> </plugins>
</build> </build>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>com.sun.jersey</groupId> <groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId> <artifactId>jersey-client</artifactId>
<version>1.18.1</version> <version>1.19.4</version>
</dependency> </dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.19.4</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.19.4</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.19.4</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.19.4</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies> </dependencies>
</project> </project>
This source diff could not be displayed because it is too large. You can view the blob instead.
package org.jivesoftware.openfire.plugin.rest.controller;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.ws.rs.core.Response;
import org.jivesoftware.openfire.plugin.rest.entity.SecurityAuditLog;
import org.jivesoftware.openfire.plugin.rest.entity.SecurityAuditLogs;
import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException;
import org.jivesoftware.openfire.security.AuditWriteOnlyException;
import org.jivesoftware.openfire.security.SecurityAuditEvent;
import org.jivesoftware.openfire.security.SecurityAuditManager;
public class SecurityAuditLogController {
public static final SecurityAuditLogController INSTANCE = new SecurityAuditLogController();
public static SecurityAuditLogController getInstance() {
return INSTANCE;
}
public SecurityAuditLogs getSecurityAuditLogs(String username, int offset, int limit, long startTimeTimeStamp,
long endTimeTimeStamp) throws ServiceException {
Date startTime = null;
Date endTime = null;
if (startTimeTimeStamp != 0) {
startTime = new Date(startTimeTimeStamp * 1000);
}
if (endTimeTimeStamp != 0) {
endTime = new Date(endTimeTimeStamp * 1000);
}
List<SecurityAuditEvent> events = new ArrayList<SecurityAuditEvent>();
try {
events = SecurityAuditManager.getInstance().getEvents(username, offset, limit, startTime, endTime);
} catch (AuditWriteOnlyException e) {
throw new ServiceException("Could not get security audit logs, because the permission is set to write only",
"SecurityLogs", "AuditWriteOnlyException", Response.Status.FORBIDDEN);
}
List<SecurityAuditLog> securityAuditLogs = new ArrayList<SecurityAuditLog>();
for (SecurityAuditEvent event : events) {
SecurityAuditLog log = new SecurityAuditLog(event.getMsgID(), event.getUsername(), event.getEventStamp().getTime() / 1000, event.getSummary(), event.getNode(), event.getDetails());
securityAuditLogs.add(log);
}
return new SecurityAuditLogs(securityAuditLogs);
}
}
...@@ -5,6 +5,8 @@ import java.util.List; ...@@ -5,6 +5,8 @@ import java.util.List;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonProperty;
/** /**
* The Class GroupEntities. * The Class GroupEntities.
*/ */
...@@ -35,6 +37,7 @@ public class GroupEntities { ...@@ -35,6 +37,7 @@ public class GroupEntities {
* @return the groups * @return the groups
*/ */
@XmlElement(name = "group") @XmlElement(name = "group")
@JsonProperty(value = "groups")
public List<GroupEntity> getGroups() { public List<GroupEntity> getGroups() {
return groups; return groups;
} }
......
...@@ -5,6 +5,8 @@ import java.util.List; ...@@ -5,6 +5,8 @@ import java.util.List;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonProperty;
@XmlRootElement(name = "chatRooms") @XmlRootElement(name = "chatRooms")
public class MUCRoomEntities { public class MUCRoomEntities {
List<MUCRoomEntity> mucRooms; List<MUCRoomEntity> mucRooms;
...@@ -17,6 +19,7 @@ public class MUCRoomEntities { ...@@ -17,6 +19,7 @@ public class MUCRoomEntities {
} }
@XmlElement(name = "chatRoom") @XmlElement(name = "chatRoom")
@JsonProperty(value = "chatRooms")
public List<MUCRoomEntity> getMucRooms() { public List<MUCRoomEntity> getMucRooms() {
return mucRooms; return mucRooms;
} }
......
...@@ -5,6 +5,8 @@ import java.util.List; ...@@ -5,6 +5,8 @@ import java.util.List;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonProperty;
@XmlRootElement(name = "occupants") @XmlRootElement(name = "occupants")
public class OccupantEntities { public class OccupantEntities {
List<OccupantEntity> occupants; List<OccupantEntity> occupants;
...@@ -17,6 +19,7 @@ public class OccupantEntities { ...@@ -17,6 +19,7 @@ public class OccupantEntities {
} }
@XmlElement(name = "occupant") @XmlElement(name = "occupant")
@JsonProperty(value = "occupants")
public List<OccupantEntity> getOccupants() { public List<OccupantEntity> getOccupants() {
return occupants; return occupants;
} }
......
...@@ -5,6 +5,8 @@ import java.util.List; ...@@ -5,6 +5,8 @@ import java.util.List;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonProperty;
@XmlRootElement(name = "participants") @XmlRootElement(name = "participants")
public class ParticipantEntities { public class ParticipantEntities {
List<ParticipantEntity> participants; List<ParticipantEntity> participants;
...@@ -17,6 +19,7 @@ public class ParticipantEntities { ...@@ -17,6 +19,7 @@ public class ParticipantEntities {
} }
@XmlElement(name = "participant") @XmlElement(name = "participant")
@JsonProperty(value = "participants")
public List<ParticipantEntity> getParticipants() { public List<ParticipantEntity> getParticipants() {
return participants; return participants;
} }
......
package org.jivesoftware.openfire.plugin.rest.entity;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* The Class SecurityAuditLog.
*/
@XmlRootElement(name = "log")
public class SecurityAuditLog {
/** The log id. */
private long logId;
/** The username. */
private String username;
/** The timestamp. */
private long timestamp;
/** The summary. */
private String summary;
/** The node. */
private String node;
/** The details. */
private String details;
/**
* Instantiates a new security audit log.
*/
public SecurityAuditLog() {
}
/**
* Instantiates a new security audit log.
*
* @param logId the log id
* @param username the username
* @param timestamp the timestamp
* @param summary the summary
* @param node the node
* @param details the details
*/
public SecurityAuditLog(long logId, String username, long timestamp, String summary, String node, String details) {
this.logId = logId;
this.username = username;
this.timestamp = timestamp;
this.summary = summary;
this.node = node;
this.details = details;
}
/**
* Gets the log id.
*
* @return the log id
*/
@XmlElement
public long getLogId() {
return logId;
}
/**
* Sets the log id.
*
* @param logId the new log id
*/
public void setLogId(long logId) {
this.logId = logId;
}
/**
* Gets the username.
*
* @return the username
*/
@XmlElement
public String getUsername() {
return username;
}
/**
* Sets the username.
*
* @param username the new username
*/
public void setUsername(String username) {
this.username = username;
}
/**
* Gets the timestamp.
*
* @return the timestamp
*/
@XmlElement
public long getTimestamp() {
return timestamp;
}
/**
* Sets the timestamp.
*
* @param timestamp the new timestamp
*/
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
/**
* Gets the summary.
*
* @return the summary
*/
@XmlElement
public String getSummary() {
return summary;
}
/**
* Sets the summary.
*
* @param summary the new summary
*/
public void setSummary(String summary) {
this.summary = summary;
}
/**
* Gets the node.
*
* @return the node
*/
@XmlElement
public String getNode() {
return node;
}
/**
* Sets the node.
*
* @param node the new node
*/
public void setNode(String node) {
this.node = node;
}
/**
* Gets the details.
*
* @return the details
*/
@XmlElement
public String getDetails() {
return details;
}
/**
* Sets the details.
*
* @param details the new details
*/
public void setDetails(String details) {
this.details = details;
}
}
package org.jivesoftware.openfire.plugin.rest.entity;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonProperty;
@XmlRootElement(name = "logs")
public class SecurityAuditLogs {
List<SecurityAuditLog> securityAuditLog;
public SecurityAuditLogs() {
}
public SecurityAuditLogs(List<SecurityAuditLog> securityAuditLog) {
this.securityAuditLog = securityAuditLog;
}
@XmlElement(name = "log")
@JsonProperty(value = "logs")
public List<SecurityAuditLog> getSecurityAuditLog() {
return securityAuditLog;
}
public void setSecurityAuditLog(List<SecurityAuditLog> securityAuditLog) {
this.securityAuditLog = securityAuditLog;
}
}
...@@ -5,6 +5,8 @@ import java.util.List; ...@@ -5,6 +5,8 @@ import java.util.List;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonProperty;
@XmlRootElement(name = "sessions") @XmlRootElement(name = "sessions")
public class SessionEntities { public class SessionEntities {
List<SessionEntity> sessions; List<SessionEntity> sessions;
...@@ -17,6 +19,7 @@ public class SessionEntities { ...@@ -17,6 +19,7 @@ public class SessionEntities {
} }
@XmlElement(name = "session") @XmlElement(name = "session")
@JsonProperty(value = "sessions")
public List<SessionEntity> getSessions() { public List<SessionEntity> getSessions() {
return sessions; return sessions;
} }
......
...@@ -5,6 +5,8 @@ import java.util.List; ...@@ -5,6 +5,8 @@ import java.util.List;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonProperty;
/** /**
* The Class UserEntities. * The Class UserEntities.
*/ */
...@@ -37,6 +39,7 @@ public class UserEntities { ...@@ -37,6 +39,7 @@ public class UserEntities {
* @return the users * @return the users
*/ */
@XmlElement(name = "user") @XmlElement(name = "user")
@JsonProperty(value = "users")
public List<UserEntity> getUsers() { public List<UserEntity> getUsers() {
return users; return users;
} }
......
package org.jivesoftware.openfire.plugin.rest.exceptions; package org.jivesoftware.openfire.plugin.rest.exceptions;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
/** /**
...@@ -8,91 +9,91 @@ import javax.xml.bind.annotation.XmlRootElement; ...@@ -8,91 +9,91 @@ import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "error") @XmlRootElement(name = "error")
public class ErrorResponse { public class ErrorResponse {
/** The resource. */ /** The resource. */
private String resource; private String resource;
/** The message. */ /** The message. */
private String message; private String message;
/** The exception. */ /** The exception. */
private String exception; private String exception;
/** The exception stack. */ /** The exception stack. */
private String exceptionStack; private String exceptionStack;
/** /**
* Gets the resource. * Gets the resource.
* *
* @return the resource * @return the resource
*/ */
public String getResource() { @XmlElement(name = "resource")
return resource; public String getResource() {
} return resource;
}
/** /**
* Sets the resource. * Sets the resource.
* *
* @param resource * @param ressource the new resource
* the new resource */
*/ public void setResource(String resource) {
public void setResource(String resource) { this.resource = resource;
this.resource = resource; }
}
/** /**
* Gets the message. * Gets the message.
* *
* @return the message * @return the message
*/ */
public String getMessage() { @XmlElement(name = "message")
return message; public String getMessage() {
} return message;
}
/** /**
* Sets the message. * Sets the message.
* *
* @param message * @param message the new message
* the new message */
*/ public void setMessage(String message) {
public void setMessage(String message) { this.message = message;
this.message = message; }
}
/** /**
* Gets the exception. * Gets the exception.
* *
* @return the exception * @return the exception
*/ */
public String getException() { @XmlElement(name = "exception")
return exception; public String getException() {
} return exception;
}
/** /**
* Sets the exception. * Sets the exception.
* *
* @param exception * @param exception the new exception
* the new exception */
*/ public void setException(String exception) {
public void setException(String exception) { this.exception = exception;
this.exception = exception; }
}
/** /**
* Gets the exception stack. * Gets the exception stack.
* *
* @return the exception stack * @return the exception stack
*/ */
public String getExceptionStack() { @XmlElement(name = "exceptionStack")
return exceptionStack; public String getExceptionStack() {
} return exceptionStack;
}
/** /**
* Sets the exception stack. * Sets the exception stack.
* *
* @param exceptionStack * @param exceptionStack the new exception stack
* the new exception stack */
*/ public void setExceptionStack(String exceptionStack) {
public void setExceptionStack(String exceptionStack) { this.exceptionStack = exceptionStack;
this.exceptionStack = exceptionStack; }
} }
} \ No newline at end of file
...@@ -5,9 +5,6 @@ import java.util.Map; ...@@ -5,9 +5,6 @@ import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.lang.ClassNotFoundException;
import java.lang.Class;
import javax.servlet.ServletConfig; import javax.servlet.ServletConfig;
import javax.servlet.ServletException; import javax.servlet.ServletException;
...@@ -71,6 +68,8 @@ public class JerseyWrapper extends ServletContainer { ...@@ -71,6 +68,8 @@ public class JerseyWrapper extends ServletContainer {
JERSEY_LOGGER.setLevel(Level.SEVERE); JERSEY_LOGGER.setLevel(Level.SEVERE);
config = new HashMap<String, Object>(); config = new HashMap<String, Object>();
config.put(RESOURCE_CONFIG_CLASS_KEY, RESOURCE_CONFIG_CLASS); config.put(RESOURCE_CONFIG_CLASS_KEY, RESOURCE_CONFIG_CLASS);
config.put("com.sun.jersey.api.json.POJOMappingFeature", true);
prc = new PackagesResourceConfig(SCAN_PACKAGE_DEFAULT); prc = new PackagesResourceConfig(SCAN_PACKAGE_DEFAULT);
prc.setPropertiesAndFeatures(config); prc.setPropertiesAndFeatures(config);
prc.getProperties().put(CONTAINER_RESPONSE_FILTERS, CORSFILTER); prc.getProperties().put(CONTAINER_RESPONSE_FILTERS, CORSFILTER);
...@@ -95,6 +94,7 @@ public class JerseyWrapper extends ServletContainer { ...@@ -95,6 +94,7 @@ public class JerseyWrapper extends ServletContainer {
prc.getClasses().add(MsgArchiveService.class); prc.getClasses().add(MsgArchiveService.class);
prc.getClasses().add(StatisticsService.class); prc.getClasses().add(StatisticsService.class);
prc.getClasses().add(MessageService.class); prc.getClasses().add(MessageService.class);
prc.getClasses().add(SecurityAuditLogService.class);
prc.getClasses().add(RESTExceptionMapper.class); prc.getClasses().add(RESTExceptionMapper.class);
} }
......
package org.jivesoftware.openfire.plugin.rest.service;
import javax.annotation.PostConstruct;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jivesoftware.openfire.plugin.rest.controller.SecurityAuditLogController;
import org.jivesoftware.openfire.plugin.rest.entity.SecurityAuditLogs;
import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException;
@Path("restapi/v1/logs/security")
public class SecurityAuditLogService {
private SecurityAuditLogController securityAuditLogController;
@PostConstruct
public void init() {
securityAuditLogController = SecurityAuditLogController.getInstance();
}
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public SecurityAuditLogs getSecurityAuditLogs(@QueryParam("username") String username,
@QueryParam("offset") int offset,
@DefaultValue("100") @QueryParam("limit") int limit, @QueryParam("startTime") long startTime,
@QueryParam("endTime") long endTime) throws ServiceException {
return securityAuditLogController.getSecurityAuditLogs(username, offset, limit, startTime, endTime);
}
}
...@@ -181,7 +181,7 @@ ...@@ -181,7 +181,7 @@
<p>You can find here detailed documentation over the Openfire REST API: <p>You can find here detailed documentation over the Openfire REST API:
<a <a
href="/plugin-admin.jsp?plugin=restapi&showReadme=true&decorator=none">REST href="/plugin-showfile.jsp?plugin=restapi&showReadme=true&decorator=none">REST
API Documentation</a> API Documentation</a>
</p> </p>
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment