Creating a user profile page using a database - c#

I am doing a simple project for school where I have to create a login form and make it so when a person logs in it then shows their profile with all their user information. So how would I code the textboxes in windows forms C# so when a person logs in the textboxes show information gathered from database of person who just logged in.
This is the code for the login form.
OleDbConnection connection = new OleDbConnection(); connection.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\RAV21001310\\OneDrive\\Database1.accdb;";
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
command.CommandText = "select * from tblUser where Username= '"+username.Text+"' and Password= '"+password.Text+"'";
OleDbDataReader reader = command.ExecuteReader();
int count = 0;
while (reader.Read())
{
count = count + 1;
}
if (count == 1)
{
MessageBox.Show("Username and password is correct");
var profile = new profile();
}
if (count > 1)
{
MessageBox.Show("Duplicate username and password");
}
else
{
MessageBox.Show("Username or password incorrect");
}
connection.Close();

As I said in the comments, always use parameters in your query strings. Also, since OleDbDataReader is forward reading only, what I would do is create a new user and add to a list for each record returned. Then, if you only get one record, use that user data to populate the form. One other major flaw in your code... You are storing passwords as plain text in the database. The best practice is to encrypt/hash the password using one-way encryption and only store the hash in the database. Everytime the user enters a password at login, hash it using the same algorithm and compare it against the hash stored in the DB.
Here's an example incorporating Using (suggested by #Flydog57) and Parameters. But I'm not showing how to hash and store encrypted passwords.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
public class Program
{
public static void Main()
{
using (OleDbConnection connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\RAV21001310\\OneDrive\\Database1.accdb;"))
{
connection.Open();
using (OleDbCommand command = new OleDbCommand("SELECT * FROM tblUser WHERE Username=#Username AND Password=#Password", connection))
{
command.Parameters.AddWithValue("#Username", username.text);
command.Parameters.AddWithValue("#Password", password.text);
using (OleDbDataReader reader = command.ExecuteReader())
{
int count = 0;
List<User> UserList = new List<User>();
while (reader.Read())
{
count = count + 1;
User user = new User() {
Username = reader.GetString(1),
FirstName = reader.GetString(2),
LastName = reader.GetString(3),
DateCreated = reader.GetDateTime(4)
};
UserList.Add(user);
}
if (count == 1)
{
//Alert User
MessageBox.Show("Username and password is correct");
//Create an instance of the ProfileForm and populated it with the User data.
var ProfileForm pf = new ProfileForm(UserList[0]);
//Show the Profile Form as a modal window.
pf.ShowDialog();
}
if (count > 1)
{
MessageBox.Show("Duplicate username and password");
}
else
{
MessageBox.Show("Username or password incorrect");
}
}
}
connection.Close();
}
}
}
//This is a class to hold user data.
public class User {
public string Username { get; set; } = "";
public string Password { get; set; } = "";
public string FirstName { get; set; } = "";
public string LastName { get; set; } = "";
public DateTime DateCreated { get; set; } = DateTime.MinValue;
}
This is a quick sample of the code-behind for a "ProfileForm". When you verify the user is authenticated, then create an instance of the ProfileForm, populate it with the userdata, then show the form to the user. There are many other ways to populate a profile form and handle updates to user data, this is just one example.
public class ProfileForm : Form
{
public User User
{
get
{
//When you get the User, update all the user data from text boxes.
User.FirstName = firstnameTextBox.Text;
User.LastName = lastnameTextBox.Text;
//return the newly updated User variable.
return User;
}
set
{
//When we write new data to the form User variable,
//populate each relevant text box on the form.
usernameTextBox.Text = User.Username;
firstnameTextBox.Text = User.FirstName;
lastnameTextBox.Text = User.LastName;
}
}
public ProfileForm(User User) {
this.User = User;
}
}

Related

How to assign database values into global variables in a class

I am creating a windows forms in C# with following code:
private void button1_Click(object sender, EventArgs e)
{
using (OleDbConnection connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\RAV21001310\\OneDrive\\Database1.accdb;"))
{
connection.Open();
using (OleDbCommand command = new OleDbCommand("SELECT * FROM tblUser WHERE Username=#Username AND Password=#Password", connection))
{
command.Parameters.AddWithValue("#Username", username.Text);
command.Parameters.AddWithValue("#Password", password.Text);
using (OleDbDataReader reader = command.ExecuteReader())
{
int count = 0;
while (reader.Read())
{
count = count + 1;
}
if (count == 1)
{
MessageBox.Show("Username and password is correct");
}
if (count > 1)
{
MessageBox.Show("Duplicate username and password");
}
if (count == 0)
{
MessageBox.Show("Username or password incorrect");
}
}
}
connection.Close();
}
}
}
public class User
{
public string Username;
public string Password;
public string FirstName;
public string LastName;
public string Gender;
public int Age;
public int TotalPoints;
}
The first part is for a login form. The part I am struggling with is how to make it so when a user logs in it gets all his relevant information like username, password, TotalPoints etc from the database in ms access and assigns it to the variables in the class so they can be called throughout different forms.
// Add parameters for the username and password
command.Parameters.Add("#Username").Value = username.text;
command.Parameters.Add("#Password").Value = password.text;
// Execute the query
SqlDataReader reader = command.ExecuteReader();
// Validate the user's credentials
bool isValid = false;
if (reader.Read())
{
User user = new User
{
Id = Convert.ToInt32(reader["Id"]),
// Add all fileds you want to use...
}
isValid = true;
}
// Close the reader and the connection
reader.Close();
connection.Close();
// Do someting with result
...

C# winforms save UserID value to class

I'm trying to save UserID value to a class after an successful login. When the login button is clicked, it validates the login into in text boxes using the #user, #pass.
My problem is that I do not know how to write a sql reader and save the resulting int to a class. I also do not know how to write that class.
I need to save it to a class so I can use it on different forms to check what account the user is logged into.
EDIT: Updated code from suggestions but i get errors Error picture any ideas where i did a mistake?
private LoginUser validate_login(string user, string pass)
{
db_connection();
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = "Select * from table2 where username=#user and password=#pass";
cmd.Parameters.AddWithValue("#user", user);
cmd.Parameters.AddWithValue("#pass", pass);
cmd.Connection = connect;
LoginUser usr = new LoginUser();
MySqlDataReader login = cmd.ExecuteReader();
while(login.Read())
{
connect.Close();
usr.UserID = login["UserID"];
usr.valid = true;
}
return usr;
}
private void button1_Click(object sender, EventArgs e)
{
{
string user = usertype.Text;
string pass = password.Text;
if (user == "" || pass == "")
{
MessageBox.Show("Empty Fields Detected ! Please fill up all the fields");
return;
}
bool r = validate_login(user, pass);
if (r)
{
LoginUser usr = new LoginUser();
usr = validate_login(user, pass);
if (usr.valid)
{
Console.WriteLine(String.Format("{0}", usr.UserID));
UserDetails.m_gnUserId = Convert.ToInt32(reader["UserID"]);
}
}
}
}
public partial class Form1 : Form
{
private LoginUser validate_login(string user, string pass)
{
...
LoginUser usr = new LoginUser();
MySqlDataReader login = cmd.ExecuteReader();
while(login.Read())
{
connect.Close();
usr.UserID = login["UserID"];
usr.valid = true;
}
return usr;
}
private void button1_Click(object sender, EventArgs e)
{
...
LoginUser usr = new LoginUser();
usr = validate_login(user, pass);
if (usr.valid)
{
Console.WriteLine(String.Format("{0}", usr.UserID));
}
}
}
public class LoginUser
{
public Bool valid = false;
public String UserID = "";
// You can have more column name up to matching with your table column.
}
One of the method is as follow
Create a class UserDetails with all the data you want to store
public static class UserDetails
{
public static int m_gnUserId {get;set;}
//Add other variables which you want to store and use across different forms
}
To Store Value
UserDetails.m_gnUserId = Convert.ToInt32(reader["UserID"]); .
This storing of Value will go after Console.WriteLine(String.Format("{0}", reader["UserID"])); in your button1_click event.
To get the value on other form
int UserId = UserDetails.m_gnUserId;

Authenticating username and password using Session

I looked around here on stackoverflow, as well Google, but was not able to find an answer that pertained to my problem, so i'm posting it here.
I have a login page where the user is directed to input their username and password, which are both stored in a MySQL database. The username is stored as plain text and the password is hashed (using the CrackStation - https://crackstation.net/hashing-security.htm#aspsourcecode) and the hash is stored in the database. I am able to successfully have the user login one time using the username and password, but I would like to use SESSION so that the user can navigate around the website and not have to login each time they go to a different page. I was easily able to use SESSION in my test environment because the password was stored as plain text, but now with the password being hashed i'm not able to get the Session to work in my code. So I wanted to know what can I do to get the password to validate in SESSION.
My code that I am using on my login page is the following:
protected void Page_Load(object sender, EventArgs e)
{
try
{
admin = Convert.ToInt16(Request.QueryString["Admin"]);
Instructor = Convert.ToInt16(Request.QueryString["Inst"]);
if (Session["username"] == null || (string)(Session["username"]) == "")
{
token = Request.QueryString["tokenNumber"];
lblUsername.Visible = true;
txtUsername.Visible = true;
lblPassword.Visible = true;
txtPassword.Visible = true;
btnlogin.Visible = true;
}
else if (Session["username"] != null || (string)(Session["username"]) != "")
{
username = (string)Session["username"];
userType = (string)Session["userType"];
pass = (string)Session["password"];
if (userType == "Participant")
{
Response.Redirect("/srls/StudentUser");
}
else if (userType == "Coordinator")
{
Response.Redirect("/srls/CoordinatorUser");
}
else if (userType == "Instructor")
{
Response.Redirect("/srls/InstructorUser");
}
}
}
catch (Exception exc) //Module failed to load
{
Exceptions.ProcessModuleLoadException(this, exc);
}
}
protected void btnlogin_Click(object sender, System.EventArgs e)
{
char activation;
if (Request.QueryString["tokenNum"] != null)
{
using (OdbcConnection dbConnection = new OdbcConnection(srlsConnStr))
{
dbConnection.Open();
{
OdbcCommand dbCommand = new OdbcCommand();
dbCommand.Connection = dbConnection;
dbCommand.CommandText = #"SELECT tokenNum FROM srlslogin WHERE user_email_pk = ?";
dbCommand.Parameters.AddWithValue("#user_email_pk", txtUsername.Text);
dbCommand.ExecuteNonQuery();
OdbcDataReader dataReader = dbCommand.ExecuteReader();
while (dataReader.Read())
{
if (token == dataReader["tokenNum"].ToString())
{
updateActivationStatus(txtUsername.Text);
LoginWithPasswordHashFunction();
}
else
{
test.Text = "You are not authorized to login! Please activate your account following the activation link sent to your email " + txtUsername.Text + " !";
}
}
}
dbConnection.Close();
}
}
else if (Request.QueryString["tokenNum"] == null)
{
using (OdbcConnection dbConnection = new OdbcConnection(srlsConnStr))
{
dbConnection.Open();
{
OdbcCommand dbCommand1 = new OdbcCommand();
dbCommand1.Connection = dbConnection;
dbCommand1.CommandText = #"SELECT * FROM srlslogin WHERE user_email_pk = ?;";
dbCommand1.Parameters.AddWithValue("#user_email_pk", txtUsername.Text);
dbCommand1.ExecuteNonQuery();
OdbcDataReader dataReader1 = dbCommand1.ExecuteReader();
if (dataReader1.Read())
{
activation = Convert.ToChar(dataReader1["activation_status"]);
if (activation == 'Y')
{
activation status, activation == Y";
LoginWithPasswordHashFunction();
}
else
{
lblMessage.Text = "Please activate your account following the Activation link emailed to you at <i>" + txtUsername.Text + "</i> to Continue!";
}
}
else
{
lblMessage.Text = "Invalid Username or Password";
}
dataReader1.Close();
}
dbConnection.Close();
}
}
}
private void LoginWithPasswordHashFunction()
{
List<string> salthashList = null;
List<string> usernameList = null;
try
{
using (OdbcConnection dbConnection = new OdbcConnection(srlsConnStr))
{
dbConnection.Open();
{
OdbcCommand dbCommand = new OdbcCommand();
dbCommand.Connection = dbConnection;
dbCommand.CommandText = #"SELECT slowhashsalt, user_email_pk FROM srlslogin WHERE user_email_pk = ?;";
dbCommand.Parameters.AddWithValue(#"user_email_pk", txtUsername.Text);
OdbcDataReader dataReader = dbCommand.ExecuteReader();
while (dataReader.HasRows && dataReader.Read())
{
if (salthashList == null)
{
salthashList = new List<string>();
usernameList = new List<string>();
}
string saltHashes = dataReader.GetString(dataReader.GetOrdinal("slowhashsalt"));
salthashList.Add(saltHashes);
string userInfo = dataReader.GetString(dataReader.GetOrdinal("user_email_pk"));
usernameList.Add(userInfo);
}
dataReader.Close();
if (salthashList != null)
{
for (int i = 0; i < salthashList.Count; i++)
{
bool validUser = PasswordHash.ValidatePassword(txtPassword.Text, salthashList[i]);
if (validUser == true)
{
Session["user_email_pk"] = usernameList[i];
OdbcCommand dbCommand1 = new OdbcCommand();
dbCommand1.Connection = dbConnection;
dbCommand1.CommandText = #"SELECT user_status FROM srlslogin WHERE user_email_pk = ?;";
dbCommand1.Parameters.AddWithValue("#user_email_pk", txtUsername.Text);
dbCommand1.ExecuteNonQuery();
OdbcDataReader dataReader1 = dbCommand1.ExecuteReader();
while (dataReader1.Read())
{
user_status = dataReader1["user_status"].ToString();
Session["userType"] = user_status;
}
Response.BufferOutput = true;
if (user_status == "Participant")
{
Response.Redirect("/srls/StudentUser", false);
}
else if (user_status == "Coordinator")
{
Response.Redirect("/srls/CoordinatorUser", false);
}
else if (user_status == "Instructor")
{
Response.Redirect("/srls/InstructorUser", false);
}
dataReader1.Close();
Response.Redirect(/srls/StudentUser) - Goes to Login Page";
}
else
{
lblMessage.Text = "Invalid Username or Password! Please Try Again!";
}
}
}
}
dbConnection.Close();
}
}
catch (Exception ex)
{
}
You should not store the username and password in the session. You should store the 'fact' that the user has been successfully logged in. But actually you shouldn't even be doing that yourself. ASP.NET comes with various authentication methods. Please have a look at http://www.asp.net/identity to get started.
That is not so good solution. Don't store username's login, password, type, so on, in your sessions. Once user is logging in your system, just store his ID. I use next way: I have login page, and I have MasterPage and all my web-forms are inherited from MasterPage. And in the MasterPage on Page_Init I do something like:
string users_role = MyClass.GetUsersRoleById(Session["id"].ToString());
I have user's role in the database, so by ID I may exclude user's role. And, for example, you have by one folder for every role. You may do something like:
if (String.IsNullOrEmpty(users_role)) //if null it means that user have no any role or you didn't checked for authorization first
Response.Redirect(users_role); //redirect to role's page: e.g. Admin, User, Student, Teacher, so on.

Listing database values via a List in C#

I am trying to show database values assigned to a List in C# but am running into an issue when trying to show them. Instead of what I want it to show, it shows this: System.Collections.Generic.List`1[System.String]
Here is my code:
public List<string>[] selectQuery(string query)
{
// create a list to hold the firt name, last name, and password
List<string>[] list = new List<string>[4];
list[0] = new List<string>(); // will hold the first name
list[1] = new List<string>(); // will hold the last name
list[2] = new List<string>(); // will hold the username
list[3] = new List<string>(); // will hold the password
if (this.openDbConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, this.connection);
MySqlDataReader dr = cmd.ExecuteReader();
// read the data and store it in the list
while (dr.Read())
{
list[0].Add(dr["first_name"] + "");
list[1].Add(dr["last_name"] + "");
list[2].Add(dr["username"] + "");
list[3].Add(dr["password"] + "");
}
// close reading the data operator
dr.Close();
// close connection
this.connection.Close();
// return the list of results to be displayed
return list;
}
else
{
return list;
}
}
List<string>[] data = db.selectQuery("SELECT first_name, last_name, username, password FROM member WHERE username = '" + name + "'" + " AND password = PASSWORD('" + pass + "')");
if (data != null)
{
// assign the username, password, first and last name to the session variables
Session["first_name"] = data[0].ToString();
Session["last_name"] = data[1].ToString();
Session["username"] = data[2].ToString();
Session["password"] = data[3].ToString();
// redirect to member page
Response.Redirect("members.aspx", false);
}
and the html is:
<tr>
<td id="user"><%=Session["username"].ToString()%></td>
<td id="greeting"><%=Session["first_name"].ToString()%></td>
</tr>
Any help would be appreciated!
Thanks!
This is so much more complex then it needs to be. Create an object:
public class User
{
public string first_name { get; set; }
public string last_name { get; set; }
public string username { get; set; }
public string password { get; set; }
public User()
{
}
}
then in your code:
public User selectQuery(string query)
{
User myuser = new User();
//use this if you want to create a List of users and change the method type to "List<User>" and the return to userList.
List<User> userList = new List<User> ();
if (this.openDbConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, this.connection);
MySqlDataReader dr = cmd.ExecuteReader();
// read the data and store it in the list
while (dr.Read())
{
myuser.first_name = dr["first_name"] + "";
myuser.last_name= dr["last_name"] + "");
myuser.username = dr["username"] + "");
myuser.password = dr["password"] + "");
//use the below line only if you are expecting to return multiple users
userList.Add(myuser);
}
// close reading the data operator
dr.Close();
// close connection
this.connection.Close();
// return the list of results to be displayed
return myuser;
}
else
{
return myuser;
}
}
finally you just call the method then access the properties of the returned value
User myuser = db.selectQuery("blah");
if (data != null)
{
// assign the username, password, first and last name to the session variables
Session["first_name"] = myuser.first_name.ToString();
Session["last_name"] = myuser.last_name.ToString();
Session["username"] = myuser.username.ToString();
Session["password"] = myuser.password.ToString();
}
etc or if your returning a list do the following
List<User> myusers = db.selectQuery("blah")
if(!myusers.Count == 1) //this will let you check if it returns multiple users for some reason
{
Session["first_name"] = myusers[0].first_name.ToString();
Session["last_name"] = myusers[0].last_name.ToString();
Session["username"] = myusers[0].username.ToString();
Session["password"] = myusers[0].password.ToString();
}

MySQLDataReader not loading any data into specified places on form shown

I'm having problems loading information from my database into labels and pictureboxes. I think my code is correct to do what i'm wanting but i'm guessing not since it's not working. Below is the code i'm using. For the picture column in my database, I store the picture's path, not the actual blob. If you need anymore relevant information, please ask.
Code:
private void AirSpace_Shown(object sender, EventArgs e)
{
string connectionString = "datasource=localhost;port=3306;username=Admin;password=August211989";
Login login = new Login();
using (MySqlConnection conn = new MySqlConnection(connectionString))
{
using (MySqlCommand cmd = conn.CreateCommand())
{
string select = "SELECT username, email, premium, picture FROM userinfo.users WHERE username = #username;";
// (1) (2) (3) (4)
conn.Open();
cmd.CommandText = select;
cmd.Parameters.AddWithValue("#username", login.UsernameTextBox.Text);
using (MySqlDataReader Reader = cmd.ExecuteReader())
{
while (Reader.Read())
{
//Set the user's profile picture to the user's profile picture.
ProfilePicture.Load(Reader.GetString(4));
//Set the username to the user's username
Username.Text = Reader.GetString(1);
//Set the app version to the user's version
if (Reader.GetString(3) == "1")
{
AppVersionLabel.Text = "Premium";
}
else
{
AppVersionLabel.Text = "Free";
}
}
}
}
}
You might try this. This looks to be a log in code as well so I would add logic to where if you loop more than one it throws an error cause there should only be 1 result.
While(Reader.Read()){
//Set the user's profile picture to the user's profile picture.
string UserProfilePictureLocation = Reader.GetString(3);
ProfilePicture.Load(UserProfilePictureLocation);
//Set the username to the user's username
Username.Text = Reader.GetString(0);
//Set the app version to the user's version
if (Reader.GetString(2) == "1")
{
AppVersionLabel.Text = "Premium";
}
else
{
AppVersionLabel.Text = "Free";
}
}

Categories