diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLAuthenticationProvider.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLAuthenticationProvider.java index f3ec72410..34c7f6d43 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLAuthenticationProvider.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLAuthenticationProvider.java @@ -30,6 +30,7 @@ import com.google.inject.Module; import com.google.inject.name.Names; import java.util.Properties; import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionMapper; +import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionRecordMapper; import net.sourceforge.guacamole.net.auth.mysql.dao.ParameterMapper; import net.sourceforge.guacamole.net.auth.mysql.dao.SystemPermissionMapper; import org.glyptodon.guacamole.GuacamoleException; @@ -144,6 +145,7 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider { // Add MyBatis mappers addMapperClass(ConnectionMapper.class); + addMapperClass(ConnectionRecordMapper.class); addMapperClass(ParameterMapper.class); addMapperClass(SystemPermissionMapper.class); addMapperClass(UserMapper.class); diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnection.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnection.java index fed0d4660..1e938c08b 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnection.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnection.java @@ -24,7 +24,6 @@ package net.sourceforge.guacamole.net.auth.mysql; import com.google.inject.Inject; import com.google.inject.Provider; -import java.util.Collections; import java.util.List; import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionModel; import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionService; @@ -181,8 +180,7 @@ public class MySQLConnection implements Connection, DirectoryObject getHistory() throws GuacamoleException { - /* STUB */ - return Collections.EMPTY_LIST; + return connectionService.retrieveHistory(currentUser, this.getIdentifier()); } @Override diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnectionRecord.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnectionRecord.java index e723f89b6..27fcb5a42 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnectionRecord.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnectionRecord.java @@ -24,72 +24,52 @@ package net.sourceforge.guacamole.net.auth.mysql; import java.util.Date; +import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionRecordModel; import org.glyptodon.guacamole.net.auth.ConnectionRecord; /** * A ConnectionRecord which is based on data stored in MySQL. * * @author James Muehlner + * @author Michael Jumper */ public class MySQLConnectionRecord implements ConnectionRecord { /** - * The start date of the ConnectionRecord. + * The model object backing this connection record. */ - private Date startDate; + private ConnectionRecordModel model; /** - * The end date of the ConnectionRecord. + * Creates a new MySQLConnectionRecord backed by the given model object. + * Changes to this record will affect the backing model object, and changes + * to the backing model object will affect this record. + * + * @param model + * The model object to use to back this connection record. */ - private Date endDate; - - /** - * The name of the user that is associated with this ConnectionRecord. - */ - private String username; - - /** - * Whether this connection is currently active. - */ - private boolean active; - - /** - * Initialize this MySQLConnectionRecord with the start/end dates, - * and the name of the user it represents. - * - * @param startDate The start date of the connection history. - * @param endDate The end date of the connection history. - * @param username The name of the user that used the connection. - * @param active Whether the connection is currently active. - */ - public MySQLConnectionRecord(Date startDate, Date endDate, - String username, boolean active) { - if (startDate != null) this.startDate = new Date(startDate.getTime()); - if (endDate != null) this.endDate = new Date(endDate.getTime()); - this.username = username; - this.active = active; + public MySQLConnectionRecord(ConnectionRecordModel model) { + this.model = model; } @Override public Date getStartDate() { - if (startDate == null) return null; - return new Date(startDate.getTime()); + return model.getStartDate(); } @Override public Date getEndDate() { - if (endDate == null) return null; - return new Date(endDate.getTime()); + return model.getEndDate(); } @Override public String getUsername() { - return username; + return model.getUsername(); } @Override public boolean isActive() { - return active; + return false; } } diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/dao/ConnectionRecordMapper.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/dao/ConnectionRecordMapper.java new file mode 100644 index 000000000..a584d3fbf --- /dev/null +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/dao/ConnectionRecordMapper.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2015 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package net.sourceforge.guacamole.net.auth.mysql.dao; + +import java.util.List; +import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionRecordModel; +import org.apache.ibatis.annotations.Param; + +/** + * Mapper for connection record objects. + * + * @author Michael Jumper + */ +public interface ConnectionRecordMapper { + + /** + * Returns a collection of all connection records associated with the + * connection having the given identifier. + * + * @param identifier + * The identifier of the connection whose records are to be retrieved. + * + * @return + * A collection of all connection records associated with the + * connection having the given identifier. This collection will be + * empty if no such connection exists. + */ + List select(@Param("identifier") String identifier); + + /** + * Inserts the given connection record. + * + * @param record + * The connection record to insert. + * + * @return + * The number of rows inserted. + */ + int insert(@Param("record") ConnectionRecordModel record); + +} diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/model/ConnectionRecordModel.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/model/ConnectionRecordModel.java new file mode 100644 index 000000000..200918da7 --- /dev/null +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/model/ConnectionRecordModel.java @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2015 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package net.sourceforge.guacamole.net.auth.mysql.model; + +import java.util.Date; + +/** + * A single connection record representing a past usage of a particular + * connection. + * + * @author Michael Jumper + */ +public class ConnectionRecordModel { + + /** + * The identifier of the connection associated with this connection record. + */ + private String connectionIdentifier; + + /** + * The database ID of the user associated with this connection record. + */ + private Integer userID; + + /** + * The username of the user associated with this connection record. + */ + private String username; + + /** + * The time the connection was initiated by the associated user. + */ + private Date startDate; + + /** + * The time the connection ended, or null if the end time is not known or + * the connection is still running. + */ + private Date endDate; + + /** + * Returns the identifier of the connection associated with this connection + * record. + * + * @return + * The identifier of the connection associated with this connection + * record. + */ + public String getConnectionIdentifier() { + return connectionIdentifier; + } + + /** + * Sets the identifier of the connection associated with this connection + * record. + * + * @param connectionIdentifier + * The identifier of the connection to associate with this connection + * record. + */ + public void setConnectionIdentifier(String connectionIdentifier) { + this.connectionIdentifier = connectionIdentifier; + } + + /** + * Returns the database ID of the user associated with this connection + * record. + * + * @return + * The database ID of the user associated with this connection record. + */ + public Integer getUserID() { + return userID; + } + + /** + * Sets the database ID of the user associated with this connection record. + * + * @param userID + * The database ID of the user to associate with this connection + * record. + */ + public void setUserID(Integer userID) { + this.userID = userID; + } + + /** + * Returns the username of the user associated with this connection record. + * + * @return + * The username of the user associated with this connection record. + */ + public String getUsername() { + return username; + } + + /** + * Sets the username of the user associated with this connection record. + * + * @param username + * The username of the user to associate with this connection record. + */ + public void setUsername(String username) { + this.username = username; + } + + /** + * Returns the date that the associated connection was established. + * + * @return + * The date the associated connection was established. + */ + public Date getStartDate() { + return startDate; + } + + /** + * Sets the date that the associated connection was established. + * + * @param startDate + * The date that the associated connection was established. + */ + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + /** + * Returns the date that the associated connection ended, or null if no + * end date was recorded. The lack of an end date does not necessarily + * mean that the connection is still active. + * + * @return + * The date the associated connection ended, or null if no end date was + * recorded. + */ + public Date getEndDate() { + return endDate; + } + + /** + * Sets the date that the associated connection ended. + * + * @param endDate + * The date that the associated connection ended. + */ + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + +} diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java index 38dd55559..a18fc468e 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java @@ -27,14 +27,18 @@ import com.google.inject.Provider; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; import net.sourceforge.guacamole.net.auth.mysql.AuthenticatedUser; import net.sourceforge.guacamole.net.auth.mysql.MySQLConnection; +import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionRecord; import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionMapper; +import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionRecordMapper; import net.sourceforge.guacamole.net.auth.mysql.dao.DirectoryObjectMapper; import net.sourceforge.guacamole.net.auth.mysql.dao.ParameterMapper; import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionModel; +import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionRecordModel; import net.sourceforge.guacamole.net.auth.mysql.model.ParameterModel; import org.glyptodon.guacamole.GuacamoleClientException; import org.glyptodon.guacamole.GuacamoleException; @@ -67,6 +71,12 @@ public class ConnectionService extends DirectoryObjectService retrieveHistory(AuthenticatedUser user, + String identifier) throws GuacamoleException { + + // Retrieve history only if READ permission is granted + if (hasObjectPermission(user, identifier, ObjectPermission.Type.READ)) { + + // Retrieve history + List models = connectionRecordMapper.select(identifier); + + // Convert model objects into standard records + List records = new ArrayList(models.size()); + for (ConnectionRecordModel model : models) + records.add(new MySQLConnectionRecord(model)); + + // Return converted history list + return records; + + } + + // The user does not have permission to read the history + throw new GuacamoleSecurityException("Permission denied."); + + } /** * Connects to the given connection as the given user, using the given diff --git a/extensions/guacamole-auth-mysql/src/main/resources/net/sourceforge/guacamole/net/auth/mysql/dao/ConnectionRecordMapper.xml b/extensions/guacamole-auth-mysql/src/main/resources/net/sourceforge/guacamole/net/auth/mysql/dao/ConnectionRecordMapper.xml new file mode 100644 index 000000000..24ba70408 --- /dev/null +++ b/extensions/guacamole-auth-mysql/src/main/resources/net/sourceforge/guacamole/net/auth/mysql/dao/ConnectionRecordMapper.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + INSERT INTO guacamole_connection_history ( + connection_id, + user_id, + start_date, + end_date + ) + VALUES ( + #{record.connectionIdentifier,jdbcType=VARCHAR}, + #{record.userID,jdbcType=INTEGER}, + #{record.startDate,jdbcType=TIMESTAMP}, + #{record.endDate,jdbcType=TIMESTAMP} + ) + + + + \ No newline at end of file