Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Rob Watkins 369 posts 701 karma points
    Aug 09, 2023 @ 14:02
    Rob Watkins
    0

    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:

    1. 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.

    2. 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?

  • Huw Reddick 1737 posts 6098 karma points MVP c-trib
    Aug 09, 2023 @ 14:42
    Huw Reddick
    100

    Unfortunately you will have to roll your own way as there is no OOB method to do this.

  • Rob Watkins 369 posts 701 karma points
    Aug 10, 2023 @ 09:09
    Rob Watkins
    0

    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;
        }
    
  • Rob Watkins 369 posts 701 karma points
    Aug 10, 2023 @ 10:07
    Rob Watkins
    0

    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.

  • Rob Watkins 369 posts 701 karma points
    Aug 10, 2023 @ 10:06
    Rob Watkins
    0

    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:

     currentry = new PublicAccessEntry(
                            content,
                            loginpage,
                            noaccesspage,
                            new List<PublicAccessRule>()
                            {
                                new PublicAccessRule()
                                {
                                    RuleType = ACCESS_RULE_TYPE_ROLE,
                                    RuleValue = role
                                }
                            }
                        );
    
Please Sign in or register to post replies

Write your reply to:

Draft