force page permissions to cascade after children are created
Hi.
I programatically create a tree of pages. When I create the children pages I set InheritsPermissions to true.
After that. I set the permissions on the root page of the tree.
However, the children pages do not then show that they have the same permissions.
Is there a way I can force the permissions to cascade to the children?
Thanks.
Hi Phil,
When a page node is created, it inherits permissions from its parent page node by default.
For front-end pages, the topmost node is the Frontend root node under which pages can be created, and for back-end pages, the topmost node is the Backend root node.
Note that a page node may inherit permissions from its parent node (or ancestor, if the inheritance chain is longer), in which case, the "effective" permissions are the inherited ones.
Other permissions (which are attached directly to the page node) do not show in the UI, and are not effective when evaluating an action performed by a certain user.
So, in the case you describe, the logic should be-
01.string transactionName = "transact" + Guid.NewGuid().ToString();02.PageManager pm = PageManager.GetManager(null, transactionName);03.RoleManager rm = RoleManager.GetManager();04. 05.Role someRole = rm.GetRole("SomeRole");06.PageNode frontendRoot = pm.GetPageNode(SiteInitializer.FrontendRootNodeId);07. 08.string topPageTitle = "New Page 1";09.string childPageTitle = "Child Page 2";10.string grandchildPageTitle = "Grandchild Page 3";11. 12.//Create the top page, if doesn't exist13.PageNode topPage = pm.GetPageNodes()14. .Where(node => node.Title == topPageTitle)15. .FirstOrDefault();16.if (topPage == null)17.18. topPage = pm.CreatePage(19. frontendRoot, Guid.NewGuid(), 20. PageType.Standard);21.22.topPage.Page.Title = topPageTitle;23. 24.//The top page does not inherit permissions, but uses its own25.pm.BreakPermiossionsInheritance(topPage);26.//Create the permission if doesn't exist27.Permission someRolePermission = pm.GetPermission(28. SecurityConstants.Sets.Pages.SetName, 29. topPage.Id, 30. someRole.Id);31.if (someRolePermission == null)32. someRolePermission = pm.CreatePermission(33. SecurityConstants.Sets.Pages.SetName, 34. topPage.Id, 35. someRole.Id);36.//Deny some role from modifying37.someRolePermission.DenyActions(38. true, 39. SecurityConstants.Sets.Pages.Modify);40.//Add the permission to the page, if it's not already there41.if (!topPage.Permissions.Contains(someRolePermission))42. pm.AddPermissionToObject(topPage, someRolePermission, transactionName);43. 44.PageNode childPage = pm.GetPageNodes()45. .Where(node => node.Title == childPageTitle)46. .FirstOrDefault();47.if (childPage == null)48.49. //the child page inherits permissions from its parent by default50. childPage = pm.CreatePage(51. topPage, 52. Guid.NewGuid(), 53. PageType.Standard);54.55.childPage.Page.Title = childPageTitle;56. 57.//It's possible to manually make sure the inheritance is applied,58.//by calling CreatePermissionInheritanceAssociation:59.//60.//pm.CreatePermissionInheritanceAssociation(topPage, childPage);61. 62.PageNode grandchildPage = pm.GetPageNodes()63. .Where(node => node.Title == grandchildPageTitle)64. .FirstOrDefault();65.if (grandchildPage == null)66.67. //the grandchild page inherits permissions from the child page by default68. grandchildPage = pm.CreatePage(69. childPage, Guid.NewGuid(), 70. PageType.Standard);71.72.grandchildPage.Page.Title = grandchildPageTitle;73. 74.//Create a permission AFTER the pages exist75.Role anotherRole = rm.GetRole("anotherRole");76.Permission anotherRolePermission = pm.GetPermission(77. SecurityConstants.Sets.Pages.SetName, 78. topPage.Id, 79. anotherRole.Id);80.if (anotherRolePermission == null)81. anotherRolePermission = pm.CreatePermission(82. SecurityConstants.Sets.Pages.SetName, 83. topPage.Id, 84. anotherRole.Id);85.//Deny some role from deleting86.anotherRolePermission.DenyActions(87. true, 88. SecurityConstants.Sets.Pages.Delete);89.//Add the permission to the page, if it's not already there90.if (!topPage.Permissions.Contains(anotherRolePermission))91. pm.AddPermissionToObject(topPage, anotherRolePermission, transactionName);92. 93.TransactionManager.CommitTransaction(transactionName);
The problem at this time is that the last pages in the tree are not inheriting the permissions they way that they should. They are copies of existing pages. The code that I am using to create them is here:
public bool CopyAPage(Guid guidSourcePage, Guid parentId, string newPageName) var mgr = App.WorkWith().Page(guidSourcePage); PageNode parentPage = mgr.PageManager.GetPageNodes(). Where(pi => pi.Id == parentId).OrderByDescending(pd => pd.DateCreated).FirstOrDefault(); mgr.Duplicate().Do( p => p.Title = newPageName; p.UrlName = newPageName; p.ShowInNavigation = true; p.Parent = parentPage; // parentPage is a PageNode object p.CanInheritPermissions = true; p.InheritsPermissions = true; if (p.Page != null) // This is a normal page with Page Data (not a group page) p.Page.Title = newPageName; ).SaveChanges(); return true;Hello Phil,
Thanks for the update.
This time I wasn't able reproduce your problem by re-using your code, which means you're probably doing something right (or I'm doing something wrong).
Here's what I tried to do:
Initially I had 2 pages in the system, where one is defined to be a parent of the other.
In this sample, ParentPage was breaking the permission inheritance, and has its own permissions set.

ChildPage was inheriting its permissions from its parent, namely from ParentPage.

Now using your code, I'm trying to create a sibling to ChildPage which would inherit permissions from ParentPage, just lilke ChildPage does.
This is my code, which is 1:1 adaptation of yours:
01.void CreateSibling()02.03. Guid guidSourcePage = App04. .WorkWith()05. .Pages()06. .Get()07. .Where(node => node.Title == "ChildPage").FirstOrDefault().Id;08. Guid parentId = App09. .WorkWith()10. .Pages()11. .Get()12. .Where(node => node.Title == "ParentPage").FirstOrDefault().Id;13. string newPageName = "New Sibling";14. 15. var mgr = App.WorkWith().Page(guidSourcePage);16. PageNode parentPage = mgr17. .PageManager.GetPageNodes()18. .Where(pi => pi.Id == parentId)19. .OrderByDescending(pd => pd.DateCreated).FirstOrDefault();20. 21. mgr.Duplicate().Do(22. p =>23. 24. p.Title = newPageName;25. p.UrlName = newPageName;26. p.ShowInNavigation = true;27. p.Parent = parentPage;28. p.CanInheritPermissions = true;29. p.InheritsPermissions = true;30. if (p.Page != null)31. 32. p.Page.Title = newPageName;33. 34. ).SaveChanges();35.
I placed it in a sample page, and ran it (as an event handler of a click of a button, but that does not matter).
The result, in terms of the pages hierarchy tree was:
And in terms of permissions, New Siblinb now inherits permissions just like its brother, ChildPage:
- which I think is what you were trying to achieve...
Thus, in order to assist you better, I'd need additional information about the version and build of Sitefinity which you are using, and additional details about your system, its configuration and the scenario.
I hope this information helps. Please provide additional information about your case, should you need additional help.
All the best,
Alon Rotem
the Telerik team