| … | |
… | |
| 3 | # $Id$ |
3 | # $Id$ |
| 4 | ################################################################################ |
4 | ################################################################################ |
| 5 | |
5 | |
| 6 | package WeBWorK::DB::Auth; |
6 | package WeBWorK::DB::Auth; |
| 7 | |
7 | |
|
|
8 | =head1 NAME |
|
|
9 | |
|
|
10 | WeBWorK::DB::Auth - interface with the WeBWorK authentication/authorization |
|
|
11 | databases. |
|
|
12 | |
|
|
13 | =cut |
|
|
14 | |
|
|
15 | use strict; |
|
|
16 | use warnings; |
| 8 | # there should be a `use' line for each database type |
17 | # there should be a `use' line for each database type |
| 9 | use WeBWorK::DB::GDBM; |
18 | use WeBWorK::DB::GDBM; |
| 10 | |
19 | |
| 11 | # new($invocant, $courseEnv) |
20 | # new($invocant, $courseEnv) |
| 12 | # $invocant implicitly set by caller |
21 | # $invocant implicitly set by caller |
| … | |
… | |
| 19 | my $self = { |
28 | my $self = { |
| 20 | password_file => $courseEnv->{dbInfo}->{auth_passwd_file}, |
29 | password_file => $courseEnv->{dbInfo}->{auth_passwd_file}, |
| 21 | permissions_file => $courseEnv->{dbInfo}->{auth_perm_file}, |
30 | permissions_file => $courseEnv->{dbInfo}->{auth_perm_file}, |
| 22 | keys_file => $courseEnv->{dbInfo}->{auth_keys_file}, |
31 | keys_file => $courseEnv->{dbInfo}->{auth_keys_file}, |
| 23 | key_timeout => $courseEnv->{sessionKeyTimeout}, |
32 | key_timeout => $courseEnv->{sessionKeyTimeout}, |
|
|
33 | permission_hash => $courseEnv->{permissionLevels}, |
| 24 | }; |
34 | }; |
| 25 | $self->{password_db} = $dbModule->new($self->{password_file}); |
35 | $self->{password_db} = $dbModule->new($self->{password_file}); |
| 26 | $self->{permissions_db} = $dbModule->new($self->{permissions_file}); |
36 | $self->{permissions_db} = $dbModule->new($self->{permissions_file}); |
| 27 | $self->{keys_db} = $dbModule->new($self->{keys_file}); |
37 | $self->{keys_db} = $dbModule->new($self->{keys_file}); |
| 28 | bless $self, $class; |
38 | bless $self, $class; |
| … | |
… | |
| 34 | my $package = __PACKAGE__; |
44 | my $package = __PACKAGE__; |
| 35 | $package =~ s/([^:]*)$/$n/; |
45 | $package =~ s/([^:]*)$/$n/; |
| 36 | return $package; |
46 | return $package; |
| 37 | } |
47 | } |
| 38 | |
48 | |
| 39 | =pod |
|
|
| 40 | sub connect($$$) { |
|
|
| 41 | my $self = shift; |
|
|
| 42 | my $db = shift; |
|
|
| 43 | my $mode = shift; |
|
|
| 44 | return if defined $self->{$db."_db"}; |
|
|
| 45 | $self->{$db."_db"} = $self->{dbModule}->new($db."_file", $mode); |
|
|
| 46 | $self->{$db."_db"}->connect(); |
|
|
| 47 | } |
|
|
| 48 | |
|
|
| 49 | sub disconnect($$) { |
|
|
| 50 | my $self = shift; |
|
|
| 51 | my $db = shift; |
|
|
| 52 | return unless defined $self->{$db."_db"}; |
|
|
| 53 | $self->{$db."_db"}->disconnect; |
|
|
| 54 | } |
|
|
| 55 | =cut |
|
|
| 56 | |
|
|
| 57 | # ----- |
49 | # ----- |
| 58 | |
50 | |
| 59 | =pod |
|
|
| 60 | sub getUsers($) { |
51 | sub getUsers($) { |
| 61 | my $self = shift; |
52 | my $self = shift; |
| 62 | my @password_users, @permissions_users, @keys_users; |
53 | my %all_users; |
| 63 | if ($self->{password_db}->connect("ro")) { |
54 | if ($self->{password_db}->connect("ro")) { |
| 64 | @password_users = keys %{$self->{password_db}->hashRef}; |
55 | $all_users{$_}++ foreach keys %{$self->{password_db}->hashRef}; |
| 65 | $self->{password_db}->disconnect; |
56 | $self->{password_db}->disconnect; |
| 66 | } |
57 | } |
| 67 | if ($self->{permissions_db}->connect("ro")) { |
58 | if ($self->{permissions_db}->connect("ro")) { |
| 68 | @permissions_users = keys %{$self->{permissions_db}->hashRef}; |
59 | $all_users{$_}++ foreach keys %{$self->{permissions_db}->hashRef}; |
| 69 | $self->{permissions_db}->disconnect; |
60 | $self->{permissions_db}->disconnect; |
| 70 | } |
61 | } |
| 71 | if ($self->{keys_db}->connect("ro")) { |
62 | if ($self->{keys_db}->connect("ro")) { |
| 72 | @keys_users = keys %{$self->{keys_db}->hashRef}; |
63 | $all_users{$_}++ foreach keys %{$self->{keys_db}->hashRef}; |
| 73 | $self->{keys_db}->disconnect; |
64 | $self->{keys_db}->disconnect; |
| 74 | } |
65 | } |
| 75 | my %all_users; |
|
|
| 76 | foreach (@password_users, @permissions_users, @keys_users) { |
|
|
| 77 | $all_users{$_}++; |
|
|
| 78 | } |
|
|
| 79 | return keys %all_users; |
66 | return keys %all_users; |
| 80 | } |
67 | } |
| 81 | =cut |
|
|
| 82 | |
68 | |
| 83 | # ----- |
69 | # ----- |
| 84 | |
70 | |
| 85 | sub getPassword($$) { |
71 | sub getPassword($$) { |
| 86 | my $self = shift; |
72 | my $self = shift; |
| … | |
… | |
| 125 | my $user = shift; |
111 | my $user = shift; |
| 126 | return unless $self->{keys_db}->connect("ro"); |
112 | return unless $self->{keys_db}->connect("ro"); |
| 127 | my $result = $self->{keys_db}->hashRef->{$user}; |
113 | my $result = $self->{keys_db}->hashRef->{$user}; |
| 128 | $self->{keys_db}->disconnect; |
114 | $self->{keys_db}->disconnect; |
| 129 | my ($key, $timestamp) = defined $result ? split /\s+/, $result : (undef, undef); |
115 | my ($key, $timestamp) = defined $result ? split /\s+/, $result : (undef, undef); |
| 130 | return ($key, $timestamp); |
116 | if (time <= $timestamp+$self->{key_timeout}) { |
|
|
117 | return $key; |
|
|
118 | } else { |
|
|
119 | $self->deleteKey($user); |
|
|
120 | return 0; |
|
|
121 | } |
| 131 | } |
122 | } |
| 132 | |
123 | |
| 133 | sub setKey($$$$) { |
124 | sub setKey($$$) { |
| 134 | my $self = shift; |
125 | my $self = shift; |
| 135 | my $user = shift; |
126 | my $user = shift; |
| 136 | my $key = shift; |
127 | my $key = shift; |
| 137 | my $timestamp = shift; |
|
|
| 138 | my $key_string = "$key $timestamp"; |
|
|
| 139 | $self->{keys_db}->connect("rw"); |
128 | $self->{keys_db}->connect("rw"); |
| 140 | $self->{keys_db}->hashRef->{$user} = $key_string; |
129 | $self->{keys_db}->hashRef->{$user} = "$key " . time; |
| 141 | $self->{keys_db}->disconnect; |
130 | $self->{keys_db}->disconnect; |
| 142 | } |
131 | } |
| 143 | |
132 | |
| 144 | sub verifyKey($$$$$) { |
133 | sub verifyKey($$$) { |
| 145 | my $self = shift; |
134 | my $self = shift; |
| 146 | my $user = shift; |
135 | my $user = shift; |
| 147 | my $key = shift; |
136 | my $key = shift; |
| 148 | my $timestamp = shift; |
|
|
| 149 | my ($real_key, $real_timestamp) = $self->getKey($user); |
137 | my $real_key = $self->getKey($user); |
| 150 | return unless defined $real_key and defined $real_timestamp; |
138 | return unless defined $real_key; |
| 151 | if ($key eq $real_key and $timestamp <= $real_timestamp+$self->{key_timeout}) { |
139 | if ($key eq $real_key) { |
| 152 | # update timestamp |
140 | # update timestamp |
| 153 | $self->setKey($user, $key, $timestamp); |
141 | $self->setKey($user, $real_key); |
| 154 | return 1; |
142 | return 1; |
| 155 | } else { |
143 | } else { |
| 156 | return 0; |
144 | return 0; |
| 157 | } |
145 | } |
| 158 | } |
146 | } |