245 lines
8.5 KiB
Perl
245 lines
8.5 KiB
Perl
# ==================================================================
|
|
# Gossamer Links - enhanced directory management system
|
|
#
|
|
# Website : http://gossamer-threads.com/
|
|
# Support : http://gossamer-threads.com/scripts/support/
|
|
# CVS Info : 087,071,086,086,085
|
|
# Revision : $Id: Authenticate.pm,v 1.34 2008/10/06 17:41:18 brewt Exp $
|
|
#
|
|
# Copyright (c) 2001 Gossamer Threads Inc. All Rights Reserved.
|
|
# Redistribution in part or in whole strictly prohibited. Please
|
|
# see LICENSE file for full details.
|
|
# ==================================================================
|
|
|
|
package Links::Authenticate;
|
|
# ==================================================================
|
|
use strict;
|
|
use Links qw/:objects/;
|
|
use GT::Session::SQL;
|
|
|
|
# This package lets you integrate Gossamer Links into another authentication
|
|
# system. You can do this by replacing the functions with your own
|
|
# code. Note: to return error results, simply set error => message in
|
|
# the passed in hash.
|
|
|
|
sub auth {
|
|
# -----------------------------------------------------------------------------
|
|
# Runs the request auth function through the plugin system.
|
|
#
|
|
shift if UNIVERSAL::isa($_[0], 'Links::Authenticate');
|
|
my ($auth, $args) = @_;
|
|
my $code = exists $Links::Authenticate::{"auth_$auth"}
|
|
? $Links::Authenticate::{"auth_$auth"}
|
|
: die "Invalid Authenticate method 'auth_$auth' called";
|
|
$PLG->dispatch("auth_$auth", $code, $args);
|
|
}
|
|
|
|
sub auth_init {
|
|
# -----------------------------------------------------------------------------
|
|
# This function is guaranteed to be called before any other authentication
|
|
# function, but may be called multiple times during one request.
|
|
#
|
|
return 1;
|
|
}
|
|
|
|
sub auth_add_user {
|
|
# -----------------------------------------------------------------------------
|
|
# This function is called whenever a user is added to the database. It takes a
|
|
# hash reference with Username and Password as input. If there is an error, set
|
|
# $args->{error} to the message.
|
|
#
|
|
my $args = shift;
|
|
return { Username => $args->{Username}, Password => $args->{Password} };
|
|
}
|
|
|
|
sub auth_del_user {
|
|
# -----------------------------------------------------------------------------
|
|
# This function is called whenever a user is trying to be deleted. It returns
|
|
# the username on success, or undef on failure.
|
|
#
|
|
my $args = shift;
|
|
return $args->{Username};
|
|
}
|
|
|
|
sub auth_valid_user {
|
|
# -----------------------------------------------------------------------------
|
|
# This function returns true if the user/pass combo is valid, 0/undef
|
|
# otherwise.
|
|
#
|
|
my $args = shift;
|
|
return int $DB->table('Users')->count({ Username => $args->{Username}, Password => $args->{Password} });
|
|
}
|
|
|
|
sub auth_valid_format {
|
|
# -----------------------------------------------------------------------------
|
|
# This function returns 1 if the user format is valid, undef otherwise.
|
|
#
|
|
my $args = shift;
|
|
my $user = $args->{Username};
|
|
return if length $user > 50 or $user !~ /^[\w\s\-\@\.]+$/;
|
|
return 1;
|
|
}
|
|
|
|
sub auth_change_pass {
|
|
# -----------------------------------------------------------------------------
|
|
# This function takes the username, old pass and new pass and returns 1 if
|
|
# successful, false otherwise.
|
|
#
|
|
my $args = shift;
|
|
return 1;
|
|
}
|
|
|
|
sub auth_get_pass {
|
|
# -----------------------------------------------------------------------------
|
|
# This function returns the password (if available) of a given user, undef
|
|
# otherwise.
|
|
#
|
|
my $args = shift;
|
|
my $user = $args->{Username};
|
|
my $pass = $DB->table('Users')->select(Password => { Username => $user })->fetchrow;
|
|
return $pass;
|
|
}
|
|
|
|
sub auth_get_user {
|
|
# -----------------------------------------------------------------------------
|
|
# This function returns user information for a given user, auto creating if it
|
|
# doesn't exist.
|
|
#
|
|
my $args = shift;
|
|
my $user = $args->{Username};
|
|
my $pass = $args->{Password};
|
|
my $db = $DB->table('Users');
|
|
my $user_r = $db->get($user);
|
|
if (!$user_r and $args->{auto_create}) {
|
|
$user_r->{Username} = $user;
|
|
$user_r->{Password} = defined $pass ? $pass : Links::Authenticate::auth('get_pass', { Username => $user });
|
|
$user_r->{Email} = $user . '@noemail.nodomain';
|
|
$user_r->{ReceiveMail} = 'No';
|
|
$user_r->{Password} = '' unless defined $user_r->{Password};
|
|
my $defaults = $db->default();
|
|
for (keys %$defaults) {
|
|
$user_r->{$_} = $defaults->{$_} unless exists $user_r->{$_};
|
|
}
|
|
$db->insert($user_r) or die "Unable to auto-create user: $user. Reason: $GT::SQL::error";
|
|
}
|
|
return $user_r;
|
|
}
|
|
|
|
sub auth_valid_session {
|
|
# -----------------------------------------------------------------------------
|
|
# This functions checks to see if the session is valid, and returns the
|
|
# username.
|
|
#
|
|
my $args = shift;
|
|
my $session_id = $IN->param('s') || $IN->cookie($CFG->{user_cookie_prefix} . 's') || return;
|
|
my $session;
|
|
unless ($session = GT::Session::SQL->new({
|
|
_debug => $CFG->{debug_level},
|
|
tb => $DB->table('Sessions'),
|
|
session_id => $session_id,
|
|
expires => $CFG->{user_session_length},
|
|
session_data => { sessions => $CFG->{user_sessions}, d => scalar($IN->param('d')) },
|
|
})) { # Possibly an expired session
|
|
GT::Session::SQL->new({
|
|
tb => $DB->table('Sessions'),
|
|
expires => $CFG->{user_session_length}
|
|
})->cleanup; # Clear out old sessions
|
|
return;
|
|
}
|
|
|
|
return $session->{info}->{session_user_id};
|
|
}
|
|
|
|
sub auth_create_session {
|
|
# -----------------------------------------------------------------------------
|
|
# This function creates a session, and prints the header and returns a hash
|
|
# reference with session => $id, and redirect => 0/1.
|
|
#
|
|
my $args = shift;
|
|
my $user = $args->{Username};
|
|
my $remember = ($CFG->{user_sessions} eq 'Cookies' and ($args->{Remember} or $IN->param('Remember')));
|
|
|
|
# Create a new session.
|
|
my $session = GT::Session::SQL->new({
|
|
_debug => $CFG->{debug_level},
|
|
tb => $DB->table('Sessions'),
|
|
session_user_id => $user,
|
|
session_data => { sessions => $CFG->{user_sessions}, d => scalar($IN->param('d')) },
|
|
expires => ($remember ? 0 : $CFG->{user_session_length}),
|
|
});
|
|
|
|
# Clear out old sessions.
|
|
$session->cleanup;
|
|
|
|
# Get session id
|
|
my $session_id = $session->{info}->{session_id};
|
|
|
|
# Now redirect to another URL and set cookies, or set URL string.
|
|
my $url = $IN->param('url');
|
|
my $redirect = 0;
|
|
if ($CFG->{user_sessions} eq 'Cookies') {
|
|
my $session_cookie = $IN->cookie(
|
|
-name => $CFG->{user_cookie_prefix} . 's',
|
|
-value => $session_id,
|
|
-path => '/',
|
|
-domain => $CFG->{user_cookie_domain},
|
|
-expires => ($remember ? '+10y' : '')
|
|
);
|
|
if ($url) {
|
|
print $IN->redirect(-force => 1, -cookie => [$session_cookie], -url => $url);
|
|
$redirect = 1;
|
|
}
|
|
else {
|
|
print $IN->header(-force => 1, -cookie => [$session_cookie]);
|
|
}
|
|
}
|
|
else {
|
|
# If URL sessions are used, then the user will be forced into dynamic mode
|
|
# since there's no way to pass around the session id with the static URLs.
|
|
if ($url) {
|
|
unless ($url =~ s/([;&\?]s=)([^&;]+)/$1$session_id/) {
|
|
$url .= ($url =~ /\?/ ? ';' : '?') . "s=$session_id";
|
|
}
|
|
unless ($url =~ /([;&\?]d=)([^&;]+)/) {
|
|
$url .= ($url =~ /\?/ ? ';' : '?') . "d=1";
|
|
}
|
|
print $IN->redirect($url);
|
|
$redirect = 1;
|
|
}
|
|
else {
|
|
$IN->param(s => $session_id);
|
|
$IN->param(d => 1);
|
|
print $IN->header();
|
|
}
|
|
}
|
|
return { session => $session_id, redirect => $redirect };
|
|
}
|
|
|
|
sub auth_delete_session {
|
|
# -----------------------------------------------------------------------------
|
|
# This function removes a session, returns 1 on success, undef on failure.
|
|
#
|
|
print $IN->header(
|
|
-cookie => $IN->cookie(
|
|
-name => $CFG->{user_cookie_prefix} . 's',
|
|
-value => '',
|
|
-path => '/',
|
|
-domain => $CFG->{user_cookie_domain},
|
|
-expires => '-1y'
|
|
)
|
|
);
|
|
my $session_id = $IN->cookie($CFG->{user_cookie_prefix} . 's') || $IN->param('s') || return;
|
|
|
|
my $session = GT::Session::SQL->new({
|
|
_debug => $CFG->{debug_level},
|
|
tb => $DB->table('Sessions'),
|
|
session_id => $session_id
|
|
}) or return;
|
|
|
|
# Delete the cookie
|
|
$session->delete or return;
|
|
1;
|
|
}
|
|
|
|
1;
|