49
|
1 package Security::Auth;
|
|
2 use strict;
|
|
3 use Common;
|
|
4 use Security;
|
|
5 use DateTime;
|
|
6 use Digest::MD5 qw(md5_hex);
|
|
7 our @ISA = qw(Object);
|
|
8
|
|
9 our $Package;
|
|
10 our $DataSource;
|
|
11
|
|
12 srand time;
|
|
13
|
|
14 BEGIN {
|
|
15 DeclareProperty DS => ACCESS_READ;
|
|
16 DeclareProperty SecPackage => ACCESS_READ;
|
|
17 }
|
|
18
|
|
19 {
|
|
20 my $i = 0;
|
|
21 sub GenSSID() {
|
|
22 return md5_hex(time,rand,$i++);
|
|
23 }
|
|
24 }
|
|
25
|
|
26 sub CTOR {
|
|
27 my ($this,%args) = @_;
|
|
28 $this->{$DS} = $args{'DS'} or die new Exception('A data source is required');
|
|
29 $this->{$SecPackage} = $args{'SecPackage'} or die new Exception('A security package is required');
|
|
30 }
|
|
31
|
|
32 sub AuthenticateUser {
|
|
33 my ($this,$Name,$SecData) = @_;
|
|
34
|
|
35 my $User = $this->{$DS}->FindUser($Name);
|
|
36 if (not $User or not $User->Active ) {
|
|
37 return new Security::AuthResult (
|
|
38 State => Security::AUTH_FAILED,
|
|
39 AuthModule => $this
|
|
40 );
|
|
41 } else {
|
|
42
|
|
43
|
|
44 if (my $StoredData = $this->{$DS}->GetUserAuthData($User,$this->{$SecPackage})) {
|
|
45 my $AuthData = $this->{$SecPackage}->ConstructAuthData($StoredData->AuthData);
|
|
46 if ((my $status = $AuthData->DoAuth($SecData)) != Security::AUTH_FAILED) {
|
|
47 $AuthData = $this->{$SecPackage}->NewAuthData(GenSSID);
|
|
48 return new Security::AuthResult (
|
|
49 State => $status,
|
|
50 Session => $this->{$DS}->CreateSession(GenSSID,$User,$AuthData),
|
|
51 ClientSecData => $AuthData->ClientAuthData,
|
|
52 AuthModule => $this
|
|
53 )
|
|
54 } else {
|
|
55 return new Security::AuthResult (
|
|
56 State => Security::AUTH_FAILED,
|
|
57 AuthModule => $this
|
|
58 );
|
|
59 }
|
|
60 } else {
|
|
61 # the user isn't allowed to authenticate using this method
|
|
62 return new Security::AuthResult (
|
|
63 State => Security::AUTH_FAILED,
|
|
64 AuthModule => $this
|
|
65 );
|
|
66 }
|
|
67 }
|
|
68 }
|
|
69
|
|
70 sub AuthenticateSession {
|
|
71 my ($this,$SSID,$SecData) = @_;
|
|
72
|
|
73 my $Session = $this->{$DS}->LoadSession($SSID) or return new Security::AuthResult(State => Security::AUTH_FAILED);
|
|
74
|
|
75 my $AuthData = $this->{$SecPackage}->ConstructAuthData($Session->SecData);
|
|
76 if ((my $status = $AuthData->DoAuth($SecData)) != Security::AUTH_FAILED) {
|
|
77 $Session->SecData($AuthData->SessionAuthData);
|
|
78 $Session->LastUsage(DateTime->now());
|
|
79 return new Security::AuthResult(State => $status, Session => $Session, ClientSecData => $AuthData->ClientAuthData, AuthModule => $this);
|
|
80 } else {
|
|
81 $this->{$DS}->CloseSession($Session);
|
|
82 return new Security::AuthResult(State => Security::AUTH_FAILED, AuthModule => $this);
|
|
83 }
|
|
84 }
|
|
85
|
|
86 sub CreateUser {
|
|
87 my ($this,$uname,$description,$active,$secData) = @_;
|
|
88
|
|
89 my $user = $this->{$DS}->CreateUser($uname,$description,$active);
|
|
90 $this->{$DS}->SetUserAuthData($user,$this->{$SecPackage},$this->{$SecPackage}->NewAuthData($secData));
|
|
91
|
|
92 return $user;
|
|
93 }
|
|
94
|
|
95 sub try_construct {
|
|
96 my $package = shift;
|
|
97 return $package->can('construct') ? $package->construct() : $package;
|
|
98 }
|
|
99
|
|
100 sub construct {
|
|
101 $Package or die new Exception('A security package is reqiured');
|
|
102 $DataSource or die new Exception('A data source is required');
|
|
103 eval "require $DataSource;" or die new Exception('Failed to load the data source module',$@) if not ref $DataSource;
|
|
104 eval "require $Package;" or die new Exception('Failed to load the security package module',$@) if not ref $Package;
|
|
105 return __PACKAGE__->new(DS => try_construct($DataSource), SecPackage => try_construct($Package));
|
|
106 }
|
|
107
|
|
108 1;
|