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? :(
Read
permissions applied, but I add my second permission level to the visitor group.