home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 June / Chip_2002-06_cd1.bin / zkuste / delphi / kolekce / d6 / rxlibsetup.exe / {app} / units / LoginDlg.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2002-02-19  |  13.5 KB  |  466 lines

  1. {*******************************************************}
  2. {                                                       }
  3. {         Delphi VCL Extensions (RX)                    }
  4. {                                                       }
  5. {         Copyright (c) 2001,2002 SGB Software          }
  6. {         Copyright (c) 1997, 1998 Fedor Koshevnikov,   }
  7. {                        Igor Pavluk and Serge Korolev  }
  8. {                                                       }
  9. {*******************************************************}
  10.  
  11. unit LoginDlg;
  12.  
  13. {$I RX.INC}
  14.  
  15. interface
  16.  
  17. uses SysUtils, Messages, Classes, Controls, Forms, Dialogs, StdCtrls,
  18.   ExtCtrls, DB, DBTables, DBLists, RxLogin, BdeUtils;
  19.  
  20. type
  21.   TCheckUserNameEvent = function(UsersTable: TTable;
  22.     const UserName, Password: string): Boolean of object;
  23.  
  24.   TDialogMode = (dmAppLogin, dmDBLogin, dmUnlock);
  25.  
  26.   TDBLoginDialog = class
  27.   private
  28.     FDialog: TRxLoginForm;
  29.     FMode: TDialogMode;
  30.     FSelectDatabase: Boolean;
  31.     FIniAliasName: string;
  32.     FCheckUserEvent: TCheckUserNameEvent;
  33.     FCheckUnlock: TCheckUnlockEvent;
  34.     FIconDblClick: TNotifyEvent;
  35.     procedure Login(Database: TDatabase; LoginParams: TStrings);
  36.     function GetUserInfo: Boolean;
  37.     function CheckUser(Table: TTable): Boolean;
  38.     function CheckUnlock: Boolean;
  39.     procedure OkBtnClick(Sender: TObject);
  40.     procedure FormShow(Sender: TObject);
  41.     function ExecuteAppLogin: Boolean;
  42.     function ExecuteDbLogin(LoginParams: TStrings): Boolean;
  43.     function ExecuteUnlock: Boolean;
  44.   public
  45.     Database: TDatabase;
  46.     AttemptNumber: Integer;
  47.     ShowDBName: Boolean;
  48.     UsersTableName: string;
  49.     UserNameField: string;
  50.     MaxPwdLen: Integer;
  51.     LoginName: string;
  52.     IniFileName: string;
  53.     UseRegistry: Boolean;
  54.     constructor Create(DialogMode: TDialogMode; DatabaseSelect: Boolean);
  55.     destructor Destroy; override;
  56.     function Execute(LoginParams: TStrings): Boolean;
  57.     function GetUserName: string;
  58.     function CheckDatabaseChange: Boolean;
  59.     procedure FillParams(LoginParams: TStrings);
  60.     property Mode: TDialogMode read FMode;
  61.     property SelectDatabase: Boolean read FSelectDatabase;
  62.     property OnCheckUnlock: TCheckUnlockEvent read FCheckUnlock write FCheckUnlock;
  63.     property OnCheckUserEvent: TCheckUserNameEvent read FCheckUserEvent write FCheckUserEvent;
  64.     property OnIconDblClick: TNotifyEvent read FIconDblClick write FIconDblClick;
  65.   end;
  66.  
  67. procedure OnLoginDialog(Database: TDatabase; LoginParams: TStrings;
  68.   AttemptNumber: Integer; ShowDBName: Boolean);
  69.  
  70. function LoginDialog(Database: TDatabase; AttemptNumber: Integer;
  71.   const UsersTableName, UserNameField: string; MaxPwdLen: Integer;
  72.   CheckUserEvent: TCheckUserNameEvent; IconDblClick: TNotifyEvent;
  73.   var LoginName: string; const IniFileName: string;
  74.   UseRegistry, SelectDatabase: Boolean): Boolean;
  75.  
  76. function UnlockDialog(const UserName: string; OnUnlock: TCheckUnlockEvent;
  77.   IconDblClick: TNotifyEvent): Boolean;
  78. function UnlockDialogEx(const UserName: string; OnUnlock: TCheckUnlockEvent;
  79.   IconDblClick: TNotifyEvent; MaxPwdLen, AttemptNumber: Integer): Boolean;
  80.  
  81. implementation
  82.  
  83. uses {$IFDEF WIN32} Windows, Registry, BDE, {$ELSE} WinTypes, WinProcs,
  84.   DbiTypes, {$ENDIF} IniFiles, Graphics, AppUtils, RxDConst, Consts,
  85.   VclUtils, RxConst;
  86.  
  87. const
  88.   keyLastLoginUserName = 'LastUser';
  89.   keySelectDatabase = 'SelectDatabase'; { dialog never writes this value }
  90.   keyLastAliasName = 'LastAlias';       { used if SelectDatabase = True  }
  91.  
  92. { TDBLoginDialog }
  93.  
  94. constructor TDBLoginDialog.Create(DialogMode: TDialogMode; DatabaseSelect: Boolean);
  95. begin
  96.   inherited Create;
  97.   FMode := DialogMode;
  98.   FSelectDatabase := DatabaseSelect;
  99.   FDialog := CreateLoginDialog((FMode = dmUnlock), FSelectDatabase,
  100.     FormShow, OkBtnClick);
  101.   AttemptNumber := 3;
  102.   ShowDBName := True;
  103. end;
  104.  
  105. destructor TDBLoginDialog.Destroy;
  106. begin
  107.   FDialog.Free;
  108.   inherited Destroy;
  109. end;
  110.  
  111. procedure TDBLoginDialog.OkBtnClick(Sender: TObject);
  112. var
  113.   Ok: Boolean;
  114.   SaveLogin: TDatabaseLoginEvent;
  115.   SetCursor: Boolean;
  116. begin
  117.   if FMode = dmUnlock then begin
  118.     Ok := False;
  119.     try
  120.       Ok := CheckUnlock;
  121.     except
  122.       Application.HandleException(Self);
  123.     end;
  124.     if Ok then FDialog.ModalResult := mrOk
  125.     else FDialog.ModalResult := mrCancel;
  126.   end
  127.   else if Mode = dmAppLogin then begin
  128. {$IFDEF WIN32}
  129.     SetCursor := GetCurrentThreadID = MainThreadID;
  130. {$ELSE}
  131.     SetCursor := True;
  132. {$ENDIF}
  133.     SaveLogin := Database.OnLogin;
  134.     try
  135.       try
  136.         if FSelectDatabase then
  137.           Database.AliasName := FDialog.CustomCombo.Text;
  138.         Database.OnLogin := Login;
  139.         if SetCursor then Screen.Cursor := crHourGlass;
  140.         try
  141.           Database.Open;
  142.         finally
  143.           if SetCursor then Screen.Cursor := crDefault;
  144.         end;
  145.       except
  146.         Application.HandleException(Self);
  147.       end;
  148.     finally
  149.       Database.OnLogin := SaveLogin;
  150.     end;
  151.     if Database.Connected then
  152.     try
  153.       if SetCursor then Screen.Cursor := crHourGlass;
  154.       Ok := False;
  155.       try
  156.         Ok := GetUserInfo;
  157.       except
  158.         Application.HandleException(Self);
  159.       end;
  160.       if Ok then FDialog.ModalResult := mrOk
  161.       else begin
  162.         FDialog.ModalResult := mrNone;
  163.         Database.Close;
  164.       end;
  165.     finally
  166.       if SetCursor then Screen.Cursor := crDefault;
  167.     end;
  168.   end
  169.   else { dmDBLogin } FDialog.ModalResult := mrOk
  170. end;
  171.  
  172. procedure TDBLoginDialog.FormShow(Sender: TObject);
  173. var
  174.   S: string;
  175. begin
  176.   if (FMode in [dmAppLogin, dmDBLogin]) and FSelectDatabase then begin
  177.     with TBDEItems.Create(FDialog) do
  178.     try
  179. {$IFDEF WIN32}
  180.       SessionName := Database.SessionName;
  181. {$ENDIF}
  182.       ItemType := bdDatabases;
  183.       FDialog.CustomCombo.Items.Clear;
  184.       Open;
  185.       while not Eof do begin
  186.         FDialog.CustomCombo.Items.Add(FieldByName('NAME').AsString);
  187.         Next;
  188.       end;
  189.       if FIniAliasName = '' then S := Database.AliasName
  190.       else S := FIniAliasName;
  191.       with FDialog.CustomCombo do ItemIndex := Items.IndexOf(S);
  192.     finally
  193.       Free;
  194.     end;
  195.   end;
  196. end;
  197.  
  198. function TDBLoginDialog.ExecuteAppLogin: Boolean;
  199. var
  200.   Ini: TObject;
  201. begin
  202.   try
  203. {$IFDEF WIN32}
  204.     if UseRegistry then begin
  205.       Ini := TRegIniFile.Create(IniFileName);
  206. {$IFDEF RX_D5}
  207.       TRegIniFile(Ini).Access := KEY_READ;
  208. {$ENDIF}
  209.     end
  210.     else 
  211.       Ini := TIniFile.Create(IniFileName);
  212. {$ELSE}
  213.     Ini := TIniFile.Create(IniFileName);
  214. {$ENDIF WIN32}
  215.     try
  216.       FDialog.UserNameEdit.Text := IniReadString(Ini, FDialog.ClassName,
  217.         keyLastLoginUserName, LoginName);
  218.       FSelectDatabase := IniReadBool(Ini, FDialog.ClassName,
  219.         keySelectDatabase, FSelectDatabase);
  220.       FIniAliasName := IniReadString(Ini, FDialog.ClassName,
  221.         keyLastAliasName, '');
  222.     finally
  223.       Ini.Free;
  224.     end;
  225.   except
  226.     IniFileName := '';
  227.   end;
  228.   FDialog.SelectDatabase := SelectDatabase;
  229.   Result := (FDialog.ShowModal = mrOk);
  230.   Database.OnLogin := nil;
  231.   if Result then begin
  232.     LoginName := GetUserName;
  233.     if IniFileName <> '' then begin
  234. {$IFDEF WIN32}
  235.       if UseRegistry then Ini := TRegIniFile.Create(IniFileName)
  236.       else Ini := TIniFile.Create(IniFileName);
  237. {$ELSE}
  238.       Ini := TIniFile.Create(IniFileName);
  239. {$ENDIF WIN32}
  240.       try
  241.         IniWriteString(Ini, FDialog.ClassName, keyLastLoginUserName, GetUserName);
  242.         IniWriteString(Ini, FDialog.ClassName, keyLastAliasName, Database.AliasName);
  243.       finally
  244.         Ini.Free;
  245.       end;
  246.     end;
  247.   end;
  248. end;
  249.  
  250. function TDBLoginDialog.ExecuteDbLogin(LoginParams: TStrings): Boolean;
  251. {$IFDEF WIN32}
  252. var
  253.   CurrSession: TSession;
  254. {$ENDIF}
  255. begin
  256.   Result := False;
  257.   if (Database = nil) or not Assigned(LoginParams) then Exit;
  258.   if ShowDBName then
  259.     FDialog.AppTitleLabel.Caption := FmtLoadStr(SDatabaseName,
  260.       [Database.DatabaseName]);
  261.   FDialog.UserNameEdit.Text := LoginParams.Values[szUSERNAME];
  262. {$IFDEF WIN32}
  263.   CurrSession := Sessions.CurrentSession;
  264. {$ENDIF}
  265.   try
  266.     Result := FDialog.ShowModal = mrOk;
  267.     if Result then FillParams(LoginParams)
  268.     else SysUtils.Abort;
  269.   finally
  270. {$IFDEF WIN32}
  271.     Sessions.CurrentSession := CurrSession;
  272. {$ENDIF}
  273.   end;
  274. end;
  275.  
  276. function TDBLoginDialog.ExecuteUnlock: Boolean;
  277. begin
  278.   with FDialog.UserNameEdit do begin
  279.     Text := LoginName;
  280.     ReadOnly := True;
  281.     Font.Color := clGrayText;
  282.   end;
  283.   Result := (FDialog.ShowModal = mrOk);
  284. end;
  285.  
  286. function TDBLoginDialog.Execute(LoginParams: TStrings): Boolean;
  287. var
  288.   SaveCursor: TCursor;
  289. begin
  290.   SaveCursor := Screen.Cursor;
  291.   Screen.Cursor := crDefault;
  292.   try
  293.     if Assigned(FIconDblClick) then begin
  294.       with FDialog.AppIcon do begin
  295.         OnDblClick := OnIconDblClick;
  296.         Cursor := crHand;
  297.       end;
  298.       with FDialog.KeyImage do begin
  299.         OnDblClick := OnIconDblClick;
  300.         Cursor := crHand;
  301.       end;
  302.     end;
  303.     FDialog.PasswordEdit.MaxLength := MaxPwdLen;
  304.     FDialog.AttemptNumber := AttemptNumber;
  305.     case FMode of
  306.       dmAppLogin: Result := ExecuteAppLogin;
  307.       dmDBLogin: Result := ExecuteDbLogin(LoginParams);
  308.       dmUnlock: Result := ExecuteUnlock;
  309.       else Result := False;
  310.     end;
  311.     if Result then LoginName := GetUserName;
  312.   finally
  313.     Screen.Cursor := SaveCursor;
  314.   end;
  315. end;
  316.  
  317. function TDBLoginDialog.GetUserName: string;
  318. begin
  319.   if CheckDatabaseChange then
  320.     Result := Copy(FDialog.UserNameEdit.Text, 1,
  321.       Pos('@', FDialog.UserNameEdit.Text) - 1)
  322.   else
  323.     Result := FDialog.UserNameEdit.Text;
  324. end;
  325.  
  326. function TDBLoginDialog.CheckDatabaseChange: Boolean;
  327. begin
  328.   Result := (FMode in [dmAppLogin, dmDBLogin]) and
  329.     (Pos('@', Fdialog.UserNameEdit.Text) > 0) and
  330.     ((Database <> nil) and (Database.DriverName <> '') and
  331.     (CompareText(Database.DriverName, szCFGDBSTANDARD) <> 0));
  332. end;
  333.  
  334. procedure TDBLoginDialog.FillParams(LoginParams: TStrings);
  335. begin
  336.   LoginParams.Values[szUSERNAME] := GetUserName;
  337.   LoginParams.Values['PASSWORD'] := FDialog.PasswordEdit.Text;
  338.   if CheckDatabaseChange then begin
  339.     LoginParams.Values[szSERVERNAME] := Copy(FDialog.UserNameEdit.Text,
  340.       Pos('@', FDialog.UserNameEdit.Text) + 1, MaxInt)
  341.   end;
  342. end;
  343.  
  344. procedure TDBLoginDialog.Login(Database: TDatabase; LoginParams: TStrings);
  345. begin
  346.   FillParams(LoginParams);
  347. end;
  348.  
  349. function TDBLoginDialog.GetUserInfo: Boolean;
  350. var
  351.   Table: TTable;
  352. begin
  353.   if UsersTableName = '' then Result := CheckUser(nil)
  354.   else begin
  355.     Result := False;
  356.     Table := TTable.Create(Database);
  357.     try
  358.       try
  359.         Table.DatabaseName := Database.DatabaseName;
  360. {$IFDEF WIN32}
  361.         Table.SessionName := Database.SessionName;
  362. {$ENDIF}
  363.         Table.TableName := UsersTableName;
  364.         Table.IndexFieldNames := UserNameField;
  365.         Table.Open;
  366.         if Table.FindKey([GetUserName]) then begin
  367.           Result := CheckUser(Table);
  368.           if not Result then
  369.             raise EDatabaseError.Create(LoadStr(SInvalidUserName));
  370.         end
  371.         else
  372.           raise EDatabaseError.Create(LoadStr(SInvalidUserName));
  373.       except
  374.         Application.HandleException(Self);
  375.       end;
  376.     finally
  377.       Table.Free;
  378.     end;
  379.   end;
  380. end;
  381.  
  382. function TDBLoginDialog.CheckUser(Table: TTable): Boolean;
  383. begin
  384.   if Assigned(FCheckUserEvent) then
  385.     Result := FCheckUserEvent(Table, GetUserName, FDialog.PasswordEdit.Text)
  386.   else Result := True;
  387. end;
  388.  
  389. function TDBLoginDialog.CheckUnlock: Boolean;
  390. begin
  391.   if Assigned(FCheckUnlock) then
  392.     Result := FCheckUnlock(FDialog.PasswordEdit.Text)
  393.   else Result := True;
  394. end;
  395.  
  396. { Utility routines }
  397.  
  398. procedure OnLoginDialog(Database: TDatabase; LoginParams: TStrings;
  399.   AttemptNumber: Integer; ShowDBName: Boolean);
  400. var
  401.   Dlg: TDBLoginDialog;
  402. begin
  403.   Dlg := TDBLoginDialog.Create(dmDBLogin, False);
  404.   try
  405.     Dlg.Database := Database;
  406.     Dlg.ShowDBName := ShowDBName;
  407.     Dlg.AttemptNumber := AttemptNumber;
  408.     Dlg.Execute(LoginParams);
  409.   finally
  410.     Dlg.Free;
  411.   end;
  412. end;
  413.  
  414. function UnlockDialogEx(const UserName: string; OnUnlock: TCheckUnlockEvent;
  415.   IconDblClick: TNotifyEvent; MaxPwdLen, AttemptNumber: Integer): Boolean;
  416. var
  417.   Dlg: TDBLoginDialog;
  418. begin
  419.   Dlg := TDBLoginDialog.Create(dmUnlock, False);
  420.   try
  421.     Dlg.LoginName := UserName;
  422.     Dlg.OnIconDblClick := IconDblClick;
  423.     Dlg.OnCheckUnlock := OnUnlock;
  424.     Dlg.MaxPwdLen := MaxPwdLen;
  425.     Dlg.AttemptNumber := AttemptNumber;
  426.     Result := Dlg.Execute(nil);
  427.   finally
  428.     Dlg.Free;
  429.   end;
  430. end;
  431.  
  432. function UnlockDialog(const UserName: string; OnUnlock: TCheckUnlockEvent;
  433.   IconDblClick: TNotifyEvent): Boolean;
  434. begin
  435.   Result := UnlockDialogEx(UserName, OnUnlock, IconDblClick, 0, 1);
  436. end;
  437.  
  438. function LoginDialog(Database: TDatabase; AttemptNumber: Integer;
  439.   const UsersTableName, UserNameField: string; MaxPwdLen: Integer;
  440.   CheckUserEvent: TCheckUserNameEvent; IconDblClick: TNotifyEvent;
  441.   var LoginName: string; const IniFileName: string;
  442.   UseRegistry, SelectDatabase: Boolean): Boolean;
  443. var
  444.   Dlg: TDBLoginDialog;
  445. begin
  446.   Dlg := TDBLoginDialog.Create(dmAppLogin, SelectDatabase);
  447.   try
  448.     Dlg.LoginName := LoginName;
  449.     Dlg.OnIconDblClick := IconDblClick;
  450.     Dlg.OnCheckUserEvent := CheckUserEvent;
  451.     Dlg.MaxPwdLen := MaxPwdLen;
  452.     Dlg.Database := Database;
  453.     Dlg.AttemptNumber := AttemptNumber;
  454.     Dlg.UsersTableName := UsersTableName;
  455.     Dlg.UserNameField := UserNameField;
  456.     Dlg.IniFileName := IniFileName;
  457.     Dlg.UseRegistry := UseRegistry;
  458.     Result := Dlg.Execute(nil);
  459.     if Result then LoginName := Dlg.LoginName;
  460.   finally
  461.     Dlg.Free;
  462.   end;
  463. end;
  464.  
  465. end.
  466.