Add .gitignore and .ratignore files for various directories
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
gyurix
2025-04-29 21:43:12 +02:00
parent 983ecbfc53
commit be9f66dee9
2167 changed files with 254128 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
src/main/resources/generated/
target/
*~

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.guacamole</groupId>
<artifactId>guacamole-history-recording-storage</artifactId>
<packaging>jar</packaging>
<version>1.6.0</version>
<name>guacamole-history-recording-storage</name>
<url>http://guacamole.apache.org/</url>
<parent>
<groupId>org.apache.guacamole</groupId>
<artifactId>extensions</artifactId>
<version>1.6.0</version>
<relativePath>../</relativePath>
</parent>
<dependencies>
<!-- Guacamole Extension API -->
<dependency>
<groupId>org.apache.guacamole</groupId>
<artifactId>guacamole-ext</artifactId>
<version>1.6.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>dist</id>
<baseDirectory>${project.artifactId}-${project.version}</baseDirectory>
<!-- Output tar.gz -->
<formats>
<format>tar.gz</format>
</formats>
<!-- Include licenses and extension .jar -->
<fileSets>
<!-- Include licenses -->
<fileSet>
<outputDirectory></outputDirectory>
<directory>target/licenses</directory>
</fileSet>
<!-- Include extension .jar -->
<fileSet>
<directory>target</directory>
<outputDirectory></outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
</fileSets>
</assembly>

View File

@@ -0,0 +1,89 @@
/*
* 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.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
* entries with session recordings, typescripts, etc. History association is
* determined by matching the history entry UUID with the filenames of files
* located within a standardized/configurable directory.
*/
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";
}
@Override
public UserContext decorate(UserContext context,
AuthenticatedUser authenticatedUser, Credentials credentials)
throws GuacamoleException {
return new HistoryUserContext(context.self(), context);
}
}

View File

@@ -0,0 +1,71 @@
/*
* 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.history.connection;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.net.auth.ActivityRecordSet;
import org.apache.guacamole.net.auth.Connection;
import org.apache.guacamole.net.auth.ConnectionRecord;
import org.apache.guacamole.net.auth.DelegatingConnection;
import org.apache.guacamole.net.auth.User;
/**
* Connection implementation that automatically defines ActivityLogs for
* files that relate to history entries associated with the wrapped connection.
*/
public class HistoryConnection extends DelegatingConnection {
/**
* The current Guacamole user.
*/
private final User currentUser;
/**
* Creates a new HistoryConnection that wraps the given connection,
* automatically associating history entries with ActivityLogs based on
* related files (session recordings, typescripts, etc.).
*
* @param currentUser
* The current Guacamole user.
*
* @param connection
* The connection to wrap.
*/
public HistoryConnection(User currentUser, Connection connection) {
super(connection);
this.currentUser = currentUser;
}
/**
* Returns the connection wrapped by this HistoryConnection.
*
* @return
* The connection wrapped by this HistoryConnection.
*/
public Connection getWrappedConnection() {
return getDelegateConnection();
}
@Override
public ActivityRecordSet<ConnectionRecord> getConnectionHistory() throws GuacamoleException {
return new RecordedConnectionActivityRecordSet(currentUser, super.getConnectionHistory());
}
}

View File

@@ -0,0 +1,329 @@
/*
* 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.history.connection;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.history.HistoryAuthenticationProvider;
import org.apache.guacamole.io.GuacamoleReader;
import org.apache.guacamole.io.ReaderGuacamoleReader;
import org.apache.guacamole.language.TranslatableMessage;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* ConnectionRecord implementation that automatically defines ActivityLogs for
* files that relate to the wrapped record.
*/
public class HistoryConnectionRecord extends DelegatingConnectionRecord {
/**
* Logger for this class.
*/
private static final Logger logger = LoggerFactory.getLogger(HistoryConnectionRecord.class);
/**
* The namespace for URL UUIDs as defined by RFC 4122.
*/
private static final UUID UUID_NAMESPACE_URL = UUID.fromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8");
/**
* The filename suffix of typescript timing files.
*/
private static final String TIMING_FILE_SUFFIX = ".timing";
/**
* The recording file associated with the wrapped connection record. This
* may be a single file or a directory that may contain any number of
* relevant recordings.
*/
private final File recording;
/**
* Returns the file or directory providing recording storage for the given
* history record. If no such file or directory exists, or the file cannot
* be read, null is returned.
*
* @param record
* The ConnectionRecord whose associated recording storage file
* or directory should be returned.
*
* @return
* A File pointing to the file or directory providing recording storage
* for the given history record, or null if no such file exists.
*
* @throws GuacamoleException
* If the configured path for stored recordings cannot be read.
*/
private static File getRecordingFile(ConnectionRecord record) throws GuacamoleException {
UUID uuid = record.getUUID();
if (uuid != null) {
File recordingFile = new File(HistoryAuthenticationProvider.getRecordingSearchPath(), uuid.toString());
if (recordingFile.canRead())
return recordingFile;
}
return null;
}
/**
* Creates a new HistoryConnectionRecord that wraps the given
* ConnectionRecord, automatically associating ActivityLogs based on
* related files (session recordings, typescripts, etc.).
*
* @param record
* The ConnectionRecord to wrap.
*
* @throws GuacamoleException
* If the configured path for stored recordings cannot be read.
*/
public HistoryConnectionRecord(ConnectionRecord record) throws GuacamoleException {
super(record);
this.recording = getRecordingFile(record);
}
/**
* Returns whether the given file appears to be a Guacamole session
* recording. As there is no standard extension for session recordings,
* this is determined by attempting to read a single Guacamole instruction
* from the file.
*
* @param file
* The file to test.
*
* @return
* true if the file appears to be a Guacamole session recording, false
* otherwise.
*/
private boolean isSessionRecording(File file) {
Reader reader = null;
try {
reader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);
GuacamoleReader guacReader = new ReaderGuacamoleReader(reader);
if (guacReader.readInstruction() != null)
return true;
}
catch (GuacamoleException e) {
logger.debug("File \"{}\" does not appear to be a session "
+ "recording, as it could not be parsed as Guacamole "
+ "protocol data.", file, e);
}
catch (IOException e) {
logger.warn("Possible session recording \"{}\" could not be "
+ "identified as it cannot be read: {}", file, e.getMessage());
logger.debug("Possible session recording \"{}\" could not be read.", file, e);
}
finally {
// If the reader was successfully constructed, close it
if (reader != null) {
try {
reader.close();
}
catch (IOException e) {
logger.warn("Unexpected error closing recording file \"{}\": {}",
file, e.getMessage());
logger.debug("Session recording file \"{}\" could not be closed.",
file, e);
}
}
}
return false;
}
/**
* Returns whether the given file appears to be a typescript (text
* recording of a terminal session). As there is no standard extension for
* session recordings, this is determined by testing whether there is an
* associated timing file. Guacamole will always include a timing file for
* its typescripts.
*
* @param file
* The file to test.
*
* @return
* true if the file appears to be a typescript, false otherwise.
*/
private boolean isTypescript(File file) {
return new File(file.getAbsolutePath() + TIMING_FILE_SUFFIX).exists();
}
/**
* Returns whether the given file appears to be a typescript timing file.
* Typescript timing files have the standard extension ".timing".
*
* @param file
* The file to test.
*
* @return
* true if the file appears to be a typescript timing file, false
* otherwise.
*/
private boolean isTypescriptTiming(File file) {
return file.getName().endsWith(TIMING_FILE_SUFFIX);
}
/**
* Returns the type of session recording or log contained within the given
* file by inspecting its name and contents.
*
* @param file
* The file to test.
*
* @return
* The type of session recording or log contained within the given
* file, or null if this cannot be determined.
*/
private ActivityLog.Type getType(File file) {
if (isSessionRecording(file))
return ActivityLog.Type.GUACAMOLE_SESSION_RECORDING;
if (isTypescript(file))
return ActivityLog.Type.TYPESCRIPT;
if (isTypescriptTiming(file))
return ActivityLog.Type.TYPESCRIPT_TIMING;
return ActivityLog.Type.SERVER_LOG;
}
/**
* Returns a new ActivityLog instance representing the session recording or
* log contained within the given file. If the type of recording/log cannot
* be determined, or if the file is unreadable, null is returned.
*
* @param file
* The file to produce an ActivityLog instance for.
*
* @return
* A new ActivityLog instance representing the recording/log contained
* within the given file, or null if the file is unreadable or cannot
* be identified.
*/
private ActivityLog getActivityLog(File file) {
// Verify file can actually be read
if (!file.canRead()) {
logger.warn("Ignoring file \"{}\" relevant to connection history "
+ "record as it cannot be read.", file);
return null;
}
// Determine type of recording/log by inspecting file
ActivityLog.Type logType = getType(file);
if (logType == null) {
logger.warn("Recording/log type of \"{}\" cannot be determined.", file);
return null;
}
return new FileActivityLog(
logType,
new TranslatableMessage("RECORDING_STORAGE.INFO_" + logType.name()),
file
);
}
/**
* Adds an ActivityLog instance representing the session recording or log
* contained within the given file to the given map of logs. If no
* ActivityLog can be produced for the given file (it is unreadable or
* cannot be identified), this function has no effect.
*
* @param logs
* The map of logs to add the ActivityLog to.
*
* @param file
* The file to produce an ActivityLog instance for.
*/
private void addActivityLog(Map<String, ActivityLog> logs, File file) {
ActivityLog log = getActivityLog(file);
if (log == null)
return;
// Convert file into deterministic name UUID within URL namespace
UUID fileUUID;
try {
byte[] urlBytes = file.toURI().toURL().toString().getBytes(StandardCharsets.UTF_8);
fileUUID = UUID.nameUUIDFromBytes(ByteBuffer.allocate(16 + urlBytes.length)
.putLong(UUID_NAMESPACE_URL.getMostSignificantBits())
.putLong(UUID_NAMESPACE_URL.getLeastSignificantBits())
.put(urlBytes)
.array());
}
catch (MalformedURLException e) {
logger.warn("Ignoring file \"{}\" as a unique URL and UUID for that file could not be generated: {}", e.getMessage());
logger.debug("URL for file \"{}\" could not be determined.", file, e);
return;
}
logs.put(fileUUID.toString(), log);
}
@Override
public Map<String, ActivityLog> getLogs() {
// Do nothing if there are no associated logs
if (recording == null)
return super.getLogs();
// Add associated log (or logs, if this is a directory)
Map<String, ActivityLog> logs = new HashMap<>(super.getLogs());
if (recording.isDirectory()) {
Arrays.asList(recording.listFiles()).stream()
.forEach((file) -> addActivityLog(logs, file));
}
else
addActivityLog(logs, recording);
return logs;
}
}

View File

@@ -0,0 +1,125 @@
/*
* 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.history.connection;
import java.util.Collections;
import java.util.Set;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.net.auth.ActivityRecordSet;
import org.apache.guacamole.net.auth.ConnectionRecord;
import org.apache.guacamole.net.auth.DecoratingActivityRecordSet;
import org.apache.guacamole.net.auth.Permissions;
import org.apache.guacamole.net.auth.User;
import org.apache.guacamole.net.auth.permission.ObjectPermission;
import org.apache.guacamole.net.auth.permission.SystemPermission;
/**
* ActivityRecordSet implementation that automatically defines ActivityLogs for
* files that relate to history entries within the wrapped set.
*/
public class RecordedConnectionActivityRecordSet extends DecoratingActivityRecordSet<ConnectionRecord> {
/**
* Whether the current user is an administrator.
*/
private final boolean isAdmin;
/**
* The overall set of connection permissions defined for the current user.
*/
private final Set<ObjectPermission> connectionPermissions;
/**
* Creates a new RecordedConnectionActivityRecordSet that wraps the given
* ActivityRecordSet, automatically associating history entries with
* ActivityLogs based on related files (session recordings, typescripts,
* etc.).
*
* @param currentUser
* The current Guacamole user.
*
* @param activityRecordSet
* The ActivityRecordSet to wrap.
*
* @throws GuacamoleException
* If the permissions for the current user cannot be retrieved.
*/
public RecordedConnectionActivityRecordSet(User currentUser,
ActivityRecordSet<ConnectionRecord> activityRecordSet)
throws GuacamoleException {
super(activityRecordSet);
// Determine whether current user is an administrator
Permissions perms = currentUser.getEffectivePermissions();
isAdmin = perms.getSystemPermissions().hasPermission(SystemPermission.Type.ADMINISTER);
// If not an admin, additionally pull specific connection permissions
if (isAdmin)
connectionPermissions = Collections.emptySet();
else
connectionPermissions = perms.getConnectionPermissions().getPermissions();
}
/**
* Returns whether the current user has permission to view the logs
* associated with the given history record. It is already given that the
* user has permission to view the history record itself. This extension
* considers a user to have permission to view history logs if they are
* an administrator or if they have permission to edit the associated
* connection.
*
* @param record
* The record to check.
*
* @return
* true if the current user has permission to view the logs associated
* with the given record, false otherwise.
*/
private boolean canViewLogs(ConnectionRecord record) {
// Administrator can always view
if (isAdmin)
return true;
// Non-administrator CANNOT view if permissions cannot be verified
String identifier = record.getConnectionIdentifier();
if (identifier == null)
return false;
// Non-administer can only view if they implicitly have permission to
// configure recordings (they have permission to edit)
ObjectPermission canUpdate = new ObjectPermission(ObjectPermission.Type.UPDATE, identifier);
return connectionPermissions.contains(canUpdate);
}
@Override
protected ConnectionRecord decorate(ConnectionRecord record) throws GuacamoleException {
// Provide access to logs only if permission is granted
if (canViewLogs(record))
return new HistoryConnectionRecord(record);
return record;
}
}

View File

@@ -0,0 +1,122 @@
/*
* 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.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.Directory;
import org.apache.guacamole.net.auth.TokenInjectingUserContext;
import org.apache.guacamole.net.auth.User;
import org.apache.guacamole.net.auth.UserContext;
/**
* UserContext implementation that automatically defines ActivityLogs for
* files that relate to history entries.
*/
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.
*/
private final User currentUser;
/**
* Creates a new HistoryUserContext that wraps the given UserContext,
* automatically associating history entries with ActivityLogs based on
* related files (session recordings, typescripts, etc.).
*
* @param currentUser
* The current Guacamole user.
*
* @param context
* The UserContext to wrap.
*/
public HistoryUserContext(User currentUser, UserContext context) {
super(context);
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()) {
@Override
protected Connection decorate(Connection object) {
return new HistoryConnection(currentUser, object);
}
@Override
protected Connection undecorate(Connection object) throws GuacamoleException {
return ((HistoryConnection) object).getWrappedConnection();
}
};
}
@Override
public ActivityRecordSet<ConnectionRecord> getConnectionHistory()
throws GuacamoleException {
return new RecordedConnectionActivityRecordSet(currentUser, super.getConnectionHistory());
}
}

View File

@@ -0,0 +1,17 @@
{
"guacamoleVersion" : "1.6.0",
"name" : "Session Recording Storage",
"namespace" : "recording-storage",
"authProviders" : [
"org.apache.guacamole.history.HistoryAuthenticationProvider"
],
"translations" : [
"translations/en.json",
"translations/pl.json"
]
}

View File

@@ -0,0 +1,14 @@
{
"DATA_SOURCE_RECORDING_STORAGE" : {
"NAME" : "Session Recording Storage"
},
"RECORDING_STORAGE" : {
"INFO_GUACAMOLE_SESSION_RECORDING" : "Graphical recording of remote desktop session",
"INFO_SERVER_LOG" : "Server/system log",
"INFO_TYPESCRIPT" : "Text recording of terminal session",
"INFO_TYPESCRIPT_TIMING" : "Timing information for text recording of terminal session"
}
}

View File

@@ -0,0 +1,14 @@
{
"DATA_SOURCE_RECORDING_STORAGE" : {
"NAME" : "Archiviazione della registrazione della sessione"
},
"RECORDING_STORAGE" : {
"INFO_GUACAMOLE_SESSION_RECORDING" : "Registrazione grafica della sessione desktop remoto",
"INFO_SERVER_LOG" : "Server/system log",
"INFO_TYPESCRIPT" : "Registrazione del testo della sessione del terminale",
"INFO_TYPESCRIPT_TIMING" : "Informazioni sull'orario per la registrazione del testo della sessione del terminale"
}
}

View File

@@ -0,0 +1,14 @@
{
"DATA_SOURCE_RECORDING_STORAGE" : {
"NAME" : "Session Recording Storage"
},
"RECORDING_STORAGE" : {
"INFO_GUACAMOLE_SESSION_RECORDING" : "Graficzne nagranie sesji zdalnego pulpitu",
"INFO_SERVER_LOG" : "Serwer/system log",
"INFO_TYPESCRIPT" : "Tesktowe nagranie sesji",
"INFO_TYPESCRIPT_TIMING" : "Informacje o czasie dla tesktowego nagrania sesji"
}
}