Skip to content

Commit

Permalink
GUACAMOLE-1957: Support granular permissions management.
Browse files Browse the repository at this point in the history
  • Loading branch information
necouchman committed Jul 6, 2024
1 parent 9a8a5f3 commit 5d82238
Show file tree
Hide file tree
Showing 6 changed files with 270 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -355,17 +355,20 @@ angular.module('manage').directive('connectionPermissionEditor', ['$injector',
* to reflect the addition of the given connection permission.
*
* @param {String} identifier
* The identifier of the connection to add READ permission for.
* The identifier of the connection to add a permission for.
*
* @param {ObjectPermissionType} permission
* The permission to add.
*/
var addConnectionPermission = function addConnectionPermission(identifier) {
var addConnectionPermission = function addConnectionPermission(identifier, permission) {

// If permission was previously removed, simply un-remove it
if (PermissionSet.hasConnectionPermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier))
PermissionSet.removeConnectionPermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
if (PermissionSet.hasConnectionPermission($scope.permissionsRemoved, permission, identifier))
PermissionSet.removeConnectionPermission($scope.permissionsRemoved, permission, identifier);

// Otherwise, explicitly add the permission
else
PermissionSet.addConnectionPermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
PermissionSet.addConnectionPermission($scope.permissionsAdded, permission, identifier);

};

Expand All @@ -374,17 +377,20 @@ angular.module('manage').directive('connectionPermissionEditor', ['$injector',
* to reflect the removal of the given connection permission.
*
* @param {String} identifier
* The identifier of the connection to remove READ permission for.
* The identifier of the connection to remove a permission for.
*
* @param {ObjectPermissionType} permission
* The permission to remove.
*/
var removeConnectionPermission = function removeConnectionPermission(identifier) {
var removeConnectionPermission = function removeConnectionPermission(identifier, permission) {

// If permission was previously added, simply un-add it
if (PermissionSet.hasConnectionPermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier))
PermissionSet.removeConnectionPermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
if (PermissionSet.hasConnectionPermission($scope.permissionsAdded, permission, identifier))
PermissionSet.removeConnectionPermission($scope.permissionsAdded, permission, identifier);

// Otherwise, explicitly remove the permission
else
PermissionSet.addConnectionPermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
PermissionSet.addConnectionPermission($scope.permissionsRemoved, permission, identifier);

};

Expand All @@ -393,18 +399,20 @@ angular.module('manage').directive('connectionPermissionEditor', ['$injector',
* to reflect the addition of the given connection group permission.
*
* @param {String} identifier
* The identifier of the connection group to add READ permission
* for.
* The identifier of the connection group to add a permission for.
*
* @param {ObjectPermissionType} permission
* The permission to add.
*/
var addConnectionGroupPermission = function addConnectionGroupPermission(identifier) {
var addConnectionGroupPermission = function addConnectionGroupPermission(identifier, permission) {

// If permission was previously removed, simply un-remove it
if (PermissionSet.hasConnectionGroupPermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier))
PermissionSet.removeConnectionGroupPermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
if (PermissionSet.hasConnectionGroupPermission($scope.permissionsRemoved, permission, identifier))
PermissionSet.removeConnectionGroupPermission($scope.permissionsRemoved, permission, identifier);

// Otherwise, explicitly add the permission
else
PermissionSet.addConnectionGroupPermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
PermissionSet.addConnectionGroupPermission($scope.permissionsAdded, permission, identifier);

};

Expand All @@ -413,18 +421,20 @@ angular.module('manage').directive('connectionPermissionEditor', ['$injector',
* to reflect the removal of the given connection group permission.
*
* @param {String} identifier
* The identifier of the connection group to remove READ permission
* for.
* The identifier of the connection group to remove a permission for.
*
* @param {ObjectPermissionType} permission
* The permission to remove.
*/
var removeConnectionGroupPermission = function removeConnectionGroupPermission(identifier) {
var removeConnectionGroupPermission = function removeConnectionGroupPermission(identifier, permission) {

// If permission was previously added, simply un-add it
if (PermissionSet.hasConnectionGroupPermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier))
PermissionSet.removeConnectionGroupPermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
if (PermissionSet.hasConnectionGroupPermission($scope.permissionsAdded, permission, identifier))
PermissionSet.removeConnectionGroupPermission($scope.permissionsAdded, permission, identifier);

// Otherwise, explicitly remove the permission
else
PermissionSet.addConnectionGroupPermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
PermissionSet.addConnectionGroupPermission($scope.permissionsRemoved, permission, identifier);

};

Expand All @@ -433,17 +443,20 @@ angular.module('manage').directive('connectionPermissionEditor', ['$injector',
* to reflect the addition of the given sharing profile permission.
*
* @param {String} identifier
* The identifier of the sharing profile to add READ permission for.
* The identifier of the sharing profile to add a permission for.
*
* @param {ObjectPermissionType} permission
* The permission to add.
*/
var addSharingProfilePermission = function addSharingProfilePermission(identifier) {
var addSharingProfilePermission = function addSharingProfilePermission(identifier, permission) {

// If permission was previously removed, simply un-remove it
if (PermissionSet.hasSharingProfilePermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier))
PermissionSet.removeSharingProfilePermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
if (PermissionSet.hasSharingProfilePermission($scope.permissionsRemoved, permission, identifier))
PermissionSet.removeSharingProfilePermission($scope.permissionsRemoved, permission, identifier);

// Otherwise, explicitly add the permission
else
PermissionSet.addSharingProfilePermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
PermissionSet.addSharingProfilePermission($scope.permissionsAdded, permission, identifier);

};

Expand All @@ -452,18 +465,20 @@ angular.module('manage').directive('connectionPermissionEditor', ['$injector',
* to reflect the removal of the given sharing profile permission.
*
* @param {String} identifier
* The identifier of the sharing profile to remove READ permission
* for.
* The identifier of the sharing profile to remove a permission for.
*
* @param {ObjectPermissionType} permission
* The permission to remove.
*/
var removeSharingProfilePermission = function removeSharingProfilePermission(identifier) {
var removeSharingProfilePermission = function removeSharingProfilePermission(identifier, permission) {

// If permission was previously added, simply un-add it
if (PermissionSet.hasSharingProfilePermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier))
PermissionSet.removeSharingProfilePermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
if (PermissionSet.hasSharingProfilePermission($scope.permissionsAdded, permission, identifier))
PermissionSet.removeSharingProfilePermission($scope.permissionsAdded, permission, identifier);

// Otherwise, explicitly remove the permission
else
PermissionSet.addSharingProfilePermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
PermissionSet.addSharingProfilePermission($scope.permissionsRemoved, permission, identifier);

};

Expand Down Expand Up @@ -493,14 +508,14 @@ angular.module('manage').directive('connectionPermissionEditor', ['$injector',
*/
connectionPermissionChanged : function connectionPermissionChanged(identifier) {

// Determine current permission setting
var granted = $scope.permissionFlags.connectionPermissions.READ[identifier];
// Loop through permissions to add or remove them as required.
for (const [key, value] of Object.entries($scope.permissionFlags.connectionPermissions)) {
if (value[identifier])
addConnectionPermission(identifier, PermissionSet.ObjectPermissionType[key]);
else
removeConnectionPermission(identifier, PermissionSet.ObjectPermissionType[key]);

// Add/remove permission depending on flag state
if (granted)
addConnectionPermission(identifier);
else
removeConnectionPermission(identifier);
}

},

Expand All @@ -515,14 +530,14 @@ angular.module('manage').directive('connectionPermissionEditor', ['$injector',
*/
connectionGroupPermissionChanged : function connectionGroupPermissionChanged(identifier) {

// Determine current permission setting
var granted = $scope.permissionFlags.connectionGroupPermissions.READ[identifier];
// Loop through permissions and add or remove them as required.
for (const [key, value] of Object.entries($scope.permissionFlags.connectionGroupPermissions)) {
if (value[identifier])
addConnectionGroupPermission(identifier, PermissionSet.ObjectPermissionType[key]);
else
removeConnectionGroupPermission(identifier, PermissionSet.ObjectPermissionType[key]);

// Add/remove permission depending on flag state
if (granted)
addConnectionGroupPermission(identifier);
else
removeConnectionGroupPermission(identifier);
}

},

Expand All @@ -537,14 +552,14 @@ angular.module('manage').directive('connectionPermissionEditor', ['$injector',
*/
sharingProfilePermissionChanged : function sharingProfilePermissionChanged(identifier) {

// Determine current permission setting
var granted = $scope.permissionFlags.sharingProfilePermissions.READ[identifier];
// Loop through permissions and add or remove them as required.
for (const [key, value] of Object.entries($scope.permissionFlags.sharingProfilePermissions)) {
if (value[identifier])
addSharingProfilePermission(identifier, PermissionSet.ObjectPermissionType[key]);
else
removeSharingProfilePermission(identifier, PermissionSet.ObjectPermissionType[key]);

// Add/remove permission depending on flag state
if (granted)
addSharingProfilePermission(identifier);
else
removeSharingProfilePermission(identifier);
}

}

Expand Down
61 changes: 61 additions & 0 deletions guacamole/src/main/frontend/src/app/manage/styles/permissions.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* 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.
*/

/* Draw the box for the toggle button. */
label.permission-toggle {
position: relative;
display: inline-grid;
width: fit-content;
border: 1px solid rgba(0, 0, 0, .125);
font-weight: 300;
cursor: pointer;
}

/* Padding around the label. */
label.permission-toggle div {
padding: 6px;
text-align: center;
z-index: 1;
}

/* Hide the actual checkbox */
input.permission-toggle {
display: none;
}

/* Style of the checked toggle. */
input.permission-toggle:checked + label.permission-toggle div:first-child {
color: #ffffff;
transition: color 0.3s;
background: #5a5a5a;
font-size: 0.90em;
font-weight: 700;
}

/* Style of the unchecked toggle. */
input.permission-toggle + label.permission-toggle div:first-child {
color: rgba(0, 0, 0, .125);
transition: color 0.3s;
font-size: 0.90em;
font-weight: 700;
}

.permission-container {
display: inline-block;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,50 @@
<!-- Connection group icon -->
<div class="icon type"></div>

<!-- Permission checkbox -->
<input type="checkbox" ng-model="context.getPermissionFlags().connectionGroupPermissions.READ[item.identifier]"
ng-change="context.connectionGroupPermissionChanged(item.identifier)">

<!-- Connection group name -->
<span class="name">{{item.name}}</span>

<div class="permission-container">

<!-- Connection Group Read (Connect) Permission -->
<input type="checkbox"
id="readConnectionGroup-{{item.identifier}}"
class="permission-toggle"
ng-model="context.getPermissionFlags().connectionGroupPermissions.READ[item.identifier]"
ng-change="context.connectionGroupPermissionChanged(item.identifier)">
<label for="readConnectionGroup-{{item.identifier}}" class="permission-toggle label">
<div>{{'PERMISSIONS.TOGGLE_PERMISSION_CONNECT' | translate}}</div>
</label>

<!-- Connection Group Update Permission -->
<input type="checkbox"
id="updateConnectionGroup-{{item.identifier}}"
class="permission-toggle"
ng-model="context.getPermissionFlags().connectionGroupPermissions.UPDATE[item.identifier]"
ng-change="context.connectionGroupPermissionChanged(item.identifier)">
<label for="updateConnectionGroup-{{item.identifier}}" class="permission-toggle label">
<div>{{'PERMISSIONS.TOGGLE_PERMISSION_UPDATE' | translate}}</div>
</label>

<!-- Connection Group Delete Permission -->
<input type="checkbox"
id="deleteConnectionGroup-{{item.identifier}}"
class="permission-toggle"
ng-model="context.getPermissionFlags().connectionGroupPermissions.DELETE[item.identifier]"
ng-change="context.connectionGroupPermissionChanged(item.identifier)">
<label for="deleteConnectionGroup-{{item.identifier}}" class="permission-toggle label">
<div>{{'PERMISSIONS.TOGGLE_PERMISSION_DELETE' | translate}}</div>
</label>

<!-- Connection Group Administer Permission -->
<input type="checkbox"
id="adminConnectionGroup-{{item.identifier}}"
class="permission-toggle"
ng-model="context.getPermissionFlags().connectionGroupPermissions.ADMINISTER[item.identifier]"
ng-change="context.connectionGroupPermissionChanged(item.identifier)">
<label for="adminConnectionGroup-{{item.identifier}}" class="permission-toggle label">
<div>{{'PERMISSIONS.TOGGLE_PERMISSION_ADMINISTER' | translate}}</div>
</label>

</div>
</div>
Loading

0 comments on commit 5d82238

Please sign in to comment.