I'm experiencing a serious problem (SharePoint 2010) I want to share with you. Steps to reproduce it:
Create a Web application.
Create a site collection inside the Web application previously created. Pick "Publishing Portal" as the site template.
Navigate to the top-level site.
Once in it, go to Site Actions -> New Site and create a subsite. Choose "Publishing Site with Workflow".
Navigate to the subsite.
In the default page (.../Pages/default.aspx), go to the Page tab and click on Page History, it should work correctly. Return to the default page, go to the Page tab and click on Page Permissions, it should work correctly too.
The following code calls the BreakInheritance method passing false as parameters because we need to break permissions inheritance as well as permission levels inheritance (it's a business need). Run:
using Microsoft.SharePoint; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { using (SPSite site = new SPSite("<Your SPSite URL>")) { using (SPWeb web = site.OpenWeb("<Your SPWeb URL>")) { BreakRoleDefinitionInheritance(web); } } } private static void BreakRoleDefinitionInheritance(SPWeb web) { if (!web.HasUniqueRoleDefinitions | !web.HasUniqueRoleAssignments) { web.RoleDefinitions.BreakInheritance(false, false); } } } }Go back to the default page (.../Pages/default.aspx), go to the Page tab and click on Page History, it should work correctly. Return to the default page, go to the Page tab and click on Page Permissions, it should work correctly too.
Go to the Pages library and add a new page.
Navigate to the page previously created.
Go to the Page tab and click on Page History. You should get an exception:
04/21/2011 11:52:31.83 w3wp.exe (0x19BC) 0x1EE8 SharePoint Foundation Runtime tkau Unexpected System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. at Microsoft.SharePoint.SPListItemVersionCollection.get_Item(Int32 iIndex) at Microsoft.SharePoint.WebControls.VersionDiffDescription.Render(HtmlTextWriter output) at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) at System.Web.UI.HtmlControls.HtmlForm.RenderChildren(HtmlTextWriter writer) at System.Web.UI.HtmlControls.HtmlForm.Render(HtmlTextWriter output) at System.Web.UI.HtmlControls.HtmlForm.RenderControl(HtmlTextWriter writer) at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) at System.Web.UI.HtmlControls.HtmlContainerControl.Render(HtmlTextWriter writer) at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) at Microsoft.SharePoint.WebControls.UnsecuredLayoutsPageBase.RenderChildren(HtmlTextWriter writer) at System.Web.UI.Page.Render(HtmlTextWriter writer) at Microsoft.SharePoint.WebControls.UnsecuredLayoutsPageBase.Render(HtmlTextWriter writer) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) 491e09ce-80cf-4789-b32f-4dbfb074c09d
... finally return to the page previously created, go to the Page tab and click on Page Permissions. You should get an exception:
Microsoft.SharePoint.SPException: The object specified does not belong to a list. at Microsoft.SharePoint.SPWeb.GetItem(String strUrl, Boolean bFile, Boolean cacheRowsetAndId, Boolean bDatesInUtc, String[] fields) at Microsoft.SharePoint.SPFolder.get_Item() at Microsoft.SharePoint.SPListItem.get_FirstUniqueAncestorSecurableObject() at Microsoft.SharePoint.ApplicationPages.UserRoles.GetParentPermissionPage(String& strParentName) at Microsoft.SharePoint.ApplicationPages.UserRoles.SetInheritStatus() at Microsoft.SharePoint.ApplicationPages.UserRoles.InitPage() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) ebe3dad0-c06f-4f5a-adbd-fef20ba3b350
Does anyone knows what is going on or has experienced this before?
I did a lot of research, including getting into the content database, and I'm really convinced this is a SharePoint permission bug.
If you get the SPListItem for the page created in step 9 and you ask for the FirstUniqueAncestorSecurableObject value, you will get the "The object specified does not belong to a list." exception:
using (SPSite site = new SPSite("<Your SPSite URL>"))
{
using (SPWeb web = site.OpenWeb("<Your SPWeb URL>"))
{
SPList pages = web.GetList("<Your Pages list URL>");
SPListItem page = pages.GetItemById(<Your page ID>);
SPSecurableObject firstUniqueAncestor = page.FirstUniqueAncestorSecurableObject; // Exception!
}
}
Also note that for the SPListItem object, the Versions property value is 0, which is weird:
using (SPSite site = new SPSite("<Your SPSite URL>"))
{
using (SPWeb web = site.OpenWeb("<Your SPWeb URL>"))
{
SPList pages = web.GetList("<Your Pages list URL>");
SPListItem page = pages.GetItemById(<Your page ID>);
int versionsCount = page.Versions.Count; // Count is 0!
}
}