Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more

Modify access level on creating content

Vote:
 

I'm trying to remove public access to a certain media content on creation. I have tried modifying the access rules both via SetDefaultValues and IContentEvents.CreatingContent, but with no success. This is my current code using SetDefaultValues:

public override void SetDefaultValues(ContentType contentType)
{
    base.SetDefaultValues(contentType);

    if (this is IContentSecurable securable)
    {
        var securityDescriptor = securable.GetContentSecurityDescriptor();
        securityDescriptor.IsInherited = false;

        var everyone = securityDescriptor.Entries.FirstOrDefault(x => x.EntityType == SecurityEntityType.Role && x.Name == EveryoneRole.RoleName);
        if (everyone != null)
        {
            securityDescriptor.RemoveEntry(everyone);
        }
    }
}

In the code above, I try to remove the inherited access and also entirely remove the rule which allows Everyone to read the content. Nothing seems to get applied though - when I try to view that content in Episerver, it still says that it inherits access rules and it also says the Everyone still has Read access.

I haven't tried changing these rules in the CreatedContent event, but I assume that would require me create a writable clone, do the change and then re-save that content, which just seems excessive.

#210649
Dec 02, 2019 13:47
Vote:
 

Hi,

In addition to above information. The reason your changes are not persisted is because you need to call IContentSecurityRepository explicitly to work with a content's ACL.

#210654
Dec 02, 2019 16:52
Andreas J - Dec 17, 2019 9:27
I also experienced that ACL wasn't really set up when SetDefaultValues(...) was called. For example, I could execute securityDescriptor.ToLocal() in the CreatedContent but not in SetDefaultValues(...).
Vote:
 

Thanks for your answers. I would have liked to use SetDefaultValues in order to keep the code close to its domain, but okay. This was my final solution - used in the CreatedContent event.

var securityDescriptor = (IContentSecurityDescriptor)securable.GetContentSecurityDescriptor().CreateWritableClone();
if (securityDescriptor.IsInherited)
{
    securityDescriptor.ToLocal();
    var everyone = securityDescriptor.Entries.FirstOrDefault(x => x.EntityType == SecurityEntityType.Role && x.Name == EveryoneRole.RoleName);
    if (everyone != null)
    {
        securityDescriptor.RemoveEntry(everyone);
    }

    var existingRoles = securityDescriptor.Entries
        .Where(x => x.EntityType == SecurityEntityType.Role)
        .Select(x => x.Name);
    if (!existingRoles.Contains(NewRole))
    {
        var entry = new AccessControlEntry(NewRole, AccessLevel.Read, SecurityEntityType.Role);
        securityDescriptor.AddEntry(entry);
    }

    _contentSecurityRepository.Save(e.ContentLink, securityDescriptor, SecuritySaveType.Replace);
}
#211064
Dec 17, 2019 9:25
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.