diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/connection/ModeledConnection.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/connection/ModeledConnection.java index dad6c69dd..3a1bb2ff5 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/connection/ModeledConnection.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/connection/ModeledConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Glyptodon LLC + * 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 @@ -24,17 +24,25 @@ package org.glyptodon.guacamole.auth.jdbc.connection; import com.google.inject.Inject; import com.google.inject.Provider; +import java.util.Arrays; +import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import org.glyptodon.guacamole.auth.jdbc.tunnel.GuacamoleTunnelService; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.auth.jdbc.base.ModeledGroupedDirectoryObject; +import org.glyptodon.guacamole.form.Field; +import org.glyptodon.guacamole.form.Form; +import org.glyptodon.guacamole.form.NumericField; import org.glyptodon.guacamole.net.GuacamoleTunnel; import org.glyptodon.guacamole.net.auth.Connection; import org.glyptodon.guacamole.net.auth.ConnectionRecord; import org.glyptodon.guacamole.protocol.GuacamoleClientInformation; import org.glyptodon.guacamole.protocol.GuacamoleConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * An implementation of the Connection object which is backed by a database @@ -46,6 +54,40 @@ import org.glyptodon.guacamole.protocol.GuacamoleConfiguration; public class ModeledConnection extends ModeledGroupedDirectoryObject implements Connection { + /** + * Logger for this class. + */ + private static final Logger logger = LoggerFactory.getLogger(ModeledConnection.class); + + /** + * The name of the attribute which controls the maximum number of + * concurrent connections. + */ + public static final String MAX_CONNECTIONS_NAME = "max-connections"; + + /** + * The name of the attribute which controls the maximum number of + * concurrent connections per user. + */ + public static final String MAX_CONNECTIONS_PER_USER_NAME = "max-connections-per-user"; + + /** + * All attributes related to restricting user accounts, within a logical + * form. + */ + public static final Form CONCURRENCY_LIMITS = new Form("concurrency", Arrays.asList( + new NumericField(MAX_CONNECTIONS_NAME), + new NumericField(MAX_CONNECTIONS_PER_USER_NAME) + )); + + /** + * All possible attributes of connection objects organized as individual, + * logical forms. + */ + public static final Collection
ATTRIBUTES = Collections.unmodifiableCollection(Arrays.asList( + CONCURRENCY_LIMITS + )); + /** * Service for managing connections. */ @@ -127,12 +169,35 @@ public class ModeledConnection extends ModeledGroupedDirectoryObject getAttributes() { - return Collections.emptyMap(); + + Map attributes = new HashMap(); + + // Set connection limit attribute + attributes.put(MAX_CONNECTIONS_NAME, NumericField.format(getModel().getMaxConnections())); + + // Set per-user connection limit attribute + attributes.put(MAX_CONNECTIONS_PER_USER_NAME, NumericField.format(getModel().getMaxConnectionsPerUser())); + + return attributes; } @Override public void setAttributes(Map attributes) { - // Drop all attributes - none currently supported + + // Translate connection limit attribute + try { getModel().setMaxConnections(NumericField.parse(attributes.get(MAX_CONNECTIONS_NAME))); } + catch (NumberFormatException e) { + logger.warn("Not setting maximum connections: {}", e.getMessage()); + logger.debug("Unable to parse numeric attribute.", e); + } + + // Translate per-user connection limit attribute + try { getModel().setMaxConnectionsPerUser(NumericField.parse(attributes.get(MAX_CONNECTIONS_PER_USER_NAME))); } + catch (NumberFormatException e) { + logger.warn("Not setting maximum connections per user: {}", e.getMessage()); + logger.debug("Unable to parse numeric attribute.", e); + } + } } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java index 5d46147f5..8e1403fb2 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Glyptodon LLC + * 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 @@ -23,26 +23,69 @@ package org.glyptodon.guacamole.auth.jdbc.connectiongroup; import com.google.inject.Inject; +import java.util.Arrays; +import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.Map; import java.util.Set; import org.glyptodon.guacamole.auth.jdbc.connection.ConnectionService; import org.glyptodon.guacamole.auth.jdbc.tunnel.GuacamoleTunnelService; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.auth.jdbc.base.ModeledGroupedDirectoryObject; +import org.glyptodon.guacamole.form.Field; +import org.glyptodon.guacamole.form.Form; +import org.glyptodon.guacamole.form.NumericField; import org.glyptodon.guacamole.net.GuacamoleTunnel; import org.glyptodon.guacamole.net.auth.ConnectionGroup; import org.glyptodon.guacamole.protocol.GuacamoleClientInformation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * An implementation of the ConnectionGroup object which is backed by a * database model. * * @author James Muehlner + * @author Michael Jumper */ public class ModeledConnectionGroup extends ModeledGroupedDirectoryObject implements ConnectionGroup { + /** + * Logger for this class. + */ + private static final Logger logger = LoggerFactory.getLogger(ModeledConnectionGroup.class); + + /** + * The name of the attribute which controls the maximum number of + * concurrent connections. + */ + public static final String MAX_CONNECTIONS_NAME = "max-connections"; + + /** + * The name of the attribute which controls the maximum number of + * concurrent connections per user. + */ + public static final String MAX_CONNECTIONS_PER_USER_NAME = "max-connections-per-user"; + + /** + * All attributes related to restricting user accounts, within a logical + * form. + */ + public static final Form CONCURRENCY_LIMITS = new Form("concurrency", Arrays.asList( + new NumericField(MAX_CONNECTIONS_NAME), + new NumericField(MAX_CONNECTIONS_PER_USER_NAME) + )); + + /** + * All possible attributes of connection group objects organized as + * individual, logical forms. + */ + public static final Collection ATTRIBUTES = Collections.unmodifiableCollection(Arrays.asList( + CONCURRENCY_LIMITS + )); + /** * Service for managing connections. */ @@ -112,12 +155,35 @@ public class ModeledConnectionGroup extends ModeledGroupedDirectoryObject getAttributes() { - return Collections.emptyMap(); + + Map attributes = new HashMap(); + + // Set connection limit attribute + attributes.put(MAX_CONNECTIONS_NAME, NumericField.format(getModel().getMaxConnections())); + + // Set per-user connection limit attribute + attributes.put(MAX_CONNECTIONS_PER_USER_NAME, NumericField.format(getModel().getMaxConnectionsPerUser())); + + return attributes; } @Override public void setAttributes(Map attributes) { - // Drop all attributes - none currently supported + + // Translate connection limit attribute + try { getModel().setMaxConnections(NumericField.parse(attributes.get(MAX_CONNECTIONS_NAME))); } + catch (NumberFormatException e) { + logger.warn("Not setting maximum connections: {}", e.getMessage()); + logger.debug("Unable to parse numeric attribute.", e); + } + + // Translate per-user connection limit attribute + try { getModel().setMaxConnectionsPerUser(NumericField.parse(attributes.get(MAX_CONNECTIONS_PER_USER_NAME))); } + catch (NumberFormatException e) { + logger.warn("Not setting maximum connections per user: {}", e.getMessage()); + logger.debug("Unable to parse numeric attribute.", e); + } + } } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/UserContext.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/UserContext.java index 41c61e340..12676927a 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/UserContext.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/UserContext.java @@ -29,10 +29,11 @@ import org.glyptodon.guacamole.auth.jdbc.connection.ConnectionDirectory; import com.google.inject.Inject; import com.google.inject.Provider; import java.util.Collection; -import java.util.Collections; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.auth.jdbc.base.RestrictedObject; import org.glyptodon.guacamole.auth.jdbc.activeconnection.ActiveConnectionDirectory; +import org.glyptodon.guacamole.auth.jdbc.connection.ModeledConnection; +import org.glyptodon.guacamole.auth.jdbc.connectiongroup.ModeledConnectionGroup; import org.glyptodon.guacamole.form.Form; import org.glyptodon.guacamole.net.auth.ActiveConnection; import org.glyptodon.guacamole.net.auth.Connection; @@ -140,12 +141,12 @@ public class UserContext extends RestrictedObject @Override public Collection getConnectionAttributes() { - return Collections.emptyList(); + return ModeledConnection.ATTRIBUTES; } @Override public Collection getConnectionGroupAttributes() { - return Collections.emptyList(); + return ModeledConnectionGroup.ATTRIBUTES; } } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json index b11c15741..1b631c993 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json @@ -15,6 +15,24 @@ }, + "CONNECTION_ATTRIBUTES" : { + + "FIELD_HEADER_MAX_CONNECTIONS" : "Maximum number of connections:", + "FIELD_HEADER_MAX_CONNECTIONS_PER_USER" : "Maximum number of connections per user:", + + "SECTION_HEADER_CONCURRENCY" : "Concurrency Limits" + + }, + + "CONNECTION_GROUP_ATTRIBUTES" : { + + "FIELD_HEADER_MAX_CONNECTIONS" : "Maximum number of connections:", + "FIELD_HEADER_MAX_CONNECTIONS_PER_USER" : "Maximum number of connections per user:", + + "SECTION_HEADER_CONCURRENCY" : "Concurrency Limits (Balancing Groups)" + + }, + "USER_ATTRIBUTES" : { "FIELD_HEADER_DISABLED" : "Login disabled:",