1

This code create a Treeview (in a web part) of our sites and subsites and works perfectly for the admin account but not for a normal user, it list sites and subsites even if the user doesn't have access (he's not a member of any group) and it's not suppose to.

What am i doing wrong?

Am i required to use SPSecurity.RunWithElevatedPrivileges?

    protected override void CreateChildControls()
    {
        TreeView listeTreeView = new TreeView();
        listeTreeView.ID = "farmHierarchyViewer";
        listeTreeView.ShowLines = true;
        listeTreeView.EnableViewState = true;
        this.Controls.Add(listeTreeView);

        TreeNode node;
        listeTreeView.Nodes.Clear();

        SPWebApplication currentWebApplication = SPContext.Current.Site.WebApplication;
        SPSiteCollection collSites = currentWebApplication.Sites;

        SPSecurity.RunWithElevatedPrivileges(delegate()
        {
            foreach (SPSite site in collSites)
            {
                site.CatchAccessDeniedException = false;

                // Check if site collection != Mysite Host (54) et Mysite (21) and user access
                if (site.RootWeb.WebTemplateId != 54 && site.RootWeb.WebTemplateId != 21
                    && site.RootWeb.DoesUserHavePermissions(SPBasePermissions.Open))
                {
                    try
                    {
                        node = new TreeNode();
                        TreeNode siteNode = node;
                        node = new TreeNode(site.RootWeb.Title, null, null, site.Url, "_self");
                        listeTreeView.Nodes.Add(node);
                        TreeNode parentNode = node;

                        foreach (SPWeb childWeb in site.RootWeb.Webs)
                        {
                            try
                            {
                                addWebs(childWeb, parentNode);
                            }
                            finally
                            {
                                childWeb.Dispose();
                            }
                        }
                        site.CatchAccessDeniedException = false;
                    }
                    finally
                    {
                        site.Dispose();
                    }
                }
            }
        });

        listeTreeView.CollapseAll();
    }

    void addWebs(SPWeb web, TreeNode parentNode)
    {
        // Check if site != Blog (9), != Search Center (50) and user access
        if (web.WebTemplateId != 50 &&
            web.DoesUserHavePermissions(web.CurrentUser.ToString(), SPBasePermissions.Open))
        {
            TreeNode node;
            node = new TreeNode(web.Title, null, null, web.Url, "_self");
            parentNode.ChildNodes.Add(node);
            parentNode = node;

            foreach (SPWeb childWeb in web.Webs)
            {
                try
                {
                    addWebs(childWeb, parentNode);
                }
                finally
                {
                    childWeb.Dispose();
                }
            }
        }
    }
1

DoesUserHavePermissions in your code will make the check on the elevated context (hence not checking if current user has access, but if the app pool account has)

Use this version of the method instead, passing in the LoginName of SPContext.Current.Web.CurrentUser to the function : http://msdn.microsoft.com/en-us/library/ms441848.aspx

So

site.RootWeb.DoesUserHavePermissions(SPContext.Current.Web.CurrentUser.LoginName, SPBasePermissions.Open)

Same off course on your web objects a bit further down in your code

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.