#!/usr/bin/perl -w ############################################################################### # users.pl - this code is for user creation and administration # # Copyright (C) 1997 Rob "CmdrTaco" Malda # malda@slashdot.org # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # # $Id: users.pl,v 1.1.1.1 2001/02/24 17:52:13 alessio Exp $ ############################################################################### use strict; use lib '../'; use vars '%I'; use vars '%L'; use Slash; ################################################################# sub main { *I = getSlashConf(); *L = \%Slash::L; getSlash(); my $op = $I{F}{op}; if ($op eq "$L{userlogin}" and $I{U}{uid} > 0) { my $refer = $I{F}{returnto} || $I{rootdir}; redirect($refer); return; } header("$I{sitename} $L{Users}"); print < 0 && $op ne "userclose"; [ $L{User_Info} | $L{Edit_User_Info} | $L{Customize_Homepage} | $L{Customize_Comments} | $L{Logout} ] EOT # and now the carnage begins if ($op eq "newuser") { newUser(); } elsif ($op eq "edituser") { # the users_prefs table if ($I{U}{uid} > 0) { editUser($I{U}{nickname}); } else { displayForm(); #crapMesg(); } } elsif ($op eq "edithome" || $op eq "preferences") { # also known as the user_index table if ($I{U}{uid} > 0) { editHome($I{U}{nickname}); } else { displayForm(); #crapMesg(); } } elsif ($op eq "editcomm") { # also known as the user_comments table if ($I{U}{uid} > 0) { editComm($I{U}{nickname}); } else { displayForm(); #crapMesg(); } } elsif ($op eq "userinfo" || !$op) { if ($I{F}{nick}) { userInfo($I{F}{nick}); } elsif ($I{U}{uid} < 1) { displayForm(); } else { userInfo($I{U}{nickname}); } } elsif ($op eq "$L{saveuser}") { saveUser($I{U}{uid}); userInfo($I{U}{nickname}); } elsif ($op eq "$L{savecomm}") { saveComm($I{U}{uid}); userInfo($I{U}{nickname}); } elsif ($op eq "$L{savehome}") { saveHome($I{U}{uid}); userInfo($I{U}{nickname}); } elsif ($op eq "sendpw") { mailPassword($I{U}{nickname}); } elsif ($op eq "$L{mailpasswd}") { mailPassword($I{F}{unickname}); } elsif ($op eq "suedituser" && $I{U}{aseclev} > 100) { editUser($I{F}{name}); } elsif ($op eq "susaveuser" && $I{U}{aseclev} > 100) { saveUser($I{F}{uid}); } elsif ($op eq "sudeluser" && $I{U}{aseclev} > 100) { delUser($I{F}{uid}); } elsif ($op eq "userclose") { print "$L{ok_bubbye_now}."; displayForm(); } elsif ($op eq "$L{userlogin}" && $I{U}{uid} > 0) { # print $query->redirect("$I{rootdir}/index.pl"); userInfo($I{U}{nickname}); } elsif ($op eq "preview") { previewSlashbox(); } elsif ($I{U}{uid} > 0) { userInfo($I{F}{nick}); } else { displayForm(); } miniAdminMenu() if $I{U}{aseclev} > 100; writelog("users", $I{U}{nickname}); footer(); } ################################################################# sub crapMesg { print eval prepBlock($L{Oh_Crap_}); } ################################################################# sub checkList { my $string = shift; $string = substr($string, 0, -1); $string =~ s/[^\w,-]//g; my @e = split m/,/, $string; $string = sprintf "'%s'", join "','", @e; if (length($string) > 254) { print "$L{You_selected_too_many_options}"; $string = substr($string, 0, 255); $string =~ s/,'??\w*?$//g; } elsif (length $string < 3) { $string = ""; } return $string; } ################################################################# sub previewSlashbox { my ($title, $content, $url) = sqlSelect( "title,block,url", "blocks, sectionblocks", "section='index' AND blocks.bid = sectionblocks.bid AND blocks.bid = " . $I{dbh}->quote($I{F}{bid}) ); my $cleantitle = $title; $cleantitle =~ s/<(.*?)>//g; titlebar("100%","Preview $cleantitle"); print eval prepBlock($L{What_you_see_on_the_right_hand_side_}); print < 999;

Edit $I{F}{bid} EOT print qq!!; print portalbox($I{fancyboxwidth}, $title, $content, "", $url); } ################################################################# sub miniAdminMenu { print < [ Admin | ] EOT } ################################################################# sub newUser { # Check if User Exists $I{F}{newuser} =~ s/\s+/ /g; $I{F}{newuser} =~ s/[^ a-zA-Z0-9\$_.+!*'(),-]+//g; $I{F}{newuser} = substr($I{F}{newuser}, 0, 20); (my $matchname = lc $I{F}{newuser}) =~ s/[^a-zA-Z0-9]//g; my($cnt) = sqlSelect( "matchname","users", "matchname=" . $I{dbh}->quote($matchname) ) || sqlSelect( "realemail","users", " realemail=" . $I{dbh}->quote($I{F}{email}) ); if ($matchname ne '' && $I{F}{newuser} ne '' && !$cnt && $I{F}{email} =~ /\@/) { titlebar("100%", eval prepBlock($L{User_newuser_created})); $I{F}{pubkey} = stripByMode($I{F}{pubkey}, "html"); sqlInsert("users", { realemail => $I{F}{email}, nickname => $I{F}{newuser}, matchname => $matchname, passwd => changePassword() }); my($uid) = sqlSelect("LAST_INSERT_ID()"); sqlInsert("users_info", { uid => $uid, -lastaccess=>'now()' } ); sqlInsert("users_prefs", { uid => $uid } ); sqlInsert("users_comments", { uid => $uid } ); sqlInsert("users_index", { uid => $uid } ); # sqlInsert("users_key", { uid => $uid } ); # Not necessary print <email=$I{F}{email}
user id=$uid
nick=$I{F}{newuser}
passwd=mailed to $I{F}{email}
EOT print eval prepBlock($L{Once_you_receive_your_password_}); mailPassword($I{F}{newuser}); } else { # Duplicate User displayForm(); } } ################################################################# sub changePassword { my @chars = grep !/[0O1Iil]/, 0..9, 'A'..'Z', 'a'..'z'; return join '', map { $chars[rand @chars] } 0 .. 7; } ################################################################# sub mailPassword { my($name) = @_; my($nickname, $passwd, $email) = sqlSelect( "nickname,passwd,realemail", "users", "nickname=" . $I{dbh}->quote($name) ); my $msg = blockCache("newusermsg"); $msg = prepBlock($msg); $msg = eval $msg; if ($name ne '' && (lc($name) eq lc($nickname))) { sendEmail($email, eval prepBlock($L{user_password_for_name}), $msg) if $name; print eval prepBlock($L{Passwd_just_emailed}); } else { print eval prepBlock($L{name_not_found_no_password_mailed}); } } ################################################################# sub userInfo { my($nick) = @_; my $c = $I{dbh}->prepare( "SELECT homepage,fakeemail,users.uid,bio, seclev,karma FROM users, users_info WHERE users.uid = users_info.uid AND nickname=" . $I{dbh}->quote($nick) . " and users.uid > 0" ); $c->execute; if (my($home, $email, $uid, $bio, $useclev, $karma) = $c->fetchrow) { $bio = stripByMode($bio, "html"); if ($I{U}{nickname} eq $nick) { my $sth = $I{dbh}->prepare("SELECT points FROM users_comments WHERE uid=$uid"); $sth->execute; my $points = $sth->fetchrow_array; $sth->finish; titlebar("95%", eval prepBlock($L{Welcome_back_nick_})); print eval prepBlock($L{This_is_your_User_Info_page_}); if ($I{U}{uid} == $uid && $points > 0) { print eval prepBlock($L{Youre_a_moderator_with_points_}); } print <
EOT } else { titlebar("95%", "$L{User_Info_for} $nick ($uid)"); } print qq!$home
$email
!; print eval prepBlock($L{Karma_karma_}) if $I{U}{aseclev} || $I{U}{uid} == $uid; print eval prepBlock($L{User_Bio_}) if $bio; my($k) = sqlSelect("pubkey", "users_key", "uid=$uid"); $k = stripByMode($k, "html"); print "$L{Public_Key}

\n$k

" if $k; $I{F}{min} = 0 unless $I{F}{min}; my $sqlquery = "SELECT pid,sid,cid,subject," # . getDateFormat("date","d") . "date" . ",points FROM comments WHERE uid=$uid "; $sqlquery .= " ORDER BY date DESC LIMIT $I{F}{min},50 "; my $comments = $I{dbh}->prepare($sqlquery); $comments->execute; my $commentsRows = $comments->rows; print eval prepBlock($L{nick_has_posted_comments_}); my $x; while (my($pid, $sid, $cid, $subj, $cdate, $pts) = $comments->fetchrow) { $cdate = timeCalc($cdate); $x++; my($r) = sqlSelect("count(*)", "comments", "sid='$sid' and pid=$cid"); my $replies = " $L{Replies}:$r" if $r; print <$x $subj $L{'posted on'} $cdate ($L{Score}:$pts$replies) EOT my $S = sqlSelectHashref("section, title, writestatus", "stories", "sid='$sid'"); if ($S) { my $href = $S->{writestatus} == 10 ? "$I{rootdir}/$S->{section}/$sid.shtml" : "$I{rootdir}/article.pl?sid=$sid"; print qq!
$L{attached_to} $S->{title}!; # $S->{section}/$sid.shtml } else { my $P = sqlSelectHashref("question", "pollquestions", "qid='$sid'"); print qq!
$L{attached_to} $P->{question}! if $P->{question}; } print "
"; } $comments->finish; } else { print "$nick not found."; } $c->finish; } ################################################################# sub editKey { my($k) = sqlSelect("pubkey", "users_key", "uid=$_[0]"); printf qq!

$L{Public_Key}
!, stripByMode($k, 'literal'); } ################################################################# sub editUser { my($name) = @_; my($uid, $realname, $realemail, $fakeemail, $homepage, $nickname, $passwd, $sig, $useclev, $bio, $maillist) = sqlSelect( "users.uid, realname, realemail, fakeemail, homepage, nickname, " . "passwd, sig, seclev, bio, maillist", "users, users_info", "users.uid=users_info.uid AND nickname=" . $I{dbh}->quote($name) ); return if $uid < 1; titlebar("100%", "$L{Editing} $name ($uid) $realemail"); print qq!
!; $homepage ||= "http://"; my $tempnick = $nickname; $tempnick =~ s/ /+/g; print eval prepBlock($L{You_can_automatically_login_}); print < $L{Real_Name_}
$L{Real_Email_}
$L{Fake_Email_}
$L{Homepage_}

$L{Headline_Mailing_List} EOT selectForm("maillist", "maillist", $maillist); printf <%s $L{Bio_} EOT editKey($uid); print <

EOT # print " " if $I{U}{aseclev}> 499; } ################################################################# sub tildeEd { my($extid, $exsect, $exaid, $exboxes, $userspace) = @_; titlebar("100%", "$L{Exclude_Stories_Homepage}"); print < $L{Authors} $L{Topics} $L{Sections} EOT # Customizable Authors Thingee my $C = sqlSelectMany("aid", "authors", "seclev > 99", "order by aid"); while (my($aid) = $C->fetchrow) { my $checked = ($exaid =~ /'$aid'/) ? ' CHECKED' : ''; print qq!$aid
\n!; } $C->finish; # Customizable Topic print qq!!; $C = sqlSelectMany("tid,alttext", "topics", "1=1 ", "order by tid"); while (my($tid, $alttext) = $C->fetchrow) { my $checked = ($extid =~ /'$tid'/) ? ' CHECKED' : ''; print qq!$alttext
\n! if $tid; } $C->finish; print "
"; # Customizable Sections print ''; $C = sqlSelectMany("section,title", "sections", "isolate=0", "order by title"); while (my($section,$title) = $C->fetchrow) { my $checked = ($exsect =~ /'$section'/) ? " CHECKED" : ""; print qq!$title
\n! if $section; } $C->finish; print ""; print "

"; titlebar("100%", "$L{Customize_Slashboxes}"); $userspace = stripByMode($userspace, 'literal'); print < $L{Look_ma_Im_configurable_} EOT print eval prepBlock($L{User_Space_}); print <$userspace

EOT $C = sqlSelectMany("bid,title,ordernum", "sectionblocks", "section='index' AND portal=1", "order by bid"); while (my($bid,$title,$o) = $C->fetchrow) { my $checked = ($exboxes =~ /'$bid'/) ? " CHECKED" : ""; $title =~ s/<(.*?)>//g; print "" if $o > 0; print qq!! . qq!!; unless ($bid eq "srandblock") { print $title; } else { print "Semi-Random Box"; } print "
\n"; print "
" if $o > 0; } $C->finish; print "

"; print eval prepBlock($L{If_you_have_reasonable_suggestions_}); print "

"; } ################################################################# sub editHome { my($name) = @_; my($uid, $willing, $tzformat, $tzcode, $noicons, $light, $userspace, $extid, $exaid, $exsect, $exboxes, $maxstories, $noboxes) = sqlSelect("users.uid, willing, dfid, tzcode, noicons, light, " . "mylinks, users_index.extid, users_index.exaid, " . "users_index.exsect, users_index.exboxes, users_index.maxstories, " . "users_index.noboxes", "users, users_prefs, users_index", "users.uid=users_prefs.uid AND users.uid=users_index.uid AND " . "users.nickname=" . $I{dbh}->quote($name) ); return if $uid < 1; titlebar("100%", eval prepBlock($L{Customize_sitename_Display})); print <
$L{Date_Time_Format} EOT selectGeneric("dateformats", "tzformat", "id", "description", $tzformat); selectGeneric("tzcodes", "tzcode", "tz", "description", $tzcode); print ""; my $l_check = $light ? " CHECKED" : ""; my $b_check = $noboxes ? " CHECKED" : ""; my $i_check = $noicons ? " CHECKED" : ""; my $w_check = $willing ? " CHECKED" : ""; print qq!

!; print eval prepBlock($L{Light_}); print < $L{Deactivate_Slashboxes}

$L{No_Icons} $L{Maximum_Stories}

EOT print eval prepBlock($L{Willing_to_Moderate}); print <

EOT tildeEd($extid, $exsect, $exaid, $exboxes, $userspace); print qq!\t\n!; # print qq!\t ! if $I{U}{aseclev}> 499; print "\t\n\n"; } ################################################################# sub editComm { my($name) = @_; my($uid, $points, $posttype, $defaultpoints, $maxcommentsize, $clsmall, $clbig, $reparent, $noscores, $highlightthresh, $commentlimit, $nosigs, $commentspill, $commentsort, $mode, $threshold, $hardthresh) = sqlSelect("users.uid, points, posttype, defaultpoints, " . "maxcommentsize, clsmall, clbig, reparent, noscores, " . "highlightthresh, commentlimit, nosigs, commentspill, " . "commentsort, mode, threshold, hardthresh", "users, users_comments","users.uid=users_comments.uid AND nickname=" . $I{dbh}->quote($name) ); titlebar("100%", "$L{Comment_Options}"); print <
EOT print "$L{Display_Mode}"; selectGeneric("commentmodes", "umode", "mode", "name", $mode); print "$L{Sort_Order}\n"; selectForm("sortcodes", "commentsort", $commentsort); print "

$L{Threshold}"; selectGeneric("threshcodes", "uthreshold", "thresh", "description", $threshold); print eval prepBlock($L{comments_scored_less_than_}); print "

$L{Highlight_Threshold}"; selectGeneric("threshcodes", "highlightthresh", "thresh", "description", $highlightthresh); print "
($L{comments_scoring_this_})"; my $h_check = $hardthresh ? " CHECKED" : ""; my $r_check = $reparent ? " CHECKED" : ""; my $n_check = $noscores ? " CHECKED" : ""; my $s_check = $nosigs ? " CHECKED" : ""; print < $L{Reparent_Highly_Rated_Comments_} $L{Do_Not_Display_Scores_} $L{Limit_only_display_} $L{Index_Spill_} $L{Small_Comment_Penalty_} $L{Long_Comment_Bonus_} $L{Max_Comment_Size_} $L{Disable_Sigs_} $L{Comment_Post_Mode} EOT selectGeneric("postmodes", "posttype", "code", "name", $posttype); print <

EOT # print qq! ! if $I{U}{aseclev}> 499; } ################################################################# sub saveUser { my $uid = $I{U}{aseclev} ? shift : $I{U}{uid}; my $name = $I{U}{aseclev} && $I{F}{name} ? $I{F}{name} : $I{U}{nickname}; $name = substr($name, 0, 20); return unless $uid > 0; print eval prepBlock($L{Saving_Name}); print <Your browser didn't save a cookie properly. This could mean you are behind a filter that eliminates them, you are using a browser that doesn't support them, or you rejected it. EOT # stripByMode _after_ fitting sig into schema, 120 chars $I{F}{sig} = stripByMode(substr($I{F}{sig}, 0, 120), 'html'); $I{F}{fakeemail} = chopEntity(stripByMode($I{F}{fakeemail}, 'attribute'), 50); $I{F}{homepage} = "" if $I{F}{homepage} eq "http://"; $I{F}{homepage} = fixurl($I{F}{homepage}); # for the users table my $H = { sig => $I{F}{sig}, homepage => $I{F}{homepage}, fakeemail => $I{F}{fakeemail} }; # for the users_info table my $H2 = { maillist => $I{F}{maillist}, realname => $I{F}{realname}, bio => $I{F}{bio} }; my($oldEmail) = sqlSelect("realemail", "users", "nickname=" . $I{dbh}->quote($name)); if ($oldEmail ne $I{F}{realemail}) { $H->{realemail} = chopEntity(stripByMode($I{F}{realemail}, 'attribute'), 50); print "\nNotifying $oldEmail of the change to their account.
\n"; sendEmail($oldEmail, "$I{sitename} user email change for $name", < 5) { $H->{passwd} = $I{F}{pass1}; print qq!Password Changed (You'll need to log back in now.)
!; } elsif ($I{F}{pass1} ne $I{F}{pass2}) { print "Passwords don't match. Password not changed.
"; } elsif (length $I{F}{pass1} < 6 && $I{F}{pass1}) { print "Password is too short and was not changed.
"; } # update the public key sqlReplace("users_key", { uid => $uid, pubkey => $I{F}{pubkey} } ); # Update users with the $H thing we've been playing with for this whole damn sub sqlUpdate("users", $H, "uid=" . $uid . " AND uid>0", 1); # Update users with the $H thing we've been playing with for this whole damn sub sqlUpdate("users_info", $H2, "uid=" . $uid . " AND uid>0", 1); } ################################################################# sub saveComm { my $uid = $I{U}{aseclev} ? shift : $I{U}{uid}; my $name = $I{U}{aseclev} && $I{F}{name} ? $I{F}{name} : $I{U}{nickname}; $name = substr($name, 0, 20); return unless $uid > 0; print eval prepBlock($L{Saving_Name}); print <Your browser didn't save a cookie properly. This could mean you are behind a filter that eliminates them, you are using a browser that doesn't support them, or you rejected it. EOT # Take care of the lists # Enforce Ranges for variables that need it $I{F}{commentlimit} = 0 if $I{F}{commentlimit} < 1; $I{F}{commentspill} = 0 if $I{F}{commentspill} < 1; # for users_comments my $H = { clbig => $I{F}{clbig}, clsmall => $I{F}{clsmall}, mode => $I{F}{umode}, posttype => $I{F}{posttype}, commentsort => $I{F}{commentsort}, threshold => $I{F}{uthreshold}, commentlimit => $I{F}{commentlimit}, commentspill => $I{F}{commentspill}, maxcommentsize => $I{F}{maxcommentsize}, highlightthresh => $I{F}{highlightthresh}, nosigs => ($I{F}{nosigs} ? "1" : "0"), reparent => ($I{F}{reparent} ? "1" : "0"), noscores => ($I{F}{noscores} ? "1" : "0"), hardthresh => ($I{F}{hardthresh} ? "1" : "0"), }; # Update users with the $H thing we've been playing with for this whole damn sub sqlUpdate("users_comments", $H, "uid=" . $uid . " AND uid>0", 1); } ################################################################# sub saveHome { my $uid = $I{U}{aseclev} ? shift : $I{U}{uid}; my $name = $I{U}{aseclev} && $I{F}{name} ? $I{F}{name} : $I{U}{nickname}; $name = substr($name, 0, 20); return unless $uid > 0; print eval prepBlock($L{Saving_Name}); print eval prepBlock($L{Your_browser_didnt_save_cookie_}) if $uid < 1 || !$name; my($extid, $exaid, $exsect) = ""; my($exboxes) = sqlSelect("exboxes", "users_index", "uid=$uid"); $exboxes =~ s/'//g; my @b = split m/,/, $exboxes; foreach (@b) { $_ = "" unless $I{F}{"exboxes_$_"}; } $exboxes = sprintf "'%s',", join "','", @b; $exboxes =~ s/'',//g; foreach my $k (keys %{$I{F}}) { if ($k =~ /^extid_(.*)/) { $extid .= "'$1'," } if ($k =~ /^exaid_(.*)/) { $exaid .= "'$1'," } if ($k =~ /^exsect_(.*)/) { $exsect .="'$1'," } if ($k =~ /^exboxes_(.*)/) { # Only Append a box if it doesn't exist my $box = $1; $exboxes .= "'$box'," unless $exboxes =~ /'$box'/; } } $I{F}{maxstories} = 66 if $I{F}{maxstories} > 66; $I{F}{maxstories} = 1 if $I{F}{maxstories} < 1; # Take care of the preferences table # for users_index my $H = { extid => checkList($extid), exaid => checkList($exaid), exsect => checkList($exsect), exboxes => checkList($exboxes), maxstories => $I{F}{maxstories}, noboxes => ($I{F}{noboxes} ? "1" : "0"), }; # for users_prefs my $H2 = { light => ($I{F}{light} ? "1" : "0"), noicons => ($I{F}{noicons} ? "1" : "0"), willing => ($I{F}{willing} ? "1" : "0"), }; if (defined $I{F}{tzcode} && defined $I{F}{tzformat}) { $H2->{tzcode} = $I{F}{tzcode}; $H2->{dfid} = $I{F}{tzformat}; } $H2->{mylinks} = $I{F}{mylinks} if $I{F}{mylinks}; # If a user is unwilling to moderate, we should cancel all points, lest # they be preserved when they shouldn't be. sqlUpdate("users_comments", { points => 0 }, "uid=$uid AND uid>0", 1) unless $I{F}{willing}; # Update users with the $H thing we've been playing with for this whole damn sub sqlUpdate("users_index", $H, "uid=" . $uid . " AND uid>0", 1); # Update users with the $H thing we've been playing with for this whole damn sub sqlUpdate("users_prefs", $H2, "uid=" . $uid . " AND uid>0", 1); } ################################################################# sub displayForm { print <

EOT titlebar("100%", $I{F}{unickname} ? "$L{Error_Logging_In}" : "$L{Login}"); print $I{F}{unickname} ? <
$L{Password_characters_long_}
EOT titlebar("100%", $I{F}{newuser} ? "$L{Duplicate_Account}" : "$L{Im_a_New_User}"); print $I{F}{newuser} ? <disconnect if $I{dbh}; 1;