Apache2-AuthCookieDBI
view release on metacpan or search on metacpan
lib/Apache2/AuthCookieDBI.pm view on Meta::CPAN
# this order separated by dashes.
sub _now_year_month_day_hour_minute_second {
return sprintf '%04d-%02d-%02d-%02d-%02d-%02d', Today_and_Now;
}
sub _check_password {
my ( $class, $password, $crypted_password, $crypt_type ) = @_;
return
if not $crypted_password
; # https://rt.cpan.org/Public/Bug/Display.html?id=62470
my %password_checker = (
'none' => sub { return $password eq $crypted_password; },
'crypt' => sub {
return crypt( $password, $crypted_password ) eq $crypted_password;
},
'md5' => sub { return md5_hex($password) eq $crypted_password; },
'sha256' => sub {
return Digest::SHA::sha256_hex($password) eq $crypted_password;
},
'sha384' => sub {
return Digest::SHA::sha384_hex($password) eq $crypted_password;
},
'sha512' => sub {
return Digest::SHA::sha512_hex($password) eq $crypted_password;
},
);
return $password_checker{$crypt_type}->();
}
#-------------------------------------------------------------------------------
# _percent_encode -- Percent-encode (like URI encoding) any non-alphanumberics
# in the supplied string.
sub _percent_encode {
my ($str) = @_;
my $not_a_word = qr/ ( \W ) /x;
$str =~ s/$not_a_word/ uc sprintf '%%%02x', ord $1 /xmeg;
return $str;
}
#-------------------------------------------------------------------------------
# _percent_decode -- Percent-decode (like URI decoding) any %XX sequences in
# the supplied string.
sub _percent_decode {
my ($str) = @_;
my $percent_hex_string_regex = qr/ %([0-9a-fA-F]{2}) /x;
$str =~ s/$percent_hex_string_regex/ pack( "c",hex( $1 ) ) /xmge;
return $str;
}
#-------------------------------------------------------------------------------
# _dbi_connect -- Get a database handle.
sub _dbi_connect {
my ( $class, $r, $config_hash ) = @_;
Carp::confess('Failed to pass Apache request object') if not $r;
my ( $pkg, $file, $line, $sub ) = caller(1);
my $info_message = "${class}\t_dbi_connect called in $sub at line $line";
$class->logger( $r, Apache2::Const::LOG_INFO, $info_message, undef,
LOG_TYPE_SYSTEM, $r->uri );
my %c = $config_hash ? %$config_hash : $class->_dbi_config_vars($r);
my $auth_name = $r->auth_name;
# get the crypted password from the users database for this user.
my $dbh = DBI->connect_cached( $c{'DBI_DSN'}, $c{'DBI_User'},
$c{'DBI_Password'} );
if ( defined $dbh ) {
my $info_message
= "${class}\tconnect to $c{'DBI_DSN'} for auth realm $auth_name";
$class->logger( $r, Apache2::Const::LOG_INFO, $info_message, undef,
LOG_TYPE_SYSTEM, $r->uri );
return $dbh;
}
else {
my $error_message
= "${class}\tcouldn't connect to $c{'DBI_DSN'} for auth realm $auth_name";
$class->logger( $r, Apache2::Const::LOG_ERR, $error_message,
LOG_TYPE_SYSTEM, undef, $r->uri );
return;
}
}
#-------------------------------------------------------------------------------
# _get_crypted_password -- Get the users' password from the database.
sub _get_crypted_password {
my ( $class, $r, $user, $config_hash ) = @_;
my %c = $config_hash ? %$config_hash : $class->_dbi_config_vars($r);
my $dbh = $class->_dbi_connect($r, \%c) || return;
my $auth_name = $r->auth_name;
if ( !$class->user_is_active( $r, $user, \%c ) ) {
my $message
= "${class}\tUser '$user' is not active for auth realm $auth_name.";
$class->logger( $r, Apache2::Const::LOG_NOTICE, $message, $user,
LOG_TYPE_AUTH, $r->uri );
return;
}
my $crypted_password = EMPTY_STRING;
my $PasswordField = $dbh->quote_identifier($c{'DBI_PasswordField'});
my $UsersTable = $dbh->quote_identifier($c{'DBI_UsersTable'});
my $UserField = $dbh->quote_identifier($c{'DBI_UserField'});
my $sql_query = <<"SQL";
SELECT $PasswordField
FROM $UsersTable
WHERE $UserField = ?
AND ($PasswordField != ''
AND $PasswordField IS NOT NULL)
SQL
my $sth = $dbh->prepare_cached($sql_query);
unless ( defined $sth ) {
my $message = "${class}\tcouldn\'t prepare statement handle to $c{'DBI_DSN'} for auth realm $auth_name";
lib/Apache2/AuthCookieDBI.pm view on Meta::CPAN
SQL
my $sth = $dbh->prepare_cached($sql_query);
$sth->execute($user);
my ($user_active_setting) = $sth->fetchrow_array;
$sth->finish();
return $user_active_setting;
}
#-------------------------------------------------------------------------------
sub _get_expire_time {
my $session_lifetime = shift;
$session_lifetime = lc $session_lifetime;
my $expire_time = EMPTY_STRING;
if ( $session_lifetime eq 'forever' ) {
$expire_time = '9999-01-01-01-01-01';
# expire time in a zillion years if it's forever.
return $expire_time;
}
my ( $deltaday, $deltahour, $deltaminute, $deltasecond )
= split HYPHEN_REGEX, $session_lifetime;
# Figure out the expire time.
$expire_time = sprintf(
'%04d-%02d-%02d-%02d-%02d-%02d',
Add_Delta_DHMS( Today_and_Now, $deltaday, $deltahour,
$deltaminute, $deltasecond
)
);
return $expire_time;
}
sub logger {
my ( $class, $r, $log_level, $message, $user, $log_type, @extra_args ) = @_;
# $log_level should be an Apache constant, e.g. Apache2::Const::LOG_NOTICE
# Sub-classes should override this method if they want to implent their
# own logging strategy.
#
my @log_args = ( $message, @extra_args );
my %apache_log_method_for_level = (
Apache2::Const::LOG_DEBUG => 'debug',
Apache2::Const::LOG_INFO => 'info',
Apache2::Const::LOG_NOTICE => 'notice',
Apache2::Const::LOG_WARNING => 'warn',
Apache2::Const::LOG_ERR => 'error',
Apache2::Const::LOG_CRIT => 'crit',
Apache2::Const::LOG_ALERT => 'alert',
Apache2::Const::LOG_EMERG => 'emerg',
);
my $log_method = $apache_log_method_for_level{$log_level};
if ( !$log_method ) {
my ( $pkg, $file, $line, $sub ) = caller(1);
$r->log_error(
"Unknown log_level '$log_level' passed to logger() from $sub at line $line in $file "
);
$log_method = 'log_error';
}
$r->log->$log_method(@log_args);
}
1;
__END__
=head1 SUBCLASSING
You can subclass this module to override public functions and change
their behaviour.
=head1 CLASS METHODS
=head2 authen_cred($r, $user, $password, @extra_data)
Take the credentials for a user and check that they match; if so, return
a new session key for this user that can be stored in the cookie.
If there is a problem, return a bogus session key.
=head2 authen_ses_key($r, $encrypted_session_key)
Take a session key and check that it is still valid; if so, return the user.
=head2 decrypt_session_key($r, $encryptiontype, $encrypted_session_key, $secret_key)
Returns the decrypted session key or false on failure.
=head2 extra_session_info($r, $user, $password, @extra_data)
A stub method that you may want to override in a subclass.
This method returns extra fields to add to the session key.
It should return a string consisting of ":field1:field2:field3"
(where each field is preceded by a colon).
The default implementation returns an empty string.
=head2 group($r, $groups_string)
Take a string containing a whitespace-delimited list of groups and make sur
that the current remote user is a member of one of them.
Returns either I<Apache2::Const::HTTP_FORBIDDEN>
or I<Apache2::Const::OK>.
=head2 logger($r, $log_level, $message, $user, $log_type, @extra_args)
Calls one of the I<Apache::Log> methods with:
( $message, @extra_args )
for example, if the I<log_level> is I<Apache2::Const::LOG_DEBUG> then
this method will call:
( run in 2.194 seconds using v1.01-cache-2.11-cpan-6de40a662fe )