List all users in specific role - c#

In ASP.NET Core 2.2 MVC I'm trying to get a list of all users in a specific role.
Fx. list of all users in role named "Admin":
var idsWithPermission = _userManager.GetUsersInRoleAsync("Admin").Result;
var users = _db.ApplicationUser.Where(u => idsWithPermission.Contains(u.Id)).ToListAsync();
return(users);
Compiler fails "u.Id" here: idsWithPermission.Contains(u.Id)
Error: Argument 1: Cannot convert from "string" to Microsoft.AspNetCore.Identity.IdentityUser
This is a newbie questions, so might be very simple for a shark :-)
Thanks a lot in advance...

GetUsersInRoleAsync returns a list of IdentityUser objects. To get a list of IDs, you need to access the Id property of these objects.
// Get a list of users in the role
var usersWithPermission = _userManager.GetUsersInRoleAsync("Admin").Result;
// Then get a list of the ids of these users
var idsWithPermission = usersWithPermission.Select(u => u.Id);
// Now get the users in our database with the same ids
var users = _db.ApplicationUser.Where(u => idsWithPermission.Contains(u.Id)).ToListAsync();
return users;
Note that using .Result on an async method is not advised, because it can lead to deadlocks. Instead use await and make your method async.
Also note that depending on your setup, if ApplicationUser inherits from IdentityUser and the identity system is correctly configured, GetUsersInRoleAsync will already return ApplicationUser objects and you only need to cast them to the correct type:
// Get a list of users in the role
var usersWithPermission = _userManager.GetUsersInRoleAsync("Admin").Result;
var users = usersWithPermission.OfType<ApplicationUser>();
return users;

Related

error Message: Unsupported or invalid query filter clause specified for property 'userType' of resource 'User'. Microsoft Graph SDK Filter()

I am Microsoft Graph API/SDK to retrieve users from Azure Active Directory. My Filter() function giving me error Message: Unsupported or invalid query filter clause specified for property 'userType' of resource 'User'.
My code is:
var azureUsers = await graphClient
.Users
.Request().Filter("startsWith(userType, 'P')")
.Select(x => new
{
x.Id,
x.UserType,
x.DisplayName,
x.GivenName,
x.Surname,
x.UserPrincipalName,
x.AccountEnabled,
x.Identities,
x.BusinessPhones,
x.JobTitle,
x.MobilePhone,
x.OfficeLocation,
x.PreferredLanguage,
x.Mail,
x.Extensions,
x.CreatedDateTime
})
.GetAsync();
It works absolutely fine with
.Filter("startsWith(mail, 'P')")
But not with the user type.
I have this attribute UserType in my Azure AD
Our guest users are around 700 and I want to exclude them in call.
It's giving me correct values with
x.UserType,
But I want to filter this in Call. Any help would be much appreciated.
You are seeing this error, because this filter is not supported for UserType attribute - as the error message explains.
As a general rule of thumb, userType should be either Member or Guest. The exception to this is when you're syncing an on-prem Active Directory. Since userType is an Azure AD property, the value for a synced user will be null.
If you can safely assume that your on-prem users are not guests, you can filter Azure AD user's based on if they're synced or cloud-native. You do this by looking at the onPremisesSyncEnabled property. For synced users, this will be true, for cloud-native users it will be null.
If you combine this with the userType property, you can effectively retrieve only non-guest users using the following $filter:
$filter=onPremisesSyncEnabled eq true OR userType eq 'Member'
You can check out Marc's answer on the same - How to filter users by userType = null?
You can use the below code to get the users list without guest user and according to document usertype should member or guest.please refer to the document
public static async Task ListUsers(GraphServiceClient graphClient)
{
Console.WriteLine("Getting list of users...");
// Get all users (one page)
var result = await graphClient.Users
.Request()
.Select(e => new
{
e.DisplayName,
e.Id,
e.Identities
}).Filter($"usertype eq 'Member'")
.GetAsync();
foreach (var user in result.CurrentPage)
{
var directoryObject = await graphClient.DirectoryObjects[user.Id].Request()
.GetAsync();
Console.WriteLine(JsonConvert.SerializeObject(directoryObject));
}
}

How to return IQueryable?

There is container
_userTable = new UserTable<TUser>(_database);
I need a function returns collection from this container. How to return this type of collection here?
public IQueryable<TUser> Users
{
get { return _userTable; }// <----------?
}
There is
public class UserTable<TUser>
where TUser : IdentityUser
I need the users list to display it in razor page
public void GetUsers()
{
ColUsers = new List<PUser>();
var user = _UserManager.Users.Select(x => new PUser
{
Id = x.Id,
UserName = x.UserName,
Email = x.Email,
PasswordHash = "*****"
});
foreach (var item in user)
{
ColUsers.Add(item);
}
}
Fundamentally, you've got limited options here;
get hold of a full query provider - something like EF - and use that:
public IQueryable<TUSer> Users => _myDbContext.Users;
load all the users into something like a List<T>, and use AsQueryable() - this will spoof the query API using LINQ-to-Objects, and will force it to load all the users into memory, but is simple:
public IQueryable<TUser> Users => LoadThemAll().AsQueryable();
roll your own query provider that knows how to convert expression trees into executable queries for your RDBMS; this is a huge amount of work, where just the overview and explanations (not the work itself) would fill a modest sized book
Order of usual preference is order listed. Alternatively, limit yourself to IUserStore<T> (not IQueryableUserStore<T>), and get the list of users in some other manner.

ASP.net Identity - get collection of users in "admin" or "adminlower" roles

I can get a collection of all users and order them with some Linq like this:
var Users = UserManager.Users.ToList().OrderBy(x => x.DateCreated)
I'd like to restrict users returned to those with the role "admin" or "adminlower". I've searched a lot and found things like this but they don't help:
http://aryalnishan.com.np/asp-net-mvc/list-all-users-with-associated-roles-in-asp-net-identity/
I've tried this, also doesn't work:
var AdminRoles = new string[] { "admin", "adminlower" };
var Roles = RoleManager.Roles;
Roles.Contains(AdminRoles);
I just can't seem to get the syntax, how can I do this?
I haven't tested this but you're probably looking for something similar:
You could get the roleId this way.
var roleManager= new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
//Get admin role
var adminRole= roleManager.FindByName("Admin");
var admins=context.Users.Where(x=>x.Roles.Any(role=>role.RoleId==adminRole.Id)).ToList().OrderBy(d=>d.DateCreated);
Another option may be to load all users, then loop through using UserManager.IsInRoleAsync to filter the Admins. But you don't want to do that unless you have reasonably small user base.
To get the list of user by a single role there is a build-in method in UserManager. You can try the following:
var adminUsers = (await userManager.GetUsersInRoleAsync("rolename")).ToList();
That should solve your problem.

How to get rolename from Roles object in asp.net core

I am doing this to get roles of a user:
var roles = await _userManager.GetRolesAsync(user);
After that a simple loop through can serve the purpose like this:
foreach(var r in roles)
{
if (r.Name == "School")
{
}
}
Now, I am stuck in knowing what should be the property of object r. Can you answer this very basic stuff?
UserManager<TUser>.GetRolesAsync(TUser) returns a Task<IList<String>>. In your example, you're using await, which means your roles variable becomes of type IList<String>. When iterating through roles with your foreach statement, each r value within the loop is simply of type String. It's obvious that String does not contain a property named Name and as such, the error makes sense.
It appears you were expecting r to represent a complex type (perhaps an IdentityRole), but as it's simply a string here, you can just compare r directly, like this:
foreach(var r in roles)
{
if (r == "School")
{
}
}
When you get object of Role using Identity, you have List of object with many property like: User,Id, Name, NormalizeName, and something like this. You can trace and see those.
You have to know that what do you want.
If you want to check userRoles with system Roles you can write you code like:
var roles = await _roleManager.Roles.TolistAsync();
var userRolesName = await _userManagment.GetRolesAsync(user);
Now! you have list of roles that user have, and you have all roles.and with this code you get object of roles that user have like:
var userRoles = userRolesName.Where(x=>userRolesName.Contain(x.Name));
With this code you have object of Roles that user have.and you can process them.

How to determine if a user belongs to a certain group using ASP.Net Identity Framework 2.0

Using the new ASP.Net Identity Framework 2.0, I am trying to determine the list of users that belong to a certain group.
The UserManager and RoleManager are properly instantiated and I get the right infos while debugging but I don't understand how to use user.Roles.Contains.
var _listAllUsers = UserManager.Users.ToListAsync().Result;
//var _allUsers = UserManager.Users;
var roleToMatch = RoleManager.FindByNameAsync("MyUserManager").Result;
foreach (var user in _listAllUsers){
var _listGroupAdminCat = user.Roles.Contains((IdentityUserRole)roleToMatch);
}
There's something I am missing in the syntax.
First get your IdentityRole object:
var role = RoleManager.FindByName("MyUserManager");
Then get the users in that role:
var usersInRole = role.Users;
Your question title is asking a slightly different question though, how to determine is a user is in a role. For this, use the UserManager like this:
int userId = 5;
string roleToCheck = "MyRole";
bool userIsInRole = userManager.IsInRole(5, roleToCheck );
It's also worth noting that in the code you posted you are using the asynchronous functions incorrectly. Either use them with the await keyword or use the synchronous versions:
var roleSynchronously = RoleManager.FindByName("MyUserManager");
var roleAsynchronously = await RoleManager.FindByNameAsync("MyUserManager");

Categories

Resources