Compare String with Table fields value - vba

Hello to all programmers, I am very new to MS Access, but have some experience with Excel (including VBA). I've been searching for few days now and tested several suggestions with zero success so far. It's getting frustrating already and I decided to ask directly for my case.
From a loaded form I get the user to input password via Inputbox, I need my code to search for that string in my table Crewlist, field Password and criteria is another field Admin (Yes/No).
To facilitate the search I made a query table containing all people with field Admin (all are Yes) and field Password.
Looking forward for any particular solution. So far I have tried creating array & recordset.
Edit
(e.g as requested - table containing required info to be compared)
Field1 Field2 Field3("Admin")
Name1 password1 No
Name2 password2 Yes
Name3 password3 Yes
"If " statement comparing Inputbox string with Field2 where Admin=Yes
Dlookup will return the first result, ie Password2, but Name3 and password3 should also be looked and compared).
Recordset and simple SQL code will be required, I am now working on it.

I would suggest using a simple DLookup expression for this task, for example, assuming that the password entered by the user is stored in a variable pwd, you might use:
DLookup("Password","Crewlist","Admin = True and Password = '" & pwd & "'")
The DLookup function will return Null if no match is found, which you can test with an If statement and the IsNull function, e.g.:
If IsNull(DLookup("Password","Crewlist","Admin = True and Password = '" & pwd & "'")) Then
MsgBox "Invalid Password!"
Else
' Do Stuff
End If
Here, I only specify the Password field as the field to be looked up as DLookup requires a specific field whose value should be returned. You could instead use the DCount function and test whether the return is non-zero, e.g.:
If DCount("*","Crewlist","Admin = True and Password = '" & pwd & "'") > 0 Then
' Do Stuff
Else
MsgBox "Invalid Password!"
End If
Implemented in the event handler for a button, this might be written as:
Private Sub Command0_Click()
Dim pwd As String
pwd = InputBox("Enter Password:", "Password")
If pwd <> vbNullString Then
If IsNull(DLookup("Password", "Crewlist", "Admin = True and Password = '" & pwd & "'")) Then
MsgBox "Invalid Password!"
Else
MsgBox "Access Granted!"
End If
End If
End Sub
Note that this is only checking the password, hence, with only the above code, the user could specify the password for any Admin user and be granted access.
You could easily check the username with an additonal prompt:
Private Sub Command0_Click()
Dim usr As String
Dim pwd As String
usr = InputBox("Enter Username:", "Username")
If usr <> vbNullString Then
pwd = InputBox("Enter Password:", "Password")
If pwd <> vbNullString Then
If IsNull(DLookup("Password", "Crewlist", "Admin = True and Username = '" & usr & "' and Password = '" & pwd & "'")) Then
MsgBox "Invalid Username or Password!"
Else
MsgBox "Access Granted!"
End If
End If
End If
End Sub
However, this would be more professional if you were to design your own modal form containing a textbox or combobox for the username and a textbox in which the user may specify their password.
Aside, storing passwords in a database in plain text is bad practice: consider hashing the password using an appropriate hash function and storing the hash value. Then, apply the same hash function to the user input and use the resulting hash value to test for a match in your database.
This way, only the user has knowledge of the password - since hashing is a one-way process, not even the database admin has knowledge of user's passwords. If a user needs to change their password, they would either be supplied with a new temporary password that they could change or would provide a new password following some other authentication.
As a general rule, never trust any service that is able to send you your original password - this reveals that such a service is storing passwords without encryption/masking.

This is what I came with this morning after reading some examples about recordset and looping. My code in VBA
Sub Auto_Logo0_Dblclick
Dim AdmPass As String
AdmPass = Inputbox ("Admin password required")
'next part is taken from my guide book for Access
Dim Con1 As ADODB.Connection
Set Con1 = CurrentProject.Connection
Dim rcrdPass As New ADODB.Recordset
rcrdPass.Activeconnection = Con1
'SQL part
Dim mySQL as String
mySQL = "SELECT Crewlist.Surname, Crewlist.Password,"
mySQL = mySQL & " Crewlist.Admin"
mySQL = mySQL & " From Crewlist"
mySQL = mySQL & " Where (Crewlist.Admin = 'Yes')"
rcrdPass.Open mySQL
With rcrdPass
If Not .BOF And Not .EOF Then
.MoveFirst
.MoveLast
While (Not .EOF)
If AdmPass = rcrdPass.Fields("Password") Then
Call DoCmd.SelectObject(acTable,,True)
Else Msgbox ("Wrong password, try again")
End If
.MoveNext
Wend
End If
End With
rcrdPass.Close
Set rcrdPass = Nothing
Set Con1 = Nothing
End sub

Related

How to look up data in an Access table using the UserName Environ

In MS Access, I have a table named "Table" with three fields. Besides the ID field, I have one field named "User" and one field named "Email". Both fields are "short text". The table has two rows, the first: User = Nobody and Email = nobody#yahoo.com. The second: User = Somebody and Email = somebody#aol.com.
I've created a Module with the following code:
Sub Test()
Dim rs As Recordset
Dim localUser As String
localUser = Environ("UserName")
Set rs = CurrentDb.OpenRecordset("Table", dbOpenDynaset)
rs.FindFirst "[User] = 'localUser'"
MsgBox rs![Email]
End Sub
The local user is "Somebody" as shown when performing a: MsgBox Environ("UserName")
When I execute the code, I get a message box with "nobody#yahoo.com".
What I am trying to get is a message box with "somebody#aol.com".
What am I doing wrong?
Thank you in advance.
Try with:
rs.FindFirst "[User] = '" & localUser & "'"
But you could use DLookup:
Dim localUser As String
localUser = Environ("UserName")
MsgBox Nz(DLookup("[Email]", "Table", "[User] = '" & localUser & "'"))

register form wont work- Error in Code - dbCommand.ExecuteReader()

I am currently trying to develop a register system in visual studios, however for some reason it just does not work as it brings up an error message which is the following below.
On line line Dim read As OleDb.OleDbDataReader = cmd.ExecuteReader()it says:
An unhandled exception of type 'System.Data.OleDb.OleDbException' occurred in System.Data.dl.
Please can you help as I have done everything correct, however I just do not understand why the register system will not work.
'Enables the use of the OleDb classes.
Imports System
Imports System.Data.OleDb
Imports System.Net.Mail
Public Class Register
'Determines the connection and the location within the users file system.
Dim myConnString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Environment.CurrentDirectory & "\BloodBank.mdb"
Private Sub Register_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'This line of code loads data into the 'BloodBankDataSet.User' table. You can move, or remove it, as needed.
Me.UserTableAdapter.Fill(Me.BloodBankDataSet1.User)
'BindingSource - Encloses the data source for a form, in this case Register.
' AddNew, adds a new record.
Me.UserBindingSource.AddNew()
End Sub
Private Sub Reg_Click(sender As Object, e As EventArgs) Handles Reg.Click
'creates the connection between the project and the database ensuring that any changes made will be updated within the database.
Dim con As New OleDbConnection(myConnString)
'creates a second connection between the project and the database ensuring that any changes made will be updated within the database.
Dim con2 As New OleDbConnection(myConnString)
'Opens the connections.
con.Open()
con2.Open()
'Creates a SQL command which...
'Selects the staff details dependendent on the value inputted by the user.
Dim cmd As OleDbCommand = New OleDbCommand("SELECT StaffID, FirstName, Surname FROM [Staff] WHERE (FirstName = '" & Me.FirstNameTextBox.Text & "') AND (Surname = '" & Me.SurnameTextBox.Text & "') ", con)
'sends the command above to the connection.
Dim read As OleDb.OleDbDataReader = cmd.ExecuteReader()
'Creates a SQL command which...
'Selects the User ID and Staff ID from user dependent on the value inputted by the user.
Dim cmd2 As OleDbCommand = New OleDbCommand("SELECT UserID, StaffID FROM [User] WHERE StaffID = '" & Me.StaffIDTextBox.Text & "' ", con2)
'sends the command above to the connection.
Dim read2 As OleDb.OleDbDataReader = cmd2.ExecuteReader()
'If there is no text within the staff ID text box...
If String.IsNullOrEmpty(StaffIDTextBox.Text) Then
'A message will appear telling the user to enter their staff ID.
MsgBox("Please enter StaffID")
'This will focus the user on the staff ID text box.
'Me. means the current form in use.
Me.StaffIDTextBox.Focus()
'If there is no text within the FirstName text box...
ElseIf String.IsNullOrEmpty(FirstNameTextBox.Text) Then
'A message will appear telling the user to enter their first name.
MsgBox("Please enter First Name")
'This will focus the user on the firstname text box.
Me.FirstNameTextBox.Focus()
'If there is no text within the Surname text box...
ElseIf String.IsNullOrEmpty(SurnameTextBox.Text) Then
'A message will appear telling the user to enter their surname.
MsgBox("Please enter Surname")
'This will focus the user on the surname text box.
Me.SurnameTextBox.Focus()
'If there is no text within the login ID text box...
ElseIf String.IsNullOrEmpty(UserLoginTextBox.Text) Then
'A message will appear telling the user to enter their login ID.
MsgBox("Please Enter LoginID")
'This will focus the user on the loginID text box.
Me.UserLoginTextBox.Focus()
'If there is no text within the user password text box...
ElseIf String.IsNullOrEmpty(UserPasswordTextBox.Text) Then
'A message will appear telling the user to enter their password.
MsgBox("Please Enter Password")
'This will focus the user on the password text box.
Me.UserPasswordTextBox.Focus()
'If there is no text within the user ID text box...
ElseIf String.IsNullOrEmpty(EmailAddressTextBox.Text) Then
'A message will appear telling the user to enter their email.
MsgBox("Please Enter Email")
'This will focus the user on the email text box.
Me.EmailAddressTextBox.Focus()
'If the items do not match up with that within the database then...
ElseIf read.Read = False Then
'A message box will appear informing of the failure of the registration and the reason why.
MsgBox("You must be a staff member to create a User")
'This will focus the user on the StaffID text box.
Me.StaffIDTextBox.Focus()
'If the items do match up with that within the database then...
ElseIf read2.Read = True Then
'Determines that the answer data type is a integer.
Dim answer As Integer
'creates a message box, which is assigned to answer with a question with a yes and no option
answer = MsgBox("There is already a User account with this Staff ID." & vbNewLine & "Have you forgotten your Password? ", vbYesNo + vbQuestion)
'if the user selects the yes button...
If answer = vbYes Then
'They will be redirected to the retrieve password form.
'.Show, opens the said form, in this case the retrieve password form.
RetrievePass.Show()
'.Close, closes the form, in this case it is the form currently in use.
Me.Close()
Else
'Do nothing.
End If
ElseIf read2.Read = False And Me.StaffIDTextBox.Text = read.Item("StaffID") And Me.FirstNameTextBox.Text = read.Item("FirstName") And Me.SurnameTextBox.Text = read.Item("Surname") Then
End If
MsgBox("Thank you for creating a User." & vbNewLine & "We have sent your User details to your Email")
'Security Level
'Makes a certain feild in a specified table usable or not usable for the user.
HomeF.ButForm.Enabled = True
HomeF.ButUse.Enabled = False
HomeF.Button2.Enabled = True
'Me. means the current form in use.
'.Validate checks that the information is correct and every aspect has been filled in.
Me.Validate()
'EndEdit, applies the changes to the data source.
Me.UserBindingSource.EndEdit()
'Updates the specified table within the specified dataset.
Me.UserTableAdapter.Update(Me.BloodBankDataSet1)
Me.UserLogin_L.Text = Me.UserLoginTextBox.Text
'.Validate checks that the information is correct and every aspect has been filled in.
Me.Validate()
'EndEdit, applies the changes to the data source.
Try
Dim Email As String = Me.EmailAddressTextBox.Text
Dim name As String = Me.FirstNameTextBox.Text
Dim userpassword As String = Me.UserPasswordTextBox.Text
Dim LoginID As String = Me.UserLoginTextBox.Text
Dim StaffID As Integer = Me.StaffIDTextBox.Text
Dim Smtp_Server As New SmtpClient("smtp.gmail.com")
Dim e_mail As New MailMessage
Smtp_Server.UseDefaultCredentials = False
'Have to put in the email account details to enable the use of sending emails via the account.
Smtp_Server.Credentials = New Net.NetworkCredential("blood4all1#gmail.com", "Blood1234")
Smtp_Server.Port = 587
Smtp_Server.EnableSsl = True
'smtp(Simple Mail Transfer Protocol)
e_mail.From = New MailAddress("blood4all#outlook.com")
e_mail.To.Add(Email)
e_mail.Subject = ("New User: Blood4All Blood Bank")
e_mail.IsBodyHtml = False
e_mail.Priority = MailPriority.High
e_mail.Body = ("Dear " & name & "" & vbNewLine & "" & vbNewLine & "A New User Account was created with Your StaffID: " & StaffID & ". If the account was not created by You Contact Blood4All immediately." & vbNewLine & "Your LoginID is: " & LoginID & "" & vbNewLine & "Your Password is: " & userpassword & "" & vbNewLine & "" & vbNewLine & "Regards" & vbNewLine & "Blood4All Blood Bank")
Smtp_Server.Send(e_mail)
Close()
HomeF.Show()
Catch error_t As Exception
MsgBox("Error when Sending Your Email: Email Address does not Exist or There is No Network Connection")
Close()
HomeF.Show()
End Try
End
'Closes the four objects.
read.Close()
read2.Close()
con.Close()
con2.Close()
End Sub

Redirect from Login form based on user type using Vb.net

Assume that i have a login table that stores 3 attributes:
USERNAME
PASSWORD
USERTYPE
Note that i am using Access Database
In my login.vb form, there is 2 textboxes for the user to enter their username and password. And one Login button to validate the login.
My question is how to redirect the windows form based on userType.
Below is my codes for login.vb.
Private Sub btn_login_Click(sender As System.Object, e As System.EventArgs) Handles btn_login.Click
Dim mysql As String = "SELECT COUNT(*) AS NUM_MATCHES FROM TABLE WHERE USERNAME='" & username.Text & "' and PASSWORD ='" & password.Text & "'"
Dim mydatatable As New DataTable
Dim myreader As New OleDb.OleDbDataAdapter(mysql, myconnection)
myreader.Fill(mydatatable)
Dim num_matches As String = mydatatable.Rows(0).Item("NUM_MATCHES")
If num_matches = 1 Then
If userType = "CUSTOMER" Then
username = username.Text
form_customer.Show()
Me.Hide()
ElseIf userType = "STAFF" Then
form_staff.Show()
Me.Hide()
End If
Else
txt_username.Text = ""
txt_password.Text = ""
MsgBox("Incorrect Username or Password")
End If
End Sub
I have set userType as Public userType As String in the module so that the whole application can access. But when i debug the application, there is no error and when i click the login button, nothing happened.
There is one possible case where the code posted will not throw an error but will not open a form or display a message box either: when num_matches is 1 but userType is neither "CUSTOMER" nor "STAFF".
As pointed out in the comments, your code does not assign a value to userType. I'm assuming that it needs to do so here. I don't use MS Access myself, but I do use MySQL, and your current query is only returning the count of matches, not any other column value such as USERTYPE. You need to modify your query or add a second one to get information into your VB userType variable. Perhaps this will work:
Dim mysql As String = "SELECT COUNT(*) AS NUM_MATCHES, USERTYPE..."
...
userType = mydatatable.Rows(0).Item("USERTYPE")
That's just a guess on my part, since I use MySql.Data.MySqlClient classes for queries, but you should still get the idea.
You really should read all the answers.... Irene has basically given you all you needed... here is a rewrite of your code.
Private Sub btn_login_Click(sender As System.Object, e As System.EventArgs) Handles btn_login.Click
Dim mysql As String = "SELECT * FROM TABLE WHERE USERNAME='" & username.Text & "' and PASSWORD ='" & password.Text & "'"
Dim mydatatable As New DataTable
Dim myreader As New OleDb.OleDbDataAdapter(mysql, myconnection)
myreader.Fill(mydatatable)
If mydatatable.Rows.Count = 1 Then
'we have a row
'assign userType
userType = mydatatable.Rows(0).Item("USERTYPE")
If userType = "CUSTOMER" Then
username = username.Text
form_customer.Show()
Me.Hide()
ElseIf userType = "STAFF" Then
form_staff.Show()
Me.Hide()
End If
Else
txt_username.Text = ""
txt_password.Text = ""
MsgBox("Incorrect Username or Password")
End If
End Sub
Note that the above code does not address the issue of sql injection.
I sort of wonder why you are counting matches in your select statement but then checking for the number of matches by looking at how many rows there are in the datatable.
The way your logic is set up, as long as the user name and password are found, you have a match. Therefore the code in the if clause is executed. As others have noted, you are not assigning anything to userType here. You can prove to yourself that this is the problem by adding an ELSE clause to the code like this:
If num_matches = 1 Then
If userType = "CUSTOMER" Then
username = username.Text
form_customer.Show()
Me.Hide()
ElseIf userType = "STAFF" Then
form_staff.Show()
Me.Hide()
Else
MsgBox("Incorrect user type.")
End If
Else
txt_username.Text = ""
txt_password.Text = ""
MsgBox("Incorrect Username or Password")
End If
If I were writing this code, I would change the SQL statement to select the userType based on user name and password. You don't need to use count(*) then and can simply test the number of rows in the datatable and act accordingly.
By the way, if it is at all possible that the same username/password combination could be included in the table twice with different user types, then your test should be If num_matches >= 1 Then instead of If num_matches = 1 Then as well because in the situation where there is more than one match, execution will jump to the Else portion of the statement with the message "Incorrect Username or Password."

How do I get a login form to reject entries with wrong capitalization?

I have the following code so far for a login form taking data from a database:
Dim myconnection As New SqlConnection("server=classified;database=classified")
myconnection.Open()
Dim theQuery As String = " SELECT Username, Password FROM Accounts WHERE (Username = '" & TextBox1.Text & "' ) AND (Password = '" & TextBox2.Text & "')"
Dim repeatChecker As SqlCommand = New SqlCommand(theQuery, myconnection)
'mycommand.ExecuteNonQuery()
Using reader As SqlDataReader = repeatChecker.ExecuteReader()
If reader.HasRows Then
' User already exists
While reader.Read()
If reader("Password") = TextBox2.Text.ToString And reader("Username").ToString = TextBox1.Text Then
MessageBox.Show("Logged in successfully as " & TextBox1.Text, "", MessageBoxButtons.OK, MessageBoxIcon.Information)
Firs.Show()
Me.Close()
'Clear all fields
End If
End While
Else
MessageBox.Show("Invalid username or password.", MsgBoxStyle.Critical)
End If
End Using
myconnection.Close()
If I put in the correct login info but with wrong capitalization, I don't get an acceptance or a rejection, the program just sits there and does nothing. How can I get a denial of a login when the capitalization is wrong?
As written, you really can't discern just a case-mismatch from a query as you've illustrated in this code. If a database is set up for case-sensitivity, a query will fail if two strings don't match even for the difference of a single mismatched character, but it doesn't retain that as a reason for the mismatch anymore than it would for, say "Apple" not matching "Banana."
Please note that, as the commentators of your question stated:
You're vulnerable to SQL-Injection attacks.
You should never store passwords in clear text in your DataBase. Once the DB gets cracked, all credentials are compromised. Not to mention evil DB-admins that might get tempted to misuse those credentials...
Case-Sensitivity in a password is a good thing.
With those things mentioned, if you want to provide your users with the comfort of a not case-sensitive username, just cast the TextBox1.Text as well as the query result for the Username to upper case by changing (Username = '" & TextBox1.Text & "' ) to (UPPER(Username) = '" & TextBox1.Text.ToUpper() & "')

Save query results as a string vb.net

I am creating a forgot password feature for a login form. If the users username and email match whats in the database then an email containing their password needs to be sent to their email address. Once my select statements grabs the password I do not know how to convert that over into the body of the email.
cmd2.CommandText = "Select Password from tblLogin where Username = '" & UsernameTextBox.Text & "' and EmailAddress = '" & EmailAddressTextBox.Text & "'"
pass = cmd2.ExecuteReader
If pass.HasRows Then
Do While pass.Read()
EmailMessage.Body = "Here is your password:"
Loop
Else
Console.WriteLine("No rows found.")
End If
The only thing I can think of doing is this:
EmailMessage.Body = ("Here is your password: " & pass)
However I still need to figure out how I can convert pass into a string containing the query result.
EmailMessage.Body = "Here is your password: " & pass.Item(0)
Since you only want the one value from the DB, look at ExecuteScalar instead of ExecuteReader.
However, as Alex commented, unencrypted passwords is really not a good idea.