#region License Information /* HeuristicLab * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Windows.Forms; using HeuristicLab.Clients.Access; using HeuristicLab.Common.Resources; using HeuristicLab.Core.Views; using HeuristicLab.MainForm; namespace HeuristicLab.Clients.Hive.Administrator.Views { [View("ProjectView")] [Content(typeof(Project), IsDefaultView = false)] public partial class ProjectPermissionsView : ItemView { private const int userImageIndex = 0; private const int userGroupImageIndex = 1; private readonly HashSet assignedPermissions = new HashSet(); private readonly HashSet inheritedPermissions = new HashSet(); public new Project Content { get { return (Project)base.Content; } set { base.Content = value; } } public ProjectPermissionsView() { InitializeComponent(); treeView.ImageList.Images.Add(VSImageLibrary.User); treeView.ImageList.Images.Add(VSImageLibrary.UserAccounts); } #region Overrides protected override void OnContentChanged() { base.OnContentChanged(); if (Content == null) { assignedPermissions.Clear(); inheritedPermissions.Clear(); treeView.Nodes.Clear(); detailsViewHost.Content = null; } else { UpdateAssignedPermissions(); UpdateInheritedPermissions(); var top = BuildPermissionsList(AccessClient.Instance.UsersAndGroups); detailsViewHost.Content = top; detailsViewHost.ActiveView.Locked = true; } } #endregion #region Event Handlers private void ProjectPermissionsView_Load(object sender, EventArgs e) { } private void refreshButton_Click(object sender, EventArgs e) { UpdateAssignedPermissions(); UpdateInheritedPermissions(); var top = BuildPermissionsList(AccessClient.Instance.UsersAndGroups); detailsViewHost.Content = top; } private void inheritButton_Click(object sender, EventArgs e) { SetGrantedProjectPermissions(Content.Id, Enumerable.Empty()); UpdateAssignedPermissions(); UpdateInheritedPermissions(); var top = BuildPermissionsList(AccessClient.Instance.UsersAndGroups); detailsViewHost.Content = top; } private async void saveButton_Click(object sender, EventArgs e) { await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions( action: () => SetGrantedProjectPermissions(Content.Id, assignedPermissions.Select(x => x.Id))); } private void treeView_AfterSelect(object sender, TreeViewEventArgs e) { var selectedPermission = (UserGroupBase)e.Node.Tag; detailsViewHost.Content = selectedPermission; } private void treeView_BeforeCheck(object sender, TreeViewCancelEventArgs e) { var checkedPermission = (UserGroupBase)e.Node.Tag; if (e.Node.Parent == null || inheritedPermissions.Contains(checkedPermission) || checkedPermission.Id == Guid.Empty) e.Cancel = true; } private void treeView_AfterCheck(object sender, TreeViewEventArgs e) { var checkedPermission = (UserGroupBase)e.Node.Tag; if (e.Node.Checked) assignedPermissions.Add(checkedPermission); else assignedPermissions.Remove(checkedPermission); } #endregion #region Helpers private static IEnumerable GetGrantedPermissionsForProject(Guid projectId) { var projectPermissions = HiveServiceLocator.Instance.CallHiveService(s => s.GetProjectPermissions(projectId)); var userIds = new HashSet(projectPermissions.Select(x => x.GrantedUserId)); return AccessClient.Instance.UsersAndGroups.Where(x => userIds.Contains(x.Id)); } private static void SetGrantedProjectPermissions(Guid projectId, IEnumerable userIds) { HiveServiceLocator.Instance.CallHiveService(s => { var currentlyAssignedPermissions = s.GetProjectPermissions(projectId); s.RevokeProjectPermissions(projectId, currentlyAssignedPermissions.Select(x => x.GrantedUserId).ToList()); s.GrantProjectPermissions(projectId, userIds.ToList()); }); } private void UpdateAssignedPermissions() { assignedPermissions.Clear(); foreach (var r in GetGrantedPermissionsForProject(Content.Id)) assignedPermissions.Add(r); } private void UpdateInheritedPermissions() { inheritedPermissions.Clear(); var parentProject = HiveAdminClient.Instance.Projects.SingleOrDefault(x => x.Id == Content.ParentProjectId); while (parentProject != null) { foreach (var r in GetGrantedPermissionsForProject(parentProject.Id)) inheritedPermissions.Add(r); parentProject = HiveAdminClient.Instance.Projects.SingleOrDefault(x => x.Id == parentProject.ParentProjectId); } } private UserGroupBase BuildPermissionsList(IEnumerable usersAndGroups) { treeView.Nodes.Clear(); if (!usersAndGroups.Any()) return null; treeView.BeforeCheck -= treeView_BeforeCheck; treeView.AfterCheck -= treeView_AfterCheck; var userGroups = new HashSet(usersAndGroups.OfType()); var users = new HashSet(usersAndGroups.OfType()); UserGroupBase first = null; var groupsNode = new TreeNode("Groups") { ForeColor = SystemColors.GrayText }; groupsNode.ImageIndex = groupsNode.SelectedImageIndex = userGroupImageIndex; foreach (var group in userGroups.OrderBy(x => x.Name)) { var node = new TreeNode(group.Name) { Tag = group }; node.ImageIndex = userGroupImageIndex; node.SelectedImageIndex = node.ImageIndex; if (inheritedPermissions.Contains(group)) { node.Checked = true; node.Text += " (Inherited)"; node.ForeColor = SystemColors.GrayText; } else if (assignedPermissions.Contains(group)) node.Checked = true; groupsNode.Nodes.Add(node); if (first == null) first = group; } var usersNode = new TreeNode("Users") { ForeColor = SystemColors.GrayText }; usersNode.ImageIndex = usersNode.SelectedImageIndex = userImageIndex; foreach (var user in users.OrderBy(x => x.ToString())) { var node = new TreeNode(user.ToString()) { Tag = user }; node.ImageIndex = userImageIndex; node.SelectedImageIndex = node.ImageIndex; if (inheritedPermissions.Contains(user)) { node.Checked = true; node.Text += " (Inherited)"; node.ForeColor = SystemColors.GrayText; } else if (assignedPermissions.Contains(user)) node.Checked = true; usersNode.Nodes.Add(node); if (first == null) first = user; } treeView.Nodes.Add(groupsNode); treeView.Nodes.Add(usersNode); treeView.BeforeCheck += treeView_BeforeCheck; treeView.AfterCheck += treeView_AfterCheck; treeView.ExpandAll(); return first; } #endregion } }