Can not find data from the dbcontext with linq - c#

I am trying to develop a "password reset" functionality. To achieve this, I am generating a guid when a user requests a password reset and send this as an email, with a link to the password reset page, that has the guid as a query string.
The code I have written is below:
Request.QueryString[BusinessLayerConstants.resetPasswordQueryString]) ? Request.QueryString[BusinessLayerConstants.resetPasswordQueryString] : String.Empty;
passwordCode = System.Web.HttpUtility.UrlDecode(passwordCode);
using (DBEntities entities = new DBEntities())
{
User = entities.AspNetUsers.FirstOrDefault(u => u.PasswordReset == passwordCode);
if (User != null)
{
//TODO
}
}
The problem is, linq always returns null. If I run a SQL command in the database with the same guid, I am able to see the data. And the passwordCode variable is getting the right value as well. I have even checked if the passwordCode has some hidden characters because it is coming from the query string; but it is also fine.
I am also using this exact same logic for activation as well. I am passing a guid as a query string, and for activation, I am able to find the data with the following code:
AspNetUser user = entities.AspNetUsers.FirstOrDefault(u => u.ActivationCode == activationCode);
It is not working for the password, I have also tried using .Equals() and .Contains() with no luck.
If anyone has any idea what might be wrong, I would appreciate any help. Thanks.
EDIT:
PasswordReset is just some GUID I generate to pass as a querystring.
Everything is fine when I do this:
But in the code, the code I have written returns null:

Remember that C# is case sensitive you should do like:
Request.QueryString[BusinessLayerConstants.resetPasswordQueryString]) ? Request.QueryString[BusinessLayerConstants.resetPasswordQueryString] : String.Empty;
passwordCode = System.Web.HttpUtility.UrlDecode(passwordCode);
using (DBEntities entities = new DBEntities())
{
User = entities.AspNetUsers.FirstOrDefault(u => u.PasswordReset.ToLower() == passwordCode.ToLower());
if (User != null)
{
//TODO
}
}

Related

Entity Framework connection string from .DSN file

I have a problem, so I thought I would come to the brightest minds on the web.
I have written an ASP.NET MVC application that interfaces with a web service provided by another application. My app basically just adds some features to the other web application.
Both applications have a database. I am trying to limit the configuration for my application by using the other applications SQL Server credentials. This is so that if they decide to change the password for the other application, mine will just start working.
These credentials are saved in a .DSN file that my application can reach. How can I get my application, which uses Entity Framework, to use a connection string that is created from the details read in the .DSN file?
I can figure out the code to read the .DSN file, so if you wish to provide some code examples you can base them around setting the connection string for EF.
I am also open to other solutions, or even reasons why I shouldn't do this.
Thanks in advance.
PS. As I was writing this, I came up with a little concept. I am going to test it out now to see how it goes. But here is the basics:
On start up, read the needed details into static properties.
public MyContext() : base(getConnectionString()) { }
3.
private SomeObjectTypeHere getConnectionString()
{
//read static properties
//return .....something..... not sure yet....
}
Thoughts on that maybe?
EDIT
I have created a method that reads the .DSN file and gets the server, the user id and the password. I now have these stored in static properties. In my context, how can I set my connection string now that i have the required details.
So, the biggest issue that I was really having was how to set my connection string in Entity Framework. But I was also hoping that maybe someone else had worked with .DSN files.
Anyway, here was my solution. Still looking for problems that might arise from this, so if you can see any issues, let me know!
First, I created a method that was run on startup. This method ran through the .DSN file and picked out the gems.
Keep in mind that I have never worked with .DSN files, and the section that gets the password is unique to my situation.
var DSNFileContents = File.ReadAllLines(WebConfigurationManager.AppSettings["AppPath"] + #"\App.DSN");//reads DSN into a string array
//get UID
string uid = DSNFileContents.Where(line => line.StartsWith("UID")).First().Substring(4);//get UID from array
//test if uid has quotes around it
if (uid[0] == '"' && uid[uid.Length - 1] == '"')
{
//if to starts with a quote AND ends with a quote, remove the quotes at both ends
uid = uid.Substring(1, uid.Length - 2);
}
//get server
string server = DSNFileContents.Where(line => line.StartsWith("SERVER")).First().Substring(7);//get the server from the array
//test if server has quotes around it
if (server[0] == '"' && server[server.Length - 1] == '"')
{
//if to starts with a quote AND ends with a quote, remove the quotes at both ends
server = server.Substring(1, server.Length - 2);
}
//THIS WON'T WORK 100% FOR ANYONE ELSE. WILL NEED TO BE ADAPTED
//test if PWD is encoded
string password = "";
if (DSNFileContents.Where(line => line.StartsWith("PWD")).First().StartsWith("PWD=/Crypto:"))
{
string secretkey = "<secret>";
string IV = "<alsoSecret>";
byte[] encoded = Convert.FromBase64String(DSNFileContents.Where(line => line.StartsWith("PWD")).First().Substring(12));
//THIS LINE IN PARTICULAR WILL NOT WORK AS DecodeSQLPassword is a private method I wrote to break the other applications encryption
password = DecodeSQLPassword(encoded, secretkey, IV);
}
else
{
//password was not encrypted
password = DSNFileContents.Where(line => line.StartsWith("PWD")).First().Substring(4);
}
//build connection string
SqlConnectionStringBuilder cString = new SqlConnectionStringBuilder();
cString.UserID = uid;
cString.Password = password;
cString.InitialCatalog = "mydatabase";
cString.DataSource = server;
cString.ConnectTimeout = 30;
//statProps is a static class that I have created to hold some variables that are used globally so that I don't have to I/O too much.
statProps.ConnectionString = cString.ConnectionString;
Now that I have the connection string saved, I just have my database Context use it as below,
public class myContext : DbContext
{
public myContext() : base(statProps.ConnectionString) { }
//all my DbSets e.g.
public DbSet<Person> Persons{ get; set; }
}
This is simple, yes, but I hoping that it can provide some information to anyone that was looking to do something similar but was not sure about how it should be handled.
Again, let me know if you like or dislike this solution and if you dislike it, what is your solution and why.
Thanks again!

Inserting a row into Relational database table

I am very new to c# and asp.net mvc. I'm building a HR portal for our company where a user can submit a leave form among other things... So I'm using mssql as the database server and using Entity Frame work to communicate with it. I have 3 entities, user (Containing user details), permissions (the user permissions for allowing actions in the app) and then the leave form table (where the leave form details are stored). There is a one to many relationship between user - permission and then a one to many relationship between user-leave. I am not fazed about the permissions as that gets created when the user account is being created.
The problem I am facing is, how do I add a leave form for a specific user? Below is my controller code:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Leave(MasterViewModel model)
{
DocSubViewModel mv = model.DSModel;
int userId = Convert.ToInt32(Session["userID"]);
try
{
using (HrDcpDBContainer db = new HrDcpDBContainer())
{
var leave = db.leaves.Create();
leave.dateFrom = mv.DateFrom;
leave.dateSubmitted = DateTime.Now;
leave.dateTo = mv.DateTo;
leave.nrDays = mv.NrDays;
leave.reason = mv.SpecialLeave;
leave.TLApproval = null;
leave.TLApprovalDate = null;
leave.TLApprovalID = mv.TeamLeaderID;
leave.DMApprovalDate = null;
leave.DMApprovalID = mv.DepManagerID;
leave.DMApproval = null;
leave.type = mv.Type;
leave.user = userId;
db.leaves.Add(leave);
db.SaveChanges();
}
ViewBag.Message = "Leave Form submitted Successfully. You will be redirected shortly...";
return View("result");
}
catch (Exception ex)
{
ViewBag.Message = ex;
//ViewBag.Message = "Leave Form submitted Successfully. You will be redirected shortly...";
return View("result");
}
The problem comes in leave.user = userId;. It says:
Cannot implicitly convert int to Portal.Model.user
I can't seem to find out how to do this...
You're telling it to put the UserId where your leave model is asking for a User.
Your relationship requires a User to go in there, so you'll have to update your code a little bit:
using (HrDcpDBContainer db = new HrDcpDBContainer())
{
var leave = db.leaves.Create();
leave.user = db.users.First(x => x.Id == userId);
}
This will put reference to the actual user in the new leave record. If you go later and check it out you'll see a column in the leave table called user_Id that has an integer value in it and is set as a foreign key to the users table.
Note that this will error if no user exists having the specified Id value. If you anticipate this to be a problem, rather use .FirstOrDefault() instead of .First() and then account for the value being null before you add it to your new leave object.
That's expected since User is a object and not int. What you should be doing probably is leave.user.UserId = userId; instead [Assuming leave.user is of type User which has a UserId property]

certain user(s) can only use a command

Essentially this program allows a user to use a command !weaponrequest, it then saves their request into a list, with !nextweapon you can see what the next weapon in the list is, this allows a streamer to take weapon requests in a game with a fully automated system.
Anyway moving onto my problem, I need a way to make it so that a certain user(s) can only use a command. I know that I am going to need a list to store the users in. I will write them in manually so I don't need any kind of system for that. All I am wondering is using an IF statement how would I check to see if the user is in this list and then make it so that only that user(s) can activate that command and receive a response.
case "nextweapon":
{
if (new FileInfo("MyFile.txt").Length == 0)
{
irc.sendChatMessage("There are no weapons in the list!");
break;
}
string Lines = File.ReadLines("MyFile.txt").Take(1).First();
//irc.sendChatMessage(Lines);
List<string> WeaponList = File.ReadAllLines("MyFile.txt").ToList();
string FirstItem = WeaponList[0];
WeaponList.RemoveAt(0);
File.WriteAllLines("MyFile.txt", WeaponList.ToArray());
irc.sendChatMessage(Lines);
break;
}
This is the command that I want to only be used by a certain user(s).
Add your special users from a source (in-code, text, database, etc.) into a List<string> variable using the List<string>.Add(strUserName) function.
List<string> lstCertainUsers = new List<string>();
/*
* ToDo: Add users from source (in-code, text, database, etc.) into lstCertainUsers
*/
Then, get the list of users and check if it contains the certain user.
// Check if user has access to special commands
if (lstCertainUsers.Contains(strUserName))
{
/* nextweapon code here */
}
if ((username == "") || (username == "") || (username == ""))
{
}
This is how I solved the issue, it's not the most efficient way but there are only limited users that I needed so making a list was not necessary.
Obviously you need to replace the names with your own names you want to be able to use the command. For example:
(username == "RandomStranger")
{
}
You'd read the file into a buffer, split it line-by-line, loop through those lines and break the loop if and when their username is found. I'm not used to C# but the following pseudocode should highlight my idea:
username = /* the current user's username */;
userfile = readfile('users.txt');
userlist = split(userfile, "\n");
is_valid = false;
for user in userlist
if user equals username
command_is_valid = true;
break;
if command_is_valid:
// your code
else
// do nothing
I'm sure there's a better way to do it because, as I say, I'm not used to C#. On another note, MyFile.txt probably isn't the best name for your flat-file database. Hope this helps!

Get Logged in User Role: Asp.net MVC5

I have a doubt. I am using Asp.net mvc5 in VS2013. When the user is logged in, username of the logged in user can be identified using,
User.Identity.GetUserId
But i couldn't be able to identify the role of the user in the view page.
I tried the following:
#{
var store = new Microsoft.AspNet.Identity.EntityFramework.UserStore<RaspberryPi.Models.ApplicationUser>(new RaspberryPi.Models.ApplicationDbContext());
var manager = new Microsoft.AspNet.Identity.UserManager<RaspberryPi.Models.ApplicationUser>(store);
var l = manager.IsInRole(User.Identity.GetUserId, "Moderator");
}
But resulted in error.
CS1928: 'Microsoft.AspNet.Identity.UserManager<RaspberryPi.Models.ApplicationUser>' does not contain a definition for 'IsInRole' and the best extension method overload 'Microsoft.AspNet.Identity.UserManagerExtensions.IsInRole<TUser>(Microsoft.AspNet.Identity.UserManager<TUser>, string, string)' has some invalid arguments
How can i do that?
Please help,
Thanks
The exception is pretty self explanatory really, the parameters you are providing do not tie up with the IsInRole extension method.
The problem (assuming your code is exactly as you have shown) is thatGetUserId is a function, not a property, therefore you need to actually call it
manager.IsInRole(User.Identity.GetUserId(), "Moderator");
Does your ApplicationUser derive from IdentityUser?
public class ApplicationUser : IdentityUser
This should work in the cshtml
#{
var context = new RaspberryPi.Models.ApplicationDbContext();
if (context.Users.Any(u => u.UserName == User.Identity.Name))
{
var store = new Microsoft.AspNet.Identity.EntityFramework.UserStore<applicationuser>();
var manager = new Microsoft.AspNet.Identity.UserManager<applicationuser>(store);
ApplicationUser user = manager.FindByName<applicationuser>(User.Identity.Name);
if (manager.IsInRole(user.Id, "Moderator") == true)
{
// Do whatever you want...
}
}
Or if you want to do it the simple way just do this.
#if (User.IsInRole("Moderator")){
}

How to store login user id in asp.net?

i am new to asp.net. my question is that how one can save login userid in asp.net webform?
code i am writing in asp.net webform is:
foreach (var s in db.Users)
{
if (tbUserName.Text==s.user_name && tbPassword.Text == s.user_password)
{
if (string.IsNullOrEmpty(Request.QueryString["ReturnUrl"]))
{
FormsAuthentication.SetAuthCookie(tbUserName.Text, false);
Response.Redirect("~/");
}
else
{
FormsAuthentication.RedirectFromLoginPage(tbUserName.Text, false);
}
flag = 1;
break;
}
else
flag=0;
}
if(flag==0)
{
tbUserName.ErrorText = "Invalid user";
tbUserName.IsValid = false;
}
}
As Tim said, you can get the authenticated user with
User.Identity.Name
You can also get the AuthenticationType and IsAuthenticated properties from the same object.
A suggestion would be to NOT query your DB for all of the users and then loop through them for the correct one. Based off of the user input, you should query the db for the one and only user which matches the form post.
Based off of what you wrote, it looks like the passwords are in clear text and not encrypted, which is a huge security issue. Being new to .Net, take a look at the .Net Membership Providers or SimpleMembership or a comparable pattern.
Good luck!
I would suggest you look at using the Session object to store the user ID. A Session will be available throughout that user's session on the site. Thus, you can call Session anywhere in your site's code to reference that user ID.
For example, to store the id, simply do this, pretend we're in Page_Load()
Session["UserId"] = userID // Or wherever you get the ID from.
then in your code behind, you can do this:
string userId = Session["UserId"]
If the user ID is a number, say an int, then you will need to cast the userID:
int userId = 0;
int.TryParse(Session["UserID"], out userID)
Quick dirty link to a Session example :
http://asp.net-tutorials.com/state/sessions/

Categories