-2

This program requires a user to select their card number from a combo box, then enter their password. If their password matches the one in the database, then they get logged in. Problem is, my code doesn't select one specific user, it only takes the first user in the database, I cannot log in any other user because I don't know how to write the code that chooses a specific user.

Here is what I've written so far. The problem I think is in the RetriveAccountInformation() function. Somewhere in there I need code that specifies it retrieves the data of the CardNumber selected in the cboAccountNumbers combo box. Any help is appreciated.

Imports MySql.Data

Imports MySql.Data.MySqlClient

Public Class Form1

Dim dbCon As MySqlConnection
Dim strQuery As String = ""
Dim SQLcmd As MySqlCommand
Dim DataReader As MySqlDataReader

Private m_strPass As String
Private m_decBalance As Decimal
Private m_strName As String
Private m_strUserPass As String
Private m_strCardNumber As String



Private Sub Button2_Click(sender As Object, e As EventArgs) Handles btnLogin.Click

    'Assign users guessed password to variable
    m_strUserPass = txtPass.Text

    RetrieveAccountInformation() ' invoke 


    ' determine if PIN number is within valid range
    If m_strUserPass = m_strPass Then
        lblWelcome.Text = "Hi"


    Else

        ' indicate that incorrect password was provided
        lblWelcome.Text = "Sorry, Password the is incorrect." _
           & "Please re-enter the password ."

        ' clear user's previous PIN entry
        m_strUserPass = ""

    End If

    txtPass.Clear() ' clear TextBox

End Sub


' load application Form
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

    'Prepare connection and query
    Try
        dbCon = New MySqlConnection("Server=localhost;Database=test;Uid=root;Pwd=mysql")

        strQuery = "SELECT CardNumber " &
                   "FROM Account"

        SQLcmd = New MySqlCommand(strQuery, dbCon)

        'Open the connection
        dbCon.Open()

        ' create database reader to read information from database
        DataReader = SQLcmd.ExecuteReader

        ' fill ComboBox with account numbers
        While DataReader.Read
            cboAccountNumbers.Items.Add(DataReader("CardNumber"))
        End While

        'Close the connection
        DataReader.Close()
        dbCon.Close()

    Catch ex As Exception
        'Output error message to user with explaination of error
        MsgBox("Failure to communicate" & vbCrLf & vbCrLf & ex.Message)


    End Try
End Sub


' invoke when user provides account number
Private Sub RetrieveAccountInformation()

    ' specify account number of record from which data
    ' will be retrieved
    dbCon = New MySqlConnection("Server=localhost;Database=***;Uid=***;Pwd=***")

    strQuery = "SELECT Password, Name, Balance " &
               "FROM Account"

    SQLcmd = New MySqlCommand(strQuery, dbCon)

    dbCon.Open() ' open database connection

    ' create database reader to read information from database
    DataReader = SQLcmd.ExecuteReader

    DataReader.Read() ' open data reader connection

    ' retrieve PIN number, balance amount and first name
    ' information from database
    m_strPass = Convert.ToString(DataReader("Password"))
    m_decBalance = Convert.ToDecimal(DataReader("Balance"))
    m_strName = Convert.ToString(DataReader("Name"))


    DataReader.Close() ' close data reader connection
    dbCon.Close() ' close database connection
End Sub ' RetrieveAccountInformation

End Class

user3275784
  • 437
  • 1
  • 9
  • 18

1 Answers1

0

You need to use a WHERE clause in your sql statement to retrieve the info about a particular user.
By the way, just using the password as key to retrieve your info is not enough (what blocks two users to have the same password?) So I suppose you pass to your RetrieveAccountInformation both the Password value and the CardNumber and use these values to uniquely identify a user record in the Account.

Private Function RetrieveAccountInformation(cardNum as String, pwd As String) As Boolean

    Dim result as Boolean
    strQuery = "SELECT Password, Name, Balance FROM Account " & _
               "WHERE Password = @pwd AND CardNumber=@card"

    Using dbCon = New MySqlConnection("Server=localhost;Database=***;Uid=***;Pwd=***")
    Using SQLcmd = New MySqlCommand(strQuery, dbCon)
        dbCon.Open() 
        SQLcmd.Parameters.AddWithValue("@pwd", pwd)
        SQLcmd.Parameters.AddWithValue("@card", cardNum)
        Using DataReader = SQLcmd.ExecuteReader

            if DataReader.Read() then
                m_strPass = Convert.ToString(DataReader("Password"))
                m_decBalance = Convert.ToDecimal(DataReader("Balance"))
                m_strName = Convert.ToString(DataReader("Name"))
                result = true
            else
                result = false
            End If
        End Using
    End Using
    End Using
End Function

The revised function could be called from the first button click in this way

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
    Dim result As Boolean 
    if cboAccountNumbers.SelectedValue Is Nothing Then
         MessageBox.Show("Please select a Card Number")
    End If

    result = RetrieveAccountInformation(cboAccountNumbers.SelectedValue.ToString, txtPass.Text) 

    If result = True Then
        lblWelcome.Text = "Hi"
    Else
        ....

I have also changed your Sub to a Boolean Function that returns true if you have found the user or false if not. As a last note, keep always in mind that passing password in clear text in a database command is not a good practice from the security standpoint. There is a large consensus that the most secure way is to use an Hashing function when storing the password and then apply the same hash to the clear text of your password before passing the value along the wire.

Steve
  • 213,761
  • 22
  • 232
  • 286
  • A comment on the downvote would be appreciated. It might help to improve the answer – Steve Feb 05 '14 at 17:42
  • No the card number and password don't get passed to the function. The system is meant to check if the password that they've entered corresponds with the password associated with CardNumber they've selected in the combo box. Also what does '@pwd' and '@card' mean exactly? I thought maybe you use WHERE to go "where the Card Number is equal to the numbered selected in the combo box" but I don't get how you write it. – user3275784 Feb 05 '14 at 19:08
  • 1
    When you search the database for the password, what happen if two users have the same password? You can't be sure to have found the user with the matching card number. The @xxx are parameters. This method is more secure than string concatenation because you avoid Sql Injection and parsing problems (what if the password contains a single quote?) – Steve Feb 05 '14 at 19:11
  • This is a short summary about Sql Injection http://www.c-sharpcorner.com/uploadfile/puranindia/parameterized-query-and-sql-injection-attacks/ and this is a situation where a single quote wreak havoc with a query http://stackoverflow.com/questions/19326563/string-field-with-single-quotation-mark-is-causing-an-error-when-inserting-recor#19326598 – Steve Feb 05 '14 at 19:14
  • And this is one of the most [famous question on Sql Injection](http://stackoverflow.com/questions/332365/how-does-the-sql-injection-from-the-bobby-tables-xkcd-comic-work) here on SO – Steve Feb 05 '14 at 19:21
  • But the CardNumber is the primary key, so no two card numbers will be the same. It should matter if 2 or more users have the same password because it is associated with only 1 unique card number. At least that's what I'm trying to do. Maybe I'm not coding it right. When I typed in your code, I understand what you are trying to do, but where are the cardNum and pwd in `Dim cardNum as String, Dim pwd As String` coming from? – user3275784 Feb 05 '14 at 19:37
  • In the most basic way I would have thought it would be something like this `strQuery = "SELECT Password, Name, Balance " & "FROM Account" & "WHERE CardNumber " = Val(cboAccountNumbers.Text)` But that's not the right syntax – user3275784 Feb 05 '14 at 19:40
  • I copied in your code exactly and I'm still getting and error. This time there's a squiggly line under the first Dim in `Dim cardNum as String, Dim pwd As String` saying "specifiers valid only at the beginning of a declaration" and when I run it crashes when I select an account number saying "Object reference not set to an instance of an object." ? – user3275784 Feb 05 '14 at 20:05
  • Sorry, my fault, I have written the code above directly in the answer box. Answer updated – Steve Feb 05 '14 at 20:24
  • Only one error this time saying "Please select a Card Number". So now I'm assuming the problem is that it's not recognising that a card number has been selected? I just want to say thanks as well for your help with this. It's been well over a year since I did any VB work and that was with Access databases, not SQL. So thanks for being patient at my lack of knowledge! – user3275784 Feb 05 '14 at 21:02
  • That's really strange. cboAccountNumbers is a combox right? and this is a winform app? SelectedItem should be Nothing only if you don't select anything or type something that is not included in the list of items added to the combo, otherwise should be set to the corresponding item text – Steve Feb 05 '14 at 22:39
  • I suggest to post a new question with the updated code. So someone less tired than me could take a look and find the obvious problem – Steve Feb 05 '14 at 22:41
  • I ended up getting it sorted in the end. Thanks for your help with it! – user3275784 Feb 06 '14 at 15:29