Link to home
Start Free TrialLog in
Avatar of ThatSharepointGuy
ThatSharepointGuyFlag for Japan

asked on

Web Part Permissions?

Greetings!

I have a question that I have tried to search for an answer to, but so far haven't found anything to help yet.

I have two web parts, to which I'll post the code below in their own posts (to keep things clean).

One web part queries the web application that the page being viewed is currently in, and displays all of the groups that the current user is a member of, as well as the URL to the site that the group exists on.  I'll call it "Query User" web part.

The other web part, is a basic "hello world" web part that allows you to change the text (from "hello world" to whatever you want), as well as the color of the text.  Very simple, but I used a webcast from Microsoft to do it because I didn't understand the get/set methods and what they were supposed to do.

Anyway, the problem is this:
I have the three default groups on my test site: Owners, Members, Readers, as well as Site Collection Administrators for my site collection.  So, I add myself to the Owners group (but I am not a Site Collection Administrator).

I can browse to my site, and add the "hello world" web part to the page, change the text, and change the color.  Everything works fine there.  I tried it on Owners, Members, and Readers, and the site displays (although Readers cannot change the web part attributes since they cannot edit the page).

So now my current membership is only "Owners", and I go to add my "Query User" web part to the page...it starts thinking...and then I get "Access Denied".  So, I remote desktop into my VM, and log in with the "SP Admin" account that I created, and browse to my site.  Voila!  There it is, my web part, displaying exactly what it should be showing.

I then added myself as a Site Collection Administrator (by using the service account on the remote-desktop), went back to my normal pc, and tried browsing to the site...and it worked.

So what it comes down to, is that I have two web parts:
Hello World Web Part - can be put on the page, and the page can be seen by ALL users regardless of permission.
Query User Web Part - requires Site Collection Administrator permissions to even view the site, once this web part is added to a page.


Does anyone know why it does this, and what I have to do to fix it?  I'd like other people to be able to use this web part (once I'm done with it, I have more ideas for it but first i want to get this sorted), however I don't want to add everyone to the site collection administrators group, as that's very insecure.
Avatar of ThatSharepointGuy
ThatSharepointGuy
Flag of Japan image

ASKER

Here is the code for the "Query User" web part.

using System;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Portal;

namespace My.SharePoint.WebParts
{
    // Inherit from Microsoft.SharePoint's WebPart, not System.Web.UI.WebControls'
    public class GetCurrentUser : Microsoft.SharePoint.WebPartPages.WebPart
    {
        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            // Get contextual reference to the current SPWeb
            SPWeb currentWeb = SPContext.Current.Web;

            // Create HTML table to display information returned
            writer.Write("<table width='100%' cellpadding=5 cellspacing=1 bgcolor='silver'>");
                    writer.Write("<tr align='center'  bgcolor='white'>");
                        writer.Write("<th align='center' bgcolor='white'>Group Name</th>");
                        writer.Write("<th align='center' bgcolor='white'>URL</th>");
                    writer.Write("</tr>");


            // Set current web applicatoin.
            SPWebApplication webApp = SPContext.Current.Site.WebApplication;


            // SPSiteCollection siteCollections = webApp.Sites;
                foreach (SPSite siteCollection in webApp.Sites)
                {
                    int skip = 0;
                    if (System.Text.RegularExpressions.Regex.IsMatch(siteCollection.Url, "/personal/")) { skip = 1; }
                    if (System.Text.RegularExpressions.Regex.IsMatch(siteCollection.Url, "8001")) { skip = 1; }
                    if (System.Text.RegularExpressions.Regex.IsMatch(siteCollection.Url, "/ssp/")) { skip = 1; }
                    if (skip == 1)
                    {
                        // Do nothing, Do not display personal sites, MySite, or SSPs
                    }
                    else
                    {
                        // Process current site collectoin
                        foreach (SPWeb oWeb in siteCollection.AllWebs)
                        {
                            SPUser user = oWeb.CurrentUser;
                            SPGroupCollection groupCollection = user.Groups;
                            foreach (SPGroup group in groupCollection)
                            {
                                // display a new row for each group
                                writer.Write("<tr align='center' bgcolor='white'>");
                                    writer.Write("<td align='center' bgcolor='white'>" + group.Name + "</td>");
                                    writer.Write("<td align='center' bgcolor='white'>" + oWeb.Url + "</td>");
                                writer.Write("</tr>");
                            }
                        }
                    }
                }
                writer.Write("</table><br/>");
//            }
        }
    }
}

Open in new window

Here is the code for the Hello World web part.

using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;

using System.ComponentModel;
using System.Drawing;

namespace HelloWorldWebPart
{
    [Guid("b59c21d9-7738-4fbb-8da7-beefaa3dce20")]

    public class HelloWorld : System.Web.UI.WebControls.WebParts.WebPart
    {
        public HelloWorld()
        {
        }

        private KnownColor _textColor = KnownColor.Black;

        [WebBrowsable(true),
        Personalizable(PersonalizationScope.User),
        WebDescription("Hello World Text Color"),
        Category("Hello World"),
        WebDisplayName("Text Color")]
        public KnownColor TextColor
        {
            get { return _textColor; }
            set { _textColor = value; }
        }

        private string _helloWorldText = "Hello SharePoint!";

        [WebBrowsable(true),
        Personalizable(PersonalizationScope.User),
        WebDescription("Hello World Text"),
        Category("Hello World"),
        WebDisplayName("Text")]
        public string HelloWorldText
        {
            get { return _helloWorldText; }
            set { _helloWorldText = value; }
        }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            if (string.IsNullOrEmpty(HelloWorldText))
            {
                HelloWorldText = "Hello SharePoint!";
            }

            //TODO: add custom rendering code here.
            Label label = new Label();
            label.Text = HelloWorldText;
            label.ForeColor = Color.FromKnownColor(TextColor);
            this.Controls.Add(label);
        }
    }
}

Open in new window

I'm hoping that someone will have an idea of why this happens, and how to fix it, as Google, MSDN, and the SDK haven't shown me anything of use yet.

When I go to the Web Part Gallery and look at permissions, they are the same.  
Avatar of Ted Bouskill
A web part cannot bypass built in security restrictions.  The ability to 'Query' Sharepoint is restricted to people with the highest level permissions within the API even it it's only about themselves.

Sharepoint's permission model isn't always perfect however they are trying to prevent users from creating web parts that could see far more than they should.

Have you downloaded the WSS and Sharepoint SDK's.  They both have different types of documentation to thoroughly cover the API.  I'm sure there is another mechanism to query Sharepoint without using the low level Site Collection access you are attempting.

Have you considered using Search?  The search API is actually an excellent way to gather data like this behind the scenes in Sharepoint because it manages the permissions for you.  I've seen an entire Sharepoint site that uses search to dynamically build all it's content even for navigation.
Thank you for replying, tedbilly!

If you are talking about using Search (programmatically), what would be the difference between that, and this (what I posted above).  For instance, one of the main things i wanted to do to "get my feet wet" with SharePoint's development side, was to create a web part to show a list of site collection administrators on each site.  However, not everyone that will view this list will BE a site collection administrator.  I might restrict it to just display for the current site, so people know who they are, etc, and can contact them...but normal users will have Contribute permissions at most, so they won't be able to access their page if I throw my web part on there.
ASKER CERTIFIED SOLUTION
Avatar of Ted Bouskill
Ted Bouskill
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Greetings Tedbilly!

Thank you very much for the explanation.  It turns out that my brain was misplaced, and that I haven't actually seen the SDK...I thought the SDK = MSDN.  I'll have to download that and take a look at it.  Hopefully, it has a well thought out "plan" (learn this, then learn this, etc, etc).  

Thanks again, Tedbilly!
Thank you for the very encouraging information to help my journey as an expert in SharePoint!  You're great, TedBilly!