Public access on all children, including newly created, but not parent
So I'm surprised I've not come across this anywhere, or needed to do it, but is this scenario possible?
I have a List Page which has a number of Detail Pages.
I want anonymous users to see the list page, but when they click on the children, they will be asked to log in.
It's not quite this use-case, but imagine a summary page of article titles to spark public interest, but then you have to join the site to read the articles.
Obviously I can set public access on each child, but that'd have to be done every single time I create an article.
I can think of a couple of ways of doing this:
Rework the tree structure; put the child items under a separate, secured parent, then have the anonymous list page look there for titles. I have done this in the past, but it feels like it messes up the simplicity of the tree and makes it less semantic - the tree structure is now based on the security model not the content model.
Use a content save notification to set the public access - this feels hacky and opaque and also if the requirement changes it needs a code rebuild.
Thanks! I have decided to do the automatic option because messing with the tree breaks the URL structure unless I hack that too.
I have got this and it is half working; it restricts the access and sets the login and error pages but it doesn't actually set the group? This messes up the role checking logic and also means that the tree UI thinks it's not restricted so you can't clear it without going in and setting a group manually.
public class PublicAccessHelper
{
public const string ACCESS_RULE_TYPE_ROLE = Constants.Conventions.PublicAccess.MemberRoleRuleType;
public PublicAccessHelper(IPublicAccessService publicaccessservice, IContentService contentservice, ILogger logger)
{
_publicaccessservice = publicaccessservice;
_contentservice = contentservice;
_logger = logger;
}
public void RestrictAccess(IContent content, string role, int loginnodeid, int noaccessnodeid)
{
// Get the current role for the content
var currentry = _publicaccessservice.GetEntryForContent(content);
bool doable = true;
if (currentry != null)
{
var deleteres = _publicaccessservice.Delete(currentry);
doable = deleteres.Success;
if (!doable)
_logger.LogError(deleteres.Exception, $"Could not remove current access rule for for {content.Id}");
}
if (doable)
{
var loginpage = _contentservice.GetById(loginnodeid);
var noaccesspage = _contentservice.GetById(noaccessnodeid);
if (loginpage != null && noaccesspage != null)
{
currentry = new PublicAccessEntry(
content,
loginpage,
noaccesspage,
new List<PublicAccessRule>()
);
currentry.AddRule(ACCESS_RULE_TYPE_ROLE, role);
}
if (currentry != null)
{
var updateres = _publicaccessservice.Save(currentry);
if (updateres.Success)
_logger.LogInformation($"Auto updated public access for {content.Id} to {role}");
else
_logger.LogError(updateres.Exception, $"Failed to update public access for for {content.Id} to {role}");
}
}
}
// ------------------------------------------------------------------------------------------------------------------------------------------------
private IPublicAccessService _publicaccessservice;
private IContentService _contentservice;
private ILogger _logger;
}
Marking this as solution so you get the points and it is in fact the answer to my original question, but anyone interested in option 2 can check out my code below.
Public access on all children, including newly created, but not parent
So I'm surprised I've not come across this anywhere, or needed to do it, but is this scenario possible?
I have a
List Page
which has a number ofDetail Pages
.I want anonymous users to see the list page, but when they click on the children, they will be asked to log in.
It's not quite this use-case, but imagine a summary page of article titles to spark public interest, but then you have to join the site to read the articles.
Obviously I can set public access on each child, but that'd have to be done every single time I create an article.
I can think of a couple of ways of doing this:
Rework the tree structure; put the child items under a separate, secured parent, then have the anonymous list page look there for titles. I have done this in the past, but it feels like it messes up the simplicity of the tree and makes it less semantic - the tree structure is now based on the security model not the content model.
Use a content save notification to set the public access - this feels hacky and opaque and also if the requirement changes it needs a code rebuild.
Is there a better option?
Unfortunately you will have to roll your own way as there is no OOB method to do this.
Thanks! I have decided to do the automatic option because messing with the tree breaks the URL structure unless I hack that too.
I have got this and it is half working; it restricts the access and sets the login and error pages but it doesn't actually set the group? This messes up the role checking logic and also means that the tree UI thinks it's not restricted so you can't clear it without going in and setting a group manually.
Marking this as solution so you get the points and it is in fact the answer to my original question, but anyone interested in option 2 can check out my code below.
Aha! I've managed to solve it myself, the AddRule() doesn't seem to work, but if I add those values to the list when creating, it does:
is working on a reply...