Skip to content

Instantly share code, notes, and snippets.

@PNergard
Created May 16, 2016 20:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PNergard/2d09e075afa99f81f93ced842f40b064 to your computer and use it in GitHub Desktop.
Save PNergard/2d09e075afa99f81f93ced842f40b064 to your computer and use it in GitHub Desktop.
A admin mode plugin to give admins and developers a better overview of how acccess rights are configured in a site.
<%@ Page Language="C#" AutoEventWireup="false" CodeBehind="AccessrightsOverview.aspx.cs" Inherits="AlloyDemoKit.modules.Nergard.AccessRightsOverview.AccessrightsOverview" %>
<%@ Import Namespace="EPiServer.Security" %>
<%@ Register TagPrefix="EPiServerUI" Namespace="EPiServer.UI.WebControls" Assembly="EPiServer.UI" %>
<%@ Register TagPrefix="EPiServerScript" Namespace="EPiServer.ClientScript.WebControls" Assembly="EPiServer" %>
<asp:content contentplaceholderid="MainRegion" runat="server">
<div class="epi-formArea epi-paddingHorizontal">
<fieldset>
<legend>Pages summary</legend>
<dl>
<dt>Pages starting from start page</dt><dd><asp:Literal runat="server" id="allPagesCount" /></dd>
<dt>Pages wich does not have inherited access rights</dt><dd><asp:Literal runat="server" id="allPagesNotInheritCount" /></dd>
<dt>Number of groups</dt><dd><asp:Literal runat="server" id="numberOfGroupsPages" /></dd>
<dt>Group names:</dt>
<dd>
<asp:Repeater runat="server" id="rptPagesGroups">
<ItemTemplate>
<a href="<%=UiUrl()%>Admin/admingroup.aspx?rolename=<%# Container.DataItem.ToString()%>&provider=""><%# Container.DataItem.ToString()%></a>
</ItemTemplate>
</asp:Repeater>
<asp:Literal runat="server" id="groupNamesPages" />
</dd>
<dt>Number of users</dt><dd><asp:Literal runat="server" id="numberOfUsersPages" /></dd>
<dt>User names:</dt>
<dd>
<asp:Repeater runat="server" id="rptPagesUsers">
<ItemTemplate>
<a href="<%=UiUrl()%>Admin/EditUser.aspx?membershipUsername=<%# Container.DataItem.ToString()%>"><%# Container.DataItem.ToString()%></a>
</ItemTemplate>
</asp:Repeater>
<asp:Literal runat="server" id="userNamesPages" />
</dd>
</dl>
</fieldset>
<fieldset>
<legend><a href="#" onclick="$( '#pagedetails' ).toggle();">Hide / Show pagelist</a></legend>
<div id="pagedetails">
<asp:Repeater runat="server" id="rptPagesDetails">
<ItemTemplate>
<a href="<%=UiUrl()%>Admin/security.aspx?id=<%# Eval("key")%>"><%# Eval("value")%></a>
<br />
</ItemTemplate>
</asp:Repeater>
</div>
</fieldset>
<fieldset>
<legend>Assets summary</legend>
<dl>
<dt>Assets starting from asset root</dt><dd><asp:Literal runat="server" id="allAssetsCount" /></dd>
<dt>Assets wich does not have inherited access rights</dt><dd><asp:Literal runat="server" id="allAssetsNotInheritCount" /></dd>
<dt>Assets wich does not have inherited access rights - blocks</dt><dd><asp:Literal runat="server" id="numberOfBlocks" /></dd>
<dt>Assets wich does not have inherited access rights - media</dt><dd><asp:Literal runat="server" id="numberofMedia" /></dd>
<dt>Number of groups</dt><dd><asp:Literal runat="server" id="numberOfGroupsAssets" /></dd>
<dt>Group names:</dt>
<dd>
<asp:Repeater runat="server" id="rptAssetsGroups">
<ItemTemplate>
<a href="<%=UiUrl()%>Admin/admingroup.aspx?rolename=<%# Container.DataItem.ToString()%>&provider=""><%# Container.DataItem.ToString()%></a>
</ItemTemplate>
</asp:Repeater>
<asp:Literal runat="server" id="groupNamesAssets" />
</dd>
<dt>Number of users</dt><dd><asp:Literal runat="server" id="numberOfUsersAssets" /></dd>
<dt>User names:</dt>
<dd>
<asp:Repeater runat="server" id="rptAssetsUsers">
<ItemTemplate>
<a href="<%=UiUrl()%>/Admin/EditUser.aspx?membershipUsername=<%# Container.DataItem.ToString()%>"><%# Container.DataItem.ToString()%></a>
</ItemTemplate>
</asp:Repeater>
<asp:Literal runat="server" id="userNamesAssets" />
</dd>
</dl>
</fieldset>
<fieldset>
<legend><a href="#" onclick="$( '#assetdetails' ).toggle();" >Hide / show assetlist</a></legend>
<div id="assetdetails">
<asp:Repeater runat="server" id="rptAssetDetails">
<ItemTemplate>
<a href="<%=UiUrl()%>Admin/security.aspx?id=<%# Eval("key")%>"><%# Eval("value")%></a>
<br />
</ItemTemplate>
</asp:Repeater>
</div>
</fieldset>
</asp:content>
using EPiServer;
using EPiServer.Core;
using EPiServer.Filters;
using EPiServer.PlugIn;
using EPiServer.Security;
using EPiServer.ServiceLocation;
using EPiServer.Shell.WebForms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace AlloyDemoKit.modules.Nergard.AccessRightsOverview
{
[GuiPlugIn(DisplayName = "Access Rights Overview", Area = PlugInArea.AdminMenu, Url = ("~/modules/Nergard.AccessRightsOverview/AccessrightsOverview.aspx"))]
public partial class AccessrightsOverview : WebFormsBase
{
IContentRepository contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
protected class ContentSummary
{
public int totalCount = 0;
public int totalNoInheritance = 0;
public int totalGroupsUsed = 0;
public int totalUsersUsed = 0;
public int totalBlocks = 0;
public int totalMedia = 0;
public List<string> groupNames = new List<string>();
public List<string> userNames = new List<string>();
public SortedDictionary<ContentReference, string> iContentNoInheritance = new SortedDictionary<ContentReference, string>();
public ContentSummary()
{
}
}
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
MasterPageFile = UriSupport.ResolveUrlFromUIBySettings("MasterPages/EPiServerUI.master");
SystemMessageContainer.Heading = "Overview of how access rights are configured in the current site.";
SystemMessageContainer.Description = "This plugin is intended to help administrators and developers to get a better overview of how access rights are configured in a site.";
}
protected override void OnLoad(EventArgs e)
{
//PageTree
ContentSummary summary = GroupsAndUsers(GetContent(AllReferences((ContentReference.StartPage))));
allPagesCount.Text = summary.totalCount.ToString();
allPagesNotInheritCount.Text = summary.totalNoInheritance.ToString();
numberOfGroupsPages.Text = summary.totalGroupsUsed.ToString();
//groupNamesPages.Text = string.Join(",", summary.groupNames);;
numberOfUsersPages.Text = summary.totalUsersUsed.ToString();
//userNamesPages.Text = string.Join(",", summary.userNames);
rptPagesGroups.DataSource = summary.groupNames;
rptPagesGroups.DataBind();
rptPagesUsers.DataSource = summary.userNames;
rptPagesUsers.DataBind();
rptPagesDetails.DataSource = summary.iContentNoInheritance;
rptPagesDetails.DataBind();
//Assets
ContentSummary assetSummary = GroupsAndUsers(GetContent(AllReferences((ContentReference.SiteBlockFolder))));
allAssetsCount.Text = assetSummary.totalCount.ToString();
allAssetsNotInheritCount.Text = assetSummary.totalNoInheritance.ToString();
numberOfGroupsAssets.Text = assetSummary.totalGroupsUsed.ToString();
//groupNamesAssets.Text = string.Join(",", assetSummary.groupNames); ;
numberOfUsersAssets.Text = assetSummary.totalUsersUsed.ToString();
//userNamesAssets.Text = string.Join(",", assetSummary.userNames);
numberOfBlocks.Text = assetSummary.totalBlocks.ToString();
numberofMedia.Text = assetSummary.totalMedia.ToString();
rptAssetsGroups.DataSource = assetSummary.groupNames;
rptAssetsGroups.DataBind();
rptAssetsUsers.DataSource = assetSummary.userNames;
rptAssetsUsers.DataBind();
rptAssetDetails.DataSource = assetSummary.iContentNoInheritance;
rptAssetDetails.DataBind();
}
protected IEnumerable<ContentReference> AllReferences(ContentReference start)
{
List<ContentReference> allReferences = new List<ContentReference>();
allReferences.AddRange(contentRepository.GetDescendents(start));
allReferences.Insert(0, ContentReference.RootPage);
return allReferences;
}
protected IEnumerable<IContent> GetContent(IEnumerable<ContentReference> references)
{
return contentRepository.GetItems(references, LanguageSelector.AutoDetect());
}
protected AccessControlList GetAclFromContent(IContent content)
{
IContentSecurable currentContent = content as IContentSecurable;
AccessControlList list = new AccessControlList();
if (currentContent != null)
{
IContentSecurityDescriptor contentSecurityDescriptor = currentContent.GetContentSecurityDescriptor();
if (contentSecurityDescriptor == null)
{
return list;
}
foreach (AccessControlEntry entry in contentSecurityDescriptor.Entries)
{
list.Add(new AccessControlEntry(entry.Name, entry.Access, entry.EntityType));
}
list.IsInherited = contentSecurityDescriptor.IsInherited;
}
return list;
}
protected ContentSummary GroupsAndUsers(IEnumerable<IContent> allContent)
{
var summary = new ContentSummary();
string type = "";
List<KeyValuePair<string, AccessControlEntry>> allGroupsAndUsers = new List<KeyValuePair<string, AccessControlEntry>>();
AccessControlList acl = new AccessControlList();
summary.totalCount = allContent.Count();
foreach (var content in allContent)
{
acl = GetAclFromContent(content);
allGroupsAndUsers.AddRange(acl);
if (!acl.IsInherited)
{
type = "";
if (content as BlockData != null)
{
summary.totalBlocks++;
type = " (Block)";
}
if (content as MediaData != null)
{
summary.totalMedia++;
type = " (Media)";
}
summary.totalNoInheritance++;
summary.iContentNoInheritance.Add(content.ContentLink,BreadCrumb(content) + type);
}
}
summary.groupNames = allGroupsAndUsers.Where(x => x.Value.EntityType == SecurityEntityType.Role).Select(x => x.Key).Distinct().ToList();
summary.userNames = allGroupsAndUsers.Where(x => x.Value.EntityType == SecurityEntityType.User).Select(x => x.Key).Distinct().ToList();
summary.totalGroupsUsed = summary.groupNames.Count();
summary.totalUsersUsed = summary.userNames.Count();
return summary;
}
private string BreadCrumb(IContent content)
{
var ancestor = contentRepository.GetAncestors(content.ContentLink).ToList();
string path = "";
for (int x = ancestor.Count() - 1; x >= 0; x--)
{
path += "\\" + ancestor[x].Name;
}
return (path + "\\" + content.Name);
}
protected string UiUrl()
{
return EPiServer.Configuration.Settings.Instance.UIUrl.ToString().Trim('~');
}
}
}
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace AlloyDemoKit.modules.Nergard.AccessRightsOverview {
public partial class AccessrightsOverview {
/// <summary>
/// allPagesCount control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal allPagesCount;
/// <summary>
/// allPagesNotInheritCount control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal allPagesNotInheritCount;
/// <summary>
/// numberOfGroupsPages control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal numberOfGroupsPages;
/// <summary>
/// rptPagesGroups control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Repeater rptPagesGroups;
/// <summary>
/// groupNamesPages control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal groupNamesPages;
/// <summary>
/// numberOfUsersPages control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal numberOfUsersPages;
/// <summary>
/// rptPagesUsers control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Repeater rptPagesUsers;
/// <summary>
/// userNamesPages control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal userNamesPages;
/// <summary>
/// rptPagesDetails control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Repeater rptPagesDetails;
/// <summary>
/// allAssetsCount control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal allAssetsCount;
/// <summary>
/// allAssetsNotInheritCount control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal allAssetsNotInheritCount;
/// <summary>
/// numberOfBlocks control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal numberOfBlocks;
/// <summary>
/// numberofMedia control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal numberofMedia;
/// <summary>
/// numberOfGroupsAssets control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal numberOfGroupsAssets;
/// <summary>
/// rptAssetsGroups control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Repeater rptAssetsGroups;
/// <summary>
/// groupNamesAssets control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal groupNamesAssets;
/// <summary>
/// numberOfUsersAssets control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal numberOfUsersAssets;
/// <summary>
/// rptAssetsUsers control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Repeater rptAssetsUsers;
/// <summary>
/// userNamesAssets control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Literal userNamesAssets;
/// <summary>
/// rptAssetDetails control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Repeater rptAssetDetails;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment