Asp.Net Core : Get the value after siding in DbContext? - asp.net-core

I want to seed a default value in the database...These values ​​include a role and a user.
How can I take the role value after seed and add it to the next seed which is adding the user?Is this possible or not?
Seed Role :
modelBuilder.Entity<Role>().HasData(
new Role { RoleId = Guid.NewGuid(), RoleName = "User" },
new Role { RoleId = Guid.NewGuid(), RoleName = "Admin"}
);
Seed User :
modelBuilder.Entity<User>().HasData(
new User { UserId = 1,RoleId = ?}
);
Actually I want to get the Admin role ID and add it to the RoleId field in the User table?

Related

One-to-many relation with additional field

I am creating a schema in prisma with the model User and Guild.
User can have one guild or none
Guild can have multiple User
Now I want to add an additional field of the role a user have in the guild.
What would be the best to achieve this?
I could add them to the user but then I have to manage it in the code that all are null or not null.
enum GuildRole {
MEMBER
CO_LEADER
LEADER
}
model Guild {
id Int #id #default(autoincrement())
name String
users User[]
}
model User {
id Int #id #default(autoincrement())
username String? #unique
guild Guild? #relation(fields: [guildId], references: [id])
guildId Int?
guildRole GuildRole?
}
You can do it as following when adding an existing user to a guild.
import { PrismaClient, GuildRole } from '#prisma/client'
const prisma = new PrismaClient()
// add user to guild
const addAnExistingUserToAGuild = async (userId: number, guildId: number, guildRole: GuildRole) => {
return await prisma.user?.create({
data: {
guildId: guildId,
userId: userId,
guildRole: guildRole,
},
})
}
The modelling will completely depend on your personal/company preference/style, I've modelled your schema like this :
enum GuildRole {
MEMBER
CO_LEADER
LEADER
}
model User {
userId Int #id #default(autoincrement())
username String? #unique
guild Guild? #relation(fields: [guildId], references: [guildId])
guildId Int?
guildRole GuildRole?
}
model Guild {
guildId Int #id #default(autoincrement())
name String
users User[]
}
More examples in our docs here for how you can create a one-to-many relationship :
https://www.prisma.io/docs/concepts/components/prisma-schema/relations/one-to-many-relations

ASP.NET Core Identity Role, Claim and User

I am an ASP.NET Core beginner. I'm stuck in role, claim and user relationship.
I have a user Ben, user belongs to Admin role. Admin role has claims view-page and edit-page in database.
But I can't get claims and roles to be belonging to that user:
(Please see comment in code)
var user = await _userManager.FindByNameAsync(applicationUser.UserName);
if(user != null) {
var userClaims = await _userManager.GetClaimsAsync(user); // empty, WHY ?
var userRoles = await _userManager.GetRolesAsync(user); // ['admin']
var adminRole = DbContext.Roles.FirstOrDefault(x => x.Name == "Admin");
IList<Claim> adminClaims;
if(adminRole != null)
{
adminClaims = await _roleManager.GetClaimsAsync(adminRole);
// correct => ['view-page', 'edit-page']
}
}
}
In my mind, I understand when a user is a member of a role, he inherit that role's claims.
Default ASP.NET Identity have 5 tables:
Users.
Roles.
UserRoles - A user can have many roles.
RoleClaims - A role can have many claims.
UserClaims - A user can have many claims.
Do i think correct ? Why userManager.GetClaimsAsync(user) returns empty claims ?
Any suggestion?
Why userManager.GetClaimsAsync(user) returns empty claims ?
Because UserManager.GetClaimsAsync(user) queries the UserClaims table. Same for
RoleManager.GetClaimsAsync(role) queries the RoleClaims table.
But by design in ASP.NET Identity Core when a user is a member of a role, they automatically inherit the role's claims. You can check the ClaimsPrincipal, for example inside a controller action:
var claims = User.Claims.ToList();
You can see the code in UserClaimsPrincipalFactory.cs that creates a ClaimsPrincipal from an user.
I have had to deal with this issue recently and to solve the problem of locating Users by a particular Claim that came from a Role is to create a new Claim object with the values from the Role Claim:
var role = await roleManager.FindByNameAsync(yourRoleName);
if(role != null)
{
var roleClaims = await roleManager.GetClaimsAsync(role);
if(roleClaims != null && roleClaims.Count() > 0)
{
foreach(var claim in roleClaims.ToList())
{
var users = await userManager.GetUsersForClaimAsync(new Claim(claim.Type, claim.Value));
if(users != null && users.Count() > 0)
{
foreach(var user in users.ToList())
{
//This is an example of only removing a claim, but this is the
//area where you could remove/add the updated claim
await userManager.RemoveClaimAsync(user, new Claim(claim.Type, claim.Value));
}
}
}
}
}
This allowed me to Update/Delete a role with claims and pass those changes to the Users to be Re-Issued/Removed that were assigned the roles and claims. However, I am still looking for something more elegant/easier with less code.

How to use Where sentence to find username equal to ID in data base?

How to do this:
var tmpUser = System.Web.HttpContext.Current.User.Identity;
This returns me what user is logged in, e.g. it returns, when I am login, the name of username, so Identity is e.g. daniel (username)
Now in some other form, I want to return the ID of this username, so I have start with this:
var db = new userDbEntities(); // this is my connection to Database
Then:
var connectedUser = from user in db.UserTable
select user
now here I need WHERE sentence, where I can check if USERNAME is equal to tmpUser, then return the ID of this user in UserTable.
Thanks for any ideas...
Assuming UserName is the column name in UserTable this way will work:
string tmpUser = System.Web.HttpContext.Current.User.Identity.Name;
using(var db = new userDbEntities())
{
var connectedUser = (from user in db.UserTable
where user.UserName == tmpUser
select user).FirstOrDefault();
}
or you can simply do using SingleOrDefault:
string tmpUser = System.Web.HttpContext.Current.User.Identity.Name;
using(var db = new userDbEntities())
{
var connectedUser = db.UserTable.SingleOrDefault(x=>x.UserName == tmpUser);
}

Create User Role in mvc 4

Thanks in advance
I need to set Role in particular users depends on their Role. I had
try to goggled many websites but I did not get clear idea about this
Roles. I need to implement this Role concept in my mvc project.
Controller:-
[AllowAnonymous]
public ActionResult EditableUserDetails( )
{
if (!Roles.RoleExists("test"))
Roles.CreateRole("test");
var UserName = Session["UserName"].ToString();
Roles.AddUserToRole(UserName, "test");
var linq = (from db in EntityObj.Users
where db.IsActive == true
select new EditableUserDetails
{
UserId = db.UserId,
UserName = db.UserName,
Password = db.Password,
Category = db.Category
}).ToList();
var data = linq.ToList();
return View(data);
}
If I run this code I got this following error:-

Fluent NHibernate only cascade delete of association record

We're using NHibernate for our membership system. A User can be a member of many Roles and a Role can have many users.
When a Role or a User is deleted, it should only cascade the delete of the association record ("RoleUsers" table).
Deleting a Role works as expected. However, deleting a User does not delete the association record and as such fails due to a foreign key constraint.
My mapping on the Role side:
HasManyToMany(r => r.Users)
.Access.CamelCaseField()
.Table("RoleUsers")
.ParentKeyColumn("RoleId")
.ChildKeyColumn("UserId")
.AsSet();
Mapping on the User side:
HasManyToMany(u => u.Roles)
.Access.CamelCaseField()
.Table("RoleUsers")
.ParentKeyColumn("UserId")
.ChildKeyColumn("RoleId")
.Inverse(); // we'll add user to role, not role to user
And the failing test:
[Test]
public void Deleting_user_should_not_delete_roles()
{
var user = new User("john#doe.com", "John", "Doe", "Secr3t");
var role = new Role("Admin");
role.AddUser(user);
object id;
using (var txn = Session.BeginTransaction())
{
id = Session.Save(user);
Session.Save(role);
txn.Commit();
}
Session.Clear();
var fromDb = Session.Get<User>(id);
using (var txn = Session.BeginTransaction())
{
Session.Delete(fromDb);
txn.Commit();
}
Session.Query<Role>().Count().ShouldEqual(1);
}
I've tried every combination of Cascade on the user mapping and it either fails or deletes the association record AND the role (not what I want).
Inverse and cascading are two different concepts. And of course, both are supported on <many-to-many> relation. See the documentation 6.8 (scroll down almost to 6.9)
http://nhibernate.info/doc/nh/en/index.html#collections-bidirectional
1) Firstly, we can remove the inverse setting of the User.Roles collection. This will straightens the behavior of the Users`s relations to Roles, and force their deletion before User itself is deleted.
2) Secondly. If the Roles collection of the User is marked as inverse,
HasManyToMany(u => u.Roles)
...
.Inverse(); // we'll add user to role, not role to user
deletion of any User, will never trigger deletion of the pair. That's because we are explicitly saying: the one and only one who care about the relation is the Role.
So if we would like to continue in your scenario:
.Inverse(); // we'll add user to role, not role to user
we should be consitent. "we'll remove user from roles, not roles from user":
[Test]
public void Deleting_user_should_not_delete_roles()
{
var user = new User("john#doe.com", "John", "Doe", "Secr3t");
var role = new Role("Admin");
role.AddUser(user);
object roleId;
object id;
using (var txn = Session.BeginTransaction())
{
id = Session.Save(user);
roleId = Session.Save(role);
txn.Commit();
}
Session.Clear();
// take both from DB
var userFromDb = Session.Get<User>(id);
var roleFromDb = Session.Get<Role>(roleId);
using (var txn = Session.BeginTransaction())
{
// HERE just remove the user from collection
roleFromDb.Users.Remove(userFromDb);
// all relations will be deleted
Session.Save(roleFromDb);
txn.Commit();
}
...
// assertions
// "John's" relation to Role "admin" is deleted
}
NOTE:
3) Cascade was not used in there, but could help to reduce Session.Save(user)...
EDIT: Extending the point 3)
Deletion of the user as Ben Foster noticed in a comment.
3) We should even allow the Role to manage its Users collection completely. Let's introduce the casdace="all" (casdace="all-delete-orhpan" if User without any Role should be deleted at all). Now we can add/update users only via Role object.
the mapping of the Role's Users collection should look like:
HasManyToMany(r => r.Users)
.Access.CamelCaseField()
.Table("RoleUsers")
.ParentKeyColumn("RoleId")
.ChildKeyColumn("UserId")
//.Cascade.All(); // just save or update instance of users
.Cascade.AllDeleteOrphan(); // will even delete User without any Role
.AsSet();
Having inverse and cascade we can adjust the test:
[Test]
public void Deleting_user_should_not_delete_roles()
{
var user = new User("john#doe.com", "John", "Doe", "Secr3t");
var role = new Role("Admin");
role.AddUser(user);
object roleId;
using (var txn = Session.BeginTransaction())
{
// I. no need to save user
roleId = Session.Save(role);
...
And later call this to get rid of a User
...
using (var txn = Session.BeginTransaction())
{
var user = Session.Get<User>(id);
var roles = user.Roles.ToList();
roles.ForEach(role => role.RemoveUser(user))
// II. not only relations, but even the User is deleted
// becuase updated roles triggered delete orhpan
// (no Session.Update() call there)
txn.Commit();
}