GUACAMOLE-462: Add ${HISTORY_PATH} convenience token for automatically placing recordings in the expected location.

This commit is contained in:
Michael Jumper
2022-02-17 12:11:50 -08:00
parent a123eacab5
commit f83ee0c60b
3 changed files with 82 additions and 29 deletions

View File

@@ -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";

View File

@@ -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;
}

View File

@@ -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<String, String> getTokens() throws GuacamoleException {
return Collections.singletonMap(HISTORY_PATH_TOKEN_NAME,
HistoryAuthenticationProvider.getRecordingSearchPath().getAbsolutePath());
}
@Override
protected Map<String, String> getTokens(ConnectionGroup connectionGroup)
throws GuacamoleException {
return getTokens();
}
@Override
protected Map<String, String> getTokens(Connection connection)
throws GuacamoleException {
return getTokens();
}
@Override
public Directory<Connection> getConnectionDirectory() throws GuacamoleException {
return new DecoratingDirectory<Connection>(super.getConnectionDirectory()) {