I have a Microsoft Blazor Application which has many entities and therefore each entity has each one razor component, interface, controller and service.
Now I need to implement security roles based on user's team, for example, a user belonging into "Greece" team should see only data created by users belonging into "Greece" team with type Member, of course there will be cases where a user with type Admin could see everything. But let's leave the User Type outside for a moment.
Here is my team class:
public class Team
{
[Key]
public int team_id { get; set; }
public string team_name { get; set; } = null!;
}
Here is my user class:
public class User
{
[Key]
public int user_id { get; set; }
public string user_name { get; set; } = null!;
public string user_pass { get; set; } = null!;
public string user_mail { get; set; } = null!;
public string user_type { get; set; } = null!;
public int user_team { get; set; }
}
I am trying to find the best/correct/elegant solution, so for example could be that in each List getFunction(), I can pass the user id and make global function which will filter the sql results based on other ids belonging to the same team, but I have to call that function to all get methods and I have also to pass the user_id to all functions like add or edit.
Currently I have an Interface which all of my entities are inheriting:
public interface IUser
{
public int reference_user_id { get; set; }
}
Here is an example of an entity I need to filter:
public class DataSetting : IUser
{
[Key]
public int datasetting_id { get; set; }
public string datasetting_name { get; set; } = null!;
public int reference_user_id { get; set; }
}
So I need a function that takes as input a list which will have reference_user_id as an attribute and matches the user, something like this:
public IList<object> TeamFilter(IList<object> inputlist, int user_id)
{
teams = _dbContext.Teams.ToList();
users = _dbContext.Users.ToList();
}
Is there any idea how I can archive that?
Found out that this can be implemented like the following:
public List<T> TeamFilter<T>(List<T> inputlist, int user_id) where T : IUser
{
User? requesting_user = users.Where(x => x.user_id == user_id).FirstOrDefault();
if (requesting_user != null)
{
Team? requesting_team = teams.Where(x => x.team_id == requesting_user.user_team).FirstOrDefault();
if (requesting_team != null)
{
int requesting_team_id = requesting_team.team_id;
List<T> outputList = inputlist
.Join(users,
input => input.reference_user_id,
user => user.user_id,
(input, user) => (input, user)
)
.Where(x => x.user.user_team == requesting_team_id)
.Select(x => x.input)
.ToList();
return outputList;
}
else
{ throw new ArgumentNullException(); }
}
else
{ throw new ArgumentNullException(); }
}