diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/history/APIActivityRecord.java b/guacamole/src/main/java/org/apache/guacamole/rest/history/APIActivityRecord.java new file mode 100644 index 000000000..c1a0149d6 --- /dev/null +++ b/guacamole/src/main/java/org/apache/guacamole/rest/history/APIActivityRecord.java @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.guacamole.rest.history; + +import java.util.Date; +import org.apache.guacamole.net.auth.ActivityRecord; + +/** + * A activity record which may be exposed through the REST endpoints. + */ +public class APIActivityRecord { + + /** + * The date and time the activity began. + */ + private final Date startDate; + + /** + * The date and time the activity ended, or null if the activity is + * still in progress or if the end time is unknown. + */ + private final Date endDate; + + /** + * The hostname or IP address of the remote host that performed the + * activity associated with this record, if known. + */ + private final String remoteHost; + + /** + * The name of the user who performed or is performing the activity + * associated with this record. + */ + private final String username; + + /** + * Whether the activity is still in progress. + */ + private final boolean active; + + /** + * Creates a new APIActivityRecord, copying the data from the given activity + * record. + * + * @param record + * The record to copy data from. + */ + public APIActivityRecord(ActivityRecord record) { + this.startDate = record.getStartDate(); + this.endDate = record.getEndDate(); + this.remoteHost = record.getRemoteHost(); + this.username = record.getUsername(); + this.active = record.isActive(); + } + + /** + * Returns the date and time the activity began. + * + * @return + * The date and time the activity began. + */ + public Date getStartDate() { + return startDate; + } + + /** + * Returns the date and time the activity ended, if applicable. + * + * @return + * The date and time the activity ended, or null if the activity is + * still in progress or if the end time is unknown. + */ + public Date getEndDate() { + return endDate; + } + + /** + * Returns the hostname or IP address of the remote host that performed the + * activity associated with this record, if known. + * + * @return + * The hostname or IP address of the remote host that performed the + * activity associated with this record, or null if the remote host is + * unknown. + */ + public String getRemoteHost() { + return remoteHost; + } + + /** + * Returns the name of the user who performed or is performing the activity + * associated with this record. + * + * @return + * The name of the user who performed or is performing the activity + * associated with this record. + */ + public String getUsername() { + return username; + } + + /** + * Returns whether the activity associated with this record is still in + * progress. + * + * @return + * true if the activity associated with this record is still in + * progress, false otherwise. + */ + public boolean isActive() { + return active; + } + +} diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecord.java b/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecord.java index 97c99a04d..9d17fbf83 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecord.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecord.java @@ -19,13 +19,12 @@ package org.apache.guacamole.rest.history; -import java.util.Date; import org.apache.guacamole.net.auth.ConnectionRecord; /** * A connection record which may be exposed through the REST endpoints. */ -public class APIConnectionRecord { +public class APIConnectionRecord extends APIActivityRecord { /** * The identifier of the connection associated with this record. @@ -47,32 +46,6 @@ public class APIConnectionRecord { */ private final String sharingProfileName; - /** - * The date and time the connection began. - */ - private final Date startDate; - - /** - * The date and time the connection ended, or null if the connection is - * still running or if the end time is unknown. - */ - private final Date endDate; - - /** - * The host from which the connection originated, if known. - */ - private final String remoteHost; - - /** - * The name of the user who used or is using the connection. - */ - private final String username; - - /** - * Whether the connection is currently active. - */ - private final boolean active; - /** * Creates a new APIConnectionRecord, copying the data from the given * record. @@ -81,15 +54,11 @@ public class APIConnectionRecord { * The record to copy data from. */ public APIConnectionRecord(ConnectionRecord record) { + super(record); this.connectionIdentifier = record.getConnectionIdentifier(); this.connectionName = record.getConnectionName(); this.sharingProfileIdentifier = record.getSharingProfileIdentifier(); this.sharingProfileName = record.getSharingProfileName(); - this.startDate = record.getStartDate(); - this.endDate = record.getEndDate(); - this.remoteHost = record.getRemoteHost(); - this.username = record.getUsername(); - this.active = record.isActive(); } /** @@ -139,58 +108,4 @@ public class APIConnectionRecord { return sharingProfileName; } - /** - * Returns the date and time the connection began. - * - * @return - * The date and time the connection began. - */ - public Date getStartDate() { - return startDate; - } - - /** - * Returns the date and time the connection ended, if applicable. - * - * @return - * The date and time the connection ended, or null if the connection is - * still running or if the end time is unknown. - */ - public Date getEndDate() { - return endDate; - } - - /** - * Returns the remote host from which this connection originated. - * - * @return - * The remote host from which this connection originated. - */ - public String getRemoteHost() { - return remoteHost; - } - - /** - * Returns the name of the user who used or is using the connection at the - * times given by this connection record. - * - * @return - * The name of the user who used or is using the associated connection. - */ - public String getUsername() { - return username; - } - - /** - * Returns whether the connection associated with this record is still - * active. - * - * @return - * true if the connection associated with this record is still active, - * false otherwise. - */ - public boolean isActive() { - return active; - } - } diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecordSortPredicate.java b/guacamole/src/main/java/org/apache/guacamole/rest/history/APISortPredicate.java similarity index 92% rename from guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecordSortPredicate.java rename to guacamole/src/main/java/org/apache/guacamole/rest/history/APISortPredicate.java index d2281d037..c45ae9a81 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecordSortPredicate.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/history/APISortPredicate.java @@ -25,10 +25,10 @@ import org.apache.guacamole.net.auth.ActivityRecordSet; import org.apache.guacamole.rest.APIException; /** - * A sort predicate which species the property to use when sorting connection + * A sort predicate which species the property to use when sorting activity * records, along with the sort order. */ -public class APIConnectionRecordSortPredicate { +public class APISortPredicate { /** * The prefix which will be included before the name of a sortable property @@ -43,8 +43,8 @@ public class APIConnectionRecordSortPredicate { public enum SortableProperty { /** - * The date that the connection associated with the connection record - * began (connected). + * The date that the activity associated with the activity record + * began. */ startDate(ActivityRecordSet.SortableProperty.START_DATE); @@ -70,7 +70,7 @@ public class APIConnectionRecordSortPredicate { } /** - * The property to use when sorting ConnectionRecords. + * The property to use when sorting ActivityRecords. */ private ActivityRecordSet.SortableProperty property; @@ -93,7 +93,7 @@ public class APIConnectionRecordSortPredicate { * @throws APIException * If the provided sort predicate string is invalid. */ - public APIConnectionRecordSortPredicate(String value) + public APISortPredicate(String value) throws APIException { // Parse whether sort order is descending @@ -124,7 +124,7 @@ public class APIConnectionRecordSortPredicate { * @return * The ActivityRecordSet.SortableProperty which refers to the same * property as the string originally provided when this - * APIConnectionRecordSortPredicate was created. + * APISortPredicate was created. */ public ActivityRecordSet.SortableProperty getProperty() { return property; diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/history/HistoryResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/history/HistoryResource.java index 53a8cdba8..559ebd565 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/history/HistoryResource.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/history/HistoryResource.java @@ -28,6 +28,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.net.auth.ActivityRecord; import org.apache.guacamole.net.auth.ActivityRecordSet; import org.apache.guacamole.net.auth.ConnectionRecord; import org.apache.guacamole.net.auth.UserContext; @@ -88,7 +89,7 @@ public class HistoryResource { @Path("connections") public List getConnectionHistory( @QueryParam("contains") List requiredContents, - @QueryParam("order") List sortPredicates) + @QueryParam("order") List sortPredicates) throws GuacamoleException { // Retrieve overall connection history @@ -101,7 +102,7 @@ public class HistoryResource { } // Sort according to specified ordering - for (APIConnectionRecordSortPredicate predicate : sortPredicates) + for (APISortPredicate predicate : sortPredicates) history = history.sort(predicate.getProperty(), predicate.isDescending()); // Limit to maximum result size @@ -117,4 +118,59 @@ public class HistoryResource { } + /** + * Retrieves the login history for all users, restricted by optional filter + * parameters. + * + * @param requiredContents + * The set of strings that each must occur somewhere within the + * returned user records, whether within the associated username or any + * associated date. If non-empty, any user record not matching each of + * the strings within the collection will be excluded from the results. + * + * @param sortPredicates + * A list of predicates to apply while sorting the resulting user + * records, describing the properties involved and the sort order for + * those properties. + * + * @return + * A list of user records, describing the start and end times of user + * sessions. + * + * @throws GuacamoleException + * If an error occurs while retrieving the user history. + */ + @GET + @Path("users") + public List getUserHistory( + @QueryParam("contains") List requiredContents, + @QueryParam("order") List sortPredicates) + throws GuacamoleException { + + // Retrieve overall user history + ActivityRecordSet history = userContext.getUserHistory(); + + // Restrict to records which contain the specified strings + for (String required : requiredContents) { + if (!required.isEmpty()) + history = history.contains(required); + } + + // Sort according to specified ordering + for (APISortPredicate predicate : sortPredicates) + history = history.sort(predicate.getProperty(), predicate.isDescending()); + + // Limit to maximum result size + history = history.limit(MAXIMUM_HISTORY_SIZE); + + // Convert record set to collection of API user records + List apiRecords = new ArrayList(); + for (ActivityRecord record : history.asCollection()) + apiRecords.add(new APIActivityRecord(record)); + + // Return the converted history + return apiRecords; + + } + }