November Happy Hour will be moved to Thursday December 5th.

Restrict CMS functionalities per role/website - Geta NotFoundHandler redirects

Vote:
 

This question is specific for Geta.NotFoundHandler, but it could be more general question about restricting other Admin functionalities per account role/website.

Our solution has multiple websites with separate roles for access. We're using Geta.NotFoundHandler and I'm looking for a way to restrict access for redirects per role. For example if account has a role with access only to website X, then only redirects with hostname of website X should be visible for editing.

Apart from creating a change request in Geta.NotFoundHandler github I thought about using services.Intercept to intercept IRedirectsService (or even more interfaces if required) and changing returned results based on current url, matched website and current user roles.

Is there a better way to do this than intercepting service? Did someone already created something similar for this module or other admin functionalities?

This is example (through ACL as somehow UIRoleProvider could not be resolved with serviceProvider or ServiceLocator) which can be treated as work in progress, but it shows base logic:

public static class NotFoundHandlerExtensions
{
    public static IServiceCollection AddCustomNotFoundHandlerServices(this IServiceCollection services)
    {
        return services.Intercept<IRedirectsService>((a, b) => new CustomRedirectsService(a, b));
    }
}
public class CustomRedirectsService : IRedirectsService
{
    private readonly IServiceProvider _serviceProvider;
    private readonly IRedirectsService _instance;

    public CustomRedirectsService(IServiceProvider serviceProvider, IRedirectsService instance)
    {
        _serviceProvider = serviceProvider;
        _instance = instance;
    }

    public IEnumerable<CustomRedirect> GetSaved()
    {
        var httpContextAccessor = _serviceProvider.GetService<IHttpContextAccessor>();
        var siteDefinitionResolver = _serviceProvider.GetService<ISiteDefinitionResolver>();
        var contentLoader = _serviceProvider.GetService<IContentLoader>();

        if (httpContextAccessor == null || siteDefinitionResolver == null || contentLoader == null)
        {
            return Enumerable.Empty<CustomRedirect>();
        }

        var host = httpContextAccessor.HttpContext.Request.Host.Value;
        var site = siteDefinitionResolver.GetByHostname(host, false);

        if (site == null)
        {
            return Enumerable.Empty<CustomRedirect>();
        }

        var content = contentLoader.Get<IContent>(site.StartPage);

        if (content is not PageData currentPage)
        {
            return Enumerable.Empty<CustomRedirect>();
        }

        var currentPrincipal = PrincipalInfo.CurrentPrincipal;
        var hasEditAccess = currentPage.ACL.QueryDistinctAccess(currentPrincipal, AccessLevel.FullAccess | AccessLevel.Edit);

        if (hasEditAccess)
        {
            var savedRedirects = _instance.GetSaved();
            var result = savedRedirects.Where(x => x.OldUrl.Contains(host));
            return result;
        }

        return Enumerable.Empty<CustomRedirect>();
    }
//other methods
}
#316745
Feb 06, 2024 11:48
Vote:
 

I don't think Geta Not Found Handler has been built with this in mind.  Some of the more bulk operations may well by pass this and you'd have to intercept a lot more such as the creation of new rules etc.  It's probably worth raising an issue on their repository for advice and tagging marisks: https://github.com/Geta/geta-notfoundhandler/issues

#316801
Feb 07, 2024 11:14
Vote:
 

Geta Not Found Handler confirmed that they don't have any plans to add this feature and my services.Intercept approach can be used, so ultimately that's what I used (of course with better implementation).

#317582
Feb 23, 2024 7:36
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.