mvc entity framework many to many user and role insert - asp.net-mvc

I have an mvc project with database first entityframework. In Project I have 3 tables.
Users >>> UsersInRoles <<< Roles with many to many relationship.
and my CreateUser codes below;
public bool CreateUser(string email, string password, string birthday,string firstname,string lastname)
{
bool result;
var dogumgunu = Convert.ToDateTime(birthday);
var sifre = FormsAuthentication.HashPasswordForStoringInConfigFile(password, "sha1");
var confirmation = CreateConfirmationToken(email);
try
{
var user = new User
{
UserName = email,
Password = sifre,
UserJoinDate = DateTime.Now,
UserBirthDay = dogumgunu,
UserConfirmationToken = confirmation,
UserID = Guid.NewGuid(),
MemberFirstName = firstname,
MemberLastName = lastname
};
var role = new Role
{
RoleName = "Client"
};
user.Roles.Add(role); //problem is here!!!!!!!!!
_bb.Users.AddObject(user);
_bb.SaveChanges();
result = true;
}
catch (Exception)
{
result = false;
}
return result;
}
In this code I am new user creating. And I am adding a role. But This code include a new Role in Roles table. I dont want to this. I want to just add UsersInRoles table a new user. What is wrong? Thanks for reply.

Swap these two lines:
_bb.Users.AddObject(user);
user.Roles.Add(role);
because AddObject converts the whole object graph to the Added state. If you add the role afterwards, its state will remain Unchanged.
And you should fetch the role from the database first or create a Role object that only has an existing RoleId. (A so called stub entity).
So in stead of new Role you could do
var role = _bb.Roles.Single(r => r.RoleName == "Client");

Related

Will Identity fail if I assign roles and every time I use User.Identity.GetUserId()?

I want to create web portal, where there will be multiple users of 3-4 types. So I have created roles in Startup.cs Like
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
createRolesandUsers();
}
// In this method we will create default User & roles
private void createRolesandUsers()
{
ApplicationDbContext context = new ApplicationDbContext();
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
if (!roleManager.RoleExists("Admin"))
{
var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
role.Name = "Admin";
roleManager.Create(role);
var user = new ApplicationUser();
user.UserName = "1";
user.Email = "a#b.com";
user.ScreenName = "Ra";
user.UserType = "Admin";
string userPWD = "1";
var chkUser = UserManager.Create(user, userPWD);
if (chkUser.Succeeded)
{
var result1 = UserManager.AddToRole(user.Id, "Investor");
}
}
It creates Usertypes and on login page I give radio button to select own type.
Now, suppose there are 4 roles.
Admin
Player
Coach
And suppose 10 people signup to site
2 people as admin
4 people as player
4 people as coach.
Now each one has it's type and user id. And if they log in, they can't access controllers of each other due to Autorize attribute. But my question is, what about 4 players? Will they be ever able to access each others account?
They have same authorize rights and they are authenticate too. How can I prevent users from same type to access each other's account ?
I use " User.Identity.GetUserId() " on each page to get current user and I log all transactions by current id.

Select MVC Membership usernames to list

I am trying to select all usernames in MVC membership provider into a queryable list to plug into a function that checks if a given username exists and modifies it by adding a number at the end if it is so. I am struggling to get the list. I am not sure if what I am trying to achieve is achievable.
So far this is what I have come up with as below
var allusers = (from MembershipUser u in Membership.GetAllUsers()
select new
{
Uname = u.UserName
}).ToList();
But It does not work and gives the error
cannot convert from 'System.Collections.Generic.List<AnonymousType#1>' to 'System.Collections.Generic.List<string>'
I have realised that the error goes away only when the below code is in place.
private string GetUniqueSlug(string Uname, object allusers)
{
throw new NotImplementedException();
}
But this is the function that is supposed to be evaluated
//unique username for autogenerate
private string GetUniqueSlug(string Uname, List<string> allusers)
{
var slug = Uname.ToSeoUrl();
return allusers.Any(s => s == slug)? GetUniqueSlugInternal(slug, allusers) : slug;
}
When the condition is triggered to generate a new uname, the not implemented step gets the focus
It worked with this instead
List<string> allusers = (from MembershipUser c in Membership.GetAllUsers()
select new { UserName = c.ToString() }).Select(t=>t.UserName).ToList();

How to add role and Users in asp.net mvc 5?

I want to add User authorization and authentication in asp.net mvc project. I am Entity Framework Code First. Now I want to create some default user and default role for it. For this I want to create a Admin Role, but it is preventing me that User and Role Named admin and Admin Exists already. But when I see in my Database Table such as AspNetUSers , Role etc. there I did not find any named Admin. So how can I do this?
If the admin role and users are built in, so where is the password. And also how can I create some other default users and roles each time when my application is running first.
I am using MVC 5 ,not mvc 4. There are difference for both of these two.
Thanks,
Abdus Salam Azad
Since no one ever answered your question, I though I would add some code that shows how to do this from the Seed method on a migration. This code is used to seed an initial user in the database with an admin role. In my case, only the 'admin' user can add new users to the site.
protected override void Seed(PerSoft.Marketing.Website.Models.ApplicationDbContext context)
{
const string defaultRole = "admin";
const string defaultUser = "someUser";
// This check for the role before attempting to add it.
if (!context.Roles.Any(r => r.Name == defaultRole))
{
context.Roles.Add(new IdentityRole(defaultRole));
context.SaveChanges();
}
// This check for the user before adding them.
if (!context.Users.Any(u => u.UserName == defaultUser))
{
var store = new UserStore<ApplicationUser>(context);
var manager = new UserManager<ApplicationUser>(store);
var user = new ApplicationUser { UserName = defaultUser };
manager.Create(user, "somePassword");
manager.AddToRole(user.Id, defaultRole);
}
else
{
// Just for good measure, this adds the user to the role if they already
// existed and just weren't in the role.
var user = context.Users.Single(u => u.UserName.Equals(defaultUser, StringComparison.CurrentCultureIgnoreCase));
var store = new UserStore<ApplicationUser>(context);
var manager = new UserManager<ApplicationUser>(store);
manager.AddToRole(user.Id, defaultRole);
}
}

Duplicate users added to database

I try to add a new value to my database. UserPassword and RePassword must have the same value and a user with UserName must not already exist in the database.
public User NewUser(int HotelID, string UserName, string UserPassword, string RePassword, string FullName, string Email, bool Active, bool MasterUser)
{
User user = new User();
user.HotelID = HotelID;
user.UserName = UserName;
user.UserPassword = UserPassword;
user.FullName = FullName;
user.Email = Email;
user.IsActiveq = Active;
user.IsMaster = MasterUser;
var cekUser = (from c in _UserRepository.All()
where c.HotelID == HotelID
select c.UserName).ToList();
if (UserPassword == RePassword)
{
foreach (string cek in cekUser)
{
var x = cek;
if (UserName != x)
{
_UserRepository.Add(user);
}
}
}
_UserRepository.CommitChanges();
return user;
}
Every time I run my code a new line is added to the database, although a user with the supplied user name already exists in the database.
Why does this happen? Which part of my code is wrong?
I think your code should be something like this:
if (UserPassword == RePassword)
{
// Also I thinks you should finish whether user existed logic in database
// but for now, let's follow your original logic
var existedUsers = (from c in _UserRepository.All()
where c.HotelID == HotelID
select c.UserName).ToList();
if (!existedUsers.Any(u => u == UserName))
{
_UserRepository.Add(user);
_UserRepository.CommitChanges();
}
}
You have your logic wrong. If there is more than one user in a given hotel, your code will be adding more users for all users with names different from UserName.
bool found = false;
foreach(string cek in cekUser)
{
if ( UserName == cek)
{
found = true;
break;
}
}
if (!found)
_UserRepository.Add(user);
Just offering an alternate idea.
If you have access to the database, the best approach will be to make the Username field UNIQUE. That way, even if you get your code wrong, a duplicate insert will fail. Then you capture that fail gracefully in your Repository, and Bob's your uncle.

MVC4: Getting Active Directory User Guid

Once a user is logged into a Windows-Authentication site, how do I get their Active Directoy user guid from the User.
Eg in an Action:
ViewBag.Message = User.Identity.GUID????
You should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find the current user
UserPrincipal user = UserPrincipal.Current;
if(user != null)
{
// get guid
var userGuid = user.Guid;
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!
string userName = user.Identity.Name.Split('\\')[1];
using (var oRoot = new DirectoryEntry(ConfigurationManager.AppSettings["LDAPDomain"], null, null, AuthenticationTypes.Secure))
{
using (var deSearch = new DirectorySearcher(oRoot))
{
deSearch.Filter = string.Format("(&(sAMAccountName={0}))", userName);
SearchResult searchResult = deSearch.FindOne();
if (searchResult != null)
{
DirectoryEntry de = searchResult.GetDirectoryEntry();
}
}
}

Resources