ljr/local/htdocs/update.bml

412 lines
16 KiB
Plaintext
Raw Normal View History

2019-02-05 21:49:12 +00:00
<?_code
{
use strict;
use vars qw(%GET %POST %ML);
# $_[1] is a pre-request scratch area
# put variables here so that we can access them later
# outside of this _code block
my $title = \$_[1]->{'title'};
my $head = \$_[1]->{'head'};
my $body = \$_[1]->{'body'};
my $bodyopts = \$_[1]->{'bodyopts'};
$$title = $ML{'.title'};
# server down?
if ($LJ::SERVER_DOWN) {
$$body = LJ::server_down_html();
return;
}
LJ::set_active_crumb("update");
# invalid text input?
unless (LJ::text_in(\%POST)) {
BML::set_status(403); # 403 Forbidden
$$body = "<?badinput?>";
return;
}
# get remote and see if they can post right now
my $remote = LJ::get_remote();
# Errors that are unlikely to change between starting
# to compose an entry and submitting it.
if ($remote) {
if ($remote->underage) {
return BML::redirect("$LJ::SITEROOT/agecheck/?s=1");
}
if ($remote->identity) {
BML::set_status(403); # 403 Forbidden
$$title = "Sorry";
$$body = "Non-$LJ::SITENAME users can't post, as they don't actually have journals here. You can leave comments in other journals, though.";
return;
}
if (! LJ::get_cap($remote, "can_post")) {
BML::set_status(403); # 403 Forbidden
$$title = "Can't Post";
$$body = $LJ::MSG_NO_POST || $ML{'.error.cantpost'};
return;
}
if (LJ::get_cap($remote, "disable_can_post")) {
unless (LJ::run_hook("update.bml_disable_can_post", {
title => $title, body => $body,
})) {
#BML::set_status(403); # 403 Forbidden
$$title = $ML{'.error.disabled.title'};
$$body = $ML{'.error.disabled'};
}
return;
}
}
my %res = ();
# see if we need to do any transformations
LJ::run_hooks("transform_update_$POST{transform}", \%GET, \%POST) if $POST{transform};
# Set up form default values:
my @time = localtime(time);
my ($year, $mon, $mday, $hour, $min) = ($time[5] + 1900,
sprintf("%02d", $time[4] + 1),
sprintf("%02d", $time[3]),
$time[2],
sprintf("%02d", $time[1]));
my $subject = $POST{'subject'} || $GET{'subject'};
my $event = $POST{'event'} || $GET{'event'};
### define some bools with common logic ###
my $did_post = LJ::did_post() && !$POST{transform}; # transforms aren't posts
my $user_is_remote = $remote && $remote->{'user'} eq $POST{'user'}; # user is remote
my $auth_as_remote = $remote && (! $GET{'altlogin'} || $user_is_remote); # auth as remote
my $auth_missing = $POST{'user'} &&
! $POST{'password'} &&
! $user_is_remote &&
! $POST{'response'}; # user w/o password
# which authentication option do we display by default?
my $altlogin_display = 'none';
my $remotelogin_display = 'none';
if ($auth_as_remote) {
$remotelogin_display = 'table-row';
} else {
$altlogin_display = 'table-row';
}
# Check for errors, store in hash to render later
my $errors; my $onload = "shift_contents(); ";
my $showform = $POST{'showform'} || $auth_missing; # show entry form
my $preview = $POST{'action:preview'};
# are we spellchecking before we post?
my $did_spellcheck; my $spellcheck_html;
if ($LJ::SPELLER && $POST{'action:spellcheck'}) {
$did_spellcheck++;
my $s = new LJ::SpellCheck { 'spellcommand' => $LJ::SPELLER,
'color' => '<?hotcolor?>', };
my $event = LJ::ehtml($event);
$spellcheck_html = $s->check_html(\$event);
$spellcheck_html = "<?inerr $ML{'entryform.spellcheck.noerrors'} inerr?>" unless $spellcheck_html ne "";
$onload .= "pageload(0); "; # js fill-in off
my $date = LJ::html_datetime_decode({ 'name' => "date_ymd", }, \%POST);
($year, $mon, $mday) = split( /\D/, $date);
$hour = $POST{'hour'};
$min = $POST{'min'};
} else {
$onload .= "pageload(1); "; # js fill-in on
my @time = localtime(time);
$year = $time[5] + 1900;
$mon = sprintf("%02d", $time[4] + 1);
$mday = sprintf("%02d", $time[3]);
$hour = $time[2];
$min = sprintf("%02d", $time[1]);
}
# richtext
# 'switched_rte_on' is only set when the user first enables rte. We do this in a POST
# so any pre-existing text in the event and subject fields aren't lost when going to RTE.
# 'rich' is used to keep RTE mode enabled between pages, such as spellchecks.
# The $GET{'rich'} is simply for user bookmarking / faq linking convenience.
my $enabled_rte = $POST{'switched_rte_on'};
my $richtext = 1 if $GET{rich} || $POST{rich} ||
($enabled_rte && ! $spellcheck_html && ! $preview);
$$bodyopts .= "onunload=\"save_entry();\" " if $richtext;
my $print_entry_form = sub {
my $opts = shift;
# authentication box
my $auth = '';
if ($remote) { # so lynx won't show this
$auth .= "<tr valign='top' id='remotelogin' style='display: $remotelogin_display'><th>$ML{'.auth.poster'}</th><td><span id='remotelogin_content'>";
$auth .= BML::ml(".loggedinas", {'user' => $remote->{'user'}, 'altget' => "?altlogin=1" });
$auth .= "</span></td></tr>\n";
}
# table with username/password fields
$auth .= "<tr id='altlogin_username' style='display: $altlogin_display;' valign='top'>\n";
$auth .= "<th>" . BML::ml('Username') . ":</th>";
$auth .= "<td>" . LJ::html_text({ 'name' => 'user', 'size' => '15', 'maxlength' => '15',
'value' => $POST{'user'} || $GET{'user'} });
$auth .= "</td></tr>\n";
$auth .= "<tr id='altlogin_password' style='display: $altlogin_display;' valign='top'>";
$auth .= "<th>" . BML::ml('Password') . ":</th>";
$auth .= "<td>" . LJ::html_text({ 'type' => 'password', 'name' => 'password',
'size' => '15', 'maxlength' => '30' });
# posted with a user, but no password
if ($did_post && $auth_missing) {
$auth .= "<br /><?inerr $ML{'.error.nopass'} inerr?>";
}
$auth .= "</td></tr>";
# if they submit the form and are spellchecking, remember
# their settings from the GET requests
my $getextra;
$getextra .= "altlogin=1&" if $GET{'altlogin'};
$getextra .= "rich=1&" if $richtext;
chop $getextra;
$getextra = "?$getextra" if $getextra;
my $entry = {
'mode' => "update",
'auth_as_remote' => $auth_as_remote,
'subject' => $subject,
'event' => $event,
'datetime' => "$year-$mon-$mday $hour:$min",
'usejournal' => $POST{'usejournal'} || $GET{'usejournal'},
'auth' => $auth,
'remote' => $remote,
'spellcheck_html' => $spellcheck_html,
'clientversion' => "WebUpdate/2.0.0",
'richtext' => 1,
'richtext_on' => $richtext,
};
if ($did_post) {
$entry->{$_} = $POST{$_} foreach keys %POST;
}
if (LJ::isu($remote) && (!$did_post || $did_spellcheck) && $remote->readonly) {
$$body .= "<div id='readonly'><?warningbar ";
if ($LJ::HELPURL{'readonly'}) {
$$body .= BML::ml('.rowarn', {
'a_open' => "<a href='$LJ::HELPURL{readonly}'>",
'a_close' => "</a>"}
);
} else {
$$body .= BML::ml('.rowarn', {
'a_open' => '',
'a_close' => ''}
);
}
$$body .= " warningbar?><br /></div>";
}
$$body .= "<div style='width: 80%'><form method='post' action='update.bml$getextra' id='updateForm' name='updateForm'>";
if ($opts->{require_tos}){
$$body .= LJ::tosagree_html('update', $POST{agree_tos}, $errors->{require_tos});
}
$$body .= LJ::entry_form($entry, \$$head, \$onload, $errors);
$$body .= "</form></div>";
$$bodyopts .= "onload=\"$onload\" onresize=\"shift_contents();\" ";
return;
};
if ($did_post && !$did_spellcheck && !$showform && !$enabled_rte && !$preview ) {
# what's our authentication scheme for subsequent protocol actions?
my $flags = {};
my ($u, $user);
if ($POST{'user'} && # user argument given
! $user_is_remote && # user != remote
(!$remote || $GET{'altlogin'})) { # user has clicked alt auth
$user = $POST{'user'};
$u = LJ::load_user($user);
# Verify entered password, if it is present.
my $ok;
if ($POST{response}) {
$ok = LJ::challenge_check_login($u, $POST{chal}, $POST{response});
} else { # js disabled, fallback to plaintext
$ok = LJ::auth_okay($u, $POST{password});
}
$flags = { 'noauth' => 1, 'u' => $u } if $ok;
} elsif ($remote && LJ::check_referer()) { # assume remote if we have it
$flags = { 'noauth' => 1, 'u' => $remote };
$user = $remote->{'user'};
$u = $remote;
}
if ($u && ! $u->tosagree_verify) {
if ($POST{agree_tos}) {
my $err = "";
unless ($u->tosagree_set(\$err)) {
# error
BML::set_status(403); # 403 Forbidden
$errors->{require_tos} = $err;
$print_entry_form->({ require_tos => 1 });
return;
}
# successfully set
} else {
BML::set_status(403); # 403 Forbidden
$errors->{require_tos} = $ML{'tos.error'};
$print_entry_form->({ require_tos => 1 });
return;
}
}
# Check if the account they're posting to is read-only
my $uj = $POST{'usejournal'} ? LJ::load_user($POST{'usejournal'}) : $u;
if ($uj && $uj->readonly) {
# Tell the user they can't post since read only
BML::set_status(403); # 403 Forbidden
$$body .= "<?errorbar ";
$$body .= "<strong>$ML{'.error.update'}</strong> ";
$$body .= $LJ::MSG_READONLY_USER;
$$body .= " errorbar?><br />";
$print_entry_form->();
return
}
# do a login action
my $login_message;
{
# build a clientversion string
my $clientversion = "Web/2.0.0";
$clientversion .= 's' if $did_spellcheck;
# build a request object
my %req = ( 'mode' => 'login',
'ver' => $LJ::PROTOCOL_VER,
'clientversion' => $clientversion,
'user' => $user,
);
my %res;
LJ::do_request(\%req, \%res, $flags);
# error logging in ?
unless ($res{'success'} eq 'OK') {
$errors->{'auth'} = $ML{'.error.login'} . " " . LJ::ehtml($res{'errmsg'});
}
# server login message for user?
$login_message = LJ::auto_linkify(LJ::ehtml($res{'message'}))
if $res{'message'};
}
# any messages from the server?
if ($login_message) {
$$body .= "<?p <strong>$ML{'.loggingin'}</strong> $ML{'.servermsg'} p?><div style='margin-left: 40px'><b>$login_message</b></div>";
}
my %req = ( 'mode' => 'postevent',
'ver' => $LJ::PROTOCOL_VER,
'user' => $user,
'password' => $POST{'password'},
'usejournal' => $POST{'usejournal'},
);
LJ::entry_form_decode(\%req, \%POST);
if ($req{'event'} eq "") {
$errors->{'entry'} = "Must provide entry text";
}
my %res;
LJ::do_request(\%req, \%res, $flags);
if (!$errors) {
# examine response
my $update_message;
if ($res{'success'} eq "OK" && $res{'message'}) {
$update_message = LJ::auto_linkify(LJ::ehtml($res{'message'}));
}
# report results
$$body .= "<?p <strong>$ML{'.updating'}</strong> ";
if ($res{'success'} ne 'OK') {
# update failed?
BML::set_status(403); # 403 Forbidden
$$body .= "<br /><?errorbar <strong>$ML{'.error.update'}</strong> ";
$$body .= LJ::ehtml($res{'errmsg'}) . " errorbar?>";
$$body .= "<br /> p?>";
} else {
# short bail if this was posted moderated or some other special case (no itemid but a message)
if (!defined $res{itemid} && $res{message}) {
BML::set_status(403); # 403 Forbidden
$$body .= "<br />$res{message} p?>";
return;
}
# update success
my $ju;
if ($POST{'usejournal'}) {
$ju = LJ::load_user($POST{'usejournal'}); # posting as community
} elsif ($user) {
$ju = LJ::load_user($user); # posting not as user from form
} else {
$ju = $remote; # posting as remote
};
$$body .= BML::ml(".update.success", { 'uri' => LJ::journal_base($ju) . "/" });
my $juser = $ju->{'user'};
my ($itemid, $anum) = ($res{'itemid'}, $res{'anum'});
my $itemlink = LJ::item_link($ju, $itemid, $anum);
$itemid = $itemid * 256 + $anum;
$$body .= " p?><?p $ML{'.success.links'} p?><ul>" .
"<li><a href=\"$itemlink\">$ML{'.success.links.view'}</a></li>" .
"<li><a href=\"/editjournal.bml?journal=$juser&itemid=$itemid\">$ML{'.success.links.edit'}</a></li>" .
"<li><a href=\"/tools/memadd.bml?journal=$juser&itemid=$itemid\">$ML{'.success.links.memories'}</a></li>" .
"<li><a href=\"/edittags.bml?journal=$juser&itemid=$itemid\">$ML{'.success.links.tags'}</a></li>" .
"</ul>";
return;
}
}
}
$print_entry_form->();
return;
}
_code?><?page
title=> <?_code return $_[1]->{'title'}; _code?>
body=> <?_code return $_[1]->{'body'}; _code?>
bodyopts=><?_code return $_[1]->{'bodyopts'}; _code?>
head<=
<?entryformcss?>
<?_code
{
my $ret = $_[1]->{'head'};
$ret .= "<script language='JavaScript' type='text/javascript' src='$LJ::JSPREFIX/entry.js'></script>";
$ret .= (! $LJ::REQ_HEAD_HAS{'chalresp_js'}++) ? $LJ::COMMON_CODE{'chalresp_js'} : "";
return $ret;
}
_code?>
<=head
page?><?_c <LJDEP>
lib: LJ::SpellCheck
link: htdocs/users, htdocs/download/index.bml, htdocs/moodlist.bml
link: htdocs/update.bml, htdocs/lostinfo.bml, htdocs/support/faqbrowse.bml
link: htdocs/allpics.bml
post: htdocs/update.bml
</LJDEP> _c?>