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 exist
13.
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 own
25.
pm.BreakPermiossionsInheritance(topPage);
26.
//Create the permission if doesn't exist
27.
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 modifying
37.
someRolePermission.DenyActions(
38.
true
,
39.
SecurityConstants.Sets.Pages.Modify);
40.
//Add the permission to the page, if it's not already there
41.
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 default
50.
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 default
68.
grandchildPage = pm.CreatePage(
69.
childPage, Guid.NewGuid(),
70.
PageType.Standard);
71.
72.
grandchildPage.Page.Title = grandchildPageTitle;
73.
74.
//Create a permission AFTER the pages exist
75.
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 deleting
86.
anotherRolePermission.DenyActions(
87.
true
,
88.
SecurityConstants.Sets.Pages.Delete);
89.
//Add the permission to the page, if it's not already there
90.
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 = App
04.
.WorkWith()
05.
.Pages()
06.
.Get()
07.
.Where(node => node.Title ==
"ChildPage"
).FirstOrDefault().Id;
08.
Guid parentId = App
09.
.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 = mgr
17.
.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