mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
Ticket #362: Added session timeout.
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
|
||||
package org.glyptodon.guacamole.properties;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-ext.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Michael Jumper.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.GuacamoleServerException;
|
||||
|
||||
/**
|
||||
* A GuacamoleProperty whose value is an long.
|
||||
*
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public abstract class LongGuacamoleProperty implements GuacamoleProperty<Long> {
|
||||
|
||||
@Override
|
||||
public Long parseValue(String value) throws GuacamoleException {
|
||||
|
||||
// If no property provided, return null.
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
try {
|
||||
Long longValue = new Long(value);
|
||||
return longValue;
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw new GuacamoleServerException("Property \"" + getName() + "\" must be an long.", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -20,6 +20,7 @@ package org.glyptodon.guacamole.net.basic.properties;
|
||||
*/
|
||||
|
||||
import org.glyptodon.guacamole.properties.FileGuacamoleProperty;
|
||||
import org.glyptodon.guacamole.properties.LongGuacamoleProperty;
|
||||
|
||||
/**
|
||||
* Properties used by the default Guacamole web application.
|
||||
@@ -64,4 +65,14 @@ public class BasicGuacamoleProperties {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The session timeout for the API, in milliseconds.
|
||||
*/
|
||||
public static final LongGuacamoleProperty API_SESSION_TIMEOUT = new LongGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "api-session-timeout"; }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -18,13 +18,113 @@ package org.glyptodon.guacamole.net.basic.rest.auth;
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.UserContext;
|
||||
import org.glyptodon.guacamole.net.basic.properties.BasicGuacamoleProperties;
|
||||
import org.glyptodon.guacamole.properties.GuacamoleProperties;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* A Basic, HashMap-based implementation of the TokenUserContextMap.
|
||||
* A basic, HashMap-based implementation of the TokenUserContextMap with support
|
||||
* for session timeouts.
|
||||
*
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class BasicTokenUserContextMap extends HashMap<String, UserContext>
|
||||
implements TokenUserContextMap {}
|
||||
public class BasicTokenUserContextMap implements TokenUserContextMap {
|
||||
|
||||
/**
|
||||
* Logger for this class.
|
||||
*/
|
||||
private static Logger logger = LoggerFactory.getLogger(BasicTokenUserContextMap.class);
|
||||
|
||||
/**
|
||||
* The last time a user with a specific auth token accessed the API.
|
||||
*/
|
||||
private Map<String, Long> lastAccessTimeMap = new HashMap<String, Long>();
|
||||
|
||||
/**
|
||||
* Keeps track of the authToken to UserContext mapping.
|
||||
*/
|
||||
private Map<String, UserContext> userContextMap = new HashMap<String, UserContext>();
|
||||
|
||||
/**
|
||||
* The session timeout configuration for an API session.
|
||||
*/
|
||||
private final long SESSION_TIMEOUT;
|
||||
|
||||
/**
|
||||
* Create a new BasicTokenUserContextMap and initialize the session timeout value.
|
||||
*/
|
||||
public BasicTokenUserContextMap() {
|
||||
|
||||
// Set up the authToken => userContext hashmap
|
||||
super();
|
||||
|
||||
// Set up the SESSION_TIMEOUT value, with a one hour default.
|
||||
long sessionTimeoutValue = 3600000l;
|
||||
try {
|
||||
sessionTimeoutValue = GuacamoleProperties.getProperty(BasicGuacamoleProperties.API_SESSION_TIMEOUT, 3600000l);
|
||||
} catch (GuacamoleException e) {
|
||||
logger.error("Unexpected GuacamoleException caught while reading API_SESSION_TIMEOUT property.", e);
|
||||
}
|
||||
|
||||
SESSION_TIMEOUT = sessionTimeoutValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evict an authentication token from the map of logged in users and last
|
||||
* access times.
|
||||
*
|
||||
* @param authToken The authentication token to evict.
|
||||
*/
|
||||
private void evict(String authToken) {
|
||||
userContextMap.remove(authToken);
|
||||
lastAccessTimeMap.remove(authToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log that the user represented by this auth token has just used the API.
|
||||
*
|
||||
* @param authToken The authentication token to record access time for.
|
||||
*/
|
||||
private void logAccessTime(String authToken) {
|
||||
lastAccessTimeMap.put(authToken, new Date().getTime());
|
||||
}
|
||||
|
||||
private boolean sessionHasTimedOut(String authToken) {
|
||||
if(!lastAccessTimeMap.containsKey(authToken))
|
||||
return true;
|
||||
|
||||
long lastAccessTime = lastAccessTimeMap.get(authToken);
|
||||
long currentTime = new Date().getTime();
|
||||
|
||||
return currentTime - lastAccessTime > SESSION_TIMEOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserContext get(String authToken) {
|
||||
|
||||
// If the session has timed out, evict the token and force the user to log in again
|
||||
if(sessionHasTimedOut(authToken)) {
|
||||
evict(authToken);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Update the last access time and return the UserContext
|
||||
logAccessTime(authToken);
|
||||
return userContextMap.get(authToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(String authToken, UserContext userContext) {
|
||||
|
||||
// Update the last access time, and create the token/UserContext mapping
|
||||
logAccessTime(authToken);
|
||||
userContextMap.put(authToken, userContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -18,7 +18,6 @@ package org.glyptodon.guacamole.net.basic.rest.auth;
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.util.Map;
|
||||
import org.glyptodon.guacamole.net.auth.UserContext;
|
||||
|
||||
/**
|
||||
@@ -27,4 +26,24 @@ import org.glyptodon.guacamole.net.auth.UserContext;
|
||||
*
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public interface TokenUserContextMap extends Map<String, UserContext> {}
|
||||
public interface TokenUserContextMap {
|
||||
|
||||
/**
|
||||
* Registers that a user has just logged in with the specified authToken and
|
||||
* UserContext.
|
||||
*
|
||||
* @param authToken The authentication token for the logged in user.
|
||||
* @param userContext The UserContext for the logged in user.
|
||||
*/
|
||||
public void put(String authToken, UserContext userContext);
|
||||
|
||||
/**
|
||||
* Get the UserContext for a logged in user. If the auth token does not
|
||||
* represent a user who is currently logged in, returns null.
|
||||
*
|
||||
* @param authToken The authentication token for the logged in user.
|
||||
* @return The UserContext for the given auth token, if the auth token
|
||||
* represents a currently logged in user, null otherwise.
|
||||
*/
|
||||
public UserContext get(String authToken);
|
||||
}
|
||||
|
Reference in New Issue
Block a user