Mercurial > pub > Impl
diff Lib/Security/Auth.pm @ 0:03e58a454b20
Создан репозитарий
author | Sergey |
---|---|
date | Tue, 14 Jul 2009 12:54:37 +0400 |
parents | |
children | 16ada169ca75 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/Security/Auth.pm Tue Jul 14 12:54:37 2009 +0400 @@ -0,0 +1,108 @@ +package Security::Auth; +use strict; +use Common; +use Security; +use DateTime; +use Digest::MD5 qw(md5_hex); +our @ISA = qw(Object); + +our $Package; +our $DataSource; + +srand time; + +BEGIN { + DeclareProperty DS => ACCESS_READ; + DeclareProperty SecPackage => ACCESS_READ; +} + +{ + my $i = 0; + sub GenSSID() { + return md5_hex(time,rand,$i++); + } +} + +sub CTOR { + my ($this,%args) = @_; + $this->{$DS} = $args{'DS'} or die new Exception('A data source is required'); + $this->{$SecPackage} = $args{'SecPackage'} or die new Exception('A security package is required'); +} + +sub AuthenticateUser { + my ($this,$Name,$SecData) = @_; + + my $User = $this->{$DS}->FindUser($Name); + if (not $User or not $User->Active ) { + return new Security::AuthResult ( + State => Security::AUTH_FAILED, + AuthModule => $this + ); + } else { + + + if (my $StoredData = $this->{$DS}->GetUserAuthData($User,$this->{$SecPackage})) { + my $AuthData = $this->{$SecPackage}->ConstructAuthData($StoredData->AuthData); + if ((my $status = $AuthData->DoAuth($SecData)) != Security::AUTH_FAILED) { + $AuthData = $this->{$SecPackage}->NewAuthData(GenSSID); + return new Security::AuthResult ( + State => $status, + Session => $this->{$DS}->CreateSession(GenSSID,$User,$AuthData), + ClientSecData => $AuthData->ClientAuthData, + AuthModule => $this + ) + } else { + return new Security::AuthResult ( + State => Security::AUTH_FAILED, + AuthModule => $this + ); + } + } else { + # the user isn't allowed to authenticate using this method + return new Security::AuthResult ( + State => Security::AUTH_FAILED, + AuthModule => $this + ); + } + } +} + +sub AuthenticateSession { + my ($this,$SSID,$SecData) = @_; + + my $Session = $this->{$DS}->LoadSession($SSID) or return new Security::AuthResult(State => Security::AUTH_FAILED); + + my $AuthData = $this->{$SecPackage}->ConstructAuthData($Session->SecData); + if ((my $status = $AuthData->DoAuth($SecData)) != Security::AUTH_FAILED) { + $Session->SecData($AuthData->SessionAuthData); + $Session->LastUsage(DateTime->now()); + return new Security::AuthResult(State => $status, Session => $Session, ClientSecData => $AuthData->ClientAuthData, AuthModule => $this); + } else { + $this->{$DS}->CloseSession($Session); + return new Security::AuthResult(State => Security::AUTH_FAILED, AuthModule => $this); + } +} + +sub CreateUser { + my ($this,$uname,$description,$active,$secData) = @_; + + my $user = $this->{$DS}->CreateUser($uname,$description,$active); + $this->{$DS}->SetUserAuthData($user,$this->{$SecPackage},$this->{$SecPackage}->NewAuthData($secData)); + + return $user; +} + +sub try_construct { + my $package = shift; + return $package->can('construct') ? $package->construct() : $package; +} + +sub construct { + $Package or die new Exception('A security package is reqiured'); + $DataSource or die new Exception('A data source is required'); + eval "require $DataSource;" or die new Exception('Failed to load the data source module',$@) if not ref $DataSource; + eval "require $Package;" or die new Exception('Failed to load the security package module',$@) if not ref $Package; + return __PACKAGE__->new(DS => try_construct($DataSource), SecPackage => try_construct($Package)); +} + +1; \ No newline at end of file