Giving end users a list of all the SharePoint sites they have access to

When You’re running a medium sized SharePoint Farm you may often get requests from end users for a list of all the SharePoint sites they have access to.

As with almost anything in SharePoint where you work with multiple Site Collections Search is the best solution, but if you for some reason can’t use that, then I’ve implemented a small feature which provides this information as an application page, which you can access through a new menu item on the Welcome menu.

The implementation of this is quiet simple:

Add a menuitem to the Welcome menu pointing to our own application page:

<CustomAction Id="6346660F-707E-40d2-A7CF-AB6BAC7A98FD"
              Location="Microsoft.SharePoint.StandardMenu"
              GroupId="PersonalActions"
              Sequence="400"
              Title="Show All Sites"
              Description="Shows all sites which you have access to">
    <UrlAction Url="_layouts/ShowAllSites/ShowAllSites.aspx" />
</CustomAction>

The application page just contains a ASP.NET TreeView control and the following code:

Get Login of current user:

login = SPContext.Current.Web.CurrentUser.LoginName;

Loop through all SiteCollections inside RunWithElevatedPrivileges:

SPSecurity.RunWithElevatedPrivileges(delegate()
{
    SPWebService cs = SPWebService.ContentService;
    foreach (SPWebApplication wa in cs.WebApplications)
    {
        foreach (SPSite site in wa.Sites)
        {
            using (SPWeb web = site.RootWeb)
            {
                AddWebToTreeIfAccess(web, tvSites.Nodes);
            }
            site.Dispose();
        }
    }
});

Skip Shared Services Administration and My Sites:

if (web.WebTemplate == "OSRV"
 || web.WebTemplate == "SPSMSITEHOST"
 || web.WebTemplate == "SPSPERS")
    return;

Process all child sites:

TreeNode tn = new TreeNode();
foreach (SPWeb childweb in web.Webs)
{
    AddWebToTreeIfAccess(childweb, tn.ChildNodes);
    childweb.Dispose();
}

Check if user can view pages on this site:

bool userHasAccess = web.DoesUserHavePermissions(login, SPBasePermissions.ViewPages);

Add site to treeview if user can access it or any of it’s decendents:

if (userHasAccess
 || tn.ChildNodes.Count > 0)
    {
    if (userHasAccess)
    {
        tn.Text = web.Title;
        tn.NavigateUrl = web.Url;
    }
    else
    {
        tn.Text = "(" + web.Title + ")";
        tn.SelectAction = TreeNodeSelectAction.Expand;
    }
    treeNodeCollection.Add(tn);
}

A prebuilt solution package can be found here and the full source code here

comments powered by Disqus