From f83ee0c60b953c05ee48950d25a05ff3127b985a Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 17 Feb 2022 12:11:50 -0800 Subject: [PATCH] GUACAMOLE-462: Add ${HISTORY_PATH} convenience token for automatically placing recordings in the expected location. --- .../HistoryAuthenticationProvider.java | 40 ++++++++++++++++++ .../connection/HistoryConnectionRecord.java | 29 +------------ .../history/user/HistoryUserContext.java | 42 ++++++++++++++++++- 3 files changed, 82 insertions(+), 29 deletions(-) diff --git a/extensions/guacamole-history-recording-storage/src/main/java/org/apache/guacamole/history/HistoryAuthenticationProvider.java b/extensions/guacamole-history-recording-storage/src/main/java/org/apache/guacamole/history/HistoryAuthenticationProvider.java index 61c551956..43f4424f2 100644 --- a/extensions/guacamole-history-recording-storage/src/main/java/org/apache/guacamole/history/HistoryAuthenticationProvider.java +++ b/extensions/guacamole-history-recording-storage/src/main/java/org/apache/guacamole/history/HistoryAuthenticationProvider.java @@ -19,12 +19,16 @@ package org.apache.guacamole.history; +import java.io.File; import org.apache.guacamole.history.user.HistoryUserContext; import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.environment.Environment; +import org.apache.guacamole.environment.LocalEnvironment; import org.apache.guacamole.net.auth.AbstractAuthenticationProvider; import org.apache.guacamole.net.auth.AuthenticatedUser; import org.apache.guacamole.net.auth.Credentials; import org.apache.guacamole.net.auth.UserContext; +import org.apache.guacamole.properties.FileGuacamoleProperty; /** * AuthenticationProvider implementation which automatically associates history @@ -34,6 +38,42 @@ import org.apache.guacamole.net.auth.UserContext; */ public class HistoryAuthenticationProvider extends AbstractAuthenticationProvider { + /** + * The default directory to search for associated session recordings, if + * not overridden with the "recording-search-path" property. + */ + private static final File DEFAULT_RECORDING_SEARCH_PATH = new File("/var/lib/guacamole/recordings"); + + /** + * The directory to search for associated session recordings. By default, + * "/var/lib/guacamole/recordings" will be used. + */ + private static final FileGuacamoleProperty RECORDING_SEARCH_PATH = new FileGuacamoleProperty() { + + @Override + public String getName() { + return "recording-search-path"; + } + + }; + + /** + * Returns the directory that should be searched for session recordings + * associated with history entries. + * + * @return + * The directory that should be searched for session recordings + * associated with history entries. + * + * @throws GuacamoleException + * If the "recording-search-path" property cannot be parsed. + */ + public static File getRecordingSearchPath() throws GuacamoleException { + Environment environment = LocalEnvironment.getInstance(); + return environment.getProperty(RECORDING_SEARCH_PATH, + DEFAULT_RECORDING_SEARCH_PATH); + } + @Override public String getIdentifier() { return "recording-storage"; diff --git a/extensions/guacamole-history-recording-storage/src/main/java/org/apache/guacamole/history/connection/HistoryConnectionRecord.java b/extensions/guacamole-history-recording-storage/src/main/java/org/apache/guacamole/history/connection/HistoryConnectionRecord.java index 13c76bd6a..676682130 100644 --- a/extensions/guacamole-history-recording-storage/src/main/java/org/apache/guacamole/history/connection/HistoryConnectionRecord.java +++ b/extensions/guacamole-history-recording-storage/src/main/java/org/apache/guacamole/history/connection/HistoryConnectionRecord.java @@ -32,8 +32,7 @@ import java.util.HashMap; import java.util.Map; import java.util.UUID; import org.apache.guacamole.GuacamoleException; -import org.apache.guacamole.environment.Environment; -import org.apache.guacamole.environment.LocalEnvironment; +import org.apache.guacamole.history.HistoryAuthenticationProvider; import org.apache.guacamole.io.GuacamoleReader; import org.apache.guacamole.io.ReaderGuacamoleReader; import org.apache.guacamole.language.TranslatableMessage; @@ -41,7 +40,6 @@ import org.apache.guacamole.net.auth.ActivityLog; import org.apache.guacamole.net.auth.ConnectionRecord; import org.apache.guacamole.net.auth.DelegatingConnectionRecord; import org.apache.guacamole.net.auth.FileActivityLog; -import org.apache.guacamole.properties.FileGuacamoleProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,25 +64,6 @@ public class HistoryConnectionRecord extends DelegatingConnectionRecord { */ private static final String TIMING_FILE_SUFFIX = ".timing"; - /** - * The default directory to search for associated session recordings, if - * not overridden with the "recording-search-path" property. - */ - private static final File DEFAULT_RECORDING_SEARCH_PATH = new File("/var/lib/guacamole/recordings"); - - /** - * The directory to search for associated session recordings. By default, - * "/var/lib/guacamole/recordings" will be used. - */ - private static final FileGuacamoleProperty RECORDING_SEARCH_PATH = new FileGuacamoleProperty() { - - @Override - public String getName() { - return "recording-search-path"; - } - - }; - /** * The recording file associated with the wrapped connection record. This * may be a single file or a directory that may contain any number of @@ -106,12 +85,8 @@ public class HistoryConnectionRecord extends DelegatingConnectionRecord { public HistoryConnectionRecord(ConnectionRecord record) throws GuacamoleException { super(record); - Environment environment = LocalEnvironment.getInstance(); - File recordingPath = environment.getProperty(RECORDING_SEARCH_PATH, - DEFAULT_RECORDING_SEARCH_PATH); - String uuid = record.getUUID().toString(); - File recordingFile = new File(recordingPath, uuid); + File recordingFile = new File(HistoryAuthenticationProvider.getRecordingSearchPath(), uuid); this.recording = recordingFile.canRead() ? recordingFile : null; } diff --git a/extensions/guacamole-history-recording-storage/src/main/java/org/apache/guacamole/history/user/HistoryUserContext.java b/extensions/guacamole-history-recording-storage/src/main/java/org/apache/guacamole/history/user/HistoryUserContext.java index 62d639698..a103a6e5e 100644 --- a/extensions/guacamole-history-recording-storage/src/main/java/org/apache/guacamole/history/user/HistoryUserContext.java +++ b/extensions/guacamole-history-recording-storage/src/main/java/org/apache/guacamole/history/user/HistoryUserContext.java @@ -19,15 +19,19 @@ package org.apache.guacamole.history.user; +import java.util.Collections; +import java.util.Map; import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.history.HistoryAuthenticationProvider; import org.apache.guacamole.history.connection.HistoryConnection; import org.apache.guacamole.history.connection.RecordedConnectionActivityRecordSet; import org.apache.guacamole.net.auth.ActivityRecordSet; import org.apache.guacamole.net.auth.Connection; +import org.apache.guacamole.net.auth.ConnectionGroup; import org.apache.guacamole.net.auth.ConnectionRecord; import org.apache.guacamole.net.auth.DecoratingDirectory; -import org.apache.guacamole.net.auth.DelegatingUserContext; import org.apache.guacamole.net.auth.Directory; +import org.apache.guacamole.net.auth.TokenInjectingUserContext; import org.apache.guacamole.net.auth.User; import org.apache.guacamole.net.auth.UserContext; @@ -35,8 +39,14 @@ import org.apache.guacamole.net.auth.UserContext; * UserContext implementation that automatically defines ActivityLogs for * files that relate to history entries. */ -public class HistoryUserContext extends DelegatingUserContext { +public class HistoryUserContext extends TokenInjectingUserContext { + /** + * The name of the parameter token that contains the automatically-searched + * history recording/log path. + */ + private static final String HISTORY_PATH_TOKEN_NAME = "HISTORY_PATH"; + /** * The current Guacamole user. */ @@ -58,6 +68,34 @@ public class HistoryUserContext extends DelegatingUserContext { this.currentUser = currentUser; } + /** + * Returns the tokens which should be added to an in-progress call to + * connect() for any Connectable object. + * + * @return + * The tokens which should be added to the in-progress call to + * connect(). + * + * @throws GuacamoleException + * If the relevant tokens cannot be generated. + */ + private Map getTokens() throws GuacamoleException { + return Collections.singletonMap(HISTORY_PATH_TOKEN_NAME, + HistoryAuthenticationProvider.getRecordingSearchPath().getAbsolutePath()); + } + + @Override + protected Map getTokens(ConnectionGroup connectionGroup) + throws GuacamoleException { + return getTokens(); + } + + @Override + protected Map getTokens(Connection connection) + throws GuacamoleException { + return getTokens(); + } + @Override public Directory getConnectionDirectory() throws GuacamoleException { return new DecoratingDirectory(super.getConnectionDirectory()) {