Disclaimer: I am author of Entity REST SDK.
I took different approach and created Security Context which contains all necessary lambda expressions that should be applied before querying anything.
public class DefaultSecurityContext : BaseSecurityContext {
public static DefaultSecurityContext Instance = new DefaultSecurityContext();
// UserID for currently logged in User
public static long UserID{
get{
return long.Parse( HttpContext.Current.User.Identity.Name );
}
}
public DefaultSecurityContext(){
}
protected override void OnCreate(){
// User can access his own Account only
var acc = CreateRules<Account>();
acc.SetRead( y => x=> x.AccountID == UserID ) ;
acc.SetWrite( y => x=> x.AccountID == UserID );
// User can only modify AccountName and EmailAddress fields
acc.SetProperties( SecurityRules.ReadWrite,
x => x.AccountName,
x => x.EmailAddress);
// User can read AccountType field
acc.SetProperties<Account>( SecurityRules.Read,
x => x.AccountType);
// User can access his own Orders only
var order = CreateRules<Order>();
order.SetRead( y => x => x.CustomerID == UserID );
// User can modify Order only if OrderStatus is not complete
order.SetWrite( y => x => x.CustomerID == UserID && x.OrderStatus != "Complete" );
// User can only modify OrderNotes and OrderStatus
order.SetProperties( SecurityRules.ReadWrite,
x => x.OrderNotes,
x => x.OrderStatus );
// User can not delete orders
order.SetDelete(order.NotSupportedRule);
}
}
As you can see, we can filter down access to properties as well.
In the case most of your duplicate code gets replaced with Security Context, you can create different Security Context as per different User role & still keep same controller.
public class OrdersController : WebAtomsController <MyEntities> {
protected override BaseSecurityContext CreateSecurityContext(){
return DefaultSecurityContext.Instance;
}
public ActionResult SearchOrders(
string productName,
string orderBy = "OrderID DESC",
int start = 0,
int size = 10)
{
// Where method automatically applies
// filter based on current SecurityContext
var aq = Where<Order>();
if(!string.IsNullOrEmpty(productName)){
aq = aq.Where(
x=> x.OrderItems.Any(
y=> y.Product.ProductName.StartsWith(productName)));
}
// OrderBy accepts string as a parameter
aq = aq.OrderBy(orderBy);
return aq.Page(start,size).Select(
y=> new {
y.OrderID,
y.OrderDate,
y.OrderStatus,
});
}
}
for more details, please visit
https://entityrestsdk.codeplex.com