diff --git a/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js b/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js
index b174a8da0..6616853ee 100644
--- a/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js
+++ b/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js
@@ -169,6 +169,30 @@ angular.module('settings').directive('guacSettingsConnections', [function guacSe
};
+ /**
+ * Returns whether the current user can create new sharing profiles
+ * within the current data source.
+ *
+ * @return {Boolean}
+ * true if the current user can create new sharing profiles
+ * within the current data source, false otherwise.
+ */
+ $scope.canCreateSharingProfiles = function canCreateSharingProfiles() {
+
+ // Abort if permissions have not yet loaded
+ if (!$scope.permissions)
+ return false;
+
+ // Can create sharing profiles if adminstrator or have explicit permission
+ if (PermissionSet.hasSystemPermission($scope.permissions, PermissionSet.SystemPermissionType.ADMINISTER)
+ || PermissionSet.hasSystemPermission($scope.permissions, PermissionSet.SystemPermissionType.CREATE_SHARING_PROFILE))
+ return true;
+
+ // Current data source does not allow sharing profile creation
+ return false;
+
+ };
+
/**
* Returns whether the current user can create new connections or
* connection groups or make changes to existing connections or
@@ -188,7 +212,9 @@ angular.module('settings').directive('guacSettingsConnections', [function guacSe
return false;
// Creating connections/groups counts as management
- if ($scope.canCreateConnections() || $scope.canCreateConnectionGroups())
+ if ($scope.canCreateConnections()
+ || $scope.canCreateConnectionGroups()
+ || $scope.canCreateSharingProfiles())
return true;
// Can manage connections if granted explicit update or delete
@@ -206,6 +232,34 @@ angular.module('settings').directive('guacSettingsConnections', [function guacSe
};
+ /**
+ * Returns whether the current user can update the connection having
+ * the given identifier within the current data source.
+ *
+ * @param {String} identifier
+ * The identifier of the connection to check.
+ *
+ * @return {Boolean}
+ * true if the current user can update the connection having the
+ * given identifier within the current data source, false
+ * otherwise.
+ */
+ $scope.canUpdateConnection = function canUpdateConnection(identifier) {
+
+ // Abort if permissions have not yet loaded
+ if (!$scope.permissions)
+ return false;
+
+ // Can update the connection if adminstrator or have explicit permission
+ if (PermissionSet.hasSystemPermission($scope.permissions, PermissionSet.SystemPermissionType.ADMINISTER)
+ || PermissionSet.hasConnectionPermission($scope.permissions, PermissionSet.ObjectPermissionType.UPDATE, identifier))
+ return true;
+
+ // Current data sources does not allow the connection to be updated
+ return false;
+
+ };
+
/**
* Returns whether the current user can update the connection group
* having the given identifier within the current data source.
@@ -276,6 +330,38 @@ angular.module('settings').directive('guacSettingsConnections', [function guacSe
};
+ /**
+ * Adds connection-specific contextual actions to the given array of
+ * GroupListItems. Each contextual action will be represented by a
+ * new GroupListItem.
+ *
+ * @param {GroupListItem[]} items
+ * The array of GroupListItems to which new GroupListItems
+ * representing connection-specific contextual actions should
+ * be added.
+ *
+ * @param {GroupListItem} [parent]
+ * The GroupListItem representing the connection which contains
+ * the given array of GroupListItems, if known.
+ */
+ var addConnectionActions = function addConnectionActions(items, parent) {
+
+ // Do nothing if we lack permission to modify the parent at all
+ if (parent && !$scope.canUpdateConnection(parent.identifier))
+ return;
+
+ // Add action for creating a child sharing profile, if the user
+ // has permission to do so
+ if ($scope.canCreateSharingProfiles())
+ items.push(new GroupListItem({
+ type : 'new-sharing-profile',
+ dataSource : $scope.dataSource,
+ weight : 1,
+ wrappedItem : parent
+ }));
+
+ };
+
/**
* Decorates the given GroupListItem, including all descendants,
* adding contextual actions.
@@ -291,6 +377,11 @@ angular.module('settings').directive('guacSettingsConnections', [function guacSe
if (item.type === GroupListItem.Type.CONNECTION_GROUP)
addConnectionGroupActions(item.children, item);
+ // If the item is a connection, add actions specific to
+ // connections
+ else if (item.type === GroupListItem.Type.CONNECTION)
+ addConnectionActions(item.children, item);
+
// Decorate all children
angular.forEach(item.children, decorateItem);
diff --git a/guacamole/src/main/webapp/app/settings/styles/connection-list.css b/guacamole/src/main/webapp/app/settings/styles/connection-list.css
index 7bf35538a..efcb9dc3b 100644
--- a/guacamole/src/main/webapp/app/settings/styles/connection-list.css
+++ b/guacamole/src/main/webapp/app/settings/styles/connection-list.css
@@ -18,7 +18,8 @@
*/
.settings.connections .connection-list .new-connection,
-.settings.connections .connection-list .new-connection-group {
+.settings.connections .connection-list .new-connection-group,
+.settings.connections .connection-list .new-sharing-profile {
opacity: 0.5;
font-style: italic;
}
@@ -28,7 +29,10 @@
.settings.connections .connection-list .new-connection a:visited,
.settings.connections .connection-list .new-connection-group a,
.settings.connections .connection-list .new-connection-group a:hover,
-.settings.connections .connection-list .new-connection-group a:visited {
+.settings.connections .connection-list .new-connection-group a:visited,
+.settings.connections .connection-list .new-sharing-profile a,
+.settings.connections .connection-list .new-sharing-profile a:hover,
+.settings.connections .connection-list .new-sharing-profile a:visited {
text-decoration:none;
color: black;
}
diff --git a/guacamole/src/main/webapp/app/settings/templates/connectionGroup.html b/guacamole/src/main/webapp/app/settings/templates/connectionGroup.html
index 8b480f1b0..ccf4592be 100644
--- a/guacamole/src/main/webapp/app/settings/templates/connectionGroup.html
+++ b/guacamole/src/main/webapp/app/settings/templates/connectionGroup.html
@@ -1,4 +1,9 @@
+
+
+
+
{{item.name}}
+
diff --git a/guacamole/src/main/webapp/app/settings/templates/newSharingProfile.html b/guacamole/src/main/webapp/app/settings/templates/newSharingProfile.html
new file mode 100644
index 000000000..12303e8e6
--- /dev/null
+++ b/guacamole/src/main/webapp/app/settings/templates/newSharingProfile.html
@@ -0,0 +1,3 @@
+
+ {{'SETTINGS_CONNECTIONS.ACTION_NEW_SHARING_PROFILE' | translate}}
+
diff --git a/guacamole/src/main/webapp/app/settings/templates/settingsConnections.html b/guacamole/src/main/webapp/app/settings/templates/settingsConnections.html
index dfdf686ef..0b1e22ca5 100644
--- a/guacamole/src/main/webapp/app/settings/templates/settingsConnections.html
+++ b/guacamole/src/main/webapp/app/settings/templates/settingsConnections.html
@@ -37,9 +37,11 @@
templates="{
'connection' : 'app/settings/templates/connection.html',
+ 'sharing-profile' : 'app/settings/templates/sharingProfile.html',
'connection-group' : 'app/settings/templates/connectionGroup.html',
'new-connection' : 'app/settings/templates/newConnection.html',
+ 'new-sharing-profile' : 'app/settings/templates/newSharingProfile.html',
'new-connection-group' : 'app/settings/templates/newConnectionGroup.html'
}"/>
diff --git a/guacamole/src/main/webapp/app/settings/templates/sharingProfile.html b/guacamole/src/main/webapp/app/settings/templates/sharingProfile.html
new file mode 100644
index 000000000..bce7edc1f
--- /dev/null
+++ b/guacamole/src/main/webapp/app/settings/templates/sharingProfile.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+ {{item.name}}
+
+
diff --git a/guacamole/src/main/webapp/translations/en.json b/guacamole/src/main/webapp/translations/en.json
index 01f332e18..f934a22de 100644
--- a/guacamole/src/main/webapp/translations/en.json
+++ b/guacamole/src/main/webapp/translations/en.json
@@ -557,6 +557,7 @@
"ACTION_ACKNOWLEDGE" : "@:APP.ACTION_ACKNOWLEDGE",
"ACTION_NEW_CONNECTION" : "New Connection",
"ACTION_NEW_CONNECTION_GROUP" : "New Group",
+ "ACTION_NEW_SHARING_PROFILE" : "New Sharing Profile",
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",