ljr/local/cgi-bin/LJR/Gate.pm

235 lines
7.6 KiB
Perl
Raw Normal View History

2019-02-05 21:49:12 +00:00
use strict;
use XMLRPC::Lite;
use Digest::MD5;
use Time::Local;
use LJR::Distributed;
use LJR::xmlrpc;
use LJR::Viewuserstandalone;
require "$ENV{'LJHOME'}/cgi-bin/ljpoll.pl";
package LJR::Gate;
$LJR::Gate::clientver = 'LJR::Gate/0.02';
sub Authenticate {
my ($server, $user, $pass) = @_;
my $xmlrpc = new XMLRPC::Lite;
$xmlrpc->proxy("http://" . $server . "/interface/xmlrpc", timeout => 60);
my $xmlrpc_ret = LJR::xmlrpc::xmlrpc_call($xmlrpc, "LJ.XMLRPC.getchallenge");
return $xmlrpc_ret if $xmlrpc_ret->{"err_text"};
my $challenge = $xmlrpc_ret->{'result'}->{'challenge'};
my $response = Digest::MD5::md5_hex($challenge . Digest::MD5::md5_hex($pass));
my $xmlrpc_req = {
'username' => $user,
'auth_method' => 'challenge',
'auth_challenge' => $challenge,
'auth_response' => $response,
'ver' => 1,
'clientver' => $LJR::Gate::clientver,
};
$xmlrpc_ret = LJR::xmlrpc::xmlrpc_call($xmlrpc, "LJ.XMLRPC.login", $xmlrpc_req);
return $xmlrpc_ret if $xmlrpc_ret->{"err_text"};
return $xmlrpc;
}
sub ExportEntry {
my ($u, $req, $security, $jitemid, $anum) = @_;
return "User [" . $u->{'user'} . "] is not gated." unless LJR::Distributed::is_gated_local($u->{'user'});
my $dbr = LJ::get_db_reader();
return "Can't get database reader!" unless $dbr;
my $r;
$r = $dbr->selectrow_hashref (
"SELECT * FROM ljr_export_settings WHERE user=?",
undef, $u->{'user'});
my $ru;
$ru = LJR::Distributed::get_cached_user({ 'ru_id' => $r->{'ru_id'}});
$ru = LJR::Distributed::get_remote_server_byid($ru);
my $xmlrpc = new XMLRPC::Lite;
$xmlrpc->proxy($ru->{'servername'} . "/interface/xmlrpc", timeout => 60);
my $xmlrpc_ret;
my $xmlrpc_req;
my $challenge;
my $response;
my $real_event;
my $real_subject;
my $last_status;
if ($req->{'event'} !~ /\S/) {
$last_status = "removed entry.";
$real_event = $req->{'event'};
$real_subject = $req->{'subject'};
}
else {
my $item_url = LJ::item_link($u, $jitemid, $anum);
$last_status = "exported <a href=$item_url>entry</a>";
$real_event = LJR::Viewuserstandalone::expand_ljuser_tags($req->{'event'});
$real_subject = LJR::Viewuserstandalone::expand_ljuser_tags($req->{'subject'});
my $i=0;
while ($real_event =~ /lj-cut/ig) { $i++ };
while ($real_event =~ /\/lj-cut/ig) { $i-- };
if ($i gt 0) {
$real_event .= "</lj-cut>";
}
LJ::Poll::replace_polls_with_links(\$real_event);
LJ::EmbedModule->expand_entry($u, \$real_event, ('content_only' => 1));
unless ($req->{'props'}->{'opt_nocomments'}) {
LJR::Distributed::sign_exported_gate_entry($u, $jitemid, $anum, \$real_event);
}
}
$security = $req->{'sequrity'} if !$security && $req->{'security'};
$security = "public" unless $security;
$xmlrpc_req = {
'username' => $ru->{'username'},
'auth_method' => 'challenge',
'ver' => 1,
'clientver' => $LJR::Gate::clientver,
'subject' => $real_subject,
'event' => $real_event,
'year' => $req->{'year'},
'mon' => $req->{'mon'},
'day' => $req->{'day'},
'hour' => $req->{'hour'},
'min' => $req->{'min'},
'security' => $security,
'allowmask' => $req->{'allowmask'},
'props' => {
'current_moodid' => $req->{'props'}->{'current_moodid'},
'current_mood' => $req->{'props'}->{'current_mood'},
'current_music' => $req->{'props'}->{'current_music'},
'picture_keyword' => $req->{'props'}->{'picture_keyword'},
'taglist' => $req->{'props'}->{'taglist'},
'opt_backdated' => $req->{'props'}->{'opt_backdated'},
'opt_preformatted' => $req->{'props'}->{'opt_preformatted'},
'opt_nocomments' => 1,
},
};
my $is_invalid_remote_journal = sub {
my ($error_message) = @_;
if (
$error_message =~ /Invalid password/ ||
$error_message =~ /Selected journal no longer exists/ ||
$error_message =~ /account is suspended/ ||
$error_message =~ /Invalid username/
) {
return 1;
}
return 0;
};
my $is_invalid_remote_entry = sub {
my ($error_message) = @_;
if ($error_message =~ /Can\'t edit post from requested journal/) {
return 1;
}
return 0;
};
my $post_new_event = sub {
$xmlrpc_ret = LJR::xmlrpc::xmlrpc_call($xmlrpc, "LJ.XMLRPC.getchallenge");
return $xmlrpc_ret->{"err_text"} if $xmlrpc_ret->{"err_text"};
$challenge = $xmlrpc_ret->{'result'}->{'challenge'};
$response = Digest::MD5::md5_hex($challenge . Digest::MD5::md5_hex($r->{'remote_password'}));
$xmlrpc_req->{'auth_challenge'} = $challenge;
$xmlrpc_req->{'auth_response'} = $response;
my $item_time = Time::Local::timelocal(0, $req->{'min'}, $req->{'hour'},
$req->{'day'}, $req->{'mon'} - 1, $req->{'year'});
if ((time - $item_time) > 60*60*24) {
$xmlrpc_req->{'props'}->{'opt_backdated'} = 1;
}
$xmlrpc_ret = LJR::xmlrpc::xmlrpc_call($xmlrpc, "LJ.XMLRPC.postevent", $xmlrpc_req);
if ($xmlrpc_ret->{'err_text'}) {
if ($is_invalid_remote_journal->($xmlrpc_ret->{'err_text'})) {
$r = LJR::Distributed::update_export_status($u->{'user'}, 0, "ERROR: " . $xmlrpc_ret->{'err_text'});
}
else {
$r = LJR::Distributed::update_export_status($u->{'user'}, 1, "ERROR: " . $xmlrpc_ret->{'err_text'});
}
return $xmlrpc_ret->{"err_text"} . " " . ($r->{'err'} ? $r->{'errtext'} : "");
}
my $rhtml_id = $xmlrpc_ret->{'result'}->{'itemid'} * 256 +
$xmlrpc_ret->{'result'}->{'anum'};
$r = LJR::Distributed::store_remote_itemid(
$u,
$jitemid,
$ru->{'ru_id'},
$xmlrpc_ret->{'result'}->{'itemid'},
$rhtml_id,
"E"
);
return
"store_remote_itemid: " . $u->{'user'} . "," .
$jitemid . "," . $ru->{'ru_id'} . "," .
$xmlrpc_ret->{'result'}->{'itemid'} . "," . $rhtml_id . ": " .
$r->{"errtext"} if $r->{"err"};
};
my $ritem = LJR::Distributed::get_remote_itemid($u->{'userid'}, $jitemid, "E");
if ($ritem && ($req->{'props'}->{'revnum'} || $req->{'event'} !~ /\S/)) {
$xmlrpc_ret = LJR::xmlrpc::xmlrpc_call($xmlrpc, "LJ.XMLRPC.getchallenge");
return $xmlrpc_ret->{"err_text"} if $xmlrpc_ret->{"err_text"};
$challenge = $xmlrpc_ret->{'result'}->{'challenge'};
$response = Digest::MD5::md5_hex($challenge . Digest::MD5::md5_hex($r->{'remote_password'}));
$xmlrpc_req->{'auth_challenge'} = $challenge;
$xmlrpc_req->{'auth_response'} = $response;
$xmlrpc_req->{'itemid'} = $ritem->{'ritemid'};
$xmlrpc_ret = LJR::xmlrpc::xmlrpc_call($xmlrpc, "LJ.XMLRPC.editevent", $xmlrpc_req);
if ($xmlrpc_ret->{'err_text'}) {
if ($is_invalid_remote_entry->($xmlrpc_ret->{'err_text'})) {
LJR::Distributed::remove_remote_itemid($u, $jitemid, $ru->{'ru_id'}, $ritem->{'ritemid'}, "E");
my $errmsg = $post_new_event->();
return $errmsg if $errmsg;
}
elsif ($is_invalid_remote_journal->($xmlrpc_ret->{'err_text'})) {
$r = LJR::Distributed::update_export_status($u->{'user'}, 0, "ERROR: " . $xmlrpc_ret->{'err_text'});
return $xmlrpc_ret->{"err_text"} . " " . ($r->{'err'} ? $r->{'errtext'} : "");
}
$r = LJR::Distributed::update_export_status($u->{'user'}, 1, "ERROR: " . $xmlrpc_ret->{'err_text'});
return $xmlrpc_ret->{"err_text"} . " " . ($r->{'err'} ? $r->{'errtext'} : "");
}
if ($req->{'event'} !~ /\S/) {
LJR::Distributed::remove_remote_itemid($u, $jitemid, $ru->{'ru_id'}, $ritem->{'ritemid'}, "E");
}
}
else {
my $errmsg = $post_new_event->();
return $errmsg if $errmsg;
}
$r = LJR::Distributed::update_export_status($u->{'user'}, 1, "OK: $last_status");
return $r->{'errtext'} if $r->{'err'};
return;
}