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