mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-11-25 06:16:37 +01:00
b2dc968ab1
Signed-off-by: Konstantina Chremmou <konstantina.chremmou@citrix.com>
205 lines
7.8 KiB
C#
205 lines
7.8 KiB
C#
/* Copyright (c) Citrix Systems, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms,
|
|
* with or without modification, are permitted provided
|
|
* that the following conditions are met:
|
|
*
|
|
* * Redistributions of source code must retain the above
|
|
* copyright notice, this list of conditions and the
|
|
* following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the
|
|
* following disclaimer in the documentation and/or other
|
|
* materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Windows.Forms;
|
|
using XenAPI;
|
|
using XenAdmin.Core;
|
|
using XenAdmin.Network;
|
|
|
|
|
|
namespace XenAdmin.Dialogs
|
|
{
|
|
public partial class RoleSelectionDialog : XenDialogBase
|
|
{
|
|
private List<Subject> subjects;
|
|
|
|
private Dictionary<Role, List<Subject>> _subjectsPerRole;
|
|
|
|
public RoleSelectionDialog()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
public RoleSelectionDialog(IXenConnection connection, List<Subject> subjects)
|
|
: base(connection)
|
|
{
|
|
InitializeComponent();
|
|
|
|
this.subjects = subjects;
|
|
|
|
var allAreGroups = subjects.Count > 0 && subjects.All(s => s.IsGroup);
|
|
var allAreUsers = subjects.Count > 0 && subjects.All(s => !s.IsGroup);
|
|
|
|
pictureBoxSubjectType.Image = allAreUsers
|
|
? Images.StaticImages._000_User_h32bit_32
|
|
: Images.StaticImages._000_UserAndGroup_h32bit_32;
|
|
|
|
if (subjects.Count == 1)
|
|
{
|
|
Subject subject = subjects[0];
|
|
string sName = (subject.DisplayName ?? subject.SubjectName ?? Messages.UNKNOWN_AD_USER).Ellipsise(30);
|
|
labelBlurb.Text = string.Format(allAreGroups ? Messages.AD_SELECT_ROLE_GROUP : Messages.AD_SELECT_ROLE_USER, sName);
|
|
}
|
|
else
|
|
{
|
|
if (allAreGroups)
|
|
labelBlurb.Text = Messages.AD_SELECT_ROLE_GROUP_MANY;
|
|
else if (allAreUsers)
|
|
labelBlurb.Text = Messages.AD_SELECT_ROLE_USER_MANY;
|
|
else
|
|
labelBlurb.Text = Messages.AD_SELECT_ROLE_MIXED;
|
|
}
|
|
|
|
// Get the list of roles off the server and arrange them into rank
|
|
var serverRoles = connection.Cache.Roles
|
|
.Where(r => (!Helpers.Post82X(connection) || !Helpers.XapiEqualOrGreater_22_5_0(connection) || !r.is_internal) && r.subroles.Count > 0)
|
|
.OrderBy(r => r).Reverse().ToList();
|
|
_subjectsPerRole = new Dictionary<Role, List<Subject>>();
|
|
|
|
foreach (Role role in serverRoles)
|
|
{
|
|
var subjectsWithRole = subjects.Where(s => s.roles.Contains(new XenRef<Role>(role.opaque_ref))).ToList();
|
|
_subjectsPerRole[role] = subjectsWithRole;
|
|
|
|
var row = new RoleDataGridViewRow(role);
|
|
|
|
if (subjectsWithRole.Count == subjects.Count)
|
|
row.IsChecked = true;
|
|
else if (subjectsWithRole.Count == 0)
|
|
row.IsChecked = false;
|
|
|
|
gridRoles.Rows.Add(row);
|
|
}
|
|
|
|
UpdateRoleDescription();
|
|
tableLayoutPanel2.Visible = false;
|
|
buttonSave.Enabled = false;
|
|
}
|
|
|
|
public List<Role> SelectedRoles =>
|
|
gridRoles.Rows.Cast<RoleDataGridViewRow>().Where(r => r.IsChecked).Select(r => r.Role).ToList();
|
|
|
|
private void UpdateRoleDescription()
|
|
{
|
|
if (gridRoles.SelectedRows.Count == 1 && gridRoles.SelectedRows[0] is RoleDataGridViewRow row)
|
|
labelDescription.Text = row.Role.FriendlyDescription();
|
|
}
|
|
|
|
private void UpdateButtonsAndInfo()
|
|
{
|
|
foreach (DataGridViewRow r in gridRoles.Rows)
|
|
{
|
|
if (r is RoleDataGridViewRow row)
|
|
{
|
|
if (row.IsChecked && _subjectsPerRole[row.Role].Count < subjects.Count)
|
|
{
|
|
buttonSave.Enabled = true;
|
|
tableLayoutPanel2.Visible = false;
|
|
return;
|
|
}
|
|
|
|
if (!row.IsChecked && _subjectsPerRole[row.Role].Count > 0)
|
|
{
|
|
buttonSave.Enabled = true;
|
|
tableLayoutPanel2.Visible = row.Role.name_label == Role.MR_ROLE_POOL_ADMIN &&
|
|
connection != null && Helpers.StockholmOrGreater(connection) &&
|
|
!connection.Cache.Hosts.Any(Host.RestrictPoolSecretRotation);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
tableLayoutPanel2.Visible = false;
|
|
buttonSave.Enabled = false;
|
|
}
|
|
|
|
private void gridRoles_SelectionChanged(object sender, EventArgs e)
|
|
{
|
|
UpdateRoleDescription();
|
|
}
|
|
|
|
private void gridRoles_CellContentClick(object sender, DataGridViewCellEventArgs e)
|
|
{
|
|
//handle mouse clicks only on the check box column because the user should be able
|
|
//to select rows by clicking but without checking them so as to browse the descriptions
|
|
|
|
if (e.ColumnIndex != 0 || e.RowIndex < 0 || e.RowIndex >= gridRoles.RowCount)
|
|
return;
|
|
|
|
CheckRowByIndex(e.RowIndex);
|
|
}
|
|
|
|
private void gridRoles_KeyPress(object sender, KeyPressEventArgs e)
|
|
{
|
|
if (e.KeyChar != (char)Keys.Space || gridRoles.SelectedRows.Count != 1)
|
|
return;
|
|
|
|
CheckRowByIndex(gridRoles.SelectedRows[0].Index);
|
|
}
|
|
|
|
private void CheckRowByIndex(int index)
|
|
{
|
|
foreach (DataGridViewRow r in gridRoles.Rows)
|
|
{
|
|
if (r is RoleDataGridViewRow row)
|
|
row.IsChecked = index == r.Index;
|
|
}
|
|
|
|
UpdateButtonsAndInfo();
|
|
}
|
|
|
|
|
|
private class RoleDataGridViewRow : DataGridViewRow
|
|
{
|
|
private readonly DataGridViewCheckBoxCell _c1 = new DataGridViewCheckBoxCell {ThreeState = true};
|
|
private readonly DataGridViewTextBoxCell _c2 = new DataGridViewTextBoxCell();
|
|
|
|
public RoleDataGridViewRow(Role role)
|
|
{
|
|
Role = role;
|
|
_c1.Value = CheckState.Indeterminate;
|
|
_c2.Value = role.FriendlyName();
|
|
Cells.AddRange(_c1, _c2);
|
|
}
|
|
|
|
public Role Role { get; }
|
|
|
|
public bool IsChecked
|
|
{
|
|
get => (CheckState)_c1.Value == CheckState.Checked;
|
|
set => _c1.Value = value ? CheckState.Checked : CheckState.Unchecked;
|
|
}
|
|
}
|
|
}
|
|
} |