From b64c4f3b94f3ac98ee750e5631db7913bf42bfa1 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 26 May 2015 11:16:09 -0700 Subject: [PATCH 1/6] GUAC-800: Clarify semantics of getAttributes() / setAttributes(). --- .../glyptodon/guacamole/net/auth/Connection.java | 14 ++++++++------ .../guacamole/net/auth/ConnectionGroup.java | 14 ++++++++------ .../org/glyptodon/guacamole/net/auth/User.java | 14 ++++++++------ 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/Connection.java b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/Connection.java index 6ab34dab4..9de591be6 100644 --- a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/Connection.java +++ b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/Connection.java @@ -86,21 +86,23 @@ public interface Connection extends Identifiable, Connectable { public void setConfiguration(GuacamoleConfiguration config); /** - * Returns all attributes associated with this connection. + * Returns all attributes associated with this connection. The returned map + * may not be modifiable. * * @return * A map of all attribute identifiers to their corresponding values, - * for all attributes associated with this connection. + * for all attributes associated with this connection, which may not be + * modifiable. */ Map getAttributes(); /** - * Replaces all attributes associated with this connection with the - * attributes in the given map. + * Sets the given attributes. If an attribute within the map is not + * supported, it will simply be dropped. Any attributes not within the + * given map will be left untouched. * * @param attributes - * A map of all attribute identifiers to their corresponding values, - * for all attributes associated with this connection. + * A map of all attribute identifiers to their corresponding values. */ void setAttributes(Map attributes); diff --git a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/ConnectionGroup.java b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/ConnectionGroup.java index 25eb11797..0b20f2301 100644 --- a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/ConnectionGroup.java +++ b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/ConnectionGroup.java @@ -130,21 +130,23 @@ public interface ConnectionGroup extends Identifiable, Connectable { throws GuacamoleException; /** - * Returns all attributes associated with this connection group. + * Returns all attributes associated with this connection group. The + * returned map may not be modifiable. * * @return * A map of all attribute identifiers to their corresponding values, - * for all attributes associated with this connection group. + * for all attributes associated with this connection group, which may + * not be modifiable. */ Map getAttributes(); /** - * Replaces all attributes associated with this connection group with the - * attributes in the given map. + * Sets the given attributes. If an attribute within the map is not + * supported, it will simply be dropped. Any attributes not within the + * given map will be left untouched. * * @param attributes - * A map of all attribute identifiers to their corresponding values, - * for all attributes associated with this connection group. + * A map of all attribute identifiers to their corresponding values. */ void setAttributes(Map attributes); diff --git a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/User.java b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/User.java index b2f13ea23..355dd5def 100644 --- a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/User.java +++ b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/User.java @@ -53,21 +53,23 @@ public interface User extends Identifiable { public void setPassword(String password); /** - * Returns all attributes associated with this user. + * Returns all attributes associated with this user. The returned map may + * not be modifiable. * * @return * A map of all attribute identifiers to their corresponding values, - * for all attributes associated with this user. + * for all attributes associated with this user, which may not be + * modifiable. */ Map getAttributes(); /** - * Replaces all attributes associated with this user with the attributes in - * the given map. + * Sets the given attributes. If an attribute within the map is not + * supported, it will simply be dropped. Any attributes not within the + * given map will be left untouched. * * @param attributes - * A map of all attribute identifiers to their corresponding values, - * for all attributes associated with this user. + * A map of all attribute identifiers to their corresponding values. */ void setAttributes(Map attributes); From c8c12663b356f23e809de5d9f02b8ff62362929f Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 26 May 2015 12:42:57 -0700 Subject: [PATCH 2/6] GUAC-800: Add support for disabling user accounts. --- .../guacamole/auth/jdbc/user/ModeledUser.java | 35 +++++++++++++++++-- .../guacamole/auth/jdbc/user/UserContext.java | 2 +- .../auth/jdbc/user/UserContextService.java | 2 +- .../guacamole/auth/jdbc/user/UserModel.java | 30 ++++++++++++++++ .../main/resources/translations/en_US.json | 5 +++ .../schema/001-create-schema.sql | 1 + .../schema/upgrade/upgrade-pre-0.9.7.sql | 28 +++++++++++++++ .../src/main/resources/guac-manifest.json | 4 +++ .../guacamole/auth/jdbc/user/UserMapper.xml | 19 ++++++---- .../schema/001-create-schema.sql | 1 + .../schema/upgrade/upgrade-pre-0.9.7.sql | 28 +++++++++++++++ .../src/main/resources/guac-manifest.json | 4 +++ .../guacamole/auth/jdbc/user/UserMapper.xml | 19 ++++++---- 13 files changed, 162 insertions(+), 16 deletions(-) create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en_US.json create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.7.sql create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.7.sql diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/ModeledUser.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/ModeledUser.java index 36479f96c..aeceff64b 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/ModeledUser.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/ModeledUser.java @@ -23,7 +23,10 @@ package org.glyptodon.guacamole.auth.jdbc.user; 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 org.glyptodon.guacamole.auth.jdbc.base.ModeledDirectoryObject; import org.glyptodon.guacamole.auth.jdbc.security.PasswordEncryptionService; @@ -34,6 +37,7 @@ import org.glyptodon.guacamole.auth.jdbc.activeconnection.ActiveConnectionPermis import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionGroupPermissionService; import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionPermissionService; import org.glyptodon.guacamole.auth.jdbc.permission.UserPermissionService; +import org.glyptodon.guacamole.form.Field; import org.glyptodon.guacamole.net.auth.User; import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet; import org.glyptodon.guacamole.net.auth.permission.SystemPermission; @@ -47,6 +51,24 @@ import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet; */ public class ModeledUser extends ModeledDirectoryObject implements User { + /** + * The name of the attribute which controls whether a user account is + * disabled. + */ + public static final String DISABLED_ATTRIBUTE_NAME = "disabled"; + + /** + * A typed field corresponding to the disabled attribute of a user. + */ + public static final Field DISABLED_ATTRIBUTE = new Field(DISABLED_ATTRIBUTE_NAME, "Disabled", "true"); + + /** + * All possible attributes of user objects. + */ + public static final Collection ATTRIBUTES = Collections.unmodifiableCollection(Arrays.asList( + DISABLED_ATTRIBUTE + )); + /** * Service for hashing passwords. */ @@ -183,12 +205,21 @@ public class ModeledUser extends ModeledDirectoryObject implements Us @Override public Map getAttributes() { - return Collections.emptyMap(); + + Map attributes = new HashMap(); + + // Set disabled attribute + attributes.put("disabled", getModel().isDisabled() ? "true" : null); + + return attributes; } @Override public void setAttributes(Map attributes) { - // Drop all attributes - none currently supported + + // Translate disabled attribute + getModel().setDisabled("true".equals(attributes.get("disabled"))); + } } 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 00f7150f7..3ff9280fa 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 @@ -135,7 +135,7 @@ public class UserContext extends RestrictedObject @Override public Collection getUserAttributes() { - return Collections.emptyList(); + return ModeledUser.ATTRIBUTES; } @Override diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/UserContextService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/UserContextService.java index c0a31074f..589edd149 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/UserContextService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/UserContextService.java @@ -67,7 +67,7 @@ public class UserContextService { // Authenticate user ModeledUser user = userService.retrieveUser(credentials); - if (user != null) { + if (user != null && !user.getModel().isDisabled()) { // Upon successful authentication, return new user context UserContext context = userContextProvider.get(); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/UserModel.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/UserModel.java index 546b1927a..1f84ab566 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/UserModel.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/UserModel.java @@ -42,6 +42,12 @@ public class UserModel extends ObjectModel { */ private byte[] passwordSalt; + /** + * Whether the user account is disabled. Disabled accounts exist and can + * be modified, but cannot be used. + */ + private boolean disabled; + /** * Creates a new, empty user. */ @@ -97,4 +103,28 @@ public class UserModel extends ObjectModel { this.passwordSalt = passwordSalt; } + /** + * Returns whether the user has been disabled. Disabled users are not + * allowed to login. Although their account data exists, all login attempts + * will fail as if the account does not exist. + * + * @return + * true if the account is disabled, false otherwise. + */ + public boolean isDisabled() { + return disabled; + } + + /** + * Sets whether the user is disabled. Disabled users are not allowed to + * login. Although their account data exists, all login attempts will fail + * as if the account does not exist. + * + * @param disabled + * true if the account should be disabled, false otherwise. + */ + public void setDisabled(boolean disabled) { + this.disabled = disabled; + } + } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en_US.json b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en_US.json new file mode 100644 index 000000000..2937a9713 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en_US.json @@ -0,0 +1,5 @@ +{ + "USER_ATTRIBUTES" : { + "FIELD_HEADER_DISABLED" : "Disabled:" + } +} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/001-create-schema.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/001-create-schema.sql index 0a50bb379..e9545adae 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/001-create-schema.sql +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/001-create-schema.sql @@ -76,6 +76,7 @@ CREATE TABLE `guacamole_user` ( `username` varchar(128) NOT NULL, `password_hash` binary(32) NOT NULL, `password_salt` binary(32), + `disabled` boolean NOT NULL DEFAULT 0, PRIMARY KEY (`user_id`), UNIQUE KEY `username` (`username`) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.7.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.7.sql new file mode 100644 index 000000000..8bc41ec26 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.7.sql @@ -0,0 +1,28 @@ +-- +-- 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 +-- in the Software without restriction, including without limitation the rights +-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +-- copies of the Software, and to permit persons to whom the Software is +-- furnished to do so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in +-- all copies or substantial portions of the Software. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +-- THE SOFTWARE. +-- + +-- +-- Add per-user disable flag +-- + +ALTER TABLE guacamole_user ADD COLUMN disabled BOOLEAN NOT NULL DEFAULT 0; + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/guac-manifest.json b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/guac-manifest.json index 3c7deb865..6566bcc4b 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/guac-manifest.json +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/guac-manifest.json @@ -7,6 +7,10 @@ "authProviders" : [ "net.sourceforge.guacamole.net.auth.mysql.MySQLAuthenticationProvider" + ], + + "translations" : [ + "translations/en_US.json" ] } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/glyptodon/guacamole/auth/jdbc/user/UserMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/glyptodon/guacamole/auth/jdbc/user/UserMapper.xml index 7c5b7357f..de4b311cd 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/glyptodon/guacamole/auth/jdbc/user/UserMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/glyptodon/guacamole/auth/jdbc/user/UserMapper.xml @@ -32,6 +32,7 @@ + @@ -57,7 +58,8 @@ user_id, username, password_hash, - password_salt + password_salt, + disabled FROM guacamole_user WHERE username IN @@ -128,7 +134,8 @@ UPDATE guacamole_user SET password_hash = #{object.passwordHash,jdbcType=BINARY}, - password_salt = #{object.passwordSalt,jdbcType=BINARY} + password_salt = #{object.passwordSalt,jdbcType=BINARY}, + disabled = #{object.disabled,jdbcType=BOOLEAN} WHERE user_id = #{object.objectID,jdbcType=VARCHAR} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/001-create-schema.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/001-create-schema.sql index 4e4297693..d228b5844 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/001-create-schema.sql +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/001-create-schema.sql @@ -117,6 +117,7 @@ CREATE TABLE guacamole_user ( username varchar(128) NOT NULL, password_hash bytea NOT NULL, password_salt bytea, + disabled boolean NOT NULL DEFAULT FALSE, PRIMARY KEY (user_id), diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.7.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.7.sql new file mode 100644 index 000000000..ba8649629 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.7.sql @@ -0,0 +1,28 @@ +-- +-- 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 +-- in the Software without restriction, including without limitation the rights +-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +-- copies of the Software, and to permit persons to whom the Software is +-- furnished to do so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in +-- all copies or substantial portions of the Software. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +-- THE SOFTWARE. +-- + +-- +-- Add per-user disable flag +-- + +ALTER TABLE guacamole_user ADD COLUMN disabled boolean NOT NULL DEFAULT FALSE; + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/guac-manifest.json b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/guac-manifest.json index 2be870f25..a3ae33e4e 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/guac-manifest.json +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/guac-manifest.json @@ -7,6 +7,10 @@ "authProviders" : [ "org.glyptodon.guacamole.auth.postgresql.PostgreSQLAuthenticationProvider" + ], + + "translations" : [ + "translations/en_US.json" ] } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/glyptodon/guacamole/auth/jdbc/user/UserMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/glyptodon/guacamole/auth/jdbc/user/UserMapper.xml index 41416f7db..6b2438229 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/glyptodon/guacamole/auth/jdbc/user/UserMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/glyptodon/guacamole/auth/jdbc/user/UserMapper.xml @@ -32,6 +32,7 @@ + @@ -57,7 +58,8 @@ user_id, username, password_hash, - password_salt + password_salt, + disabled FROM guacamole_user WHERE username IN @@ -128,7 +134,8 @@ UPDATE guacamole_user SET password_hash = #{object.passwordHash,jdbcType=BINARY}, - password_salt = #{object.passwordSalt,jdbcType=BINARY} + password_salt = #{object.passwordSalt,jdbcType=BINARY}, + disabled = #{object.disabled,jdbcType=BOOLEAN} WHERE user_id = #{object.objectID,jdbcType=VARCHAR} From e31025273ab6e0fb5957675397fa49f62de5a982 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 26 May 2015 14:22:16 -0700 Subject: [PATCH 3/6] GUAC-800: Display user attributes within user editor. --- .../controllers/manageUserController.js | 15 +++++ .../webapp/app/manage/styles/attributes.css | 65 +++++++++++++++++++ .../app/manage/templates/manageUser.html | 8 ++- 3 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 guacamole/src/main/webapp/app/manage/styles/attributes.css diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js index d45491dc9..8dd282d6b 100644 --- a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js +++ b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js @@ -39,6 +39,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto var guacNotification = $injector.get('guacNotification'); var userService = $injector.get('userService'); var permissionService = $injector.get('permissionService'); + var schemaService = $injector.get('schemaService'); /** * An action to be provided along with the object sent to showStatus which @@ -102,6 +103,14 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto */ $scope.permissions = null; + /** + * All available user attributes. This is only the set of attribute + * definitions, not attribute values. + * + * @type Field[] + */ + $scope.attributes = null; + /** * Returns whether critical data has completed being loaded. * @@ -115,11 +124,17 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto && $scope.permissionFlags !== null && $scope.rootGroup !== null && $scope.permissions !== null + && $scope.attributes !== null && $scope.canSaveUser !== null && $scope.canDeleteUser !== null; }; + // Pull user attribute schema + schemaService.getUserAttributes().success(function attributesReceived(attributes) { + $scope.attributes = attributes; + }); + // Pull user data userService.getUser(username).success(function userReceived(user) { $scope.user = user; diff --git a/guacamole/src/main/webapp/app/manage/styles/attributes.css b/guacamole/src/main/webapp/app/manage/styles/attributes.css new file mode 100644 index 000000000..9b3e826ca --- /dev/null +++ b/guacamole/src/main/webapp/app/manage/styles/attributes.css @@ -0,0 +1,65 @@ +/* + * 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 + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* Do not stretch attributes to fit available area */ +.attributes input[type=text], +.attributes input[type=password], +.attributes input[type=number] { + width: auto; +} + +.attributes .form .fields { + display: table; + margin: 1em; +} + +.attributes .form .fields .labeled-field { + display: table-row; +} + +.attributes .form .fields .field-header, +.attributes .form .fields .form-field { + display: table-cell; + padding: 0.125em; + vertical-align: top; +} + +.attributes .form .fields .field-header { + padding-right: 1em; +} + +.attributes .form h3 { + + font-size: 1.25em; + font-weight: bold; + text-transform: uppercase; + padding: 0.75em 0.5em; + margin: 1em 0; + + border-bottom: 1px solid rgba(0, 0, 0, 0.125); + border-top: 1px solid rgba(0, 0, 0, 0.125); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.125); + background: rgba(0, 0, 0, 0.04); + + width: 100%; + +} diff --git a/guacamole/src/main/webapp/app/manage/templates/manageUser.html b/guacamole/src/main/webapp/app/manage/templates/manageUser.html index e3a143af3..4e0903f2d 100644 --- a/guacamole/src/main/webapp/app/manage/templates/manageUser.html +++ b/guacamole/src/main/webapp/app/manage/templates/manageUser.html @@ -47,6 +47,11 @@ THE SOFTWARE. + +
+ +
+

{{'MANAGE_USER.SECTION_HEADER_PERMISSIONS' | translate}}

@@ -63,8 +68,7 @@ THE SOFTWARE.
- - +

{{'MANAGE_USER.SECTION_HEADER_CONNECTIONS' | translate}}

Date: Tue, 26 May 2015 14:38:30 -0700 Subject: [PATCH 4/6] GUAC-800: Properly initialize name and title in Form constructor. --- .../src/main/java/org/glyptodon/guacamole/form/Form.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/guacamole-ext/src/main/java/org/glyptodon/guacamole/form/Form.java b/guacamole-ext/src/main/java/org/glyptodon/guacamole/form/Form.java index 192799a42..f85f755f3 100644 --- a/guacamole-ext/src/main/java/org/glyptodon/guacamole/form/Form.java +++ b/guacamole-ext/src/main/java/org/glyptodon/guacamole/form/Form.java @@ -73,6 +73,8 @@ public class Form { * The fields to provided within the new Form. */ public Form(String name, String title, Collection fields) { + this.name = name; + this.title = title; this.fields = fields; } From e7574c0276bcfd5e069a98d32aaf0a563c8a3fce Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 26 May 2015 14:42:39 -0700 Subject: [PATCH 5/6] GUAC-800: Use Forms for attributes, not just Fields. --- .../guacamole/auth/jdbc/user/ModeledUser.java | 15 ++++++--- .../guacamole/auth/jdbc/user/UserContext.java | 12 +++---- .../main/resources/translations/en_US.json | 6 +++- .../guacamole/net/auth/UserContext.java | 8 ++--- .../net/auth/simple/SimpleUserContext.java | 14 ++++---- .../basic/rest/schema/SchemaRESTService.java | 20 +++++------ .../controllers/manageUserController.js | 5 +-- .../webapp/app/rest/services/schemaService.js | 33 ++++++++++--------- 8 files changed, 63 insertions(+), 50 deletions(-) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/ModeledUser.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/ModeledUser.java index aeceff64b..0f234c494 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/ModeledUser.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/user/ModeledUser.java @@ -38,6 +38,7 @@ import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionGroupPermissionSer import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionPermissionService; import org.glyptodon.guacamole.auth.jdbc.permission.UserPermissionService; import org.glyptodon.guacamole.form.Field; +import org.glyptodon.guacamole.form.Form; import org.glyptodon.guacamole.net.auth.User; import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet; import org.glyptodon.guacamole.net.auth.permission.SystemPermission; @@ -58,15 +59,19 @@ public class ModeledUser extends ModeledDirectoryObject implements Us public static final String DISABLED_ATTRIBUTE_NAME = "disabled"; /** - * A typed field corresponding to the disabled attribute of a user. + * All attributes related to restricting user accounts, within a logical + * form. */ - public static final Field DISABLED_ATTRIBUTE = new Field(DISABLED_ATTRIBUTE_NAME, "Disabled", "true"); + public static final Form ACCOUNT_RESTRICTIONS = new Form("restrictions", "Account Restrictions", Arrays.asList( + new Field(DISABLED_ATTRIBUTE_NAME, "Disabled", "true") + )); /** - * All possible attributes of user objects. + * All possible attributes of user objects organized as individual, + * logical forms. */ - public static final Collection ATTRIBUTES = Collections.unmodifiableCollection(Arrays.asList( - DISABLED_ATTRIBUTE + public static final Collection
ATTRIBUTES = Collections.unmodifiableCollection(Arrays.asList( + ACCOUNT_RESTRICTIONS )); /** 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 3ff9280fa..41c61e340 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 @@ -33,7 +33,7 @@ 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.form.Field; +import org.glyptodon.guacamole.form.Form; import org.glyptodon.guacamole.net.auth.ActiveConnection; import org.glyptodon.guacamole.net.auth.Connection; import org.glyptodon.guacamole.net.auth.ConnectionGroup; @@ -134,18 +134,18 @@ public class UserContext extends RestrictedObject } @Override - public Collection getUserAttributes() { + public Collection getUserAttributes() { return ModeledUser.ATTRIBUTES; } @Override - public Collection getConnectionAttributes() { - return Collections.emptyList(); + public Collection getConnectionAttributes() { + return Collections.emptyList(); } @Override - public Collection getConnectionGroupAttributes() { - return Collections.emptyList(); + public Collection getConnectionGroupAttributes() { + return Collections.emptyList(); } } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en_US.json b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en_US.json index 2937a9713..920ded08f 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en_US.json +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en_US.json @@ -1,5 +1,9 @@ { "USER_ATTRIBUTES" : { - "FIELD_HEADER_DISABLED" : "Disabled:" + + "FIELD_HEADER_DISABLED" : "Login disabled:", + + "SECTION_HEADER_RESTRICTIONS" : "Account Restrictions" + } } diff --git a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/UserContext.java b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/UserContext.java index 44ca67f20..e1dddb23c 100644 --- a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/UserContext.java +++ b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/UserContext.java @@ -24,7 +24,7 @@ package org.glyptodon.guacamole.net.auth; import java.util.Collection; import org.glyptodon.guacamole.GuacamoleException; -import org.glyptodon.guacamole.form.Field; +import org.glyptodon.guacamole.form.Form; /** * The context of an active user. The functions of this class enforce all @@ -121,7 +121,7 @@ public interface UserContext { * @return * A collection of all attributes applicable to users. */ - Collection getUserAttributes(); + Collection getUserAttributes(); /** * Retrieves a collection of all attributes applicable to connections. This @@ -132,7 +132,7 @@ public interface UserContext { * @return * A collection of all attributes applicable to connections. */ - Collection getConnectionAttributes(); + Collection getConnectionAttributes(); /** * Retrieves a collection of all attributes applicable to connection @@ -143,6 +143,6 @@ public interface UserContext { * @return * A collection of all attributes applicable to connection groups. */ - Collection getConnectionGroupAttributes(); + Collection getConnectionGroupAttributes(); } diff --git a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleUserContext.java b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleUserContext.java index ee5f24ab3..5a41e44d2 100644 --- a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleUserContext.java +++ b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleUserContext.java @@ -28,7 +28,7 @@ import java.util.Collections; import java.util.Map; import java.util.UUID; import org.glyptodon.guacamole.GuacamoleException; -import org.glyptodon.guacamole.form.Field; +import org.glyptodon.guacamole.form.Form; import org.glyptodon.guacamole.net.auth.ActiveConnection; import org.glyptodon.guacamole.net.auth.Connection; import org.glyptodon.guacamole.net.auth.ConnectionGroup; @@ -176,18 +176,18 @@ public class SimpleUserContext implements UserContext { } @Override - public Collection getUserAttributes() { - return Collections.emptyList(); + public Collection getUserAttributes() { + return Collections.emptyList(); } @Override - public Collection getConnectionAttributes() { - return Collections.emptyList(); + public Collection getConnectionAttributes() { + return Collections.emptyList(); } @Override - public Collection getConnectionGroupAttributes() { - return Collections.emptyList(); + public Collection getConnectionGroupAttributes() { + return Collections.emptyList(); } } diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/schema/SchemaRESTService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/schema/SchemaRESTService.java index fa1dda932..05d0c6d77 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/schema/SchemaRESTService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/schema/SchemaRESTService.java @@ -34,7 +34,7 @@ import javax.ws.rs.core.MediaType; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.environment.Environment; import org.glyptodon.guacamole.environment.LocalEnvironment; -import org.glyptodon.guacamole.form.Field; +import org.glyptodon.guacamole.form.Form; import org.glyptodon.guacamole.net.auth.UserContext; import org.glyptodon.guacamole.net.basic.rest.AuthProviderRESTExposure; import org.glyptodon.guacamole.net.basic.rest.auth.AuthenticationService; @@ -65,8 +65,8 @@ public class SchemaRESTService { * performing the operation. * * @return - * A collection of form fields which describe the possible attributes - * of a user object. + * A collection of forms which describe the possible attributes of a + * user object. * * @throws GuacamoleException * If an error occurs while retrieving the possible attributes. @@ -74,7 +74,7 @@ public class SchemaRESTService { @GET @Path("/users/attributes") @AuthProviderRESTExposure - public Collection getUserAttributes(@QueryParam("token") String authToken) throws GuacamoleException { + public Collection getUserAttributes(@QueryParam("token") String authToken) throws GuacamoleException { // Retrieve all possible user attributes UserContext userContext = authenticationService.getUserContext(authToken); @@ -90,8 +90,8 @@ public class SchemaRESTService { * performing the operation. * * @return - * A collection of form fields which describe the possible attributes - * of a connection object. + * A collection of forms which describe the possible attributes of a + * connection object. * * @throws GuacamoleException * If an error occurs while retrieving the possible attributes. @@ -99,7 +99,7 @@ public class SchemaRESTService { @GET @Path("/connections/attributes") @AuthProviderRESTExposure - public Collection getConnectionAttributes(@QueryParam("token") String authToken) throws GuacamoleException { + public Collection getConnectionAttributes(@QueryParam("token") String authToken) throws GuacamoleException { // Retrieve all possible connection attributes UserContext userContext = authenticationService.getUserContext(authToken); @@ -115,8 +115,8 @@ public class SchemaRESTService { * performing the operation. * * @return - * A collection of form fields which describe the possible attributes - * of a connection group object. + * A collection of forms which describe the possible attributes of a + * connection group object. * * @throws GuacamoleException * If an error occurs while retrieving the possible attributes. @@ -124,7 +124,7 @@ public class SchemaRESTService { @GET @Path("/connectionGroups/attributes") @AuthProviderRESTExposure - public Collection getConnectionGroupAttributes(@QueryParam("token") String authToken) throws GuacamoleException { + public Collection getConnectionGroupAttributes(@QueryParam("token") String authToken) throws GuacamoleException { // Retrieve all possible connection group attributes UserContext userContext = authenticationService.getUserContext(authToken); diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js index 8dd282d6b..c8a641d79 100644 --- a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js +++ b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js @@ -105,9 +105,10 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto /** * All available user attributes. This is only the set of attribute - * definitions, not attribute values. + * definitions, organized as logical groupings of attributes, not attribute + * values. * - * @type Field[] + * @type Form[] */ $scope.attributes = null; diff --git a/guacamole/src/main/webapp/app/rest/services/schemaService.js b/guacamole/src/main/webapp/app/rest/services/schemaService.js index bb8986fa2..0ca3596c5 100644 --- a/guacamole/src/main/webapp/app/rest/services/schemaService.js +++ b/guacamole/src/main/webapp/app/rest/services/schemaService.js @@ -36,12 +36,13 @@ angular.module('rest').factory('schemaService', ['$injector', /** * Makes a request to the REST API to get the list of available attributes * for user objects, returning a promise that provides an array of - * @link{Field} objects if successful. Each element of the array describes - * a possible attribute. + * @link{Form} objects if successful. Each element of the array describes + * a logical grouping of possible attributes. * - * @returns {Promise.} - * A promise which will resolve with an array of @link{Field} - * objects, where each @link{Field} describes a possible attribute. + * @returns {Promise.} + * A promise which will resolve with an array of @link{Form} + * objects, where each @link{Form} describes a logical grouping of + * possible attributes. */ service.getUserAttributes = function getUserAttributes() { @@ -63,12 +64,13 @@ angular.module('rest').factory('schemaService', ['$injector', /** * Makes a request to the REST API to get the list of available attributes * for connection objects, returning a promise that provides an array of - * @link{Field} objects if successful. Each element of the array describes - * a possible attribute. + * @link{Form} objects if successful. Each element of the array describes + * a logical grouping of possible attributes. * - * @returns {Promise.} - * A promise which will resolve with an array of @link{Field} - * objects, where each @link{Field} describes a possible attribute. + * @returns {Promise.} + * A promise which will resolve with an array of @link{Form} + * objects, where each @link{Form} describes a logical grouping of + * possible attributes. */ service.getConnectionAttributes = function getConnectionAttributes() { @@ -90,12 +92,13 @@ angular.module('rest').factory('schemaService', ['$injector', /** * Makes a request to the REST API to get the list of available attributes * for connection group objects, returning a promise that provides an array - * of @link{Field} objects if successful. Each element of the array - * describes a possible attribute. + * of @link{Form} objects if successful. Each element of the array + * a logical grouping of possible attributes. * - * @returns {Promise.} - * A promise which will resolve with an array of @link{Field} - * objects, where each @link{Field} describes a possible attribute. + * @returns {Promise.} + * A promise which will resolve with an array of @link{Form} + * objects, where each @link{Form} describes a logical grouping of + * possible attributes. */ service.getConnectionGroupAttributes = function getConnectionGroupAttributes() { From 3a619dbe0ad5acc1fa75fbec4a4b9ae39acc1c1e Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 26 May 2015 14:50:45 -0700 Subject: [PATCH 6/6] GUAC-800: Display connection and connection group attributes, if present. --- .../controllers/manageConnectionController.js | 15 +++++++++++++++ .../manageConnectionGroupController.js | 16 ++++++++++++++++ .../manage/controllers/manageUserController.js | 2 +- .../app/manage/templates/manageConnection.html | 5 +++++ .../manage/templates/manageConnectionGroup.html | 5 +++++ 5 files changed, 42 insertions(+), 1 deletion(-) diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js index 731950db3..04694f2dd 100644 --- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js +++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js @@ -145,6 +145,15 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i */ $scope.permissions = null; + /** + * All available connection attributes. This is only the set of attribute + * definitions, organized as logical groupings of attributes, not attribute + * values. + * + * @type Form[] + */ + $scope.attributes = null; + /** * Returns whether critical data has completed being loaded. * @@ -161,12 +170,18 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i && $scope.historyDateFormat !== null && $scope.historyEntryWrappers !== null && $scope.permissions !== null + && $scope.attributes !== null && $scope.canSaveConnection !== null && $scope.canDeleteConnection !== null && $scope.canCloneConnection !== null; }; + // Pull connection attribute schema + schemaService.getConnectionAttributes().success(function attributesReceived(attributes) { + $scope.attributes = attributes; + }); + // Pull connection group hierarchy connectionGroupService.getConnectionGroupTree(ConnectionGroup.ROOT_IDENTIFIER, [PermissionSet.ObjectPermissionType.ADMINISTER]) diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js index 86580d047..02119c4d0 100644 --- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js +++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js @@ -37,6 +37,7 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope' var connectionGroupService = $injector.get('connectionGroupService'); var guacNotification = $injector.get('guacNotification'); var permissionService = $injector.get('permissionService'); + var schemaService = $injector.get('schemaService'); /** * An action to be provided along with the object sent to showStatus which @@ -94,6 +95,15 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope' */ $scope.permissions = null; + /** + * All available connection group attributes. This is only the set of + * attribute definitions, organized as logical groupings of attributes, not + * attribute values. + * + * @type Form[] + */ + $scope.attributes = null; + /** * Returns whether critical data has completed being loaded. * @@ -106,11 +116,17 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope' return $scope.rootGroup !== null && $scope.connectionGroup !== null && $scope.permissions !== null + && $scope.attributes !== null && $scope.canSaveConnectionGroup !== null && $scope.canDeleteConnectionGroup !== null; }; + // Pull connection group attribute schema + schemaService.getConnectionGroupAttributes().success(function attributesReceived(attributes) { + $scope.attributes = attributes; + }); + // Query the user's permissions for the current connection group permissionService.getPermissions(authenticationService.getCurrentUserID()) .success(function permissionsReceived(permissions) { diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js index c8a641d79..e1e89e82c 100644 --- a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js +++ b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js @@ -37,9 +37,9 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto var authenticationService = $injector.get('authenticationService'); var connectionGroupService = $injector.get('connectionGroupService'); var guacNotification = $injector.get('guacNotification'); - var userService = $injector.get('userService'); var permissionService = $injector.get('permissionService'); var schemaService = $injector.get('schemaService'); + var userService = $injector.get('userService'); /** * An action to be provided along with the object sent to showStatus which diff --git a/guacamole/src/main/webapp/app/manage/templates/manageConnection.html b/guacamole/src/main/webapp/app/manage/templates/manageConnection.html index fabe59dcb..1ea45baa5 100644 --- a/guacamole/src/main/webapp/app/manage/templates/manageConnection.html +++ b/guacamole/src/main/webapp/app/manage/templates/manageConnection.html @@ -57,6 +57,11 @@ THE SOFTWARE.
+ +
+ +
+

{{'MANAGE_CONNECTION.SECTION_HEADER_PARAMETERS' | translate}}

diff --git a/guacamole/src/main/webapp/app/manage/templates/manageConnectionGroup.html b/guacamole/src/main/webapp/app/manage/templates/manageConnectionGroup.html index f1fb395df..370aa8a9b 100644 --- a/guacamole/src/main/webapp/app/manage/templates/manageConnectionGroup.html +++ b/guacamole/src/main/webapp/app/manage/templates/manageConnectionGroup.html @@ -57,6 +57,11 @@ THE SOFTWARE.
+ +
+ +
+