Can I Query multiple properties using session.Query? - c#

I want to query one more property of the "User" entity.
Basically I need to know, is it possible to extend the below statement to include something like this..
user = session.Query<User>().SingleOrDefault(u => u.Username.ToLower() == identity.ToLower()) && (u => u.Email == email);
I know thats not correct but you get the idea, I want to check the user email as well as the username.
This is the current code..
public static bool IsDuplicateIdentity(string identity, string email, Type type)
{
using(ISession session = NHibernateHelper.SessionFactory().OpenSession())
using (ITransaction tx = session.BeginTransaction())
{
User user = null;
// the entity type is checked and then DB is queried to see if an object with that name and email exists
if (type.BaseType == typeof(User))
{
user = session.Query<User>().SingleOrDefault(u => u.Username.ToLower() == identity.ToLower());
}
tx.Commit();
if (user != null)
{
return true;
}
else
{
return false;
}
}
}
Please note this is an ASP.net MVC 3 application.

Can't you just do this?:
user = session.Query<User>()
.SingleOrDefault(u =>
u.Username.ToLower() == identity.ToLower()
&& u.Email == email);

Sure:
user = session.Query<User>()
.SingleOrDefault(u => u.Username.ToLower() == identity.ToLower()
&& u.Email == email);

Yes, you can combine them and you almost got it right. Try it like this:
user = session.Query<User>().SingleOrDefault(u => u.Username.ToLower() == identity.ToLower() && u.Email == email);

You can write the below code
user = session.Query<User>()
.where(u => u.Username.ToLower() == identity.ToLower() && u.Email == email).SingleOrDefault();

Related

Set LockOutEndDate to null ASP.NET MVC

I'm trying to unlock a user account from the admin panel:
public async Task<ActionResult> EnableAccount(string id)
{
var user = UserManager.Users.FirstOrDefault(x => x.Id == id);
if(user != null)
{
await UserManager.ResetAccessFailedCountAsync(user.Id);
await UserManager.SetLockoutEndDateAsync(user.Id, null );
}
return RedirectToAction("Users");
}
I'm getting this error:
cannot convert from '<null>' to 'DateTimeOffset' in
await UserManager.SetLockoutEndDateAsync(user.Id, null);
Ended up doing it this way:
var user = UserManager.Users.FirstOrDefault(x => x.Id == id);
user.LockoutEndDateUtc = null;
user.LockoutEnabled = false;

Alter SaveChanges when Seeding database

I have a setup where I use a service to log a user in and autofill the CreatedBy, UpdatedBy, ... fields for my entities. Because of this my SaveChanges method looks like this:
public override int SaveChanges()
{
var modifiedEntries = ChangeTracker.Entries()
.Where(x => x.Entity is IAuditableEntity
&& (x.State == EntityState.Added || x.State == EntityState.Modified));
var activeUserId = ActiveUserService.UserId;
var username = Users.First(x => x.Id == activeUserId).UserName;
foreach (var entry in modifiedEntries)
{
IAuditableEntity entity = entry.Entity as IAuditableEntity;
if (String.IsNullOrEmpty(username))
{
throw new AuthenticationException(
"Trying to save entities of type IAuditable while not logged in. Use the IActiveUserService to set a logged in user");
}
if (entity != null)
{
DateTime now = DateTime.Now;
if (entry.State == EntityState.Added)
{
entity.CreatedBy = username;
entity.CreatedAt = now;
}
else
{
base.Entry(entity).Property(x => x.CreatedBy).IsModified = false;
base.Entry(entity).Property(x => x.CreatedAt).IsModified = false;
}
entity.UpdatedBy = username;
entity.UpdatedAt = now;
}
}
return base.SaveChanges();
}
The problem is when I'm seeding my database, Autofac isn't running and isn't injecting my services. Is it possible somewhere set a flag of some sort that when I'm seeding my database I use a default username or something?
In your code, if there is no user logged in (so no activeUserId) it will break with an exception on First():
var username = Users.First(x => x.Id == activeUserId).UserName;
And so the line:
if (String.IsNullOrEmpty(username))
will never be true.
I would take a nullable variable into the method: SaveChanges(int? activeUserId = null), and when called by your Seed-method it will be null, and you can handle that to set the username into SYSTEM. But for all your other code you can supply the id of the user, and handle that.
Edit: to summary: the method itself should not check if the user is logged in, do that someplace else.
My current work-around is creating an other SaveChanges-method when seeding the database which sets a default user.
internal int SaveChangesWithDefaultUser()
{
var modifiedEntries = ChangeTracker.Entries()
.Where(x => x.Entity is IAuditableEntity
&& (x.State == EntityState.Added || x.State == EntityState.Modified));
var username = "SYSTEM";
foreach (var entry in modifiedEntries)
{
IAuditableEntity entity = entry.Entity as IAuditableEntity;
if (entity != null)
{
DateTime now = DateTime.Now;
if (entry.State == EntityState.Added)
{
entity.CreatedBy = username;
entity.CreatedAt = now;
}
else
{
base.Entry(entity).Property(x => x.CreatedBy).IsModified = false;
base.Entry(entity).Property(x => x.CreatedAt).IsModified = false;
}
entity.UpdatedBy = username;
entity.UpdatedAt = now;
}
}
return base.SaveChanges();
}

Using Lists that give permissions

I'm trying to write this code for my project but it doesn't seem to work.
As you can see from the code, the last else statement won't work. I have a class Admin and it has 3 properties, Username, Password, and Permitted. I created a List with default values and granted some usernames permission while granting some no permission. From the else statement, I'm trying to match if the Permitted value is true then that user has permission, and vice versa, however even if the user has no permission is still grants him access. Any idea why?
List<Admin> result = FrmMain.AdminL.FindAll(adm => adm.UserName == txtUsername.Text);
if (result.Count == 0)
{
MessageBox.Show("Username is incorrect");
}
// Note to miss : I couldnt find a way to link the password with a specific user
List<Admin> result2 = FrmMain.AdminL.FindAll(adm => adm.PassWord == txtPassword.Text);
if (result2.Count == 0)
{
MessageBox.Show("Password is incorrect");
}
else
{
List<Admin> permission = FrmMain.AdminL.FindAll(adm => adm.Permitted == true);
if (result.Count > 0)
{
MessageBox.Show("User has been authenticated");
FrmAdminCP f1 = new FrmAdminCP();
f1.ShowDialog();
}
else
{
MessageBox.Show("Im sorry, you do not have permission to access the control panel");
}
You need to combine your predicates into a single search using &&.
List<Admin> result = FrmMain.AdminL.FindAll(adm =>
adm.UserName == txtUsername.Text &&
adm.PassWord == txtPassword.Text &&
adm.Permitted == true);
if (result2.Count == 1)
{
// authenticated with access
}
or two steps
List<Admin> result = FrmMain.AdminL.FindAll(adm =>
adm.UserName == txtUsername.Text &&
adm.PassWord == txtPassword.Text);
if (result.Count == 1)
{
// authenticated
}
else
{
// not authenticated
}
List<Admin> result = FrmMain.AdminL.FindAll(adm =>
adm.UserName == txtUsername.Text &&
adm.Permitted == true);
if (result.Count == 1)
{
// username is permitted to access
}
Update:
I'm assuming FrmMain.AdminL is a List<Admin>.
Admin singleResult = FrmMain.AdminL.Find(adm =>
adm.UserName == txtUsername.Text);
if(singleResult == null)
{
MsgBox("No User found");
return; // exit the subroutine you're in
}
if(singleResult.PassWord != txtPassword.Text)
{
MsgBox("Wrong Password");
return; // exit the subroutine you're in
}
if(singleResult.Permitted == false)
{
MsgBox("Not authorized")
return;
}

How do I get the id in the login?

How do I get the Id in the login?
I'm using entity framework and in the frmLogin I have this:
private bool IsValidUser(string userName, string pass)
{
Context context = new Context();
var query = (from c in context.Cuentas
where c.Nombre == userName && c.Password == pass
select c);
return query.Any();
}
but with this function, I can only verify if the user is in the Database.
I want to get the id of this user too.
instead of the if(query.Any()) .... try:
var user = query.FirstOrDefault();
if (user == null)
return false;
var id = user.ID;
I think is possible to have only one user with th same username :) => one username = one user
you can try this
var user = context.Cuentas.singleordefault(d=>d.userName==userName & d.password==password);
int id;
if (user!=null)
{
id=user.userId;
return true;
}
return false;
EDITED

Check Nulls in Lambda

We have the following code to check if the given username and password exists in database:
public User GetUserByUserNameAndPassword(string userName, string userPassword)
{
using (var context = DataObjectFactory.CreateContext())
{
return Mapper.Map(context.UserEntities.Single(u => u.UserName == userName && u.UserPassword == userPassword));
}
}
If we have the username and password in database this works fine but throws an error if username or password is wrong and no records found.
This might be simple but as I am new to lambda could not get get it right.
How can I change the lambda query so we can handle nulls?
Thanks
Use SingleOrDefault, which will return only one record or null if none exists.
return Mapper.Map(context.UserEntities.SingleOrDefault(u => u.UserName == userName && u.UserPassword == userPassword));
Later you can check:
User returnedObject = GetUserByUserNameAndPassword(username,password)
if(returnedObject == null)
{
//User doesn't exist
}
Remember Single/SingleOrDefault will throw an exception if multiple records exist against the criteria.
You should change from Single to SingleOrDefault, it returns null when no data match
context.UserEntities.SingleOrDefault(u => u.UserName == userName &&
u.UserPassword == userPassword)
.Any() will return true if a matching record is found or false if no record is found.
So a slight modifcation to you existing code will work.
public User GetUserByUserNameAndPassword(string userName, string userPassword)
{
using (var context = DataObjectFactory.CreateContext())
{
if (context.UserEntities.Any(u => u.UserName == userName && u.UserPassword == userPassword))
{
return Mapper.Map(context.UserEntities.Single(u => u.UserName == userName && u.UserPassword == userPassword));
}
else
{
//Deal with no user here through chosen method
}
}
}
Make use of FirstOrDefault or SingleOrDefualt and check for null like as below
var user =context.UserEntities.SingleOrDefault(u => u.UserName == userName
&&
u.UserPassword == userPassword);
if(user!=null)
{
//do code
}
Use SingleOrDefault and check for Null prior to calling Map
public User GetUserByUserNameAndPassword(string userName, string userPassword)
{
using (var context = DataObjectFactory.CreateContext())
{
var user = context.UserEntities.SingleOrDefault(u => u.UserName == userName && u.UserPassword == userPassword);
return user !=null ? Mapper.Map(user) : null;
}
}

Categories