File Coverage

blib/lib/CGI/Session/Auth/DBI.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             ###########################################################
2             # CGI::Session::Auth::DBI
3             # Authenticated sessions for CGI scripts
4             ###########################################################
5             #
6             # $Id: DBI.pm 25 2006-02-21 12:07:26Z geewiz $
7             #
8              
9             package CGI::Session::Auth::DBI;
10 1     1   131329 use base qw(CGI::Session::Auth);
  1         4  
  1         225  
11              
12 1     1   26 use 5.008;
  1         4  
  1         37  
13 1     1   6 use strict;
  1         3  
  1         51  
14 1     1   6 use warnings;
  1         2  
  1         33  
15 1     1   6 use Carp;
  1         2  
  1         77  
16 1     1   4651 use DBI;
  0            
  0            
17              
18             our $VERSION = do { q$Revision: 25 $ =~ /Revision: (\d+)/; sprintf "1.%03d", $1; };
19              
20             ###########################################################
21             ###
22             ### general methods
23             ###
24             ###########################################################
25              
26             ###########################################################
27              
28             sub new {
29            
30             ##
31             ## build new class object
32             ##
33            
34             my $class = shift;
35             my ($params) = shift;
36            
37             $class = ref($class) if ref($class);
38            
39             # initialize parent class
40             my $self = $class->SUPER::new($params);
41            
42             #
43             # class specific parameters
44             #
45              
46             # parameter 'DBHandle': use an initialized DBI database handle
47             if ($params->{DBHandle}) {
48             $self->{dbh} = $params->{DBHandle};
49             } else {
50             # parameter 'DSN': DBI data source name
51             my $dsn = $params->{DSN} || croak("No DSN parameter");
52             # parameter 'DBUser': database connection username
53             my $dbuser = $params->{DBUser} || '';
54             # parameter 'DBPasswd': database connection password
55             my $dbpasswd = $params->{DBPasswd} || "";
56             # parameter 'DBAttr': optional database connection attributes
57             my $dbattr = $params->{DBAttr} || {};
58             # database handle
59             $self->{dbh} = DBI->connect($dsn, $dbuser, $dbpasswd, $dbattr) or croak("DB error: " . $DBI::errstr);
60             }
61            
62             # parameter 'EncryptPW': passwords are MD5-encrypted (default 0)
63             $self->{encryptpw} = $params->{EncryptPW} || 0;
64             # parameter 'UserTable': name of user data table
65             $self->{usertable} = $params->{UserTable} || 'auth_user';
66             $self->{usernamefield} = $params->{UsernameField} || 'username';
67             $self->{passwordfield} = $params->{PasswordField} || 'passwd';
68             $self->{useridfield} = $params->{UserIDField} || 'userid';
69             # parameter 'GroupTable': name of user data table
70             $self->{grouptable} = $params->{GroupTable} || 'auth_group';
71             $self->{groupfield} = $params->{GroupField} || 'groupname';
72             $self->{groupuseridfield} = $params->{GroupUserIDField} || 'userid';
73             # parameter 'IPTable': name of ip network table
74             $self->{iptable} = $params->{IPTable} || 'auth_ip';
75             $self->{ipuseridfield} = $params->{IPUserIDField} || 'userid';
76             $self->{ipaddressfield} = $params->{IPAddressField} || 'network';
77             $self->{ipmaskfield} = $params->{IPNetMaskField} || 'netmask';
78            
79             #
80             # class members
81             #
82            
83             # blessed are the greek
84             bless($self, $class);
85            
86             return $self;
87             }
88              
89             ###########################################################
90             ###
91             ### backend specific methods
92             ###
93             ###########################################################
94              
95             ###########################################################
96              
97             sub _login {
98            
99             ##
100             ## check username and password
101             ##
102            
103             my $self = shift;
104             my ($username, $password) = @_;
105            
106             $self->_debug("username: $username, password: $password");
107              
108             if ($self->{encryptpw}) {
109             $password = $self->_encpw($password);
110             $self->_debug("Encrypted password: $password");
111             }
112              
113             my $result = 0;
114            
115             my $query = sprintf(
116             "SELECT * FROM %s WHERE %s = ? AND %s = ?",
117             $self->{usertable},
118             $self->{usernamefield},
119             $self->{passwordfield},
120             );
121             $self->_debug("query: $query");
122             # search for username
123             my $sth = $self->_dbh->prepare($query);
124             $sth->execute($username, $password) or croak $self->_dbh->errstr;
125             if (my $rec = $sth->fetchrow_hashref) {
126             $self->_debug("found user entry");
127             $self->_extractProfile($rec);
128             $result = 1;
129             $self->_info("user '$username' logged in");
130             }
131             $sth->finish;
132            
133             return $result;
134             }
135              
136             ###########################################################
137              
138             sub _ipAuth {
139            
140             ##
141             ## authenticate by the visitors IP address
142             ##
143            
144             my $self = shift;
145            
146             require NetAddr::IP;
147            
148             my $remoteip = new NetAddr::IP($self->_cgi->remote_host);
149             $self->_debug("checking remote IP $remoteip");
150            
151             my $result = 0;
152            
153             my $query = sprintf(
154             "SELECT %s, %s, %s FROM %s",
155             $self->{ipuseridfield},
156             $self->{ipaddressfield},
157             $self->{ipmaskfield},
158             $self->{iptable}
159             );
160             $self->_debug("query: $query");
161            
162             # search for username
163             my $sth = $self->_dbh->prepare($query);
164             $sth->execute or croak $self->_dbh()->errstr;
165             while (my $rec = $sth->fetchrow_hashref) {
166            
167             $self->_debug("compare IP network ", $rec->{$self->{ipaddressfield}}, "/", $rec->{$self->{ipmaskfield}});
168            
169             if ($remoteip->within(new NetAddr::IP( $rec->{$self->{ipaddressfield}}, $rec->{$self->{ipmaskfield}}))) {
170             $self->_debug("we have a winner!");
171             # get user record
172             my $user = $self->_getUserRecord($rec->{$self->{ipuseridfield}});
173             $self->_extractProfile($user);
174             $result = 1;
175             last;
176             }
177             else {
178             $self->_debug("no member of this network");
179             }
180            
181             }
182             $sth->finish;
183            
184             return $result;
185             }
186              
187             ###########################################################
188              
189             sub _loadProfile {
190            
191             ##
192             ## get user profile from database by userid
193             ##
194            
195             my $self = shift;
196             my ($userid) = @_;
197            
198             my $query = sprintf(
199             "SELECT * FROM %s WHERE %s = ?",
200             $self->{usertable},
201             $self->{useridfield}
202             );
203             $self->_debug("query: $query");
204             my $sth = $self->_dbh->prepare($query);
205             $sth->execute($userid) or croak $self->_dbh()->errstr;
206             if (my $rec = $sth->fetchrow_hashref) {
207             $self->_debug("Found user entry");
208             $self->_extractProfile($rec);
209             }
210             $sth->finish;
211             }
212              
213             ###########################################################
214              
215             sub saveProfile {
216              
217             ##
218             ## save probably modified user profile
219             ##
220              
221             my $self = shift;
222            
223             my $query = "UPDATE " . $self->{usertable} . " SET ";
224             my @values;
225             my $first = 1;
226             foreach (keys %{$self->{profile}}) {
227             if ($_ ne $self->{useridfield}) {
228             $query .= (($first) ? '' : ', ') . $_ . " = ?";
229             push @values, $self->{profile}{$_};
230             $first = 0;
231             }
232             }
233             $query .= " WHERE " . $self->{useridfield} . " = ?";
234             $self->_debug("update query: ", $query);
235              
236             my $sth = $self->_dbh()->prepare($query);
237             $sth->execute(@values, $self->{userid}) or croak $self->_dbh()->errstr;
238            
239             }
240              
241             ###########################################################
242              
243             sub isGroupMember {
244            
245             ##
246             ## check if user is in given group
247             ##
248            
249             my $self = shift;
250             my ($group) = @_;
251            
252             $self->_debug("group: $group");
253            
254             my $result = 0;
255            
256             my $query = sprintf(
257             "SELECT * FROM %s WHERE %s = ? AND %s = ?",
258             $self->{grouptable},
259             $self->{groupuseridfield},
260             $self->{groupfield}
261             );
262             $self->_debug("query: $query");
263             $self->_debug("values: $self->{userid}, $group");
264             # search for username
265             my $sth = $self->_dbh->prepare($query);
266             $sth->execute($self->{userid}, $group) or croak $self->_dbh->errstr;
267             if (my $rec = $sth->fetchrow_hashref) {
268             $self->_debug("found group entry");
269             $result = 1;
270             }
271             $sth->finish;
272            
273             return $result;
274             }
275              
276             ###########################################################
277             ###
278             ### internal methods
279             ###
280             ###########################################################
281              
282             ###########################################################
283              
284             sub _dbh {
285            
286             ##
287             ## return database handle
288             ##
289            
290             my $self = shift;
291            
292             return $self->{dbh};
293             }
294              
295             ###########################################################
296              
297             sub _extractProfile {
298            
299             ##
300             ## get user profile from database record
301             ##
302            
303             my $self = shift;
304             my ($rec) = @_;
305            
306             $self->{userid} = $rec->{$self->{useridfield}};
307             foreach ( keys %$rec ) {
308             $self->{profile}{$_} = $rec->{$_};
309             }
310             };
311              
312             ###########################################################
313              
314             sub _getUserRecord {
315            
316             ##
317             ## get user data by user id
318             ##
319            
320             my $self = shift;
321             my ($userid) = @_;
322            
323             $self->_debug("get data for userid: ", $userid);
324            
325             my $query = sprintf(
326             "SELECT * FROM %s WHERE %s = ?",
327             $self->{usertable},
328             $self->{useridfield}
329             );
330             $self->_debug("query: $query");
331             # search for username
332             my $sth = $self->_dbh->prepare($query);
333             $sth->execute($userid) or croak $self->_dbh->errstr;
334            
335             return $sth->fetchrow_hashref;
336             }
337              
338             ###########################################################
339             ###
340             ### end of code, module documentation below
341             ###
342             ###########################################################
343              
344             1;
345             __END__