using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using ScrewTurn.Wiki.PluginFramework; using ScrewTurn.Wiki.AclEngine; namespace ScrewTurn.Wiki { public partial class AdminGroups : BasePage { protected void Page_Load(object sender, EventArgs e) { AdminMaster.RedirectToLoginIfNeeded(); string currentUser = SessionFacade.GetCurrentUsername(); string[] currentGroups = SessionFacade.GetCurrentGroupNames(); if(!AdminMaster.CanManageGroups(currentUser, currentGroups)) UrlTools.Redirect("AccessDenied.aspx"); aclActionsSelector.Visible = AdminMaster.CanManagePermissions(currentUser, currentGroups); revName.ValidationExpression = Settings.UsernameRegex; if(!Page.IsPostBack) { rptGroups.DataBind(); providerSelector.Reload(); btnNewGroup.Enabled = providerSelector.HasProviders; } } protected void rptGroups_DataBinding(object sender, EventArgs e) { List allGroups = Users.GetUserGroups(); List result = new List(allGroups.Count); foreach(UserGroup group in allGroups) { result.Add(new UserGroupRow(group, group.Name == txtCurrentName.Value)); } rptGroups.DataSource = result; } protected void rptGroups_ItemCommand(object sender, RepeaterCommandEventArgs e) { if(e.CommandName == "Select") { txtCurrentName.Value = e.CommandArgument as string; //rptGroups.DataBind(); Not needed because the list is hidden on select UserGroup group = Users.FindUserGroup(txtCurrentName.Value); txtName.Text = group.Name; txtName.Enabled = false; txtDescription.Text = group.Description; providerSelector.SelectedProvider = group.Provider.GetType().FullName; providerSelector.Enabled = false; // Select group's global permissions aclActionsSelector.GrantedActions = AuthReader.RetrieveGrantsForGlobals(group); aclActionsSelector.DeniedActions = AuthReader.RetrieveDenialsForGlobals(group); btnCreate.Visible = false; btnSave.Visible = true; btnDelete.Visible = true; bool isDefaultGroup = group.Name == Settings.AdministratorsGroup || group.Name == Settings.UsersGroup || group.Name == Settings.AnonymousGroup; pnlEditGroup.Visible = true; pnlList.Visible = false; // Enable/disable interface sections based on provider read-only settings pnlGroupDetails.Enabled = !group.Provider.UserGroupsReadOnly; btnDelete.Enabled = !group.Provider.UserGroupsReadOnly && !isDefaultGroup; lblResult.CssClass = ""; lblResult.Text = ""; } } /// /// Resets the group editor's status. /// private void ResetEditor() { txtName.Text = ""; txtName.Enabled = true; txtDescription.Text = ""; providerSelector.Enabled = true; providerSelector.Reload(); pnlGroupDetails.Enabled = true; aclActionsSelector.GrantedActions = new string[0]; aclActionsSelector.DeniedActions = new string[0]; btnCreate.Visible = true; btnSave.Visible = false; btnDelete.Visible = false; lblResult.Text = ""; } /// /// Refreshes the group list. /// private void RefreshList() { txtCurrentName.Value = ""; ResetEditor(); rptGroups.DataBind(); } protected void cvName_ServerValidate(object sender, ServerValidateEventArgs e) { e.IsValid = Users.FindUser(txtName.Text) == null; } protected void btnNewGroup_Click(object sender, EventArgs e) { pnlList.Visible = false; pnlEditGroup.Visible = true; lblResult.Text = ""; lblResult.CssClass = ""; } protected void btnCreate_Click(object sender, EventArgs e) { if(!Page.IsValid) return; lblResult.CssClass = ""; lblResult.Text = ""; Log.LogEntry("Group creation requested for " + txtName.Text, EntryType.General, SessionFacade.CurrentUsername); // Add the new group then set its global permissions bool done = Users.AddUserGroup(txtName.Text, txtDescription.Text, Collectors.UsersProviderCollector.GetProvider(providerSelector.SelectedProvider)); UserGroup currentGroup = null; if(done) { currentGroup = Users.FindUserGroup(txtName.Text); done = AddAclEntries(currentGroup, aclActionsSelector.GrantedActions, aclActionsSelector.DeniedActions); if(done) { RefreshList(); lblResult.CssClass = "resultok"; lblResult.Text = Properties.Messages.GroupCreated; ReturnToList(); } else { lblResult.CssClass = "resulterror"; lblResult.Text = Properties.Messages.GroupCreatedCouldNotStorePermissions; } } else { lblResult.CssClass = "resulterror"; lblResult.Text = Properties.Messages.CouldNotCreateGroup; } } protected void btnSave_Click(object sender, EventArgs e) { if(!Page.IsValid) return; lblResult.CssClass = ""; lblResult.Text = ""; Log.LogEntry("Group update requested for " + txtCurrentName.Value, EntryType.General, SessionFacade.CurrentUsername); UserGroup currentGroup = Users.FindUserGroup(txtCurrentName.Value); // Perform proper actions based on provider read-only settings // 1. If possible, modify group // 2. Update ACLs bool done = true; if(!currentGroup.Provider.UserGroupsReadOnly) { done = Users.ModifyUserGroup(currentGroup, txtDescription.Text); } if(!done) { lblResult.CssClass = "resulterror"; lblResult.Text = Properties.Messages.CouldNotUpdateGroup; return; } done = RemoveAllAclEntries(currentGroup); if(done) { done = AddAclEntries(currentGroup, aclActionsSelector.GrantedActions, aclActionsSelector.DeniedActions); if(done) { RefreshList(); lblResult.CssClass = "resultok"; lblResult.Text = Properties.Messages.GroupUpdated; ReturnToList(); } else { lblResult.CssClass = "resulterror"; lblResult.Text = Properties.Messages.GroupSavedCouldNotStoreNewPermissions; } } else { lblResult.CssClass = "resulterror"; lblResult.Text = Properties.Messages.GroupSavedCouldNotDeleteOldPermissions; } } protected void btnDelete_Click(object sender, EventArgs e) { lblResult.Text = ""; lblResult.CssClass = ""; Log.LogEntry("Group deletion requested for " + txtCurrentName.Value, EntryType.General, SessionFacade.CurrentUsername); UserGroup currentGroup = Users.FindUserGroup(txtCurrentName.Value); if(currentGroup.Provider.UserGroupsReadOnly) return; // Remove all global permissions for the group then delete it bool done = RemoveAllAclEntries(currentGroup); if(done) { done = Users.RemoveUserGroup(currentGroup); if(done) { RefreshList(); lblResult.Text = Properties.Messages.GroupDeleted; lblResult.CssClass = "resultok"; ReturnToList(); } else { lblResult.CssClass = "resulterror"; lblResult.Text = Properties.Messages.PermissionsDeletedCouldNotDeleteGroup; } } else { lblResult.CssClass = "resulterror"; lblResult.Text = Properties.Messages.CouldNotDeletePermissions; } } protected void btnCancel_Click(object sender, EventArgs e) { RefreshList(); ReturnToList(); } /// /// Removes all the ACL entries for a group. /// /// The group. /// true if the operation succeeded, false otherwise. private bool RemoveAllAclEntries(UserGroup group) { return AuthWriter.RemoveEntriesForGlobals(group); } /// /// Adds some ACL entries for a group. /// /// The group. /// The granted actions. /// The denied actions. /// true if the operation succeeded, false otherwise. private bool AddAclEntries(UserGroup group, string[] grants, string[] denials) { foreach(string action in grants) { bool done = AuthWriter.SetPermissionForGlobals(AuthStatus.Grant, action, group); if(!done) return false; } foreach(string action in denials) { bool done = AuthWriter.SetPermissionForGlobals(AuthStatus.Deny, action, group); if(!done) return false; } return true; } /// /// Returns to the group list. /// private void ReturnToList() { pnlEditGroup.Visible = false; pnlList.Visible = true; } } /// /// Represents a User Group for display purposes. /// public class UserGroupRow { private string name, description, provider, additionalClass; private int users; /// /// Initializes a new instance of the class. /// /// The original group. /// A value indicating whether the user group is selected. public UserGroupRow(UserGroup group, bool selected) { name = group.Name; description = group.Description; provider = group.Provider.Information.Name; additionalClass = selected ? " selected" : ""; users = group.Users.Length; } /// /// Gets the name. /// public string Name { get { return name; } } /// /// Gets the description. /// public string Description { get { return description; } } /// /// Gets the provider. /// public string Provider { get { return provider; } } /// /// Gets the additional CSS class. /// public string AdditionalClass { get { return additionalClass; } } /// /// Gets the users. /// public int Users { get { return users; } } } }