Updating session handle to remove explicit phpBB3 dependancy.
This commit is contained in:
parent
901f879bba
commit
a79795d96b
@ -20,12 +20,12 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
## @class
|
## @class
|
||||||
# The SessionHandler class provides cookie-based session facilities for
|
# The SessionHandler class provides cookie-based session facilities for
|
||||||
# maintaining user state over http transactions. This code depends on
|
# maintaining user state over http transactions. This code depends on
|
||||||
# integration with a phpBB3 database: a number of custom tables are needed
|
# integration with a phpBB3 database: a number of custom tables are needed
|
||||||
# (see config docs), but user handling is tied to phpBB3 user tables, and
|
# (see config docs), but user handling is tied to phpBB3 user tables, and
|
||||||
# a number of joins between custom tables and phpBB3 ones require the two
|
# a number of joins between custom tables and phpBB3 ones require the two
|
||||||
# to share database space. This code provides session verification, and
|
# to share database space. This code provides session verification, and
|
||||||
# takes some steps towards ensuring security against cookie hijacking, but
|
# takes some steps towards ensuring security against cookie hijacking, but
|
||||||
# as with any cookie based auth system there is the potential for security
|
# as with any cookie based auth system there is the potential for security
|
||||||
# issues.
|
# issues.
|
||||||
@ -47,7 +47,6 @@ use MIME::Base64;
|
|||||||
use Data::Dumper;
|
use Data::Dumper;
|
||||||
|
|
||||||
# Custom module imports
|
# Custom module imports
|
||||||
use phpBB3;
|
|
||||||
use Logging qw(die_log);
|
use Logging qw(die_log);
|
||||||
|
|
||||||
# Globals...
|
# Globals...
|
||||||
@ -72,7 +71,7 @@ sub new {
|
|||||||
my $self = {
|
my $self = {
|
||||||
cgi => undef,
|
cgi => undef,
|
||||||
dbh => undef,
|
dbh => undef,
|
||||||
phpbb => undef,
|
auth => undef,
|
||||||
template => undef,
|
template => undef,
|
||||||
settings => undef,
|
settings => undef,
|
||||||
@_,
|
@_,
|
||||||
@ -81,7 +80,7 @@ sub new {
|
|||||||
# Ensure that we have objects that we need
|
# Ensure that we have objects that we need
|
||||||
return set_error("cgi object not set") unless($self -> {"cgi"});
|
return set_error("cgi object not set") unless($self -> {"cgi"});
|
||||||
return set_error("dbh object not set") unless($self -> {"dbh"});
|
return set_error("dbh object not set") unless($self -> {"dbh"});
|
||||||
return set_error("phpbb object not set") unless($self -> {"phpbb"});
|
return set_error("auth object not set") unless($self -> {"auth"});
|
||||||
return set_error("template object not set") unless($self -> {"template"});
|
return set_error("template object not set") unless($self -> {"template"});
|
||||||
return set_error("settings object not set") unless($self -> {"settings"});
|
return set_error("settings object not set") unless($self -> {"settings"});
|
||||||
|
|
||||||
@ -98,12 +97,12 @@ sub new {
|
|||||||
|
|
||||||
# Now try to obtain a session id - start by looking at the cookies
|
# Now try to obtain a session id - start by looking at the cookies
|
||||||
$self -> {"sessid"} = $self -> {"cgi"} -> cookie($cookiebase."_sid"); # The session id cookie itself
|
$self -> {"sessid"} = $self -> {"cgi"} -> cookie($cookiebase."_sid"); # The session id cookie itself
|
||||||
$self -> {"sessuser"} = $self -> {"cgi"} -> cookie($cookiebase."_u"); # Which user does this session claim to be for?
|
$self -> {"sessuser"} = $self -> {"cgi"} -> cookie($cookiebase."_u"); # Which user does this session claim to be for?
|
||||||
$self -> {"autokey"} = $self -> {"cgi"} -> cookie($cookiebase."_k"); # Do we have an autologin key for the user?
|
$self -> {"autokey"} = $self -> {"cgi"} -> cookie($cookiebase."_k"); # Do we have an autologin key for the user?
|
||||||
|
|
||||||
# If we don't have a session id now, try to pull it from the query string
|
# If we don't have a session id now, try to pull it from the query string
|
||||||
$self -> {"sessid"} = $self -> {"cgi"} -> param("sid") if(!$self -> {"sessid"});
|
$self -> {"sessid"} = $self -> {"cgi"} -> param("sid") if(!$self -> {"sessid"});
|
||||||
|
|
||||||
# If we have a session id, we need to check it
|
# If we have a session id, we need to check it
|
||||||
if($self -> {"sessid"}) {
|
if($self -> {"sessid"}) {
|
||||||
# Try to get the session...
|
# Try to get the session...
|
||||||
@ -119,9 +118,9 @@ sub new {
|
|||||||
if(!$self -> session_expired($session)) {
|
if(!$self -> session_expired($session)) {
|
||||||
# The session is valid, and can be touched.
|
# The session is valid, and can be touched.
|
||||||
$self -> touch_session($session);
|
$self -> touch_session($session);
|
||||||
|
|
||||||
return $self;
|
return $self;
|
||||||
} # if(!$self -> session_expired($session)) {
|
} # if(!$self -> session_expired($session)) {
|
||||||
} # if($self -> ip_check($ENV{"REMOTE_ADDR"}, $session -> {"session_ip"})) {
|
} # if($self -> ip_check($ENV{"REMOTE_ADDR"}, $session -> {"session_ip"})) {
|
||||||
} # if($session) {
|
} # if($session) {
|
||||||
} # if($sessid) {
|
} # if($sessid) {
|
||||||
@ -133,7 +132,7 @@ sub new {
|
|||||||
|
|
||||||
## @method $ create_session($user, $persist)
|
## @method $ create_session($user, $persist)
|
||||||
# Create a new session. If the user is not specified, this creates an anonymous session,
|
# Create a new session. If the user is not specified, this creates an anonymous session,
|
||||||
# otherwise the session is attached to the user.
|
# otherwise the session is attached to the user.
|
||||||
#
|
#
|
||||||
# @param user Optional user ID to associate with the session.
|
# @param user Optional user ID to associate with the session.
|
||||||
# @param persist If true, and autologins are permitted, an autologin key is generated for
|
# @param persist If true, and autologins are permitted, an autologin key is generated for
|
||||||
@ -147,27 +146,27 @@ sub create_session {
|
|||||||
|
|
||||||
# nuke the cookies, it's the only way to be sure
|
# nuke the cookies, it's the only way to be sure
|
||||||
delete($self -> {"cookies"}) if($self -> {"cookies"});
|
delete($self -> {"cookies"}) if($self -> {"cookies"});
|
||||||
|
|
||||||
# get the current time...
|
# get the current time...
|
||||||
my $now = time();
|
my $now = time();
|
||||||
|
|
||||||
# If persistent logins are not permitted, disable them
|
# If persistent logins are not permitted, disable them
|
||||||
$self -> {"autokey"} = $persist = '' if(!$self -> {"phpbb"} -> get_config("allow_autologin"));
|
$self -> {"autokey"} = $persist = '' if(!$self -> {"auth"} -> get_config("allow_autologin"));
|
||||||
|
|
||||||
# Set a default last visit, might be updated later
|
# Set a default last visit, might be updated later
|
||||||
$self -> {"last_visit"} = $now;
|
$self -> {"last_visit"} = $now;
|
||||||
|
|
||||||
# If we have a key, and a user in the cookies, try to get it
|
# If we have a key, and a user in the cookies, try to get it
|
||||||
if($self -> {"autokey"} && $self -> {"sessuser"} && $self -> {"sessuser"} != $phpBB3::ANONYMOUS) {
|
if($self -> {"autokey"} && $self -> {"sessuser"} && $self -> {"sessuser"} != $self -> {"auth"} -> {"ANONYMOUS"}) {
|
||||||
my $autocheck = $self -> {"dbh"} -> prepare("SELECT u.* FROM ".
|
my $autocheck = $self -> {"dbh"} -> prepare("SELECT u.* FROM ".
|
||||||
$self -> {"phpbb"} -> {"prefix"}."users AS u, ".
|
$self -> {"auth"} -> {"prefix"}."users AS u, ".
|
||||||
$self -> {"settings"} -> {"database"} -> {"keys"}." AS k
|
$self -> {"settings"} -> {"database"} -> {"keys"}." AS k
|
||||||
WHERE u.user_id = ?
|
WHERE u.user_id = ?
|
||||||
AND u.user_type IN (0, 3)
|
AND u.user_type IN (0, 3)
|
||||||
AND k.user_id = u.user_id
|
AND k.user_id = u.user_id
|
||||||
AND k.key_id = ?");
|
AND k.key_id = ?");
|
||||||
$autocheck -> execute($self -> {"sessuser"}, md5_hex($self -> {"autokey"}))
|
$autocheck -> execute($self -> {"sessuser"}, md5_hex($self -> {"autokey"}))
|
||||||
or return set_error("Unable to peform user lookup query\nError was: ".$self -> {"dbh"} -> errstr);
|
or return set_error("Unable to peform user lookup query\nError was: ".$self -> {"dbh"} -> errstr);
|
||||||
|
|
||||||
$userdata = $autocheck -> fetchrow_hashref;
|
$userdata = $autocheck -> fetchrow_hashref;
|
||||||
|
|
||||||
@ -176,11 +175,11 @@ sub create_session {
|
|||||||
$self -> {"autokey"} = '';
|
$self -> {"autokey"} = '';
|
||||||
$self -> {"sessuser"} = $user;
|
$self -> {"sessuser"} = $user;
|
||||||
|
|
||||||
my $userh = $self -> {"dbh"} -> prepare("SELECT * FROM ".$self -> {"phpbb"} -> {"prefix"}."users
|
my $userh = $self -> {"dbh"} -> prepare("SELECT * FROM ".$self -> {"auth"} -> {"prefix"}."users
|
||||||
WHERE user_id = ?
|
WHERE user_id = ?
|
||||||
AND user_type IN (0, 3)");
|
AND user_type IN (0, 3)");
|
||||||
$userh -> execute($self -> {"sessuser"})
|
$userh -> execute($self -> {"sessuser"})
|
||||||
or return set_error("Unable to peform user lookup query\nError was: ".$self -> {"dbh"} -> errstr);
|
or return set_error("Unable to peform user lookup query\nError was: ".$self -> {"dbh"} -> errstr);
|
||||||
|
|
||||||
$userdata = $userh -> fetchrow_hashref;
|
$userdata = $userh -> fetchrow_hashref;
|
||||||
}
|
}
|
||||||
@ -189,12 +188,12 @@ sub create_session {
|
|||||||
# the user doesn't exist, is inactive, or is a bot. Just get the anonymous user
|
# the user doesn't exist, is inactive, or is a bot. Just get the anonymous user
|
||||||
if(!$userdata) {
|
if(!$userdata) {
|
||||||
$self -> {"autokey"} = '';
|
$self -> {"autokey"} = '';
|
||||||
$self -> {"sessuser"} = $phpBB3::ANONYMOUS;
|
$self -> {"sessuser"} = $self -> {"auth"} -> {"ANONYMOUS"};
|
||||||
|
|
||||||
my $userh = $self -> {"dbh"} -> prepare("SELECT * FROM ".$self -> {"phpbb"} -> {"prefix"}."users
|
my $userh = $self -> {"dbh"} -> prepare("SELECT * FROM ".$self -> {"auth"} -> {"prefix"}."users
|
||||||
WHERE user_id = ?");
|
WHERE user_id = ?");
|
||||||
$userh -> execute($self -> {"sessuser"})
|
$userh -> execute($self -> {"sessuser"})
|
||||||
or return set_error("Unable to peform user lookup query\nError was: ".$self -> {"dbh"} -> errstr);
|
or return set_error("Unable to peform user lookup query\nError was: ".$self -> {"dbh"} -> errstr);
|
||||||
|
|
||||||
$userdata = $userh -> fetchrow_hashref;
|
$userdata = $userh -> fetchrow_hashref;
|
||||||
|
|
||||||
@ -209,22 +208,22 @@ sub create_session {
|
|||||||
|
|
||||||
# Fall back on now if we have no last visit time
|
# Fall back on now if we have no last visit time
|
||||||
$self -> {"last_visit"} = $visitr -> [0] if($visitr);
|
$self -> {"last_visit"} = $visitr -> [0] if($visitr);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Determine whether the session can be made persistent (requires the user to be registered, and normal)
|
# Determine whether the session can be made persistent (requires the user to be registered, and normal)
|
||||||
my $is_registered = ($userdata -> {"user_id"} && $userdata -> {"user_id"} != $phpBB3::ANONYMOUS && ($userdata -> {"user_type"} == 0 || $userdata -> {"user_type"} == 3));
|
my $is_registered = ($userdata -> {"user_id"} && $userdata -> {"user_id"} != $self -> {"auth"} -> {"ANONYMOUS"} && ($userdata -> {"user_type"} == 0 || $userdata -> {"user_type"} == 3));
|
||||||
$persist = (($self -> {"autokey"} || $persist) && $is_registered) ? 1 : 0;
|
$persist = (($self -> {"autokey"} || $persist) && $is_registered) ? 1 : 0;
|
||||||
|
|
||||||
# Do we already have a session id? If we do, and it's an anonymous session, we want to nuke it
|
# Do we already have a session id? If we do, and it's an anonymous session, we want to nuke it
|
||||||
if($self -> {"sessid"}) {
|
if($self -> {"sessid"}) {
|
||||||
my $killsess = $self -> {"dbh"} -> prepare("DELETE FROM ".$self -> {"settings"} -> {"database"} -> {"sessions"}.
|
my $killsess = $self -> {"dbh"} -> prepare("DELETE FROM ".$self -> {"settings"} -> {"database"} -> {"sessions"}.
|
||||||
" WHERE session_id = ? AND session_user_id = ?");
|
" WHERE session_id = ? AND session_user_id = ?");
|
||||||
$killsess -> execute($self -> {"sessid"}, $phpBB3::ANONYMOUS)
|
$killsess -> execute($self -> {"sessid"}, $self -> {"auth"} -> {"ANONYMOUS"})
|
||||||
or return set_error("Unable to remove anonymous session\nError was: ".$self -> {"dbh"} -> errstr);
|
or return set_error("Unable to remove anonymous session\nError was: ".$self -> {"dbh"} -> errstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
# generate a new session id. The md5 of a unique ID should be unique enough...
|
# generate a new session id. The md5 of a unique ID should be unique enough...
|
||||||
$self -> {"sessid"} = md5_hex($self -> {"phpbb"} -> unique_id());
|
$self -> {"sessid"} = md5_hex($self -> {"auth"} -> unique_id());
|
||||||
|
|
||||||
# store the time
|
# store the time
|
||||||
$self -> {"session_time"} = $now;
|
$self -> {"session_time"} = $now;
|
||||||
@ -239,7 +238,7 @@ sub create_session {
|
|||||||
$ENV{"REMOTE_ADDR"},
|
$ENV{"REMOTE_ADDR"},
|
||||||
$persist)
|
$persist)
|
||||||
or return set_error("Unable to peform session creation\nError was: ".$self -> {"dbh"} -> errstr);
|
or return set_error("Unable to peform session creation\nError was: ".$self -> {"dbh"} -> errstr);
|
||||||
|
|
||||||
$self -> set_login_key($self -> {"sessuser"}, $ENV{"REMOTE_ADDR"}) if($persist);
|
$self -> set_login_key($self -> {"sessuser"}, $ENV{"REMOTE_ADDR"}) if($persist);
|
||||||
|
|
||||||
return $self;
|
return $self;
|
||||||
@ -261,8 +260,8 @@ sub delete_session {
|
|||||||
|
|
||||||
# If we're not dealing with anonymous, we need to store the visit time,
|
# If we're not dealing with anonymous, we need to store the visit time,
|
||||||
# and nuke any autologin key for the now defunct session
|
# and nuke any autologin key for the now defunct session
|
||||||
if($self -> {"sessuser"} != $phpBB3::ANONYMOUS) {
|
if($self -> {"sessuser"} != $self -> {"auth"} -> {"ANONYMOUS"}) {
|
||||||
|
|
||||||
# If we don't have a session time for some reason, make it now
|
# If we don't have a session time for some reason, make it now
|
||||||
$self -> {"session_time"} = time() if(!$self -> {"session_time"});
|
$self -> {"session_time"} = time() if(!$self -> {"session_time"});
|
||||||
|
|
||||||
@ -281,7 +280,7 @@ sub delete_session {
|
|||||||
" WHERE key_id = ? AND user_id = ?");
|
" WHERE key_id = ? AND user_id = ?");
|
||||||
$nukekeys -> execute(md5_hex($self -> {"autokey"}), $self -> {"sessuser"})
|
$nukekeys -> execute(md5_hex($self -> {"autokey"}), $self -> {"sessuser"})
|
||||||
or return set_error("Unable to remove session key\nError was: ".$self -> {"dbh"} -> errstr);
|
or return set_error("Unable to remove session key\nError was: ".$self -> {"dbh"} -> errstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# clear all the session settings internally for safety
|
# clear all the session settings internally for safety
|
||||||
@ -318,7 +317,7 @@ sub encode_querystring {
|
|||||||
sub decode_querystring {
|
sub decode_querystring {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $query = shift;
|
my $query = shift;
|
||||||
|
|
||||||
# Bomb if we don't have a query, or it is not valid base64
|
# Bomb if we don't have a query, or it is not valid base64
|
||||||
return "" if(!$query || $query =~ m{[^A-Za-z0-9+/=]});
|
return "" if(!$query || $query =~ m{[^A-Za-z0-9+/=]});
|
||||||
|
|
||||||
@ -337,11 +336,11 @@ sub session_cookies {
|
|||||||
# removed before any changes are made... but this shouldn't really be called before
|
# removed before any changes are made... but this shouldn't really be called before
|
||||||
# create_session in reality anyway.
|
# create_session in reality anyway.
|
||||||
if(!$self -> {"cookies"}) {
|
if(!$self -> {"cookies"}) {
|
||||||
my $expires = "+".($self -> {"phpbb"} -> get_config("max_autologin_time") || 365)."d";
|
my $expires = "+".($self -> {"auth"} -> get_config("max_autologin_time") || 365)."d";
|
||||||
my $sesscookie = $self -> create_cookie($self -> {"settings"} -> {"config"} -> {"cookie_name"}.'_sid', $self -> {"sessid"}, $expires);
|
my $sesscookie = $self -> create_cookie($self -> {"settings"} -> {"config"} -> {"cookie_name"}.'_sid', $self -> {"sessid"}, $expires);
|
||||||
my $sessuser = $self -> create_cookie($self -> {"settings"} -> {"config"} -> {"cookie_name"}.'_u', $self -> {"sessuser"}, $expires);
|
my $sessuser = $self -> create_cookie($self -> {"settings"} -> {"config"} -> {"cookie_name"}.'_u', $self -> {"sessuser"}, $expires);
|
||||||
my $sesskey;
|
my $sesskey;
|
||||||
if($self -> {"sessuser"} != $phpBB3::ANONYMOUS) {
|
if($self -> {"sessuser"} != $self -> {"auth"} -> {"ANONYMOUS"}) {
|
||||||
if($self -> {"autokey"}) {
|
if($self -> {"autokey"}) {
|
||||||
$sesskey = $self -> create_cookie($self -> {"settings"} -> {"config"} -> {"cookie_name"}.'_k', $self -> {"autokey"}, $expires);
|
$sesskey = $self -> create_cookie($self -> {"settings"} -> {"config"} -> {"cookie_name"}.'_k', $self -> {"autokey"}, $expires);
|
||||||
}
|
}
|
||||||
@ -363,7 +362,7 @@ sub session_cookies {
|
|||||||
## @method ip_check($userip, $sessip)
|
## @method ip_check($userip, $sessip)
|
||||||
# Checks whether the specified IPs match. The degree of match required depends
|
# Checks whether the specified IPs match. The degree of match required depends
|
||||||
# on the ip_check setting in the SessionHandler object this is called on: 0 means
|
# on the ip_check setting in the SessionHandler object this is called on: 0 means
|
||||||
# that no checking is done, number between 1 and 4 indicate sections of the
|
# that no checking is done, number between 1 and 4 indicate sections of the
|
||||||
# dotted decimal IPs are checked (1 = 127., 2 = 127.0, 3 = 127.0.0., etc)
|
# dotted decimal IPs are checked (1 = 127., 2 = 127.0, 3 = 127.0.0., etc)
|
||||||
#
|
#
|
||||||
# @param userip The IP the user is connecting from.
|
# @param userip The IP the user is connecting from.
|
||||||
@ -375,7 +374,7 @@ sub ip_check {
|
|||||||
my $sessip = shift;
|
my $sessip = shift;
|
||||||
|
|
||||||
# How may IP address segments should be compared?
|
# How may IP address segments should be compared?
|
||||||
my $iplen = $self -> {"phpbb"} -> get_config('ip_check');
|
my $iplen = $self -> {"auth"} -> get_config('ip_check');
|
||||||
|
|
||||||
# bomb immediately if we aren't checking IPs
|
# bomb immediately if we aren't checking IPs
|
||||||
return 1 if($iplen == 0);
|
return 1 if($iplen == 0);
|
||||||
@ -399,10 +398,10 @@ sub session_cleanup {
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
my $now = time();
|
my $now = time();
|
||||||
my $timelimit = $now - $self -> {"phpbb"} -> get_config("session_length");
|
my $timelimit = $now - $self -> {"auth"} -> get_config("session_length");
|
||||||
|
|
||||||
# We only want to run the garbage collect occasionally
|
# We only want to run the garbage collect occasionally
|
||||||
if($self -> {"settings"} -> {"config"} -> {"lastgc"} < $now - $self -> {"phpbb"} -> get_config("session_gc")) {
|
if($self -> {"settings"} -> {"config"} -> {"lastgc"} < $now - $self -> {"auth"} -> get_config("session_gc")) {
|
||||||
# Okay, we're due a garbage collect, update the config to reflect that we're doing it
|
# Okay, we're due a garbage collect, update the config to reflect that we're doing it
|
||||||
$self -> {"settings"} -> set_db_config($self -> {"dbh"}, $self -> {"settings"} -> {"database"} -> {"settings"}, "lastgc", $now);
|
$self -> {"settings"} -> set_db_config($self -> {"dbh"}, $self -> {"settings"} -> {"database"} -> {"settings"}, "lastgc", $now);
|
||||||
|
|
||||||
@ -410,9 +409,9 @@ sub session_cleanup {
|
|||||||
my $nukesess = $self -> {"dbh"} -> prepare("DELETE FROM ".$self -> {"settings"} -> {"database"} -> {"sessions"}.
|
my $nukesess = $self -> {"dbh"} -> prepare("DELETE FROM ".$self -> {"settings"} -> {"database"} -> {"sessions"}.
|
||||||
" WHERE session_user_id = ?
|
" WHERE session_user_id = ?
|
||||||
AND session_time < ?");
|
AND session_time < ?");
|
||||||
$nukesess -> execute($phpBB3::ANONYMOUS, $timelimit)
|
$nukesess -> execute($self -> {"auth"} -> {"ANONYMOUS"}, $timelimit)
|
||||||
or return set_error("Unable to remove expired guest sessions\nError was: ".$self -> {"dbh"} -> errstr);
|
or return set_error("Unable to remove expired guest sessions\nError was: ".$self -> {"dbh"} -> errstr);
|
||||||
|
|
||||||
# now get the most recent expired sessions for each user
|
# now get the most recent expired sessions for each user
|
||||||
my $lastsess = $self -> {"dbh"} -> prepare("SELECT session_user_id,MAX(session_time) FROM ".$self -> {"settings"} -> {"database"} -> {"sessions"}.
|
my $lastsess = $self -> {"dbh"} -> prepare("SELECT session_user_id,MAX(session_time) FROM ".$self -> {"settings"} -> {"database"} -> {"sessions"}.
|
||||||
" WHERE session_time < ?
|
" WHERE session_time < ?
|
||||||
@ -424,7 +423,7 @@ sub session_cleanup {
|
|||||||
my $updatelast;
|
my $updatelast;
|
||||||
if($self -> {"settings"} -> {"database"} -> {"lastvisit"}) {
|
if($self -> {"settings"} -> {"database"} -> {"lastvisit"}) {
|
||||||
$updatelast = $self -> {"dbh"} -> prepare("UPDATE ".$self -> {"settings"} -> {"database"} -> {"lastvisit"}.
|
$updatelast = $self -> {"dbh"} -> prepare("UPDATE ".$self -> {"settings"} -> {"database"} -> {"lastvisit"}.
|
||||||
" SET last_visit = ?
|
" SET last_visit = ?
|
||||||
WHERE user_id = ?");
|
WHERE user_id = ?");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,13 +457,13 @@ sub session_expired {
|
|||||||
|
|
||||||
# If the session is not an autologin session, and the last update was before the session length, it is expired
|
# If the session is not an autologin session, and the last update was before the session length, it is expired
|
||||||
if(!$sessdata -> {"session_autologin"}) {
|
if(!$sessdata -> {"session_autologin"}) {
|
||||||
return 1 if($sessdata -> {"session_time"} < time() - ($self -> {"phpbb"} -> get_config("session_length") + 60));
|
return 1 if($sessdata -> {"session_time"} < time() - ($self -> {"auth"} -> get_config("session_length") + 60));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
my $max_autologin = $self -> {"phpbb"} -> get_config("max_autologin_time");
|
my $max_autologin = $self -> {"auth"} -> get_config("max_autologin_time");
|
||||||
|
|
||||||
# If the session is autologin, and it is older than the max autologin time, or autologin is not enabled, it's expired
|
# If the session is autologin, and it is older than the max autologin time, or autologin is not enabled, it's expired
|
||||||
return 1 if(!$self -> {"phpbb"} -> get_config("allow_autologin") ||
|
return 1 if(!$self -> {"auth"} -> get_config("allow_autologin") ||
|
||||||
($max_autologin && $sessdata -> {"session_time"} < time() - ((86400 * $max_autologin) + 60)));
|
($max_autologin && $sessdata -> {"session_time"} < time() - ((86400 * $max_autologin) + 60)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -474,7 +473,7 @@ sub session_expired {
|
|||||||
|
|
||||||
|
|
||||||
## @method $ get_session($sessid)
|
## @method $ get_session($sessid)
|
||||||
# Obtain the data for the session with the specified session ID. If there is no
|
# Obtain the data for the session with the specified session ID. If there is no
|
||||||
# session with the specified id in the database, this returns undef, otherwise it
|
# session with the specified id in the database, this returns undef, otherwise it
|
||||||
# returns a reference to a hash containing the session data.
|
# returns a reference to a hash containing the session data.
|
||||||
#
|
#
|
||||||
@ -522,7 +521,7 @@ sub set_login_key {
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
my $key = $self -> {"autokey"};
|
my $key = $self -> {"autokey"};
|
||||||
my $key_id = $self -> {"phpbb"} -> unique_id(substr($self -> {"sessid"}, 0, 8));
|
my $key_id = $self -> {"auth"} -> unique_id(substr($self -> {"sessid"}, 0, 8));
|
||||||
|
|
||||||
# If we don't have a key, we want to create a new key in the table
|
# If we don't have a key, we want to create a new key in the table
|
||||||
if(!$key) {
|
if(!$key) {
|
||||||
|
121
phpBB3.pm
121
phpBB3.pm
@ -25,12 +25,12 @@
|
|||||||
# a perl script low-level access to the data stored in a phpBB3 database,
|
# a perl script low-level access to the data stored in a phpBB3 database,
|
||||||
# and they should be used with caution. Unlike phpBB3, no security checks
|
# and they should be used with caution. Unlike phpBB3, no security checks
|
||||||
# are done on, for example, whether the user is supposed to be able to see
|
# are done on, for example, whether the user is supposed to be able to see
|
||||||
# a topic in a forum: while it would be technically possible to achieve
|
# a topic in a forum: while it would be technically possible to achieve
|
||||||
# this, it would add a dramatic overhead to the listing and fetching of
|
# this, it would add a dramatic overhead to the listing and fetching of
|
||||||
# posts and would involve session shenanigans to ensure users are logged
|
# posts and would involve session shenanigans to ensure users are logged
|
||||||
# into a phpBB3 account.
|
# into a phpBB3 account.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
package phpBB3;
|
package phpBB3;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
@ -84,7 +84,7 @@ BEGIN {
|
|||||||
"e" => "%Z",
|
"e" => "%Z",
|
||||||
"I" => "", # UNSUPPORTED: (capital i) Whether or not the date is in daylight saving time 1 if Daylight Saving Time, 0 otherwise.
|
"I" => "", # UNSUPPORTED: (capital i) Whether or not the date is in daylight saving time 1 if Daylight Saving Time, 0 otherwise.
|
||||||
"O" => "%z",
|
"O" => "%z",
|
||||||
"P" => "", # UNSUPPORTED: Difference to Greenwich time (GMT) with colon between hours and minutes (added in PHP 5.1.3)
|
"P" => "", # UNSUPPORTED: Difference to Greenwich time (GMT) with colon between hours and minutes (added in PHP 5.1.3)
|
||||||
"T" => "%Z",
|
"T" => "%Z",
|
||||||
"Z" => "", # UNSUPPORTED: Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive.
|
"Z" => "", # UNSUPPORTED: Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive.
|
||||||
"c" => "%FT%T%z",
|
"c" => "%FT%T%z",
|
||||||
@ -114,7 +114,7 @@ BEGIN {
|
|||||||
# you do not need to provide the username, password, or data_src.
|
# you do not need to provide the username, password, or data_src.
|
||||||
#
|
#
|
||||||
# @param args A hash of key, value pairs to initialise the object with.
|
# @param args A hash of key, value pairs to initialise the object with.
|
||||||
# @return A new phpBB3 object, or undef if no database connection has been provided or
|
# @return A new phpBB3 object, or undef if no database connection has been provided or
|
||||||
# established.
|
# established.
|
||||||
sub new {
|
sub new {
|
||||||
my $invocant = shift;
|
my $invocant = shift;
|
||||||
@ -130,6 +130,7 @@ sub new {
|
|||||||
allowanon => 0,
|
allowanon => 0,
|
||||||
dbopts => { RaiseError => 0, AutoCommit => 1 },
|
dbopts => { RaiseError => 0, AutoCommit => 1 },
|
||||||
url => "/",
|
url => "/",
|
||||||
|
ANONYMOUS => $ANONYMOUS,
|
||||||
@_,
|
@_,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -139,7 +140,7 @@ sub new {
|
|||||||
# try to open the database connection with those credentials.
|
# try to open the database connection with those credentials.
|
||||||
if(!$obj -> {"dbh"} && $self -> {"username"} & $obj -> {"password"} && $obj -> {"data_src"}) {
|
if(!$obj -> {"dbh"} && $self -> {"username"} & $obj -> {"password"} && $obj -> {"data_src"}) {
|
||||||
$obj -> {"dbh"} = DBI -> connect($obj -> {"data_src"},
|
$obj -> {"dbh"} = DBI -> connect($obj -> {"data_src"},
|
||||||
$obj -> {"username"},
|
$obj -> {"username"},
|
||||||
$obj -> {"password"},
|
$obj -> {"password"},
|
||||||
$obj -> {"dbopts"})
|
$obj -> {"dbopts"})
|
||||||
or return set_error("Unable to open database connection - ".$DBI::errstr);
|
or return set_error("Unable to open database connection - ".$DBI::errstr);
|
||||||
@ -221,10 +222,10 @@ sub register_user {
|
|||||||
my $content = $www -> content();
|
my $content = $www -> content();
|
||||||
return "Unexpected content in response to registration first step accept."
|
return "Unexpected content in response to registration first step accept."
|
||||||
unless($content =~ /PLEASE DO NOT ATTEMPT TO REGISTER USING THIS FORM/);
|
unless($content =~ /PLEASE DO NOT ATTEMPT TO REGISTER USING THIS FORM/);
|
||||||
|
|
||||||
$www -> form_id('register')
|
$www -> form_id('register')
|
||||||
or return "Unable to locate the second step registration form.";
|
or return "Unable to locate the second step registration form.";
|
||||||
|
|
||||||
# Now we can fill in fields to submit
|
# Now we can fill in fields to submit
|
||||||
$www -> field ('username' , $args -> {"username"});
|
$www -> field ('username' , $args -> {"username"});
|
||||||
$www -> field ('email' , $args -> {"email"});
|
$www -> field ('email' , $args -> {"email"});
|
||||||
@ -235,7 +236,7 @@ sub register_user {
|
|||||||
$www -> field ('question2' , 'chris page');
|
$www -> field ('question2' , 'chris page');
|
||||||
$www -> select('lang' , 'en');
|
$www -> select('lang' , 'en');
|
||||||
$www -> select('tz' , '0');
|
$www -> select('tz' , '0');
|
||||||
|
|
||||||
# And submit that
|
# And submit that
|
||||||
$www -> click('submit');
|
$www -> click('submit');
|
||||||
return "Failed when posting registration second step. Response was: ".$www -> res -> message if(!$www -> success());
|
return "Failed when posting registration second step. Response was: ".$www -> res -> message if(!$www -> success());
|
||||||
@ -334,7 +335,7 @@ sub get_group {
|
|||||||
# group_id - the id of the group to check in.
|
# group_id - the id of the group to check in.
|
||||||
# If user_id is specified, username is ignored if it is also provided. If user_id
|
# If user_id is specified, username is ignored if it is also provided. If user_id
|
||||||
# is not provided, username must be (ie: you must specify at least one of username
|
# is not provided, username must be (ie: you must specify at least one of username
|
||||||
# or user_id, and user_id takes precedence) Similarly, you must specify at least
|
# or user_id, and user_id takes precedence) Similarly, you must specify at least
|
||||||
# one of group or group_id, and group_id takes precedence over group.
|
# one of group or group_id, and group_id takes precedence over group.
|
||||||
#
|
#
|
||||||
# @param args A hash of arguments.
|
# @param args A hash of arguments.
|
||||||
@ -356,38 +357,38 @@ sub user_in_group {
|
|||||||
|
|
||||||
# If we don't have a user_id, we need to look it up
|
# If we don't have a user_id, we need to look it up
|
||||||
if(!$args{"user_id"}) {
|
if(!$args{"user_id"}) {
|
||||||
my $user = $self -> get_user($args{'username'})
|
my $user = $self -> get_user($args{'username'})
|
||||||
or return set_error("Unable to find user $args{'username'}");
|
or return set_error("Unable to find user $args{'username'}");
|
||||||
$args{"user_id"} = $user -> {"user_id"};
|
$args{"user_id"} = $user -> {"user_id"};
|
||||||
}
|
}
|
||||||
|
|
||||||
# If we don't have a group_id, we need to look it up
|
# If we don't have a group_id, we need to look it up
|
||||||
if(!$args{"group_id"}) {
|
if(!$args{"group_id"}) {
|
||||||
my $group = $self -> get_group($args{'group'})
|
my $group = $self -> get_group($args{'group'})
|
||||||
or return set_error("Unable to find user $args{'group'}");
|
or return set_error("Unable to find user $args{'group'}");
|
||||||
$args{"group_id"} = $group -> {"group_id"};
|
$args{"group_id"} = $group -> {"group_id"};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Now we should have a user id and group id, so we can go look in the user_group table
|
# Now we should have a user id and group id, so we can go look in the user_group table
|
||||||
my $ugh = $self -> {"dbh"} -> prepare("SELECT * FROM ".$self -> {"prefix"}."user_group
|
my $ugh = $self -> {"dbh"} -> prepare("SELECT * FROM ".$self -> {"prefix"}."user_group
|
||||||
WHERE group_id = ? AND user_id = ?");
|
WHERE group_id = ? AND user_id = ?");
|
||||||
$ugh -> execute($args{"group_id"}, $args{"user_id"})
|
$ugh -> execute($args{"group_id"}, $args{"user_id"})
|
||||||
or die "phpBB3::user_in_group(): Unable to execute user_group lookup query.\nError was: ".$self -> {"dbh"} -> errstr."\n";
|
or die "phpBB3::user_in_group(): Unable to execute user_group lookup query.\nError was: ".$self -> {"dbh"} -> errstr."\n";
|
||||||
|
|
||||||
# Do we have one or more rows?
|
# Do we have one or more rows?
|
||||||
my $ugr = $ugh -> fetchrow_arrayref();
|
my $ugr = $ugh -> fetchrow_arrayref();
|
||||||
|
|
||||||
return defined($ugr);
|
return defined($ugr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
## @method $ valid_user($username, $password)
|
## @method $ valid_user($username, $password)
|
||||||
# Attempt to confirm whether the provided user credentials are valid. This will check
|
# Attempt to confirm whether the provided user credentials are valid. This will check
|
||||||
# whether the specified username corresponds to a valid user, and if it does it will
|
# whether the specified username corresponds to a valid user, and if it does it will
|
||||||
# check that the hash of the provided password matches. If the password matches, this
|
# check that the hash of the provided password matches. If the password matches, this
|
||||||
# returns a reference to a hash containing the user's entry in the users table.
|
# returns a reference to a hash containing the user's entry in the users table.
|
||||||
#
|
#
|
||||||
# @param username The username of the user to check.
|
# @param username The username of the user to check.
|
||||||
# @param password The password to check against this user.
|
# @param password The password to check against this user.
|
||||||
# @return A reference to a hash containing the user's data, or undef if an error
|
# @return A reference to a hash containing the user's data, or undef if an error
|
||||||
@ -422,8 +423,8 @@ sub get_profile_url {
|
|||||||
|
|
||||||
|
|
||||||
## @method $ email_in_use($email)
|
## @method $ email_in_use($email)
|
||||||
# Determine whether the specified email address is already in use within the
|
# Determine whether the specified email address is already in use within the
|
||||||
# system.
|
# system.
|
||||||
#
|
#
|
||||||
# @param email The email address to check.
|
# @param email The email address to check.
|
||||||
# @return true if the email address already exists within the database, false
|
# @return true if the email address already exists within the database, false
|
||||||
@ -432,7 +433,7 @@ sub email_in_use {
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $email = shift;
|
my $email = shift;
|
||||||
|
|
||||||
my $emailh = $self -> {'dbh'} -> prepare("SELECT user_id FROM ".$self -> {"prefix"}."users
|
my $emailh = $self -> {'dbh'} -> prepare("SELECT user_id FROM ".$self -> {"prefix"}."users
|
||||||
WHERE user_email LIKE ?");
|
WHERE user_email LIKE ?");
|
||||||
$emailh -> execute($email)
|
$emailh -> execute($email)
|
||||||
or die "phpBB3::email_in_use(): Unable to execute email lookup query.\nError was: ".$self -> {"dbh"} -> errstr."\n";
|
or die "phpBB3::email_in_use(): Unable to execute email lookup query.\nError was: ".$self -> {"dbh"} -> errstr."\n";
|
||||||
@ -485,16 +486,16 @@ sub is_valid_password {
|
|||||||
# Session handling
|
# Session handling
|
||||||
|
|
||||||
## @method @ get_session(void)
|
## @method @ get_session(void)
|
||||||
# Attempt to obtain the userid and username of the current session user. This
|
# Attempt to obtain the userid and username of the current session user. This
|
||||||
# attempts to determine whether the session in the user's cookies is a valid
|
# attempts to determine whether the session in the user's cookies is a valid
|
||||||
# phpBB3 session, and if it is it returns a reference to a hash containing user
|
# phpBB3 session, and if it is it returns a reference to a hash containing user
|
||||||
# and session data. This will update the timestamp on the session, if needed.
|
# and session data. This will update the timestamp on the session, if needed.
|
||||||
#
|
#
|
||||||
# @return A reference to a hash containing user and session data if the session
|
# @return A reference to a hash containing user and session data if the session
|
||||||
# is valid, undef otherwise.
|
# is valid, undef otherwise.
|
||||||
#
|
#
|
||||||
# @todo This does not currently support forwarded_for checks, referer checks,
|
# @todo This does not currently support forwarded_for checks, referer checks,
|
||||||
# or load limiting. It also does not support 'alternative' auth methods:
|
# or load limiting. It also does not support 'alternative' auth methods:
|
||||||
# only database auth is supported.
|
# only database auth is supported.
|
||||||
sub get_session {
|
sub get_session {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
@ -505,7 +506,7 @@ sub get_session {
|
|||||||
|
|
||||||
# First, try to obtain a session id - start by looking at the cookies
|
# First, try to obtain a session id - start by looking at the cookies
|
||||||
my $sessid = $self -> {"cgi"} -> cookie($cookiebase."_sid");
|
my $sessid = $self -> {"cgi"} -> cookie($cookiebase."_sid");
|
||||||
my $sessuser = $self -> {"cgi"} -> cookie($cookiebase."_u"); # Which users does this session claim to be?
|
my $sessuser = $self -> {"cgi"} -> cookie($cookiebase."_u"); # Which users does this session claim to be?
|
||||||
my $autokey = $self -> {"cgi"} -> cookie($cookiebase."_k"); # Do we have an autologin key for the user?
|
my $autokey = $self -> {"cgi"} -> cookie($cookiebase."_k"); # Do we have an autologin key for the user?
|
||||||
|
|
||||||
# If we don't have a session id now, try to pull it from the query string
|
# If we don't have a session id now, try to pull it from the query string
|
||||||
@ -515,13 +516,13 @@ sub get_session {
|
|||||||
return set_error("Unable to obtain a session id for user.") if(!$sessid);
|
return set_error("Unable to obtain a session id for user.") if(!$sessid);
|
||||||
|
|
||||||
# Obtain the session and user record from the database
|
# Obtain the session and user record from the database
|
||||||
my $sessh = $self -> {"dbh"} -> prepare("SELECT u.*,s.*
|
my $sessh = $self -> {"dbh"} -> prepare("SELECT u.*,s.*
|
||||||
FROM ".$self -> {"prefix"}."users AS u, ".$self -> {"prefix"}."sessions AS s
|
FROM ".$self -> {"prefix"}."users AS u, ".$self -> {"prefix"}."sessions AS s
|
||||||
WHERE s.session_id = ? AND u.user_id = s.session_user_id");
|
WHERE s.session_id = ? AND u.user_id = s.session_user_id");
|
||||||
$sessh -> execute($sessid)
|
$sessh -> execute($sessid)
|
||||||
or die "phpBB3::get_session(): Unable to obtain session and user data from database.\nError was: ".$self -> {"dbh"} -> errstr."\n";
|
or die "phpBB3::get_session(): Unable to obtain session and user data from database.\nError was: ".$self -> {"dbh"} -> errstr."\n";
|
||||||
my $sessdata = $sessh -> fetchrow_hashref();
|
my $sessdata = $sessh -> fetchrow_hashref();
|
||||||
|
|
||||||
# if we have a session, we need to validate it
|
# if we have a session, we need to validate it
|
||||||
if($sessdata) {
|
if($sessdata) {
|
||||||
# If we have anonymous disabled, at this is the anon user, exit immediately
|
# If we have anonymous disabled, at this is the anon user, exit immediately
|
||||||
@ -546,7 +547,7 @@ sub get_session {
|
|||||||
if($self -> get_config("browser_check")) {
|
if($self -> get_config("browser_check")) {
|
||||||
$valid_ua = substr(lc($sessdata -> {"session_browser"}), 0, 150) eq
|
$valid_ua = substr(lc($sessdata -> {"session_browser"}), 0, 150) eq
|
||||||
substr(lc($self -> {"cgi"} -> user_agent()), 0, 150);
|
substr(lc($self -> {"cgi"} -> user_agent()), 0, 150);
|
||||||
}
|
}
|
||||||
|
|
||||||
# If the ip and browser checks are okay, continue with the validation
|
# If the ip and browser checks are okay, continue with the validation
|
||||||
# TODO: add referer and forwarded_for checks here?
|
# TODO: add referer and forwarded_for checks here?
|
||||||
@ -560,17 +561,17 @@ sub get_session {
|
|||||||
# If the session claims to be autologin, but the server doesn't support it, expire the session
|
# If the session claims to be autologin, but the server doesn't support it, expire the session
|
||||||
} elsif(!$self -> get_config("allow_autologin")) {
|
} elsif(!$self -> get_config("allow_autologin")) {
|
||||||
$expired = 1;
|
$expired = 1;
|
||||||
|
|
||||||
# Otherwise, if check whether a maximum autologin time limit has been set, and that the session is within it
|
# Otherwise, if check whether a maximum autologin time limit has been set, and that the session is within it
|
||||||
} else {
|
} else {
|
||||||
my $max_autologin = $self -> get_config("max_autologin_time");
|
my $max_autologin = $self -> get_config("max_autologin_time");
|
||||||
$expired = ($max_autologin && $sessdata -> {"session_time"} < (time() - ($max_autologin + 60)));
|
$expired = ($max_autologin && $sessdata -> {"session_time"} < (time() - ($max_autologin + 60)));
|
||||||
}
|
}
|
||||||
|
|
||||||
# If the session has not expired, we want to touch it
|
# If the session has not expired, we want to touch it
|
||||||
if(!$expired) {
|
if(!$expired) {
|
||||||
if(time() - $sessdata -> {"session_time"} > 60) {
|
if(time() - $sessdata -> {"session_time"} > 60) {
|
||||||
my $touch = $self -> {"dbh"} -> prepare("UPDATE ".$self -> {"prefix"}."sessions
|
my $touch = $self -> {"dbh"} -> prepare("UPDATE ".$self -> {"prefix"}."sessions
|
||||||
SET session_time = ?
|
SET session_time = ?
|
||||||
WHERE session_id = ?");
|
WHERE session_id = ?");
|
||||||
$touch -> execute(time(), $sessdata -> {"session_id"})
|
$touch -> execute(time(), $sessdata -> {"session_id"})
|
||||||
@ -602,9 +603,9 @@ sub get_session {
|
|||||||
#
|
#
|
||||||
# @note <b>This function does no permissions checking whatsoever.</b> It is up
|
# @note <b>This function does no permissions checking whatsoever.</b> It is up
|
||||||
# to the caller to determine whether or not the forum should be visible.
|
# to the caller to determine whether or not the forum should be visible.
|
||||||
# If you expose private forums with this function, you have nobody to
|
# If you expose private forums with this function, you have nobody to
|
||||||
# blame but yourself. You have been warned.
|
# blame but yourself. You have been warned.
|
||||||
#
|
#
|
||||||
# @param forumid The id of the forum to obtain data on.
|
# @param forumid The id of the forum to obtain data on.
|
||||||
# @return A reference to a hash containing the forum data, or undef if the
|
# @return A reference to a hash containing the forum data, or undef if the
|
||||||
# forum does not exist in the database.
|
# forum does not exist in the database.
|
||||||
@ -629,21 +630,21 @@ sub get_forum {
|
|||||||
# Given a forum id, a topic count, and an offset, obtain a list of topic IDs
|
# Given a forum id, a topic count, and an offset, obtain a list of topic IDs
|
||||||
# for topics in the forum. This follows the same treatement of posts as the forum
|
# for topics in the forum. This follows the same treatement of posts as the forum
|
||||||
# view in phpBB3: announcements always appear at the start of the list, regardles
|
# view in phpBB3: announcements always appear at the start of the list, regardles
|
||||||
# of the offset. The remaining posts are sorted so that sticky topics will
|
# of the offset. The remaining posts are sorted so that sticky topics will
|
||||||
# appear before normal topics, but are otherwise treated normally.
|
# appear before normal topics, but are otherwise treated normally.
|
||||||
#
|
#
|
||||||
# @note <b>This function does no permissions checking whatsoever.</b> It is up
|
# @note <b>This function does no permissions checking whatsoever.</b> It is up
|
||||||
# to the caller to determine whether or not the forum should be visible.
|
# to the caller to determine whether or not the forum should be visible.
|
||||||
# If you expose private forums with this function, you have nobody to
|
# If you expose private forums with this function, you have nobody to
|
||||||
# blame but yourself. You have been warned.
|
# blame but yourself. You have been warned.
|
||||||
#
|
#
|
||||||
# @param forum The ID of the forum to obtain a topic list for.
|
# @param forum The ID of the forum to obtain a topic list for.
|
||||||
# @param count The number of topics ids to return, if not specified defaults to 10.
|
# @param count The number of topics ids to return, if not specified defaults to 10.
|
||||||
# if set to 0, all post ids are returned.
|
# if set to 0, all post ids are returned.
|
||||||
# @param offset The number of posts to skip, if not specified defaults to 0. This is
|
# @param offset The number of posts to skip, if not specified defaults to 0. This is
|
||||||
# ignored if count is set to 0.
|
# ignored if count is set to 0.
|
||||||
# @param sort_by_last If true, posts are sorted by the last reply time rather
|
# @param sort_by_last If true, posts are sorted by the last reply time rather
|
||||||
# than the default creation time order (note that this must
|
# than the default creation time order (note that this must
|
||||||
# be true to generate the same listing phpBB3 shows)
|
# be true to generate the same listing phpBB3 shows)
|
||||||
# @return A reference to an array of topic ids, or undef if no topics are available
|
# @return A reference to an array of topic ids, or undef if no topics are available
|
||||||
# or an error ocurred.
|
# or an error ocurred.
|
||||||
@ -677,7 +678,7 @@ sub get_topic_ids {
|
|||||||
# always having announcements at the front.
|
# always having announcements at the front.
|
||||||
my $announceh = $self -> {"dbh"} -> prepare("SELECT topic_id FROM ".$self -> {"prefix"}."topics
|
my $announceh = $self -> {"dbh"} -> prepare("SELECT topic_id FROM ".$self -> {"prefix"}."topics
|
||||||
WHERE forum_id = ? AND topic_type = 2
|
WHERE forum_id = ? AND topic_type = 2
|
||||||
$order
|
$order
|
||||||
".($fetchall ? "" : "LIMIT $count"));
|
".($fetchall ? "" : "LIMIT $count"));
|
||||||
$announceh -> execute($forum)
|
$announceh -> execute($forum)
|
||||||
or die "phpBB3::get_topic_ids(): Unable to obtain announcement topic list.\nError was: ".$self -> {"dbh"} -> errstr."\n";
|
or die "phpBB3::get_topic_ids(): Unable to obtain announcement topic list.\nError was: ".$self -> {"dbh"} -> errstr."\n";
|
||||||
@ -707,7 +708,7 @@ sub get_topic_ids {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} # if($count) {
|
} # if($count) {
|
||||||
|
|
||||||
# And we're done. Return a reference to the topics array if it has any contents,
|
# And we're done. Return a reference to the topics array if it has any contents,
|
||||||
# undef if it does not.
|
# undef if it does not.
|
||||||
return scalar(@topics) ? \@topics : set_error("");
|
return scalar(@topics) ? \@topics : set_error("");
|
||||||
@ -717,7 +718,7 @@ sub get_topic_ids {
|
|||||||
## @method $ get_topic($topicid)
|
## @method $ get_topic($topicid)
|
||||||
# Obtain the data for the topic identified by the specified topicid. This will attempt
|
# Obtain the data for the topic identified by the specified topicid. This will attempt
|
||||||
# to locate a topic entry with the specified topicid and return a reference to a hash
|
# to locate a topic entry with the specified topicid and return a reference to a hash
|
||||||
# containing the topic information.
|
# containing the topic information.
|
||||||
#
|
#
|
||||||
# @param topicid The id of the topic to look up.
|
# @param topicid The id of the topic to look up.
|
||||||
# @return A reference to a hash containing the topic data, undef if the topic could
|
# @return A reference to a hash containing the topic data, undef if the topic could
|
||||||
@ -754,7 +755,7 @@ sub get_topic_firstpost {
|
|||||||
or return set_error("Unable to locate topic $topicid in the database");
|
or return set_error("Unable to locate topic $topicid in the database");
|
||||||
|
|
||||||
# Now we can obtain the first post and user details
|
# Now we can obtain the first post and user details
|
||||||
my $posth = $self -> {"dbh"} -> prepare("SELECT p.*, u.*
|
my $posth = $self -> {"dbh"} -> prepare("SELECT p.*, u.*
|
||||||
FROM ".$self -> {"prefix"}."posts AS p, ".$self -> {"prefix"}."users AS u
|
FROM ".$self -> {"prefix"}."posts AS p, ".$self -> {"prefix"}."users AS u
|
||||||
WHERE p.post_id = ? AND u.user_id = p.poster_id");
|
WHERE p.post_id = ? AND u.user_id = p.poster_id");
|
||||||
$posth -> execute($topic -> {"topic_first_post_id"})
|
$posth -> execute($topic -> {"topic_first_post_id"})
|
||||||
@ -774,15 +775,15 @@ sub get_topic_firstpost {
|
|||||||
"post_uid" => $post -> {"bbcode_uid"},
|
"post_uid" => $post -> {"bbcode_uid"},
|
||||||
"poster_username" => $post -> {"username"},
|
"poster_username" => $post -> {"username"},
|
||||||
"poster_userid" => $post -> {"user_id"}};
|
"poster_userid" => $post -> {"user_id"}};
|
||||||
|
|
||||||
# If the user has an avatar, we want to record it. Note that this expects phpBB3
|
# If the user has an avatar, we want to record it. Note that this expects phpBB3
|
||||||
# to have enforced any restrictions on avatar types.
|
# to have enforced any restrictions on avatar types.
|
||||||
if($post -> {"user_avatar_type"}) {
|
if($post -> {"user_avatar_type"}) {
|
||||||
# width and height should be there regardless of type
|
# width and height should be there regardless of type
|
||||||
$pdata -> {"avatar_width"} = $post -> {"user_avatar_width"};
|
$pdata -> {"avatar_width"} = $post -> {"user_avatar_width"};
|
||||||
$pdata -> {"avatar_height"} = $post -> {"user_avatar_height"};
|
$pdata -> {"avatar_height"} = $post -> {"user_avatar_height"};
|
||||||
|
|
||||||
# type 1 is uploaded
|
# type 1 is uploaded
|
||||||
if($post -> {"user_avatar_type"} == 1) {
|
if($post -> {"user_avatar_type"} == 1) {
|
||||||
$pdata -> {"avatar_url"} = $self -> get_config("server_protocol").
|
$pdata -> {"avatar_url"} = $self -> get_config("server_protocol").
|
||||||
$self -> get_config("server_name").
|
$self -> get_config("server_name").
|
||||||
@ -792,7 +793,7 @@ sub get_topic_firstpost {
|
|||||||
# type 2 avatars are remote linked, so the url should be usable as-is
|
# type 2 avatars are remote linked, so the url should be usable as-is
|
||||||
} elsif($post -> {"user_avatar_type"} == 2) {
|
} elsif($post -> {"user_avatar_type"} == 2) {
|
||||||
$pdata -> {"avatar_url"} = $post -> {"user_avatar"};
|
$pdata -> {"avatar_url"} = $post -> {"user_avatar"};
|
||||||
|
|
||||||
# type 3 avatars are gallery avatars
|
# type 3 avatars are gallery avatars
|
||||||
} elsif($post -> {"user_avatar_type"} == 3) {
|
} elsif($post -> {"user_avatar_type"} == 3) {
|
||||||
$pdata -> {"avatar_url"} = $self -> get_config("server_protocol").
|
$pdata -> {"avatar_url"} = $self -> get_config("server_protocol").
|
||||||
@ -863,14 +864,14 @@ sub get_smilie_url {
|
|||||||
|
|
||||||
|
|
||||||
## @method $ get_config($name, $default)
|
## @method $ get_config($name, $default)
|
||||||
# Obtain the value for the specified phpBB3 configuration variable. This will
|
# Obtain the value for the specified phpBB3 configuration variable. This will
|
||||||
# return the value for the specified configuration variable if it is found. If
|
# return the value for the specified configuration variable if it is found. If
|
||||||
# it is not found, but default is specified, the default is returned, otherwise
|
# it is not found, but default is specified, the default is returned, otherwise
|
||||||
# this returns undef.
|
# this returns undef.
|
||||||
#
|
#
|
||||||
# @param name The name of the variable to obtain the value for
|
# @param name The name of the variable to obtain the value for
|
||||||
# @param default An optional default value to return if the named variable can not be found
|
# @param default An optional default value to return if the named variable can not be found
|
||||||
# @return The value for the named variable, or the default or undef if the
|
# @return The value for the named variable, or the default or undef if the
|
||||||
# variable is not present.
|
# variable is not present.
|
||||||
sub get_config {
|
sub get_config {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
@ -890,7 +891,7 @@ sub get_config {
|
|||||||
# Otherwise, return the default or undef
|
# Otherwise, return the default or undef
|
||||||
return $default;
|
return $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
## @method $ unique_id($extra)
|
## @method $ unique_id($extra)
|
||||||
# Generate a unique ID that can be used with phpBB3 tables.
|
# Generate a unique ID that can be used with phpBB3 tables.
|
||||||
@ -915,8 +916,8 @@ sub unique_id {
|
|||||||
# by the php date() function into something that can be passed to strftime to get the same
|
# by the php date() function into something that can be passed to strftime to get the same
|
||||||
# result. Note that the following php date() format options are not supported and will be
|
# result. Note that the following php date() format options are not supported and will be
|
||||||
# replaced with the empty string: S, t, L, B, u, I, O, and T. The following options are
|
# replaced with the empty string: S, t, L, B, u, I, O, and T. The following options are
|
||||||
# partially supported but the resulting strings are not identical: n (will generate the
|
# partially supported but the resulting strings are not identical: n (will generate the
|
||||||
# same output as m), g (hour has a leading space instead of zero), and G (hour has a
|
# same output as m), g (hour has a leading space instead of zero), and G (hour has a
|
||||||
# leading space instead of zero)
|
# leading space instead of zero)
|
||||||
#
|
#
|
||||||
# @param format The php date() format string to convert.
|
# @param format The php date() format string to convert.
|
||||||
@ -960,13 +961,13 @@ sub set_error {
|
|||||||
# Seriously internal stuff
|
# Seriously internal stuff
|
||||||
|
|
||||||
# The following functions have been ported wholesale from the phpBB3 'includes/functions.php'
|
# The following functions have been ported wholesale from the phpBB3 'includes/functions.php'
|
||||||
# The port has been done with minimal regard for perlification, and it almost certainly
|
# The port has been done with minimal regard for perlification, and it almost certainly
|
||||||
# could be implemented in a far more efficient and perl-friendly fashion.
|
# could be implemented in a far more efficient and perl-friendly fashion.
|
||||||
#
|
#
|
||||||
# Beware, voodoo programming follows.
|
# Beware, voodoo programming follows.
|
||||||
|
|
||||||
## @fn $ _hash_encode64($input, $count, $itoa64)
|
## @fn $ _hash_encode64($input, $count, $itoa64)
|
||||||
# Convert a number into an encoded string form.
|
# Convert a number into an encoded string form.
|
||||||
#
|
#
|
||||||
# @param input The number to encode.
|
# @param input The number to encode.
|
||||||
# @param count The number of characters in the number to convert.
|
# @param count The number of characters in the number to convert.
|
||||||
@ -977,13 +978,13 @@ sub _hash_encode64 {
|
|||||||
|
|
||||||
my $output = '';
|
my $output = '';
|
||||||
my $i = 0;
|
my $i = 0;
|
||||||
|
|
||||||
while($i < $count) {
|
while($i < $count) {
|
||||||
my $value = ord(substr($input, $i++, 1));
|
my $value = ord(substr($input, $i++, 1));
|
||||||
$output .= substr($itoa64, $value & 0x3F, 1);
|
$output .= substr($itoa64, $value & 0x3F, 1);
|
||||||
|
|
||||||
$value |= ord(substr($input, $i, 1)) << 8 if($i < $count);
|
$value |= ord(substr($input, $i, 1)) << 8 if($i < $count);
|
||||||
|
|
||||||
$output .= substr($itoa64, ($value >> 6) & 0x3F, 1);
|
$output .= substr($itoa64, ($value >> 6) & 0x3F, 1);
|
||||||
last if($i++ >= $count);
|
last if($i++ >= $count);
|
||||||
|
|
||||||
@ -991,7 +992,7 @@ sub _hash_encode64 {
|
|||||||
|
|
||||||
$output .= substr($itoa64, ($value >> 12) & 0x3F, 1);
|
$output .= substr($itoa64, ($value >> 12) & 0x3F, 1);
|
||||||
last if($i++ >= $count);
|
last if($i++ >= $count);
|
||||||
|
|
||||||
$output .= substr($itoa64, ($value >> 18) & 0x3F, 1);
|
$output .= substr($itoa64, ($value >> 18) & 0x3F, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1011,7 +1012,7 @@ sub _hash_crypt_private {
|
|||||||
my ($password, $setting, $itoa64) = @_;
|
my ($password, $setting, $itoa64) = @_;
|
||||||
|
|
||||||
my $output = '*';
|
my $output = '*';
|
||||||
|
|
||||||
return $output if(substr($setting, 0, 3) ne '$H$');
|
return $output if(substr($setting, 0, 3) ne '$H$');
|
||||||
|
|
||||||
my $count_log2 = index($itoa64, substr($setting, 3, 1));
|
my $count_log2 = index($itoa64, substr($setting, 3, 1));
|
||||||
@ -1036,9 +1037,9 @@ sub _hash_crypt_private {
|
|||||||
|
|
||||||
## @fn $ _check_hash($password, $hash)
|
## @fn $ _check_hash($password, $hash)
|
||||||
# Determine whether the specified password hashes to the same string as the provided hash.
|
# Determine whether the specified password hashes to the same string as the provided hash.
|
||||||
# This checks whether the plain-text password, and the previously generated hash, are
|
# This checks whether the plain-text password, and the previously generated hash, are
|
||||||
# actually representing the same string by hashing the plain-text password and comparing
|
# actually representing the same string by hashing the plain-text password and comparing
|
||||||
# it to the specified hash. This function can handle phpBB3 (salted md5 hash) and phpBB2
|
# it to the specified hash. This function can handle phpBB3 (salted md5 hash) and phpBB2
|
||||||
# (straight md5 hash) hashes and chooses the appropriate algorithm based on the length of
|
# (straight md5 hash) hashes and chooses the appropriate algorithm based on the length of
|
||||||
# the hash string: if it is 34 characters, it is assumed to be a phpBB3 hash, otherwise it
|
# the hash string: if it is 34 characters, it is assumed to be a phpBB3 hash, otherwise it
|
||||||
# is assumed to be a hex encoded 32 character string.
|
# is assumed to be a hex encoded 32 character string.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user