andriu99 / GESPRO_GESTION_DE_TAREAS

Repo para la asignatura de gestión de proyectos
MIT License
0 stars 0 forks source link

Role based attribute filtering #21 #51

Open GuillermoSaldana opened 4 years ago

GuillermoSaldana commented 4 years ago

Hi Scott

I'm currently using conventionsBuilder.ResourceTypeConventions().AddPropertyDiscoveryConvention(); for auto discovering attributes which is working great.

However I'm now looking to filter attributes by user role, or other conditional. Do you know of any way to do so?

Is creating a class that inherits from IResourceTypeConvention a good place to start? Any ideas would be greatly appreciated!

Regardless, thanks for all the hard work. Cheers, Finn

CarlosOrtu commented 4 years ago

Finn,

Interesting question. I believe what you are asking is the ability at runtime to control what attributes of a resource are serialized to JSON. For example, based on a client being authenticated and authorized to use your JSON API based hypermedia API what attributes of the resource to return based on the user authorization scopes or roles. Is this correct?

I am currently working on 2.0 redesign of this framework which includes important improvements such as issue #45 which is tracking the actual incoming attributes for a true patch framework. I like this feature I believe you are asking about, the control at runtime what outgoing attributes to actually serialize either at the time of building the JSON API document or some convention configured upon startup. I am going to think on this one and get back to you soon...

Thanks, Scott

GuillermoSaldana commented 4 years ago

Hi Scott

Thanks for your answer. That's exactly what I ment.

I've gone ahead and found a working solution in the mean time but it required some minor modifications to the core module code.

I'll come back to you with more details tomorrow but it basicly amounted to changing the namingbuilders and resourcetypebuilder types with their interfaces and then adding public setters.

If you want to have a look now, I forked this repo and the changes are there, I'll also post my complete solution when I get to work tomorrow.

PS, commit details: https://github.com/GeeWizWow/JsonApiFramework/commit/8a3009f8f96db1fc8770548248972942d37b7fa0

Cheers, Finn

GuillermoSaldana commented 4 years ago

In public static class ConfigurationFactory

    public static IConventions CreateConventions(RolesEnum roleName = RolesEnum.Anon)
    {
        RoleName = roleName;

        var conventionsBuilder = new ConventionsBuilder();
        var filter = new FilteredResourceTypeConventionsBuilder(RoleName);

        ...

        // Set our custom ResourceTypeBuilder for property discovery
        conventionsBuilder.SetResourceTypeConventionsBuilder(filter);

        // Discover all public properties as JSON API resource attributes.
        // For example, FirstName property in POCO becomes an attribute of a JSON API resource.
        conventionsBuilder.ResourceTypeConventions()
                          .AddPropertyDiscoveryConvention();

        var conventions = conventionsBuilder.Create();
        return conventions;
    }

FilteredResourceTypeConventiosnBuilder

class FilteredResourceTypeConventionsBuilder : IResourceTypeConventionsBuilder
{
    private IList<IResourceTypeConvention> ResourceTypeConventions { get; set; }
    private RolesEnum RoleName { get; set; }

    public FilteredResourceTypeConventionsBuilder(RolesEnum roleName)
    {
        this.ResourceTypeConventions = new List<IResourceTypeConvention>();
        this.RoleName = roleName;
    }

    public IResourceTypeConventionsBuilder AddPropertyDiscoveryConvention()
    {
        this.ResourceTypeConventions.Add(new FilteredPropertyDiscoveryResourceTypeConvention(RoleName));
        return this;
    }

    public IEnumerable<IResourceTypeConvention> Build()
    {
        return this.ResourceTypeConventions;
    }
}

And finally FilteredPropertyDiscoveryResourceTypeConvention


public IResourceTypeBuilder Apply(IResourceTypeBuilder resourceTypeConfiguration)
    {
        Contract.Requires(resourceTypeConfiguration != null);

        // Use reflection, get all the directly declard, public, and instance-based type of properties for the given resource type.
        var clrResourceType = resourceTypeConfiguration.ClrType;
        var clrProperties = clrResourceType
            .GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
            .ToList();

 ... I can do whatever i need to here ....

}
CarlosOrtu commented 4 years ago

Finn,

Thanks for sharing your solution. I think it solves your specific use case and it didn't take you long so that is good. Since you have a working solution for now I will not address immediately in the current version but target this feature for version 2.0.

Cheers, Scott