From b2871e7da0cba79e92b70582244c1b22ac09b4d6 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 22 Feb 2017 01:23:14 -0800 Subject: [PATCH 01/10] GUACAMOLE-292: Allow restriction of form contents to defined values only. --- .../main/webapp/app/form/directives/form.js | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/guacamole/src/main/webapp/app/form/directives/form.js b/guacamole/src/main/webapp/app/form/directives/form.js index 518db7dba..a6d44f31c 100644 --- a/guacamole/src/main/webapp/app/form/directives/form.js +++ b/guacamole/src/main/webapp/app/form/directives/form.js @@ -64,7 +64,16 @@ angular.module('form').directive('guacForm', [function form() { * * @type Boolean */ - modelOnly : '=' + modelOnly : '=', + + /** + * Whether the contents of the form should be restricted to those + * fields/forms which have associated values defined within the + * given model object. By default, all fields will be shown. + * + * @type Boolean + */ + valuesOnly : '=' }, templateUrl: 'app/form/templates/form.html', @@ -184,14 +193,18 @@ angular.module('form').directive('guacForm', [function form() { */ $scope.isVisible = function isVisible(field) { - // All fields are visible if contents are not restricted to - // model properties only - if (!$scope.modelOnly) - return true; + // Forms with valuesOnly set should display only fields with + // associated values in the model object + if ($scope.valuesOnly) + return field && $scope.values[field.name]; - // Otherwise, fields are only visible if they are present - // within the model - return field && (field.name in $scope.values); + // Forms with modelOnly set should display only fields with + // associated properties in the model object + if ($scope.modelOnly) + return field && (field.name in $scope.values); + + // Otherwise, all fields are visible + return true; }; From afd051e59f947c2d14e29940ddb12ab9e42ee278 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 22 Feb 2017 00:16:14 -0800 Subject: [PATCH 02/10] GUACAMOLE-292: Add stub attributes for full name and email. --- .../guacamole/auth/jdbc/user/ModeledUser.java | 64 +++++++++++++++++++ .../src/main/resources/translations/en.json | 5 +- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java index 052849520..b3852e717 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java @@ -45,6 +45,7 @@ import org.apache.guacamole.form.BooleanField; import org.apache.guacamole.form.DateField; import org.apache.guacamole.form.Field; import org.apache.guacamole.form.Form; +import org.apache.guacamole.form.TextField; import org.apache.guacamole.form.TimeField; import org.apache.guacamole.form.TimeZoneField; import org.apache.guacamole.net.auth.User; @@ -64,6 +65,17 @@ public class ModeledUser extends ModeledDirectoryObject implements Us */ private static final Logger logger = LoggerFactory.getLogger(ModeledUser.class); + /** + * The name of the attribute which holds the user's full name, if known. + */ + public static final String FULL_NAME_ATTRIBUTE_NAME = "full-name"; + + /** + * The name of the attribute which holds the user's email address, if + * known. + */ + public static final String EMAIL_ADDRESS_ATTRIBUTE_NAME = "email-address"; + /** * The name of the attribute which controls whether a user account is * disabled. @@ -106,6 +118,15 @@ public class ModeledUser extends ModeledDirectoryObject implements Us */ public static final String TIMEZONE_ATTRIBUTE_NAME = "timezone"; + /** + * All attributes related to user profile information, within a logical + * form. + */ + public static final Form PROFILE = new Form("profile", Arrays.asList( + new TextField(FULL_NAME_ATTRIBUTE_NAME), + new TextField(EMAIL_ADDRESS_ATTRIBUTE_NAME) + )); + /** * All attributes related to restricting user accounts, within a logical * form. @@ -125,6 +146,7 @@ public class ModeledUser extends ModeledDirectoryObject implements Us * logical forms. */ public static final Collection
ATTRIBUTES = Collections.unmodifiableCollection(Arrays.asList( + PROFILE, ACCOUNT_RESTRICTIONS )); @@ -371,6 +393,25 @@ public class ModeledUser extends ModeledDirectoryObject implements Us } + /** + * Stores all unrestricted (unprivileged) attributes within the given Map, + * pulling the values of those attributes from the underlying user model. + * If no value is yet defined for an attribute, that attribute will be set + * to null. + * + * @param attributes + * The Map to store all unrestricted attributes within. + */ + private void putUnrestrictedAttributes(Map attributes) { + + // Set full name attribute + attributes.put(FULL_NAME_ATTRIBUTE_NAME, "Testy McTesterson"); // TODO + + // Set email address attribute + attributes.put(EMAIL_ADDRESS_ATTRIBUTE_NAME, "test@test.test"); // TODO + + } + /** * Parses the given string into a corresponding date. The string must * follow the standard format used by date attributes, as defined by @@ -477,11 +518,31 @@ public class ModeledUser extends ModeledDirectoryObject implements Us } + /** + * Stores all unrestricted (unprivileged) attributes within the underlying + * user model, pulling the values of those attributes from the given Map. + * + * @param attributes + * The Map to pull all unrestricted attributes from. + */ + private void setUnrestrictedAttributes(Map attributes) { + + // Translate full name attribute + logger.info("FULL NAME: \"{}\"", attributes.get(FULL_NAME_ATTRIBUTE_NAME)); // TODO + + // Translate email address attribute + logger.info("EMAIL ADDRESS: \"{}\"", attributes.get(EMAIL_ADDRESS_ATTRIBUTE_NAME)); // TODO + + } + @Override public Map getAttributes() { Map attributes = new HashMap(); + // Always include unrestricted attributes + putUnrestrictedAttributes(attributes); + // Include restricted attributes only if they should be exposed if (exposeRestrictedAttributes) putRestrictedAttributes(attributes); @@ -492,6 +553,9 @@ public class ModeledUser extends ModeledDirectoryObject implements Us @Override public void setAttributes(Map attributes) { + // Always assign unrestricted attributes + setUnrestrictedAttributes(attributes); + // Assign restricted attributes only if they are exposed if (exposeRestrictedAttributes) setRestrictedAttributes(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 f182aacb7..c6ce14b04 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 @@ -79,13 +79,16 @@ "FIELD_HEADER_DISABLED" : "Login disabled:", "FIELD_HEADER_EXPIRED" : "Password expired:", + "FIELD_HEADER_EMAIL_ADDRESS" : "Email address:", + "FIELD_HEADER_FULL_NAME" : "Full name:", "FIELD_HEADER_ACCESS_WINDOW_END" : "Do not allow access after:", "FIELD_HEADER_ACCESS_WINDOW_START" : "Allow access after:", "FIELD_HEADER_TIMEZONE" : "User time zone:", "FIELD_HEADER_VALID_FROM" : "Enable account after:", "FIELD_HEADER_VALID_UNTIL" : "Disable account after:", - "SECTION_HEADER_RESTRICTIONS" : "Account Restrictions" + "SECTION_HEADER_RESTRICTIONS" : "Account Restrictions", + "SECTION_HEADER_PROFILE" : "Profile" } From 8830123c9b38fb838dff1701b005c311adaf77e4 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 22 Feb 2017 01:04:27 -0800 Subject: [PATCH 03/10] GUACAMOLE-292: Add support for email fields. --- .../org/apache/guacamole/form/EmailField.java | 37 +++++++++++++++++++ .../java/org/apache/guacamole/form/Field.java | 6 +++ .../webapp/app/form/services/formService.js | 10 +++++ .../webapp/app/form/templates/emailField.html | 8 ++++ .../main/webapp/app/index/styles/input.css | 4 +- .../webapp/app/manage/styles/attributes.css | 1 + .../manage/styles/connection-parameter.css | 1 + .../src/main/webapp/app/rest/types/Field.js | 8 ++++ 8 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 guacamole-ext/src/main/java/org/apache/guacamole/form/EmailField.java create mode 100644 guacamole/src/main/webapp/app/form/templates/emailField.html diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/form/EmailField.java b/guacamole-ext/src/main/java/org/apache/guacamole/form/EmailField.java new file mode 100644 index 000000000..e56a75786 --- /dev/null +++ b/guacamole-ext/src/main/java/org/apache/guacamole/form/EmailField.java @@ -0,0 +1,37 @@ +/* + * 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.form; + +/** + * Represents a text field which may contain an email address. + */ +public class EmailField extends Field { + + /** + * Creates a new EmailField with the given name. + * + * @param name + * The unique name to associate with this field. + */ + public EmailField(String name) { + super(name, Field.Type.EMAIL); + } + +} diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/form/Field.java b/guacamole-ext/src/main/java/org/apache/guacamole/form/Field.java index dba10654c..19f1ead09 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/form/Field.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/form/Field.java @@ -47,6 +47,12 @@ public class Field { */ public static String TEXT = "TEXT"; + /** + * An email address field. This field type generally behaves + * identically to arbitrary text fields, but has semantic differences. + */ + public static String EMAIL = "EMAIL"; + /** * A username field. This field type generally behaves identically to * arbitrary text fields, but has semantic differences. diff --git a/guacamole/src/main/webapp/app/form/services/formService.js b/guacamole/src/main/webapp/app/form/services/formService.js index 0d12259ad..c117bbf7f 100644 --- a/guacamole/src/main/webapp/app/form/services/formService.js +++ b/guacamole/src/main/webapp/app/form/services/formService.js @@ -47,6 +47,16 @@ angular.module('form').provider('formService', function formServiceProvider() { templateUrl : 'app/form/templates/textField.html' }, + /** + * Email address field type. + * + * @see {@link Field.Type.EMAIL} + * @type FieldType + */ + 'EMAIL' : { + templateUrl : 'app/form/templates/emailField.html' + }, + /** * Numeric field type. * diff --git a/guacamole/src/main/webapp/app/form/templates/emailField.html b/guacamole/src/main/webapp/app/form/templates/emailField.html new file mode 100644 index 000000000..db6d3beda --- /dev/null +++ b/guacamole/src/main/webapp/app/form/templates/emailField.html @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/guacamole/src/main/webapp/app/index/styles/input.css b/guacamole/src/main/webapp/app/index/styles/input.css index 1eb8d9b71..4141c768c 100644 --- a/guacamole/src/main/webapp/app/index/styles/input.css +++ b/guacamole/src/main/webapp/app/index/styles/input.css @@ -17,11 +17,11 @@ * under the License. */ -input[type=checkbox], input[type=number], input[type=text], input[type=radio], label, textarea { +input[type=checkbox], input[type=number], input[type=text], input[type=email], input[type=radio], label, textarea { -webkit-tap-highlight-color: rgba(128,192,128,0.5); } -div.location, input[type=text], input[type=number], input[type=password], textarea { +div.location, input[type=text], input[type=email], input[type=number], input[type=password], textarea { border: 1px solid #777; -moz-border-radius: 0.2em; -webkit-border-radius: 0.2em; diff --git a/guacamole/src/main/webapp/app/manage/styles/attributes.css b/guacamole/src/main/webapp/app/manage/styles/attributes.css index 136ec5dee..2b5bc92fc 100644 --- a/guacamole/src/main/webapp/app/manage/styles/attributes.css +++ b/guacamole/src/main/webapp/app/manage/styles/attributes.css @@ -19,6 +19,7 @@ /* Do not stretch attributes to fit available area */ .attributes input[type=text], +.attributes input[type=email], .attributes input[type=password], .attributes input[type=number] { width: auto; diff --git a/guacamole/src/main/webapp/app/manage/styles/connection-parameter.css b/guacamole/src/main/webapp/app/manage/styles/connection-parameter.css index a005703a1..8fe19d691 100644 --- a/guacamole/src/main/webapp/app/manage/styles/connection-parameter.css +++ b/guacamole/src/main/webapp/app/manage/styles/connection-parameter.css @@ -19,6 +19,7 @@ /* Do not stretch connection parameters to fit available area */ .connection-parameters input[type=text], +.connection-parameters input[type=email], .connection-parameters input[type=password], .connection-parameters input[type=number] { width: auto; diff --git a/guacamole/src/main/webapp/app/rest/types/Field.js b/guacamole/src/main/webapp/app/rest/types/Field.js index 5204268d3..84dfe13b5 100644 --- a/guacamole/src/main/webapp/app/rest/types/Field.js +++ b/guacamole/src/main/webapp/app/rest/types/Field.js @@ -75,6 +75,14 @@ angular.module('rest').factory('Field', [function defineField() { */ TEXT : 'TEXT', + /** + * The type string associated with parameters that may contain an email + * address. + * + * @type String + */ + EMAIL : 'EMAIL', + /** * The type string associated with parameters that may contain an * arbitrary string, where that string represents the username of the From 6327fa3a17d9fd6e2647a5d61d7ec8a91d4ec7f3 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 22 Feb 2017 01:06:11 -0800 Subject: [PATCH 04/10] GUACAMOLE-292: Use email field type for email address. --- .../java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java index b3852e717..1c6582749 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java @@ -43,6 +43,7 @@ import org.apache.guacamole.auth.jdbc.permission.SharingProfilePermissionService import org.apache.guacamole.auth.jdbc.permission.UserPermissionService; import org.apache.guacamole.form.BooleanField; import org.apache.guacamole.form.DateField; +import org.apache.guacamole.form.EmailField; import org.apache.guacamole.form.Field; import org.apache.guacamole.form.Form; import org.apache.guacamole.form.TextField; @@ -124,7 +125,7 @@ public class ModeledUser extends ModeledDirectoryObject implements Us */ public static final Form PROFILE = new Form("profile", Arrays.asList( new TextField(FULL_NAME_ATTRIBUTE_NAME), - new TextField(EMAIL_ADDRESS_ATTRIBUTE_NAME) + new EmailField(EMAIL_ADDRESS_ATTRIBUTE_NAME) )); /** From e9549fbb3bc21f756445dbda137cfb91a3ff5e44 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 22 Feb 2017 01:26:11 -0800 Subject: [PATCH 05/10] GUACAMOLE-292: Display user attributes within user menu. --- .../app/navigation/directives/guacUserMenu.js | 14 ++++++++++++++ .../main/webapp/app/navigation/navigationModule.js | 1 + .../webapp/app/navigation/styles/user-menu.css | 12 ++++++++++++ .../app/navigation/templates/guacUserMenu.html | 7 +++++++ 4 files changed, 34 insertions(+) diff --git a/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js b/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js index f94d006c7..0905011bb 100644 --- a/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js +++ b/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js @@ -47,6 +47,8 @@ angular.module('navigation').directive('guacUserMenu', [function guacUserMenu() var $location = $injector.get('$location'); var $route = $injector.get('$route'); var authenticationService = $injector.get('authenticationService'); + var schemaService = $injector.get('schemaService'); + var userService = $injector.get('userService'); var userPageService = $injector.get('userPageService'); /** @@ -56,6 +58,18 @@ angular.module('navigation').directive('guacUserMenu', [function guacUserMenu() */ $scope.username = authenticationService.getCurrentUsername(); + // Pull user attribute schema + schemaService.getUserAttributes(authenticationService.getDataSource()) + .success(function attributesReceived(attributes) { + $scope.attributes = attributes; + }); + + // Pull user data + userService.getUser(authenticationService.getDataSource(), $scope.username) + .success(function userRetrieved(user) { + $scope.user = user; + }); + /** * The available main pages for the current user. * diff --git a/guacamole/src/main/webapp/app/navigation/navigationModule.js b/guacamole/src/main/webapp/app/navigation/navigationModule.js index 332dcb8b7..24c63e3c3 100644 --- a/guacamole/src/main/webapp/app/navigation/navigationModule.js +++ b/guacamole/src/main/webapp/app/navigation/navigationModule.js @@ -22,6 +22,7 @@ */ angular.module('navigation', [ 'auth', + 'form', 'notification', 'rest' ]); diff --git a/guacamole/src/main/webapp/app/navigation/styles/user-menu.css b/guacamole/src/main/webapp/app/navigation/styles/user-menu.css index b7fce98e6..a1ba79720 100644 --- a/guacamole/src/main/webapp/app/navigation/styles/user-menu.css +++ b/guacamole/src/main/webapp/app/navigation/styles/user-menu.css @@ -82,3 +82,15 @@ .user-menu .menu-dropdown .menu-contents li a.logout { background-image: url('images/action-icons/guac-logout-dark.png'); } + +.user-menu .menu-dropdown .menu-contents .profile { + margin: 1em; + padding-bottom: 1em; + border-bottom: 1px solid rgba(0, 0, 0, 0.25); + width: 2in; +} + +.user-menu .menu-dropdown .menu-contents .profile span.field-header, +.user-menu .menu-dropdown .menu-contents .profile h3 { + display: none; +} diff --git a/guacamole/src/main/webapp/app/navigation/templates/guacUserMenu.html b/guacamole/src/main/webapp/app/navigation/templates/guacUserMenu.html index 4ffd937ca..5640b3c85 100644 --- a/guacamole/src/main/webapp/app/navigation/templates/guacUserMenu.html +++ b/guacamole/src/main/webapp/app/navigation/templates/guacUserMenu.html @@ -1,6 +1,13 @@
+ +
+ +
+
  • From 9634731fe69c9ce1501880cd6bf38fd755eb9e72 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 24 Feb 2017 01:50:26 -0800 Subject: [PATCH 06/10] GUACAMOLE-292: Define and use standard attributes for user full name and email. --- .../guacamole/auth/jdbc/user/ModeledUser.java | 23 +++++------------ .../src/main/resources/translations/en.json | 2 -- .../org/apache/guacamole/net/auth/User.java | 21 ++++++++++++++++ .../src/main/webapp/app/rest/types/User.js | 25 +++++++++++++++++++ .../src/main/webapp/translations/en.json | 7 ++++++ 5 files changed, 59 insertions(+), 19 deletions(-) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java index 1c6582749..c2c7f7212 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java @@ -66,17 +66,6 @@ public class ModeledUser extends ModeledDirectoryObject implements Us */ private static final Logger logger = LoggerFactory.getLogger(ModeledUser.class); - /** - * The name of the attribute which holds the user's full name, if known. - */ - public static final String FULL_NAME_ATTRIBUTE_NAME = "full-name"; - - /** - * The name of the attribute which holds the user's email address, if - * known. - */ - public static final String EMAIL_ADDRESS_ATTRIBUTE_NAME = "email-address"; - /** * The name of the attribute which controls whether a user account is * disabled. @@ -124,8 +113,8 @@ public class ModeledUser extends ModeledDirectoryObject implements Us * form. */ public static final Form PROFILE = new Form("profile", Arrays.asList( - new TextField(FULL_NAME_ATTRIBUTE_NAME), - new EmailField(EMAIL_ADDRESS_ATTRIBUTE_NAME) + new TextField(User.Attribute.FULL_NAME), + new EmailField(User.Attribute.EMAIL_ADDRESS) )); /** @@ -406,10 +395,10 @@ public class ModeledUser extends ModeledDirectoryObject implements Us private void putUnrestrictedAttributes(Map attributes) { // Set full name attribute - attributes.put(FULL_NAME_ATTRIBUTE_NAME, "Testy McTesterson"); // TODO + attributes.put(User.Attribute.FULL_NAME, "Testy McTesterson"); // TODO // Set email address attribute - attributes.put(EMAIL_ADDRESS_ATTRIBUTE_NAME, "test@test.test"); // TODO + attributes.put(User.Attribute.EMAIL_ADDRESS, "test@test.test"); // TODO } @@ -529,10 +518,10 @@ public class ModeledUser extends ModeledDirectoryObject implements Us private void setUnrestrictedAttributes(Map attributes) { // Translate full name attribute - logger.info("FULL NAME: \"{}\"", attributes.get(FULL_NAME_ATTRIBUTE_NAME)); // TODO + logger.info("FULL NAME: \"{}\"", attributes.get(User.Attribute.FULL_NAME)); // TODO // Translate email address attribute - logger.info("EMAIL ADDRESS: \"{}\"", attributes.get(EMAIL_ADDRESS_ATTRIBUTE_NAME)); // TODO + logger.info("EMAIL ADDRESS: \"{}\"", attributes.get(User.Attribute.EMAIL_ADDRESS)); // TODO } 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 c6ce14b04..bf73c35d8 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 @@ -79,8 +79,6 @@ "FIELD_HEADER_DISABLED" : "Login disabled:", "FIELD_HEADER_EXPIRED" : "Password expired:", - "FIELD_HEADER_EMAIL_ADDRESS" : "Email address:", - "FIELD_HEADER_FULL_NAME" : "Full name:", "FIELD_HEADER_ACCESS_WINDOW_END" : "Do not allow access after:", "FIELD_HEADER_ACCESS_WINDOW_START" : "Allow access after:", "FIELD_HEADER_TIMEZONE" : "User time zone:", diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/User.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/User.java index 90167e4e2..1d365837f 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/User.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/User.java @@ -30,6 +30,27 @@ import org.apache.guacamole.net.auth.permission.SystemPermissionSet; */ public interface User extends Identifiable { + /** + * All standard attribute names with semantics defined by the Guacamole web + * application. Extensions may additionally define their own attributes + * with completely arbitrary names and semantics, so long as those names do + * not conflict with the names listed here. All standard attribute names + * have a "guac-" prefix to avoid such conflicts. + */ + public static class Attribute { + + /** + * The user's full name. + */ + public static String FULL_NAME = "guac-full-name"; + + /** + * The email address of the user. + */ + public static String EMAIL_ADDRESS = "guac-email-address"; + + } + /** * Returns this user's password. Note that the password returned may be * hashed or completely arbitrary. diff --git a/guacamole/src/main/webapp/app/rest/types/User.js b/guacamole/src/main/webapp/app/rest/types/User.js index 4a808b164..b6df12b04 100644 --- a/guacamole/src/main/webapp/app/rest/types/User.js +++ b/guacamole/src/main/webapp/app/rest/types/User.js @@ -64,6 +64,31 @@ angular.module('rest').factory('User', [function defineUser() { }; + /** + * All standard attribute names with semantics defined by the Guacamole web + * application. Extensions may additionally define their own attributes + * with completely arbitrary names and semantics, so long as those names do + * not conflict with the names listed here. All standard attribute names + * have a "guac-" prefix to avoid such conflicts. + */ + User.Attributes = { + + /** + * The user's full name. + * + * @type String + */ + FULL_NAME : 'guac-full-name', + + /** + * The email address of the user. + * + * @type String + */ + EMAIL_ADDRESS : 'guac-email-address' + + }; + return User; }]); \ No newline at end of file diff --git a/guacamole/src/main/webapp/translations/en.json b/guacamole/src/main/webapp/translations/en.json index 512524a89..79a7ea7fd 100644 --- a/guacamole/src/main/webapp/translations/en.json +++ b/guacamole/src/main/webapp/translations/en.json @@ -697,6 +697,13 @@ }, + "USER_ATTRIBUTES" : { + + "FIELD_HEADER_GUAC_EMAIL_ADDRESS" : "Email address:", + "FIELD_HEADER_GUAC_FULL_NAME" : "Full name:" + + }, + "USER_MENU" : { "ACTION_LOGOUT" : "@:APP.ACTION_LOGOUT", From ee6edb9c82eb73b5c38c7ab13bd3750c80fd2c7f Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 24 Feb 2017 01:54:41 -0800 Subject: [PATCH 07/10] GUACAMOLE-292: Define and use standard attributes for user organization and role. --- .../guacamole/auth/jdbc/user/ModeledUser.java | 16 +++++++++++++++- .../org/apache/guacamole/net/auth/User.java | 11 +++++++++++ .../src/main/webapp/app/rest/types/User.js | 17 ++++++++++++++++- guacamole/src/main/webapp/translations/en.json | 6 ++++-- 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java index c2c7f7212..418fe8012 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java @@ -114,7 +114,9 @@ public class ModeledUser extends ModeledDirectoryObject implements Us */ public static final Form PROFILE = new Form("profile", Arrays.asList( new TextField(User.Attribute.FULL_NAME), - new EmailField(User.Attribute.EMAIL_ADDRESS) + new EmailField(User.Attribute.EMAIL_ADDRESS), + new TextField(User.Attribute.ORGANIZATION), + new TextField(User.Attribute.ORGANIZATIONAL_ROLE) )); /** @@ -400,6 +402,12 @@ public class ModeledUser extends ModeledDirectoryObject implements Us // Set email address attribute attributes.put(User.Attribute.EMAIL_ADDRESS, "test@test.test"); // TODO + // Set organization attribute + attributes.put(User.Attribute.ORGANIZATION, "Example, Inc."); // TODO + + // Set role attribute + attributes.put(User.Attribute.ORGANIZATIONAL_ROLE, "Senior Lead Architect"); // TODO + } /** @@ -523,6 +531,12 @@ public class ModeledUser extends ModeledDirectoryObject implements Us // Translate email address attribute logger.info("EMAIL ADDRESS: \"{}\"", attributes.get(User.Attribute.EMAIL_ADDRESS)); // TODO + // Translate organization attribute + logger.info("ORGANIZATION: \"{}\"", attributes.get(User.Attribute.ORGANIZATION)); // TODO + + // Translate role attribute + logger.info("ORGANIZATIONAL ROLE: \"{}\"", attributes.get(User.Attribute.ORGANIZATIONAL_ROLE)); // TODO + } @Override diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/User.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/User.java index 1d365837f..88756e495 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/User.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/User.java @@ -49,6 +49,17 @@ public interface User extends Identifiable { */ public static String EMAIL_ADDRESS = "guac-email-address"; + /** + * The organization, company, group, etc. that the user belongs to. + */ + public static String ORGANIZATION = "guac-organization"; + + /** + * The role that the user has at the organization, company, group, etc. + * they belong to. + */ + public static String ORGANIZATIONAL_ROLE = "guac-organizational-role"; + } /** diff --git a/guacamole/src/main/webapp/app/rest/types/User.js b/guacamole/src/main/webapp/app/rest/types/User.js index b6df12b04..9edd1f258 100644 --- a/guacamole/src/main/webapp/app/rest/types/User.js +++ b/guacamole/src/main/webapp/app/rest/types/User.js @@ -85,7 +85,22 @@ angular.module('rest').factory('User', [function defineUser() { * * @type String */ - EMAIL_ADDRESS : 'guac-email-address' + EMAIL_ADDRESS : 'guac-email-address', + + /** + * The organization, company, group, etc. that the user belongs to. + * + * @type String + */ + ORGANIZATION : 'guac-organization', + + /** + * The role that the user has at the organization, company, group, etc. + * they belong to. + * + * @type String + */ + ORGANIZATIONAL_ROLE : 'guac-organizational-role' }; diff --git a/guacamole/src/main/webapp/translations/en.json b/guacamole/src/main/webapp/translations/en.json index 79a7ea7fd..4995f54c8 100644 --- a/guacamole/src/main/webapp/translations/en.json +++ b/guacamole/src/main/webapp/translations/en.json @@ -699,8 +699,10 @@ "USER_ATTRIBUTES" : { - "FIELD_HEADER_GUAC_EMAIL_ADDRESS" : "Email address:", - "FIELD_HEADER_GUAC_FULL_NAME" : "Full name:" + "FIELD_HEADER_GUAC_EMAIL_ADDRESS" : "Email address:", + "FIELD_HEADER_GUAC_FULL_NAME" : "Full name:", + "FIELD_HEADER_GUAC_ORGANIZATION" : "Organization:", + "FIELD_HEADER_GUAC_ORGANIZATIONAL_ROLE" : "Role:" }, From 06fb054ae24c991d7a664e01e53f577a79701938 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 6 Mar 2017 16:19:08 -0800 Subject: [PATCH 08/10] GUACAMOLE-292: Explicitly pull standard attributes when rendering user menu; do not rely on schema. --- .../app/navigation/directives/guacUserMenu.js | 56 ++++++++++++++++--- .../app/navigation/styles/user-menu.css | 9 ++- .../navigation/templates/guacUserMenu.html | 8 +-- 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js b/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js index 0905011bb..9534dd444 100644 --- a/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js +++ b/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js @@ -43,11 +43,13 @@ angular.module('navigation').directive('guacUserMenu', [function guacUserMenu() controller: ['$scope', '$injector', function guacUserMenuController($scope, $injector) { + // Required types + var User = $injector.get('User'); + // Get required services var $location = $injector.get('$location'); var $route = $injector.get('$route'); var authenticationService = $injector.get('authenticationService'); - var schemaService = $injector.get('schemaService'); var userService = $injector.get('userService'); var userPageService = $injector.get('userPageService'); @@ -57,17 +59,57 @@ angular.module('navigation').directive('guacUserMenu', [function guacUserMenu() * @type String */ $scope.username = authenticationService.getCurrentUsername(); - - // Pull user attribute schema - schemaService.getUserAttributes(authenticationService.getDataSource()) - .success(function attributesReceived(attributes) { - $scope.attributes = attributes; - }); + + /** + * The user's full name. If not yet available, or if not defined, + * this will be null. + * + * @type String + */ + $scope.fullName = null; + + /** + * A URL pointing to relevant user information such as the user's + * email address. If not yet available, or if no such URL can be + * determined, this will be null. + * + * @type String + */ + $scope.userURL = null; + + /** + * The organization, company, group, etc. that the user belongs to. + * If not yet available, or if not defined, this will be null. + * + * @type String + */ + $scope.organization = null; + + /** + * The role that the user has at the organization, company, group, + * etc. they belong to. If not yet available, or if not defined, + * this will be null. + * + * @type String + */ + $scope.role = null; // Pull user data userService.getUser(authenticationService.getDataSource(), $scope.username) .success(function userRetrieved(user) { + + // Store retrieved user object $scope.user = user; + + // Pull basic profile information + $scope.fullName = user.attributes[User.Attributes.FULL_NAME]; + $scope.organization = user.attributes[User.Attributes.ORGANIZATION]; + $scope.role = user.attributes[User.Attributes.ORGANIZATIONAL_ROLE]; + + // Link to email address if available + var email = user.attributes[User.Attributes.EMAIL_ADDRESS]; + $scope.userURL = email ? 'mailto:' + email : null; + }); /** diff --git a/guacamole/src/main/webapp/app/navigation/styles/user-menu.css b/guacamole/src/main/webapp/app/navigation/styles/user-menu.css index a1ba79720..d7759acd5 100644 --- a/guacamole/src/main/webapp/app/navigation/styles/user-menu.css +++ b/guacamole/src/main/webapp/app/navigation/styles/user-menu.css @@ -90,7 +90,10 @@ width: 2in; } -.user-menu .menu-dropdown .menu-contents .profile span.field-header, -.user-menu .menu-dropdown .menu-contents .profile h3 { - display: none; +.user-menu .menu-dropdown .menu-contents .profile .full-name { + font-weight: bold; } +.user-menu .menu-dropdown .menu-contents .profile .organization, +.user-menu .menu-dropdown .menu-contents .profile .organizational-role { + font-size: 0.8em; +} \ No newline at end of file diff --git a/guacamole/src/main/webapp/app/navigation/templates/guacUserMenu.html b/guacamole/src/main/webapp/app/navigation/templates/guacUserMenu.html index 5640b3c85..9869cd6e8 100644 --- a/guacamole/src/main/webapp/app/navigation/templates/guacUserMenu.html +++ b/guacamole/src/main/webapp/app/navigation/templates/guacUserMenu.html @@ -2,10 +2,10 @@ -
    - +
    + +
    {{ role }}
    +
    {{ organization }}
    From a34d3facc4c99354d4262101e9c516f36b25c675 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 7 Mar 2017 13:23:13 -0800 Subject: [PATCH 09/10] GUACAMOLE-292: Store user profile information within PostgreSQL/MySQL database. --- .../guacamole/auth/jdbc/user/ModeledUser.java | 16 +-- .../guacamole/auth/jdbc/user/UserModel.java | 111 ++++++++++++++++++ .../schema/001-create-schema.sql | 6 + .../schema/upgrade/upgrade-pre-0.9.13.sql | 10 ++ .../guacamole/auth/jdbc/user/UserMapper.xml | 62 +++++++--- .../schema/001-create-schema.sql | 6 + .../schema/upgrade/upgrade-pre-0.9.13.sql | 10 ++ .../guacamole/auth/jdbc/user/UserMapper.xml | 64 +++++++--- 8 files changed, 242 insertions(+), 43 deletions(-) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java index 418fe8012..418ffad81 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java @@ -397,16 +397,16 @@ public class ModeledUser extends ModeledDirectoryObject implements Us private void putUnrestrictedAttributes(Map attributes) { // Set full name attribute - attributes.put(User.Attribute.FULL_NAME, "Testy McTesterson"); // TODO + attributes.put(User.Attribute.FULL_NAME, getModel().getFullName()); // Set email address attribute - attributes.put(User.Attribute.EMAIL_ADDRESS, "test@test.test"); // TODO + attributes.put(User.Attribute.EMAIL_ADDRESS, getModel().getEmailAddress()); // Set organization attribute - attributes.put(User.Attribute.ORGANIZATION, "Example, Inc."); // TODO + attributes.put(User.Attribute.ORGANIZATION, getModel().getOrganization()); // Set role attribute - attributes.put(User.Attribute.ORGANIZATIONAL_ROLE, "Senior Lead Architect"); // TODO + attributes.put(User.Attribute.ORGANIZATIONAL_ROLE, getModel().getOrganizationalRole()); } @@ -526,16 +526,16 @@ public class ModeledUser extends ModeledDirectoryObject implements Us private void setUnrestrictedAttributes(Map attributes) { // Translate full name attribute - logger.info("FULL NAME: \"{}\"", attributes.get(User.Attribute.FULL_NAME)); // TODO + getModel().setFullName(attributes.get(User.Attribute.FULL_NAME)); // Translate email address attribute - logger.info("EMAIL ADDRESS: \"{}\"", attributes.get(User.Attribute.EMAIL_ADDRESS)); // TODO + getModel().setEmailAddress(attributes.get(User.Attribute.EMAIL_ADDRESS)); // Translate organization attribute - logger.info("ORGANIZATION: \"{}\"", attributes.get(User.Attribute.ORGANIZATION)); // TODO + getModel().setOrganization(attributes.get(User.Attribute.ORGANIZATION)); // Translate role attribute - logger.info("ORGANIZATIONAL ROLE: \"{}\"", attributes.get(User.Attribute.ORGANIZATIONAL_ROLE)); // TODO + getModel().setOrganizationalRole(attributes.get(User.Attribute.ORGANIZATIONAL_ROLE)); } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserModel.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserModel.java index 4dfb27596..2376caed9 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserModel.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserModel.java @@ -92,6 +92,28 @@ public class UserModel extends ObjectModel { */ private String timeZone; + /** + * The user's full name, or null if this is not known. + */ + private String fullName; + + /** + * The email address of the user, or null if this is not known. + */ + private String emailAddress; + + /** + * The organization, company, group, etc. that the user belongs to, or null + * if this is not known. + */ + private String organization; + + /** + * The role that the user has at the organization, company, group, etc. + * they belong to, or null if this is not known. + */ + private String organizationalRole; + /** * Creates a new, empty user. */ @@ -351,4 +373,93 @@ public class UserModel extends ObjectModel { this.timeZone = timeZone; } + /** + * Returns the user's full name, if known. If not available, null is + * returned. + * + * @return + * The user's full name, or null if this is not known. + */ + public String getFullName() { + return fullName; + } + + /** + * Sets the user's full name. + * + * @param fullName + * The user's full name, or null if this is not known. + */ + public void setFullName(String fullName) { + this.fullName = fullName; + } + + /** + * Returns the email address of the user, if known. If not available, null + * is returned. + * + * @return + * The email address of the user, or null if this is not known. + */ + public String getEmailAddress() { + return emailAddress; + } + + /** + * Sets the email address of the user. + * + * @param emailAddress + * The email address of the user, or null if this is not known. + */ + public void setEmailAddress(String emailAddress) { + this.emailAddress = emailAddress; + } + + /** + * Returns the organization, company, group, etc. that the user belongs to, + * if known. If not available, null is returned. + * + * @return + * The organization, company, group, etc. that the user belongs to, or + * null if this is not known. + */ + public String getOrganization() { + return organization; + } + + /** + * Sets the organization, company, group, etc. that the user belongs to. + * + * @param organization + * The organization, company, group, etc. that the user belongs to, or + * null if this is not known. + */ + public void setOrganization(String organization) { + this.organization = organization; + } + + /** + * Returns the role that the user has at the organization, company, group, + * etc. they belong to. If not available, null is returned. + * + * @return + * The role that the user has at the organization, company, group, etc. + * they belong to, or null if this is not known. + */ + public String getOrganizationalRole() { + return organizationalRole; + } + + /** + * Sets the role that the user has at the organization, company, group, + * etc. they belong to. + * + * @param organizationalRole + * The role that the user has at the organization, company, group, etc. + * they belong to, or null if this is not known. + */ + public void setOrganizationalRole(String organizationalRole) { + this.organizationalRole = organizationalRole; + } + } 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 37a825917..29bc47a7e 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 @@ -102,6 +102,12 @@ CREATE TABLE `guacamole_user` ( -- Timezone used for all date/time comparisons and interpretation `timezone` VARCHAR(64), + -- Profile information + `full_name` VARCHAR(256), + `email_address` VARCHAR(256), + `organization` VARCHAR(256), + `organizational_role` VARCHAR(256), + 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.13.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.13.sql index bb37c6c31..95bbc1c05 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.13.sql +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.13.sql @@ -28,3 +28,13 @@ ALTER TABLE guacamole_connection ADD COLUMN proxy_encryption_method ENUM( 'NONE', 'SSL' ); + +-- +-- Add new user profile columns +-- + +ALTER TABLE guacamole_user ADD COLUMN full_name VARCHAR(256); +ALTER TABLE guacamole_user ADD COLUMN email_address VARCHAR(256); +ALTER TABLE guacamole_user ADD COLUMN organization VARCHAR(256); +ALTER TABLE guacamole_user ADD COLUMN organizational_role VARCHAR(256); + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml index 3530b0b51..0ddb0517a 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml @@ -25,17 +25,21 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + @@ -69,7 +73,11 @@ access_window_end, valid_from, valid_until, - timezone + timezone, + full_name, + email_address, + organization, + organizational_role FROM guacamole_user WHERE username IN @@ -180,7 +204,11 @@ access_window_end = #{object.accessWindowEnd,jdbcType=TIME}, valid_from = #{object.validFrom,jdbcType=DATE}, valid_until = #{object.validUntil,jdbcType=DATE}, - timezone = #{object.timeZone,jdbcType=VARCHAR} + timezone = #{object.timeZone,jdbcType=VARCHAR}, + full_name = #{object.fullName,jdbcType=VARCHAR}, + email_address = #{object.emailAddress,jdbcType=VARCHAR}, + organization = #{object.organization,jdbcType=VARCHAR}, + organizational_role = #{object.organizationalRole,jdbcType=VARCHAR} 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 199b4bdc2..f9b235108 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 @@ -143,6 +143,12 @@ CREATE TABLE guacamole_user ( -- Timezone used for all date/time comparisons and interpretation timezone varchar(64), + -- Profile information + full_name varchar(256), + email_address varchar(256), + organization varchar(256), + organizational_role varchar(256), + PRIMARY KEY (user_id), CONSTRAINT username diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.13.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.13.sql index 015ec9a6c..0fac52846 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.13.sql +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.13.sql @@ -33,3 +33,13 @@ CREATE TYPE guacamole_proxy_encryption_method AS ENUM( ALTER TABLE guacamole_connection ADD COLUMN proxy_port integer; ALTER TABLE guacamole_connection ADD COLUMN proxy_hostname varchar(512); ALTER TABLE guacamole_connection ADD COLUMN proxy_encryption_method guacamole_proxy_encryption_method; + +-- +-- Add new user profile columns +-- + +ALTER TABLE guacamole_user ADD COLUMN full_name VARCHAR(256); +ALTER TABLE guacamole_user ADD COLUMN email_address VARCHAR(256); +ALTER TABLE guacamole_user ADD COLUMN organization VARCHAR(256); +ALTER TABLE guacamole_user ADD COLUMN organizational_role VARCHAR(256); + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml index 39ec05a01..569a8ac45 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml @@ -25,18 +25,22 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + + @@ -70,7 +74,11 @@ access_window_end, valid_from, valid_until, - timezone + timezone, + full_name, + email_address, + organization, + organizational_role FROM guacamole_user WHERE username IN @@ -181,7 +205,11 @@ access_window_end = #{object.accessWindowEnd,jdbcType=TIME}, valid_from = #{object.validFrom,jdbcType=DATE}, valid_until = #{object.validUntil,jdbcType=DATE}, - timezone = #{object.timeZone,jdbcType=VARCHAR} + timezone = #{object.timeZone,jdbcType=VARCHAR}, + full_name = #{object.fullName,jdbcType=VARCHAR}, + email_address = #{object.emailAddress,jdbcType=VARCHAR}, + organization = #{object.organization,jdbcType=VARCHAR}, + organizational_role = #{object.organizationalRole,jdbcType=VARCHAR} WHERE user_id = #{object.objectID,jdbcType=VARCHAR} From 203afd109911e2a4778b9cbf7b1fb792b5e16b4b Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 26 May 2017 20:25:12 -0700 Subject: [PATCH 10/10] GUACAMOLE-292: Remove now-unnecessary valuesOnly attribute of guacForm (reverts 4d7841a). --- .../main/webapp/app/form/directives/form.js | 29 +++++-------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/guacamole/src/main/webapp/app/form/directives/form.js b/guacamole/src/main/webapp/app/form/directives/form.js index a6d44f31c..518db7dba 100644 --- a/guacamole/src/main/webapp/app/form/directives/form.js +++ b/guacamole/src/main/webapp/app/form/directives/form.js @@ -64,16 +64,7 @@ angular.module('form').directive('guacForm', [function form() { * * @type Boolean */ - modelOnly : '=', - - /** - * Whether the contents of the form should be restricted to those - * fields/forms which have associated values defined within the - * given model object. By default, all fields will be shown. - * - * @type Boolean - */ - valuesOnly : '=' + modelOnly : '=' }, templateUrl: 'app/form/templates/form.html', @@ -193,18 +184,14 @@ angular.module('form').directive('guacForm', [function form() { */ $scope.isVisible = function isVisible(field) { - // Forms with valuesOnly set should display only fields with - // associated values in the model object - if ($scope.valuesOnly) - return field && $scope.values[field.name]; + // All fields are visible if contents are not restricted to + // model properties only + if (!$scope.modelOnly) + return true; - // Forms with modelOnly set should display only fields with - // associated properties in the model object - if ($scope.modelOnly) - return field && (field.name in $scope.values); - - // Otherwise, all fields are visible - return true; + // Otherwise, fields are only visible if they are present + // within the model + return field && (field.name in $scope.values); };