I have all my validation and authorization logic for my project in attributes on the request models. I like this as it makes it easy to see everything in one place. The only thing I can’t figure out how to do by attribute is limiting AutoQuery response records to records the user has access to.
For instance I might want to limit query results like this:
public QueryResponse<CompanyActionResponse> Get(QueryCompanyActions request)
{
var session = SessionAs<CustomUserSession>()!;
var isAdmin = session.Roles.Contains(Roles.Admin);
var query = AutoQuery.CreateQuery(request, base.Request);
if (!isAdmin)
{
var ids = Db.Select<ApplicationUserCompany>(x => x.ApplicationUserId == session.UserAuthId).Select(x => x.CompanyId);
query = query.Where(c => ids.Contains(c.CompanyId));
}
var response = AutoQuery.Execute(request, query);
return response;
}
Is it possible to do this as a custom attribute on the request model? From the docs it doesn’t seem possible and I would need to do something with registering either global filter or query filter when registering the AutoQuery plugin but I wanted to ask in case there was something I was missing.
It would be nice to have all validation and authorization logic viewable on the model attributes.
I’d recommend having separate APIs for different Access Levels, e.g. for Admin an Non Admin APIs so they can be implemented and protected independently in isolation so you’re able to correctly document and protect Admin APIs with [ValidateIsAdmin].
You’re going to be limited with what custom logic possible within Declarative attributes, but they are pretty flexible, have a look at Type Validators with how to create your own.
Yeah, I have already done that for all the validation by either using existing or building custom validation attributes. I can’t see how to filter the AutoQuery results from an attribute though so right now all the authorization and validation is in request models attributes apart from on queries which all require custom autoquery service implementation.
I wasn’t sure if there might be some way to apply a sharp script to a QueryDb request with a custom attribute that then gets access to the ISqlExpression before it returns.
You can’t modify the SqlExpression from an attribute since it’s only created within your Service implementation when you create it with AutoQuery.CreateQuery().
I have a many-to-many relation with users & accounts so users have a list of account IDs they can access then on all entities there is an account id, so the request can be contained to a specific group i.e. users but the results that are returned vary based on what they have access to. This behaviour may or may not be desired depending on the context so would be nice to represent it with an attribute.
Before I meant instead of having the custom implementation, it would be the auto generated service from SS exposing the expression to code defined inside the attribute.
Looking at it I think I can set a global filter by overriding the base class which will work and I can check if attribute exists there myself. I was just wondering if it was already possible injecting some Script Sharp magic to filter the autogenerated query service.