asp.net MVC5: How to get all users and user's role from AspnetUser table by linq - entity-framework

I am trying to get all Users and User's Roles by Linq.
The entities is from ASP.NET MVC identity Framework.
My code:
var userList = db.Users
.Include("Roles")
.ToList();
My entities:
The result i have for the Roles table is "RoleId, UserId" only
. I want to get the Roles which added for each users.
How i can do it?
Thank you.
UPDATE ANSWERS:
var userList = new List<ManagerUserViewModel>();
foreach (var user in db.Users.ToList())
{
var userRolesId = user.Roles.Select(m => m.RoleId).ToList();
var model = new ManagerUserViewModel()
{
UserId = user.Id,
UserName = user.UserName,
Email = user.Email,
UserInfo = user.UserInfo,
Roles = db.Roles.Where(r => userRolesId.Contains(r.Id))
.ToList()
};
userList.Add(model);
}

I hope you think this is sufficient:
// Dummy role name
var name = "Admin";
var rm = new RoleManager<Role>(new RoleStore<Role>(new ApplicationDbContext()));
// Get the role you need (Admin role in this case)
var r = rm.FindByName(name);
// All the user ids that have this role
var userIds = r.Users.Select(u => u.UserId);
// Get all user objects
var users = Db.Users.Where(u => userIds.Contains(u.Id)).ToList();

Related

Multiple Roles causing issues in Blazor

I add roles via the following code in the server project
foreach (var userRole in userInfo.Roles)
{
claims.Add(new Claim(ClaimTypes.Role, userRole));
}
var token = new JwtSecurityToken(
_config["JWTSettings:validIssuer"],
_config["JWTSettings:validAudience"],
claims,
null,
expires: DateTime.Now.AddMinutes(20),
signingCredentials: credentials);
Now, If I only have one role then this works fine and the following code in the OnInitializedAsync method in a razor component
var t = await AuthState;
var role1= t.User.IsInRole("admin");
leads to role1 being true.
However if I have multiple roles then role1 is then false (as it is for all the roles I add to the user) despite clearly being there!
Now, if I do the following in OnInitializedAsync
var t= await AuthState;
var claimsList= t.User.Claims;
foreach(var item in claimsList)
{
var s1 = item.Type;
var s2 = item.Value;
string asasas = string.Empty;
}
I get a single claim that has a type of role and it has the following as its value
["admin","myrole2"]
on the server side I get a number of claims of type role, each with a single role as the value.
What on earth is going on?
You need to transform your claims:
public class CustomUserFactory : AccountClaimsPrincipalFactory<RemoteUserAccount>
{
public CustomUserFactory(IAccessTokenProviderAccessor accessor)
: base(accessor)
{
}
public override async ValueTask<ClaimsPrincipal> CreateUserAsync(
RemoteUserAccount account,
RemoteAuthenticationUserOptions options)
{
var user = await base.CreateUserAsync(account, options);
ClaimsIdentity claimsIdentity = (ClaimsIdentity)user.Identity;
if (account is not null) {
MapArrayClaimsToMultipleSeparateClaims(account, claimsIdentity);
}
return user;
}
private void MapArrayClaimsToMultipleSeparateClaims(RemoteUserAccount account, ClaimsIdentity claimsIdentity)
{
foreach (var keyValuePair in account.AdditionalProperties) {
var key = keyValuePair.Key;
var value = keyValuePair.Value;
if (value is not null &&
value is JsonElement element && element.ValueKind == JsonValueKind.Array) {
claimsIdentity.RemoveClaim(claimsIdentity.FindFirst(keyValuePair.Key));
var claims = element.EnumerateArray()
.Select(x => new Claim(keyValuePair.Key, x.ToString()));
claimsIdentity.AddClaims(claims);
}
}
}
}
Program.cs in your client.
services.AddApiAuthorization().AddAccountClaimsPrincipalFactory<CustomUserFactory>();

Box.com API Usage - Get Folder Count as a service app

We are creating an app that is meant to be used with a Service Account in your system; another user (user-2) has authorized this app by adding our app key to their Custom Application list. How do I get this User-2's UserID, so we can impersonate him and access his files list and files, etc. We need their UserID, so we can pass the "AS-User: " Header. And can this header be set using some property from within the .NET SDK - a sample code will be appreciated.
This does it for all enterprise users but you can easily put an if statement to get the user you're looking for.
static async Task MainAsync()
{
// rename the private_key.pem.example to private_key.pem and put your JWT private key in the file
var privateKey = File.ReadAllText(PRIVATE_KEY_FILE);
var boxConfig = new BoxConfig(CLIENT_ID, CLIENT_SECRET, ENTERPRISE_ID, privateKey, JWT_PRIVATE_KEY_PASSWORD, JWT_PUBLIC_KEY_ID);
var boxJWT = new BoxJWTAuth(boxConfig);
var adminToken = boxJWT.AdminToken();
Console.WriteLine("Admin Token: " + adminToken);
Console.WriteLine();
var adminClient = boxJWT.AdminClient(adminToken); // adminClient == serviceAccount
var userDetails = await adminClient.UsersManager.GetCurrentUserInformationAsync();
Console.WriteLine("\tAdmin User Details:");
Console.WriteLine("\tId: {0}", userDetails.Id);
Console.WriteLine("\tName: {0}", userDetails.Name);
Console.WriteLine("\tStatus: {0}", userDetails.Status);
Console.WriteLine();
var users = await adminClient.UsersManager.GetEnterpriseUsersAsync();
users.Entries.ForEach(i =>
{
Console.WriteLine("\t{0}", i.Name);
Console.WriteLine("\t{0}", i.Status);
if (i.Status == "active")
{
var userToken = boxJWT.UserToken(i.Id);
var userClient = boxJWT.UserClient(userToken, i.Id);
Task u = getUserItems(userClient, i.Id);
u.Wait();
}
});
}
static async Task getUserItems(BoxClient userClient, string id)
{
var userDetails = await userClient.UsersManager.GetCurrentUserInformationAsync();
Console.WriteLine("\nManaged User Details:");
Console.WriteLine("\tId: {0}", userDetails.Id);
Console.WriteLine("\tName: {0}", userDetails.Name);
Console.WriteLine("\tStatus: {0}", userDetails.Status);
Console.WriteLine();
Console.WriteLine("managed users older items");
var items = await userClient.FoldersManager.GetFolderItemsAsync("0", 500);
items.Entries.ForEach(i =>
{
Console.WriteLine("\t{0}", i.Name);
});
Console.WriteLine();
}

how to update a record in database using LINQ?

I want to do the following in LINQ:
update [dbo].[AdminLogin] set [ADMIN_PASSWORD] = 'abc' where [ADMIN_ID] = 1
where i get the admin password from a model and the admin id is stored in a variable:
var userid = (from m in db.RequestPasswordReset
where m.Id == Unid
select m.UserId).FirstOrDefault();
How to do it?
To update an entity you must have to specify the Modified state.
using (var db= new DbContext())
{
var entity= db.AdminLogin.Where(x => x.ADMIN_ID == userid ).SingleOrDefault();
entity.ADMIN_PASSWORD = 'abc';
db.Entry(entity).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
}
see details here
use this code:
using (var context = new YourContext())
{
var res = context.AdminLogin.Where(x => x.ADMIN_ID == userid ).SingleOrDefault();
res.ADMIN_PASSWORD = 'abc';
context.SaveChanges();
}
You can try this:
var user = db.AdminLogin.FirstOrDefault(x => x.ADMIN_ID == id);
user.ADMIN_PASSWORD = 'abc';
db.SaveChanges();
userid.ADMIN_PASSWORD= 'abc';
db.SaveChanges(); //better then db.SubmitChanges() in some case
If you using linQ.dbml file then you have to write like this:
using (var db= new DbContext())
{
var entity= db.AdminLogin.Where(x => x.ADMIN_ID == userid ).FirstOrDefault();
entity.ADMIN_PASSWORD = 'abc';
db.SubmitChanges();
}

How can i get and use AspnetUsers UserId in migration configuration file?

This is the code of configuration file(seed method) of entity framework migration.
Through this code, i create a user and role for AspnetUsers table and i put the user in role named Admin.
AppUserManager userMgr = new AppUserManager(new UserStore<AppUser>(context));
AppRoleManager roleMgr = new AppRoleManager(new RoleStore<AppRole>(context));
string roleName = "Admin";
string userName = "admin#educationboard.com";
string password = "Sifre";
string email = "admin#educationboard.com";
if (!roleMgr.RoleExists(roleName))
{
roleMgr.Create(new AppRole(roleName));
}
AppUser user = userMgr.FindByName(userName);
if (user == null)
{
userMgr.Create(new AppUser { UserName = userName, Email = email },
password);
user = userMgr.FindByName(userName);
}
if (!userMgr.IsInRole(user.Id, roleName))
{
userMgr.AddToRole(user.Id, roleName);
}
foreach (AppUser dbUser in userMgr.Users)
{
dbUser.Cinsiyet = eCinsiyetler.Erkek;
}
context.SaveChanges();
Then i also create an entity named Articles, each article has an author id. I named AuthorId as UserId in Article entity. How can i get and use UserId I've just created above in following code?
var articles= new List<Article>
{
new Article{Title="Title 1", AddedDate=DateTime.Now, Content="content here.", UserId=.(What code should be here? };
articles.ForEach(p => context.Articles.AddOrUpdate(s => s.Title, p));
context.SaveChanges();
Why can't you query for the user like you did above?
AppUser user = userMgr.FindByName(userName);
if (user == null)
{
userMgr.Create(new AppUser { UserName = userName, Email = email },
password);
user = userMgr.FindByName(userName);
}
and then have user.Id?
If you have a handle in ApplicationDbContext you could easily do something like
ApplicationDbContext db = new ApplicationDbContext();
var user = db.AspNetUser.Single(x => x.UserName == username);
var id = user.Id;

Not able to access list of record in EF

Here is the problem I am trying to access some records from the data base based on one field . The field I am using is audit_id having type GUID .
but the line does not returning any data
var audits = ctx.Audits.Where(x => lstAudits.Contains(x.audit_id)).ToList();
Here is a my full code to update mass records in the database using EF
//will select auditId from the List
var lstAudits = _ViewModel.WorkingListAudits.Where(x => x.WorkingList).Select(x=>x.AuditId).ToList();
using (var ctx = new AuditEntities())
{
var audits = ctx.Audits.Where(x => lstAudits.Contains(x.audit_id)).ToList();
audits.ForEach(x => x.working_list = false);
ctx.SaveChanges();
}
In case of single record it return data from database
var lstAudits = _ViewModel.WorkingListAudits.Where(x => x.WorkingList).Select(x => x.AuditId).ToList();
Guid tempAuditId = lstAudits[0];
// lstAudits.ForEach(x => x.ToString().ToUpper());
using (var ctx = new AuditEntities())
{
var audits = (from au in ctx.Audits
where au.audit_id == tempAuditId
select au).ToList();
//foreach(Audit audit in audits){
//}
audits[0].working_list = false;
ctx.SaveChanges();
}
Finally I got the answer here is the updated code which is working fine .I just took some intermediate result in a temporary variable and it started working as expected
//will select auditId from the List
var lstAudits = _ViewModel.WorkingListAudits.Where(x => x.WorkingList).Select(x => x.AuditId).ToList();
using (var ctx = new AuditEntities())
{
var tempAudits = ctx.Audits.ToList();
var audits = tempAudits.Where(x => lstAudits.Contains(x.audit_id)).ToList();
audits.ForEach(x => x.working_list = false);
ctx.SaveChanges();
}