| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504 |
- {
- $Project$
- $Workfile$
- $Revision$
- $DateUTC$
- $Id$
- This file is part of the Indy (Internet Direct) project, and is offered
- under the dual-licensing agreement described on the Indy website.
- (http://www.indyproject.org/)
- Copyright:
- (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
- }
- {
- $Log$
- }
- {
- Rev 1.5 10/26/2004 10:51:40 PM JPMugaas
- Updated ref.
- Rev 1.4 7/6/2004 4:53:46 PM DSiders
- Corrected spelling of Challenge in properties, methods, types.
- Rev 1.3 2004.02.03 5:44:40 PM czhower
- Name changes
- Rev 1.2 2004.01.22 2:05:16 PM czhower
- TextIsSame
- Rev 1.1 1/21/2004 4:21:08 PM JPMugaas
- InitComponent
- Rev 1.0 11/13/2002 08:04:16 AM JPMugaas
- }
- unit IdUserAccounts;
- {
- Original Author: Sergio Perry
- Date: 24/04/2001
- 2002-05-03 - Andrew P.Rybin
- - TIdCustomUserManager,TIdSimpleUserManager,UserId
- - universal TIdUserManagerAuthenticationEvent> Sender: TObject
- }
- interface
- {$i IdCompilerDefines.inc}
- uses
- Classes,
- IdGlobal,
- IdBaseComponent,
- IdComponent;
- type
- TIdUserHandle = UInt32;//ptr,object,collection.item.id or THandle
- TIdUserAccess = Integer; //<0-denied, >=0-accept; ex: 0-guest,1-user,2-power user,3-admin
- var
- IdUserHandleNone: TIdUserHandle = High(UInt32)-1; //Special handle: empty handle
- IdUserHandleBroadcast: TIdUserHandle = High(UInt32); //Special handle
- IdUserAccessDenied: TIdUserAccess = Low(Integer); //Special access
- type
- TIdCustomUserManagerOption = (umoCaseSensitiveUsername, umoCaseSensitivePassword);
- TIdCustomUserManagerOptions = set of TIdCustomUserManagerOption;
- TIdUserManagerAuthenticationEvent = procedure(Sender: TObject; {TIdCustomUserManager, TIdPeerThread, etc}
- const AUsername: String;
- var VPassword: String;
- var VUserHandle: TIdUserHandle;
- var VUserAccess: TIdUserAccess) of object;
- TIdUserManagerLogoffEvent = procedure(Sender: TObject; var VUserHandle: TIdUserHandle) of object;
- TIdCustomUserManager = class(TIdBaseComponent)
- protected
- FDomain: String;
- FOnAfterAuthentication: TIdUserManagerAuthenticationEvent; //3
- FOnBeforeAuthentication: TIdUserManagerAuthenticationEvent;//1
- FOnLogoffUser: TIdUserManagerLogoffEvent;//4
- //
- procedure DoBeforeAuthentication(const AUsername: String; var VPassword: String;
- var VUserHandle: TIdUserHandle; var VUserAccess: TIdUserAccess); virtual;
- // Descendants must override this method:
- procedure DoAuthentication (const AUsername: String; var VPassword: String;
- var VUserHandle: TIdUserHandle; var VUserAccess: TIdUserAccess); virtual; abstract;
- procedure DoAfterAuthentication (const AUsername: String; var VPassword: String;
- var VUserHandle: TIdUserHandle; var VUserAccess: TIdUserAccess); virtual;
- procedure DoLogoffUser(var VUserHandle: TIdUserHandle); virtual;
- function GetOptions: TIdCustomUserManagerOptions; virtual;
- procedure SetDomain(const AValue: String); virtual;
- procedure SetOptions(const AValue: TIdCustomUserManagerOptions); virtual;
- // props
- property Domain: String read FDomain write SetDomain;
- property Options: TIdCustomUserManagerOptions read GetOptions write SetOptions;
- // events
- property OnBeforeAuthentication: TIdUserManagerAuthenticationEvent
- read FOnBeforeAuthentication write FOnBeforeAuthentication;
- property OnAfterAuthentication: TIdUserManagerAuthenticationEvent
- read FOnAfterAuthentication write FOnAfterAuthentication;
- property OnLogoffUser: TIdUserManagerLogoffEvent read FOnLogoffUser write FOnLogoffUser;
- public
- //Challenge user is a nice backdoor for some things we will do in a descendent class
- function ChallengeUser(var VIsSafe : Boolean; const AUserName : String) : String; virtual;
- function AuthenticateUser(const AUsername, APassword: String): Boolean; overload;
- function AuthenticateUser(const AUsername, APassword: String; var VUserHandle: TIdUserHandle): TIdUserAccess; overload;
- class function IsRegisteredUser(AUserAccess: TIdUserAccess): Boolean;
- procedure LogoffUser(AUserHandle: TIdUserHandle); virtual;
- procedure UserDisconnected(const AUser : String); virtual;
- function SendsChallange : Boolean; virtual;
- End;//TIdCustomUserManager
- //=============================================================================
- // * TIdSimpleUserManager *
- //=============================================================================
- TIdSimpleUserManager = class(TIdCustomUserManager)
- protected
- FOptions: TIdCustomUserManagerOptions;
- FOnAuthentication: TIdUserManagerAuthenticationEvent;
- //
- procedure DoAuthentication (const AUsername: String; var VPassword: String;
- var VUserHandle: TIdUserHandle; var VUserAccess: TIdUserAccess); override;
- function GetOptions: TIdCustomUserManagerOptions; override;
- procedure SetOptions(const AValue: TIdCustomUserManagerOptions); override;
- published
- property Domain;
- property Options;
- // events
- property OnBeforeAuthentication;
- property OnAuthentication: TIdUserManagerAuthenticationEvent read FOnAuthentication write FOnAuthentication;
- property OnAfterAuthentication;
- property OnLogoffUser;
- End;//TIdSimpleUserManager
- //=============================================================================
- // * TIdUserManager *
- //=============================================================================
- const
- IdUserAccountDefaultAccess = 0;//guest
- type
- TIdUserManager = class;
- TIdUserAccount = class(TCollectionItem)
- protected
- FAttributes: TStrings;
- {$IFDEF USE_OBJECT_ARC}
- // When ARC is enabled, object references MUST be valid objects.
- // It is common for users to store non-object values, though, so
- // we will provide separate properties for those purposes
- //
- // TODO; use TValue instead of separating them
- //
- FDataObject: TObject;
- FDataValue: PtrInt;
- {$ELSE}
- FData: TObject;
- {$ENDIF}
- FUserName: string;
- FPassword: string;
- FRealName: string;
- FAccess: TIdUserAccess;
- //
- procedure SetAttributes(const AValue: TStrings);
- procedure SetPassword(const AValue: String); virtual;
- public
- constructor Create(ACollection: TCollection); override;
- destructor Destroy; override;
- //
- function CheckPassword(const APassword: String): Boolean; virtual;
- //
- {$IFDEF USE_OBJECT_ARC}
- property DataObject: TObject read FDataObject write FDataObject;
- property DataValue: PtrInt read FDataValue write FDataValue;
- {$ELSE}
- property Data: TObject read FData write FData;
- {$ENDIF}
- published
- property Access: TIdUserAccess read FAccess write FAccess default IdUserAccountDefaultAccess;
- property Attributes: TStrings read FAttributes write SetAttributes;
- property UserName: string read FUserName write FUserName;
- property Password: string read FPassword write SetPassword;
- property RealName: string read FRealName write FRealName;
- End;//TIdUserAccount
- TIdUserAccounts = class(TOwnedCollection)
- protected
- FCaseSensitiveUsernames: Boolean;
- FCaseSensitivePasswords: Boolean;
- //
- function GetAccount(const AIndex: Integer): TIdUserAccount;
- function GetByUsername(const AUsername: String): TIdUserAccount;
- procedure SetAccount(const AIndex: Integer; AAccountValue: TIdUserAccount);
- public
- function Add: TIdUserAccount; reintroduce;
- constructor Create(AOwner: TIdUserManager);
- //
- property CaseSensitiveUsernames: Boolean read FCaseSensitiveUsernames
- write FCaseSensitiveUsernames;
- property CaseSensitivePasswords: Boolean read FCaseSensitivePasswords
- write FCaseSensitivePasswords;
- property UserNames[const AUserName: String]: TIdUserAccount read GetByUsername; default;
- property Items[const AIndex: Integer]: TIdUserAccount read GetAccount write SetAccount;
- end;//TIdUserAccounts
- TIdUserManager = class(TIdCustomUserManager)
- protected
- FAccounts: TIdUserAccounts;
- //
- procedure DoAuthentication (const AUsername: String; var VPassword: String;
- var VUserHandle: TIdUserHandle; var VUserAccess: TIdUserAccess); override;
- function GetOptions: TIdCustomUserManagerOptions; override;
- procedure SetAccounts(AValue: TIdUserAccounts);
- procedure SetOptions(const AValue: TIdCustomUserManagerOptions); override;
- procedure InitComponent; override;
- public
- destructor Destroy; override;
- published
- property Accounts: TIdUserAccounts read FAccounts write SetAccounts;
- property Options;
- // events
- property OnBeforeAuthentication;
- property OnAfterAuthentication;
- End;//TIdUserManager
- implementation
- uses
- SysUtils;
- { How add UserAccounts to your component:
- 1) property UserAccounts: TIdCustomUserManager read FUserAccounts write SetUserAccounts;
- 2) procedure SetUserAccounts(const AValue: TIdCustomUserManager);
- begin
- if FUserAccounts <> AValue then begin
- if Assigned(FUserAccounts) then begin
- FUserAccounts.RemoveFreeNotification(Self);
- end;
- FUserAccounts := AValue;
- if Assigned(FUserAccounts) then begin
- FUserAccounts.FreeNotification(Self);
- end;
- end;
- end;
- 3) procedure Notification(AComponent: TComponent; Operation: TOperation);
- begin
- ...
- if (Operation = opRemove) and (AComponent = FUserAccounts) then begin
- FUserAccounts := nil;
- end;
- ...
- inherited Notification(AComponent, Operation);
- end;
- 4) ... if Assigned(FUserAccounts) then begin
- FAuthenticated := FUserAccounts.AuthenticateUser(FUsername, ASender.UnparsedParams);
- if FAuthenticated then else
- }
- { TIdCustomUserManager }
- function TIdCustomUserManager.AuthenticateUser(const AUsername, APassword: String): Boolean;
- var
- LUserHandle: TIdUserHandle;
- Begin
- Result := IsRegisteredUser(AuthenticateUser(AUsername, APassword, LUserHandle));
- LogoffUser(LUserHandle);
- End;//AuthenticateUser
- function TIdCustomUserManager.AuthenticateUser(const AUsername, APassword: String; var VUserHandle: TIdUserHandle): TIdUserAccess;
- var
- LPassword: String;
- Begin
- LPassword := APassword;
- VUserHandle := IdUserHandleNone;
- Result := IdUserAccessDenied;
- DoBeforeAuthentication(AUsername, LPassword, VUserHandle, Result);
- DoAuthentication(AUsername, LPassword, VUserHandle, Result);
- DoAfterAuthentication(AUsername, LPassword, VUserHandle, Result);
- End;//
- class function TIdCustomUserManager.IsRegisteredUser(AUserAccess: TIdUserAccess): Boolean;
- Begin
- Result := AUserAccess>=0;
- End;
- procedure TIdCustomUserManager.DoBeforeAuthentication(const AUsername: String; var VPassword: String;
- var VUserHandle: TIdUserHandle; var VUserAccess: TIdUserAccess);
- Begin
- if Assigned(FOnBeforeAuthentication) then begin
- FOnBeforeAuthentication(SELF,AUsername,VPassword,VUserHandle,VUserAccess);
- end;
- End;//
- procedure TIdCustomUserManager.DoAfterAuthentication(const AUsername: String; var VPassword: String;
- var VUserHandle: TIdUserHandle; var VUserAccess: TIdUserAccess);
- Begin
- if Assigned(FOnAfterAuthentication) then begin
- FOnAfterAuthentication(SELF,AUsername,VPassword,VUserHandle,VUserAccess);
- end;
- End;//
- function TIdCustomUserManager.GetOptions: TIdCustomUserManagerOptions;
- Begin
- Result := [];
- End;//
- procedure TIdCustomUserManager.SetOptions(const AValue: TIdCustomUserManagerOptions);
- Begin
- End;
- procedure TIdCustomUserManager.SetDomain(const AValue: String);
- begin
- if FDomain<>AValue then begin
- FDomain := AValue;
- end;
- end;
- procedure TIdCustomUserManager.LogoffUser(AUserHandle: TIdUserHandle);
- Begin
- DoLogoffUser(AUserHandle);
- End;//free resources, unallocate handles, etc...
- //=============================================================================
- procedure TIdCustomUserManager.DoLogoffUser(var VUserHandle: TIdUserHandle);
- Begin
- if Assigned(FOnLogoffUser) then begin
- FOnLogoffUser(SELF, VUserHandle);
- end;
- End;//
- function TIdCustomUserManager.ChallengeUser(var VIsSafe : Boolean;
- const AUserName: String): String;
- begin
- VIsSafe := True;
- Result := '';
- end;
- procedure TIdCustomUserManager.UserDisconnected(const AUser: String);
- begin
- end;
- function TIdCustomUserManager.SendsChallange : Boolean;
- begin
- Result := False;
- end;
- { TIdUserAccount }
- function TIdUserAccount.CheckPassword(const APassword: String): Boolean;
- begin
- if (Collection as TIdUserAccounts).CaseSensitivePasswords then begin
- Result := Password = APassword;
- end else begin
- Result := TextIsSame(Password, APassword);
- end;
- end;
- constructor TIdUserAccount.Create(ACollection: TCollection);
- begin
- inherited Create(ACollection);
- FAttributes := TStringList.Create;
- FAccess := IdUserAccountDefaultAccess;
- end;
- destructor TIdUserAccount.Destroy;
- begin
- FreeAndNil(FAttributes);
- inherited Destroy;
- end;
- procedure TIdUserAccount.SetAttributes(const AValue: TStrings);
- begin
- FAttributes.Assign(AValue);
- end;
- procedure TIdUserAccount.SetPassword(const AValue: String);
- begin
- FPassword := AValue;
- end;
- { TIdUserAccounts }
- constructor TIdUserAccounts.Create(AOwner: TIdUserManager);
- begin
- inherited Create(AOwner, TIdUserAccount);
- end;
- function TIdUserAccounts.GetAccount(const AIndex: Integer): TIdUserAccount;
- begin
- Result := TIdUserAccount(inherited Items[AIndex]);
- end;
- function TIdUserAccounts.GetByUsername(const AUsername: String): TIdUserAccount;
- var
- i: Integer;
- begin
- Result := nil;
- if CaseSensitiveUsernames then begin
- for i := 0 to Count - 1 do begin
- if AUsername = Items[i].UserName then begin
- Result := Items[i];
- Break;
- end;
- end;
- end
- else begin
- for i := 0 to Count - 1 do begin
- if TextIsSame(AUsername, Items[i].UserName) then begin
- Result := Items[i];
- Break;
- end;
- end;
- end;
- end;
- procedure TIdUserAccounts.SetAccount(const AIndex: Integer; AAccountValue: TIdUserAccount);
- begin
- inherited SetItem(AIndex, AAccountValue);
- end;
- function TIdUserAccounts.Add: TIdUserAccount;
- begin
- Result := inherited Add as TIdUserAccount;
- end;
- { IdUserAccounts - Main Component }
- procedure TIdUserManager.InitComponent;
- begin
- inherited;
- FAccounts := TIdUserAccounts.Create(Self);
- end;
- destructor TIdUserManager.Destroy;
- begin
- FreeAndNil(FAccounts);
- inherited Destroy;
- end;
- procedure TIdUserManager.DoAuthentication(const AUsername: String; var VPassword: String;
- var VUserHandle: TIdUserHandle; var VUserAccess: TIdUserAccess);
- var
- LUser: TIdUserAccount;
- begin
- VUserHandle := IdUserHandleNone;
- VUserAccess := IdUserAccessDenied;
- LUser := Accounts[AUsername];
- if Assigned(LUser) then begin
- if LUser.CheckPassword(VPassword) then begin
- VUserHandle := LUser.ID;
- VUserAccess := LUser.Access;
- end;
- end;
- end;
- procedure TIdUserManager.SetAccounts(AValue: TIdUserAccounts);
- begin
- FAccounts.Assign(AValue);
- end;
- function TIdUserManager.GetOptions: TIdCustomUserManagerOptions;
- Begin
- Result := [];
- if FAccounts.CaseSensitiveUsernames then begin
- Include(Result, umoCaseSensitiveUsername);
- end;
- if FAccounts.CaseSensitivePasswords then begin
- Include(Result, umoCaseSensitivePassword);
- end;
- End;//
- procedure TIdUserManager.SetOptions(const AValue: TIdCustomUserManagerOptions);
- Begin
- FAccounts.CaseSensitiveUsernames := umoCaseSensitiveUsername in AValue;
- FAccounts.CaseSensitivePasswords := umoCaseSensitivePassword in AValue;
- End;//
- { TIdSimpleUserManager }
- procedure TIdSimpleUserManager.DoAuthentication(const AUsername: String; var VPassword: String;
- var VUserHandle: TIdUserHandle; var VUserAccess: TIdUserAccess);
- Begin
- if Assigned(FOnAuthentication) then begin
- FOnAuthentication(SELF,AUsername,VPassword,VUserHandle,VUserAccess);
- end;
- End;//
- function TIdSimpleUserManager.GetOptions: TIdCustomUserManagerOptions;
- Begin
- Result := FOptions;
- End;//
- procedure TIdSimpleUserManager.SetOptions(
- const AValue: TIdCustomUserManagerOptions);
- Begin
- FOptions := AValue;
- End;//
- end.
|