From a79795d96baa6a653c5b207f7f913e030159d8a1 Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 27 Jul 2011 16:09:54 +0100 Subject: [PATCH] Updating session handle to remove explicit phpBB3 dependancy. --- SessionHandler.pm | 95 ++++++++++++++++++------------------ phpBB3.pm | 121 +++++++++++++++++++++++----------------------- 2 files changed, 108 insertions(+), 108 deletions(-) diff --git a/SessionHandler.pm b/SessionHandler.pm index d6579a3..d5ff3ec 100644 --- a/SessionHandler.pm +++ b/SessionHandler.pm @@ -20,12 +20,12 @@ # along with this program. If not, see . ## @class -# The SessionHandler class provides cookie-based session facilities for -# maintaining user state over http transactions. This code depends on +# The SessionHandler class provides cookie-based session facilities for +# maintaining user state over http transactions. This code depends on # 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 -# a number of joins between custom tables and phpBB3 ones require the two -# to share database space. This code provides session verification, and +# a number of joins between custom tables and phpBB3 ones require the two +# to share database space. This code provides session verification, and # takes some steps towards ensuring security against cookie hijacking, but # as with any cookie based auth system there is the potential for security # issues. @@ -47,7 +47,6 @@ use MIME::Base64; use Data::Dumper; # Custom module imports -use phpBB3; use Logging qw(die_log); # Globals... @@ -72,7 +71,7 @@ sub new { my $self = { cgi => undef, dbh => undef, - phpbb => undef, + auth => undef, template => undef, settings => undef, @_, @@ -81,7 +80,7 @@ sub new { # Ensure that we have objects that we need return set_error("cgi object not set") unless($self -> {"cgi"}); 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("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 $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? # 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"}); - + # If we have a session id, we need to check it if($self -> {"sessid"}) { # Try to get the session... @@ -119,9 +118,9 @@ sub new { if(!$self -> session_expired($session)) { # The session is valid, and can be touched. $self -> touch_session($session); - + return $self; - } # if(!$self -> session_expired($session)) { + } # if(!$self -> session_expired($session)) { } # if($self -> ip_check($ENV{"REMOTE_ADDR"}, $session -> {"session_ip"})) { } # if($session) { } # if($sessid) { @@ -133,7 +132,7 @@ sub new { ## @method $ create_session($user, $persist) # 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 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 delete($self -> {"cookies"}) if($self -> {"cookies"}); - + # get the current time... my $now = time(); # 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 $self -> {"last_visit"} = $now; # 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 ". - $self -> {"phpbb"} -> {"prefix"}."users AS u, ". + $self -> {"auth"} -> {"prefix"}."users AS u, ". $self -> {"settings"} -> {"database"} -> {"keys"}." AS k - WHERE u.user_id = ? + WHERE u.user_id = ? AND u.user_type IN (0, 3) AND k.user_id = u.user_id AND k.key_id = ?"); $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; @@ -176,11 +175,11 @@ sub create_session { $self -> {"autokey"} = ''; $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 = ? AND user_type IN (0, 3)"); $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; } @@ -189,12 +188,12 @@ sub create_session { # the user doesn't exist, is inactive, or is a bot. Just get the anonymous user if(!$userdata) { $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 = ?"); $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; @@ -209,22 +208,22 @@ sub create_session { # Fall back on now if we have no last visit time $self -> {"last_visit"} = $visitr -> [0] if($visitr); - } - + } + # 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; # Do we already have a session id? If we do, and it's an anonymous session, we want to nuke it if($self -> {"sessid"}) { my $killsess = $self -> {"dbh"} -> prepare("DELETE FROM ".$self -> {"settings"} -> {"database"} -> {"sessions"}. " 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); } - + # 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 $self -> {"session_time"} = $now; @@ -239,7 +238,7 @@ sub create_session { $ENV{"REMOTE_ADDR"}, $persist) 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); return $self; @@ -261,8 +260,8 @@ sub delete_session { # If we're not dealing with anonymous, we need to store the visit time, # 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 $self -> {"session_time"} = time() if(!$self -> {"session_time"}); @@ -281,7 +280,7 @@ sub delete_session { " WHERE key_id = ? AND user_id = ?"); $nukekeys -> execute(md5_hex($self -> {"autokey"}), $self -> {"sessuser"}) or return set_error("Unable to remove session key\nError was: ".$self -> {"dbh"} -> errstr); - } + } } # clear all the session settings internally for safety @@ -318,7 +317,7 @@ sub encode_querystring { sub decode_querystring { my $self = shift; my $query = shift; - + # Bomb if we don't have a query, or it is not valid base64 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 # create_session in reality anyway. 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 $sessuser = $self -> create_cookie($self -> {"settings"} -> {"config"} -> {"cookie_name"}.'_u', $self -> {"sessuser"}, $expires); my $sesskey; - if($self -> {"sessuser"} != $phpBB3::ANONYMOUS) { + if($self -> {"sessuser"} != $self -> {"auth"} -> {"ANONYMOUS"}) { if($self -> {"autokey"}) { $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) # 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 -# 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) # # @param userip The IP the user is connecting from. @@ -375,7 +374,7 @@ sub ip_check { my $sessip = shift; # 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 return 1 if($iplen == 0); @@ -399,10 +398,10 @@ sub session_cleanup { my $self = shift; 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 - 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 $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"}. " WHERE session_user_id = ? 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); - + # 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"}. " WHERE session_time < ? @@ -424,7 +423,7 @@ sub session_cleanup { my $updatelast; if($self -> {"settings"} -> {"database"} -> {"lastvisit"}) { $updatelast = $self -> {"dbh"} -> prepare("UPDATE ".$self -> {"settings"} -> {"database"} -> {"lastvisit"}. - " SET last_visit = ? + " SET last_visit = ? 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(!$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 { - 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 - 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))); } @@ -474,7 +473,7 @@ sub session_expired { ## @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 # returns a reference to a hash containing the session data. # @@ -522,7 +521,7 @@ sub set_login_key { my $self = shift; 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(!$key) { diff --git a/phpBB3.pm b/phpBB3.pm index 1db2dc1..8d15c19 100644 --- a/phpBB3.pm +++ b/phpBB3.pm @@ -25,12 +25,12 @@ # 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 # 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 # posts and would involve session shenanigans to ensure users are logged # into a phpBB3 account. # -# +# package phpBB3; use strict; @@ -84,7 +84,7 @@ BEGIN { "e" => "%Z", "I" => "", # UNSUPPORTED: (capital i) Whether or not the date is in daylight saving time 1 if Daylight Saving Time, 0 otherwise. "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", "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", @@ -114,7 +114,7 @@ BEGIN { # 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. -# @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. sub new { my $invocant = shift; @@ -130,6 +130,7 @@ sub new { allowanon => 0, dbopts => { RaiseError => 0, AutoCommit => 1 }, url => "/", + ANONYMOUS => $ANONYMOUS, @_, }; @@ -139,7 +140,7 @@ sub new { # try to open the database connection with those credentials. if(!$obj -> {"dbh"} && $self -> {"username"} & $obj -> {"password"} && $obj -> {"data_src"}) { $obj -> {"dbh"} = DBI -> connect($obj -> {"data_src"}, - $obj -> {"username"}, + $obj -> {"username"}, $obj -> {"password"}, $obj -> {"dbopts"}) or return set_error("Unable to open database connection - ".$DBI::errstr); @@ -221,10 +222,10 @@ sub register_user { my $content = $www -> content(); return "Unexpected content in response to registration first step accept." unless($content =~ /PLEASE DO NOT ATTEMPT TO REGISTER USING THIS FORM/); - + $www -> form_id('register') or return "Unable to locate the second step registration form."; - + # Now we can fill in fields to submit $www -> field ('username' , $args -> {"username"}); $www -> field ('email' , $args -> {"email"}); @@ -235,7 +236,7 @@ sub register_user { $www -> field ('question2' , 'chris page'); $www -> select('lang' , 'en'); $www -> select('tz' , '0'); - + # And submit that $www -> click('submit'); 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. # 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 -# 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. # # @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(!$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'}"); $args{"user_id"} = $user -> {"user_id"}; } # If we don't have a group_id, we need to look it up 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'}"); $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 my $ugh = $self -> {"dbh"} -> prepare("SELECT * FROM ".$self -> {"prefix"}."user_group WHERE group_id = ? AND 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"; - + # Do we have one or more rows? my $ugr = $ugh -> fetchrow_arrayref(); - + return defined($ugr); } - + ## @method $ valid_user($username, $password) # 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 # 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. -# +# # @param username The username of the user to check. # @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 @@ -422,8 +423,8 @@ sub get_profile_url { ## @method $ email_in_use($email) -# Determine whether the specified email address is already in use within the -# system. +# Determine whether the specified email address is already in use within the +# system. # # @param email The email address to check. # @return true if the email address already exists within the database, false @@ -432,7 +433,7 @@ sub email_in_use { my $self = 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 ?"); $emailh -> execute($email) 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 ## @method @ get_session(void) -# 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 -# phpBB3 session, and if it is it returns a reference to a hash containing user +# 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 +# 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. # # @return A reference to a hash containing user and session data if the session # is valid, undef otherwise. # -# @todo This does not currently support forwarded_for checks, referer checks, -# or load limiting. It also does not support 'alternative' auth methods: +# @todo This does not currently support forwarded_for checks, referer checks, +# or load limiting. It also does not support 'alternative' auth methods: # only database auth is supported. sub get_session { my $self = shift; @@ -505,7 +506,7 @@ sub get_session { # First, try to obtain a session id - start by looking at the cookies 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? # 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); # 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 WHERE s.session_id = ? AND u.user_id = s.session_user_id"); $sessh -> execute($sessid) 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(); - + # if we have a session, we need to validate it if($sessdata) { # 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")) { $valid_ua = substr(lc($sessdata -> {"session_browser"}), 0, 150) eq substr(lc($self -> {"cgi"} -> user_agent()), 0, 150); - } + } # If the ip and browser checks are okay, continue with the validation # 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 } elsif(!$self -> get_config("allow_autologin")) { $expired = 1; - + # Otherwise, if check whether a maximum autologin time limit has been set, and that the session is within it } else { my $max_autologin = $self -> get_config("max_autologin_time"); $expired = ($max_autologin && $sessdata -> {"session_time"} < (time() - ($max_autologin + 60))); } - + # If the session has not expired, we want to touch it if(!$expired) { 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 = ? WHERE session_id = ?"); $touch -> execute(time(), $sessdata -> {"session_id"}) @@ -602,9 +603,9 @@ sub get_session { # # @note This function does no permissions checking whatsoever. It is up # 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. -# +# # @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 # 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 # 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 -# 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. # # @note This function does no permissions checking whatsoever. It is up # 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. # # @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. # @param offset The number of posts to skip, if not specified defaults to 0. This is # ignored if count is set to 0. # @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) # @return A reference to an array of topic ids, or undef if no topics are available # or an error ocurred. @@ -677,7 +678,7 @@ sub get_topic_ids { # always having announcements at the front. my $announceh = $self -> {"dbh"} -> prepare("SELECT topic_id FROM ".$self -> {"prefix"}."topics WHERE forum_id = ? AND topic_type = 2 - $order + $order ".($fetchall ? "" : "LIMIT $count")); $announceh -> execute($forum) 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) { - + # And we're done. Return a reference to the topics array if it has any contents, # undef if it does not. return scalar(@topics) ? \@topics : set_error(""); @@ -717,7 +718,7 @@ sub get_topic_ids { ## @method $ get_topic($topicid) # 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 -# containing the topic information. +# containing the topic information. # # @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 @@ -754,7 +755,7 @@ sub get_topic_firstpost { or return set_error("Unable to locate topic $topicid in the database"); # 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 WHERE p.post_id = ? AND u.user_id = p.poster_id"); $posth -> execute($topic -> {"topic_first_post_id"}) @@ -774,15 +775,15 @@ sub get_topic_firstpost { "post_uid" => $post -> {"bbcode_uid"}, "poster_username" => $post -> {"username"}, "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. if($post -> {"user_avatar_type"}) { # width and height should be there regardless of type $pdata -> {"avatar_width"} = $post -> {"user_avatar_width"}; $pdata -> {"avatar_height"} = $post -> {"user_avatar_height"}; - # type 1 is uploaded + # type 1 is uploaded if($post -> {"user_avatar_type"} == 1) { $pdata -> {"avatar_url"} = $self -> get_config("server_protocol"). $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 } elsif($post -> {"user_avatar_type"} == 2) { $pdata -> {"avatar_url"} = $post -> {"user_avatar"}; - + # type 3 avatars are gallery avatars } elsif($post -> {"user_avatar_type"} == 3) { $pdata -> {"avatar_url"} = $self -> get_config("server_protocol"). @@ -863,14 +864,14 @@ sub get_smilie_url { ## @method $ get_config($name, $default) -# Obtain the value for the specified phpBB3 configuration variable. This will -# 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 +# Obtain the value for the specified phpBB3 configuration variable. This will +# 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 # this returns undef. # # @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 -# @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. sub get_config { my $self = shift; @@ -890,7 +891,7 @@ sub get_config { # Otherwise, return the default or undef return $default; } - + ## @method $ unique_id($extra) # 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 # 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 -# 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 +# 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 # leading space instead of zero) # # @param format The php date() format string to convert. @@ -960,13 +961,13 @@ sub set_error { # Seriously internal stuff # 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. # # Beware, voodoo programming follows. ## @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 count The number of characters in the number to convert. @@ -977,13 +978,13 @@ sub _hash_encode64 { my $output = ''; my $i = 0; - + while($i < $count) { my $value = ord(substr($input, $i++, 1)); $output .= substr($itoa64, $value & 0x3F, 1); $value |= ord(substr($input, $i, 1)) << 8 if($i < $count); - + $output .= substr($itoa64, ($value >> 6) & 0x3F, 1); last if($i++ >= $count); @@ -991,7 +992,7 @@ sub _hash_encode64 { $output .= substr($itoa64, ($value >> 12) & 0x3F, 1); last if($i++ >= $count); - + $output .= substr($itoa64, ($value >> 18) & 0x3F, 1); } @@ -1011,7 +1012,7 @@ sub _hash_crypt_private { my ($password, $setting, $itoa64) = @_; my $output = '*'; - + return $output if(substr($setting, 0, 3) ne '$H$'); my $count_log2 = index($itoa64, substr($setting, 3, 1)); @@ -1036,9 +1037,9 @@ sub _hash_crypt_private { ## @fn $ _check_hash($password, $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 -# 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 # 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.