0

The details of my situation: If a user has permissions to view a certain location's items, I need the query to select items that have a facility that matches the permissions the user has. A user might have permissions to multiple facilities. There may be a user that has access to LOC1, LOC2 and also LOC3. There may be a user with only access to LOC1. I might be overlooking something extremely simple to solve this.

if(System.Web.HttpContext.Current.User.IsInRole("App_Inventory_LOC1_Access")) 
{
    items = items.Where(s => s.Facility == "LOC1");
}

if(System.Web.HttpContext.Current.User.IsInRole("App_Inventory_LOC2_Access")) 
{
    items = items.Where(s => s.Facility == "LOC2");
}

if(System.Web.HttpContext.Current.User.IsInRole("App_Inventory_LOC3_Access")) 
{
    items = items.Where(s => s.Facility == "LOC3");
}
1
  • The way I have it right now, it works if the user has access to one of those locations, but if they have multiple it is not showing any items because it's impossible for an item to have more than one facility. Commented Dec 5, 2018 at 16:55

3 Answers 3

4

So you just construct a list of allowed facilities, and then check if s.Facility is in those:

var facilities = new List<string>();
if(System.Web.HttpContext.Current.User.IsInRole("App_Inventory_LOC1_Access")) 
{
    facilities.Add("LOC1");
}
// same for other facilities
// ...

items = items.Where(s => facilities.Contains(s.Facility));

To further simplify it, you could group roles and facilities in some kind of map, and iterate through that - will make it much easier to add new facilities for example.

Sign up to request clarification or add additional context in comments.

Comments

1

You can refactor that with a dictionary to map user role to facility:

var userFacilityMapping = new Dictionary<string, string>
{
    ["App_Inventory_LOC1_Access"] = "LOC1",
    ["App_Inventory_LOC2_Access"] = "LOC2",
    ["App_Inventory_LOC3_Access"] = "LOC3",
};
var userFacilities = userFacilityMapping
    .Where(x => HttpContext.Current.User.IsInRole(x.Key))
    .Select(x => x.Value)
    .ToArray();

items = items.Where(x => userFacilities.Contains(x.Facility));

Comments

1

I think you're overwriting your result set. Say if you have access to LOC1 and LOC3, it will first choose all the LOC1 items, and then from the LOC1 items it will choose the LOC3 items which is empty.

You want to only filter the original item set. Something like

var results = new List<Item>();

if(System.Web.HttpContext.Current.User.IsInRole("App_Inventory_LOC1_Access")) 
{
    results.AddRange(items.Where(s => s.Facility == "LOC1"));
}

if(System.Web.HttpContext.Current.User.IsInRole("App_Inventory_LOC2_Access")) 
{
    results.AddRange(items.Where(s => s.Facility == "LOC2"));
}

if(System.Web.HttpContext.Current.User.IsInRole("App_Inventory_LOC3_Access")) 
{
    results.AddRange(items.Where(s => s.Facility == "LOC3"));
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.