tags:

views:

895

answers:

5

Hi. Im having this function to determine weather a user exists in a database or not

DM is my DataModule

AQ_LOGIN an ADOQuery

BENU is my Table filled with Users and their Password

Here comes the code:

function UserCheckExist(Login, pw: string): boolean;
begin
    with DM do
    begin
        AQ_LOGIN.Close;
        AQ_LOGIN.SQL.Clear;
        AQ_LOGIN.SQL.Add('select BLOGIN from BENU where BLOGIN = ''Login'' AND BPW = ''pw''');
        AQ_LOGIN.Open;
    end;
end;

My question now is: How can I make the function return true or false weather the User with the according password exists?

Thanks in advance.

+3  A: 

Use:

function UserCheckExist(Login, pw: string): boolean;
begin
  with DM do
  begin
    AQ_LOGIN.Close;
    AQ_LOGIN.SQL.Clear;
    {Use COUNT in select to determine if user exists}
    AQ_LOGIN.SQL.Add('select count(BLOGIN) from BENU where BLOGIN = ''Login'' AND BPW 'pw''');
    AQ_LOGIN.Open;
    Result:= (AQ_LOGIN.Fields[0].AsInteger = 1);
    AQ_LOGIN.Close;
 end;

end;

Two changes: first, do not select username, you should rather count values - COUNT always returns something, if no user exists - it will be zero. Second: Calculate result using comparision if count (Fields[0], since no more fields exist) is equal to one. If count of such records will be different then one, this function will return false.

smok1
+1 from me, as you posted pretty-much what I was going to put. However, I would have used parameters instead of concatenating the string inputs - and also, as the posted code stands (in the question and in the other answers) - it won't actually work, surely? :-)
robsoft
@robsoft: I think this code needs REAL refactoring...
smok1
@smok1 - indeed - and I think his code is just confusing him, because it seems he's still struggling to get the test to work. :-(
robsoft
@robsoft: Exactly...
smok1
+8  A: 

I'd go with smok1's answer (I was just posting something like it) but I'd parameterise your inputs, thus;

AQ_LOGIN.SQL.Add('select count(*) from BENU where BLOGIN=:login and BPW=:pw');
AQ_LOGIN.Parameters.ParamByName('login').AsString:=login;
AQ_LOGIN.Parameters.ParamByName('pw').AsString:=pw;

then as with smok1 - open the dataset and look at the value of the returned count.

NB - don't have an ADO delphi component handy but 99.9% sure that's the syntax :-)

edit: one of the advantages of using parameters like this is that you won't have to sanitise your input strings (for things like quotes) - the component knows what to do with your strings. You wouldn't expect to have a username with a single quote in it, but you might have a password with one. :-)

robsoft
+1 Using parameters also much safer. Injecting user entered data DIRECTLY into a SQL statement allows for abuse. If allowed, then a sophisticated user might change the behavior of the query beyond what is expected. For instance, using this example, one can bypass the login by typing the following into the password field "' or bpw > '". Using parameters as suggested would now allow this to happen.
skamradt
+2  A: 
function UserCheckExist(Login, pw: string): boolean;
begin
    with DM do
    begin
        AQ_LOGIN.Close;
        AQ_LOGIN.SQL.Clear;
        AQ_LOGIN.SQL.Add('select BLOGIN from BENU where BLOGIN = ''Login'' AND BPW = ''pw''');
        AQ_LOGIN.Open;
        Result := (AQ_LOGIN.RecordCount > 0);
        AQ_LOGIN.Close;
    end;
end;
gath
+1  A: 

You can check for Eof.

function UserCheckExist(Login, pw: string): boolean;
begin    
  with DM do    
  begin        
    AQ_LOGIN.Close;        
    AQ_LOGIN.SQL.Clear;        
    AQ_LOGIN.SQL.Add('select BLOGIN from BENU where BLOGIN = ' + QuotedStr(Login) + ' AND BPW = ' + QuotedStr(pw));        
    AQ_LOGIN.Open;        
    Result := (not AQ_Login.Eof);
    AQ_LOGIN.Close;    
  end;
end;
Pieter van Wyk
So what does that do? Eof = End of File?
Acron
@pr0wl - from help:Test Eof (end-of-file) to determine if the active record in a dataset is the last record. If Eof is true, the current record is unequivocally the last row in the dataset. Eof is true when an application: Opens an empty dataset. (...)
smok1
Yes, EOF = End of File. In this case, if the user exists you want to return True, so when EOF is false, record(s) were returned and the user exists. If EOF is True, the user does not exist.
Pieter van Wyk
A: 

I added one more check, weather the user is active. But it isnt working fine.

function UserCheck(Login, pw: string): boolean;
  begin
    with DM do
    begin
        AQ_LOGIN.Close;
        AQ_LOGIN.SQL.Clear;
        AQ_LOGIN.SQL.Add('select COUNT(*) from BENU where BLOGIN = ''Login'' AND BPW = ''pw'' AND AKTIV = 1');
        AQ_LOGIN.Open;
        Result := (AQ_LOGIN.RecordCount > 0);
        AQ_LOGIN.Close;
    end;
end;

This is where I use the function:

procedure TBenu_Login_Form.btnLoginClick(Sender: TObject);
  var pwhashed: string;
  begin
  pwhashed := MD5Print(MD5String(edtBPass.Text));
    if UserCheck(meBLogin.Text, pwhashed) then
      ShowMessage('User exists, Password is fine and active!')
    else
      ShowMessage('User does not exist, Password is wrong or not active!');
  end;

Would like to know why this does not work as intendet. It always returns the UserCheck true, never false when I i.e. enter a not existing user name.

Acron
Beacause select COUNT(*) will ALWAYS return one record - one record with the numer of records in datatable. Use either mine or gath's solution, do not mix them.
smok1
Recordcount will always return 1 in that query - you should be testing the value of the result, not the number of rows that come back. Change your test to Result:=(AQ_LOGIN.Fields[0].AsInteger>0); and you should be fine. And do something about those strings - you will get caught out one day just concatenating your input into the SQL like that! :-)
robsoft
I used now AQ_LOGIN.SQL.Add('select count(BLOGIN) from BENU where BLOGIN = ''Login'' AND BPW = ''pw''');still, this does not work
Acron
Using COUNT in SQL = Comparing with Result:=(AQ_LOGIN.Fields[0].AsInteger>0);NOT Using COUNT in SQL = Comparing with Result := (AQ_LOGIN.RecordCount > 0);
smok1
Got it working as intended now :>Thank you smok1 and robsoft as well as gath
Acron