0

In a corporate intranet portal, I want to allow any visitor (any authenticated user) to customize some pages with user web parts.

I want to restrict this customization only on some pages.

By now, I created a new permission level "Customize user webparts", which defines this permissions :

  • Add and Customize Pages
  • Add/Remove Personal Web Parts
  • Update Personal Web Parts

This is smallest set of permissions I find to allow adding user webparts.

In my portal, I have a "Visitor of my portal" group.

If I apply to this group the custom permission level (keeping the OOB read permission level) at the web level, I can add user web parts on the pages.

However, if I apply this permission level at either page's library level or specific page level (breaking permissions inheritance), I can't add user webpart.

Is it possible to apply this permissions on specific pages only?

Please note that I can remove or update webparts. It's only adding webpart that is restricted.

FYI, the webparts are actually added by code, from a custom "manager" webpart.

Especially, this code is throwing the exception :

var mgr = web.GetLimitedWebPartManager(file.ServerRelativeUrl, System.Web.UI.WebControls.WebParts.PersonalizationScope.User);
var wpFile = web.GetCatalog(SPListTemplateType.WebPartCatalog).RootFolder.Files["somewebpart.webpart"];
System.Web.UI.WebControls.WebParts.WebPart newWebPart;
using (var raw = wpFile.OpenBinaryStream())
{
    using (var xr = XmlReader.Create(raw))
    {
        string error;
        newWebPart = mgr.ImportWebPart(xr, out error); 
    }
}

The ImportWebPart method is throwing some obscure exception :

Microsoft.SharePoint.ApplicationRuntime.SafeControls+UnsafeControlException: A Web Part or Web Form Control on this Page cannot be displayed or imported. You don't have Add and Customize Pages permissions required to perform this action
   à Microsoft.SharePoint.WebPartPages.WebPartImporter.CreateWebPart(Boolean clearConnections)
   à Microsoft.SharePoint.WebPartPages.WebPartImporter.Import(SPWebPartManager manager, XmlReader reader, Boolean clearConnections, Uri webPartPageUri, SPWeb spWeb)
   à Microsoft.SharePoint.WebPartPages.WebPartImporter.Import(SPWebPartManager manager, XmlReader reader, Boolean clearConnections, SPWeb spWeb)
   à Microsoft.SharePoint.WebPartPages.SPWebPartManager.ImportWebPart(XmlReader reader, String& errorMessage)
   à Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager.ImportWebPart(XmlReader reader, String& errorMessage)
   à x.y.z.ImportWebPart(SPLimitedWebPartManager mgr, SPFile wpFile)

In the ULS logs, I only see this :

Error importing WebPart. Assembly Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, TypeName. Microsoft.SharePoint.WebPartPages.ContentEditorWebPart

Which is quite disturbing.

[Edit] With Reflector, I found in the WebPartImporter.CreateWebPart method this verification:

     if ((!this._spWeb.AllowContributorsToEditScriptableParts && !this._spWeb.DoesUserHavePermissions(SPBasePermissions.EmptyMask | SPBasePermissions.AddAndCustomizePages)) && !this._spWeb.SafeControls.SafeAgainstScript(this._type, out unsafeErrorMessage))
        {
            throw new SafeControls.UnsafeControlException(SafeControls.UnsafeControlException.MakeGenericUnsafeExceptionMessage(unsafeErrorMessage));
        }

Actually, the code to add a webpart checks the permission on the SPWeb object.

Should I conclude that my scenario is not supported? :(

2
  • when permissions are broken have the original permissions been kept or totally removed, and only your custom one applied? Commented Apr 11, 2013 at 17:20
  • Actullay, I keep the Read permissions applied, but I add my second permission level to the visitor group.
    – Steve B
    Commented Apr 11, 2013 at 17:33

3 Answers 3

1

After some experiments, here is seems-to-work solution :

var web = SPContext.Current.Web;

var mgr = web.GetLimitedWebPartManager(file.ServerRelativeUrl, System.Web.UI.WebControls.WebParts.PersonalizationScope.User);


var wpFile = web.GetCatalog(SPListTemplateType.WebPartCatalog).RootFolder.Files["somewebpart.webpart"];



/* Elevated the process just for importing the webpart */
var elevatedWeb = GetElevatedWeb(web); // Get an elevated Web object, that points on the same web
var elevatedMgr = elevatedWeb.GetLimitedWebPartManager(file.ServerRelativeUrl, System.Web.UI.WebControls.WebParts.PersonalizationScope.User);
System.Web.UI.WebControls.WebParts.WebPart newWebPart;
using (var raw = wpFile.OpenBinaryStream())
{
    using (var xr = XmlReader.Create(raw))
    {
        string error;
        newWebPart = elevatedMgr.ImportWebPart(xr, out error); 
    }
}


/* Import the webpart, created in the elevated context, but into the current user's context. */
mgr.AddWebPart(newWebPart, "Left", 0);

Basically, the idea was to import the webpart under an elevated context, but add the imported web part in the actual current context.

It seems to work, but I'm not very fan o such hacking mechanism.

0

You want to allow any visitor (any authenticated user) to customize some pages with user web parts...Right?

How we do this where I work, we created a group that includes the accounts of all authenticated users. We can apply this permission group at any level, document through an entire site collection.

Hope this helps you out in some way...

1
  • My question is not how to set up the permissions, but how to restrict this on a specific page
    – Steve B
    Commented Apr 12, 2013 at 6:45
0

In reviewing the method you find with reflector it does appear that it requires the web level permissions. You might want to consider executing the block with elevated permissions which should get you around the need for giving web level permissions. (Assuming this is a farm solution) If you go that route you might consider adding some extra logic checking in your custom manager web part to make sure the elevated privileges are not being used/invoked incorrectly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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