Search code examples
authenticationsecurityfilterblazoruser-roles

Microsoft Blazor User Authorization based on user team


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?


Solution

  • 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(); }
    }