[dw-free] Allow importing of your journal from another LiveJournal-based site.
[commit: http://hg.dwscoalition.org/dw-free/rev/0fd5c96b9882]
http://bugs.dwscoalition.org/show_bug.cgi?id=114
Add verification step to the importer so we can move password checks off to
a separate IP address. Also fixes the issue of someone importing some other
random user's bio and userpics.
Patch by
mark.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=114
Add verification step to the importer so we can move password checks off to
a separate IP address. Also fixes the issue of someone importing some other
random user's bio and userpics.
Patch by
![[staff profile]](https://www.dreamwidth.org/img/silk/identity/user_staff.png)
Files modified:
- bin/worker/content-importer-verify
- bin/worker/import-scheduler
- cgi-bin/DW/Worker/ContentImporter.pm
- cgi-bin/DW/Worker/ContentImporter/LiveJournal/Verify.pm
- cgi-bin/LJ/Event/ImportStatus.pm
- htdocs/misc/import.bml
-------------------------------------------------------------------------------- diff -r c56a6080fdcd -r 0fd5c96b9882 bin/worker/content-importer-verify --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bin/worker/content-importer-verify Wed Apr 15 02:02:34 2009 +0000 @@ -0,0 +1,32 @@ +#!/usr/bin/perl +# +# content-importer-verify +# +# This importer job only does verification steps, which is responsible for +# doing checks on the username and password given by the user. This should +# be run on a server on an IP other than your main import workers. +# +# Authors: +# Andrea Nall <anall@andreanall.com> +# Mark Smith <mark@dreamwidth.org> +# +# Copyright (c) 2009 by Dreamwidth Studios, LLC. +# +# This program is free software; you may redistribute it and/or modify it under +# the same terms as Perl itself. For a copy of the license, please reference +# 'perldoc perlartistic' or 'perldoc perlgpl'. +# + +use strict; +use lib "$ENV{LJHOME}/cgi-bin"; + +require 'ljlib.pl'; + +use LJ::Worker::TheSchwartz; +use DW::Worker::ContentImporter::LiveJournal::Verify; + +schwartz_decl( "DW::Worker::ContentImporter::LiveJournal::Verify" ); + +$0 = 'content-importer [bored]'; + +schwartz_work(); diff -r c56a6080fdcd -r 0fd5c96b9882 bin/worker/import-scheduler --- a/bin/worker/import-scheduler Tue Apr 14 17:34:07 2009 +0000 +++ b/bin/worker/import-scheduler Wed Apr 15 02:02:34 2009 +0000 @@ -109,6 +109,7 @@ sub worker { lj_userpics => 'DW::Worker::ContentImporter::LiveJournal::Userpics', lj_friends => 'DW::Worker::ContentImporter::LiveJournal::Friends', lj_friendgroups => 'DW::Worker::ContentImporter::LiveJournal::FriendGroups', + lj_verify => 'DW::Worker::ContentImporter::LiveJournal::Verify', }->{ $item->{item} } || die 'unknown item '; my $sh = LJ::theschwartz() diff -r c56a6080fdcd -r 0fd5c96b9882 cgi-bin/DW/Worker/ContentImporter.pm --- a/cgi-bin/DW/Worker/ContentImporter.pm Tue Apr 14 17:34:07 2009 +0000 +++ b/cgi-bin/DW/Worker/ContentImporter.pm Wed Apr 15 02:02:34 2009 +0000 @@ -164,14 +164,14 @@ sub temp_fail { return; } -=head2 C<< $class->ok( $import_data, $item, $job )>> +=head2 C<< $class->ok( $import_data, $item, $job, $show )>> Successfully end this import job. =cut sub ok { - my ( $class, $imp, $item, $job ) = @_; + my ( $class, $imp, $item, $job, $show ) = @_; $0 = 'content-importer [bored]'; if ( my $dbh = LJ::get_db_writer() ) { @@ -182,7 +182,8 @@ sub ok { } # advise the user this finished - LJ::Event::ImportStatus->new( $imp->{userid}, $item, { type => 'ok' } )->fire; + LJ::Event::ImportStatus->new( $imp->{userid}, $item, { type => 'ok' } )->fire + unless defined $show && $show == 0; $job->completed; return; diff -r c56a6080fdcd -r 0fd5c96b9882 cgi-bin/DW/Worker/ContentImporter/LiveJournal/Verify.pm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cgi-bin/DW/Worker/ContentImporter/LiveJournal/Verify.pm Wed Apr 15 02:02:34 2009 +0000 @@ -0,0 +1,89 @@ +#!/usr/bin/perl +# +# DW::Worker::ContentImporter::LiveJournal::Verify +# +# Importer worker for LiveJournal-based site verification of logins and +# passwords. +# +# Authors: +# Andrea Nall <anall@andreanall.com> +# Mark Smith <mark@dreamwidth.org> +# +# Copyright (c) 2009 by Dreamwidth Studios, LLC. +# +# This program is free software; you may redistribute it and/or modify it under +# the same terms as Perl itself. For a copy of the license, please reference +# 'perldoc perlartistic' or 'perldoc perlgpl'. +# + +package DW::Worker::ContentImporter::LiveJournal::Verify; +use strict; +use base 'DW::Worker::ContentImporter::LiveJournal'; + +use Carp qw/ croak confess /; + +sub work { + my ( $class, $job ) = @_; + + eval { try_work( $class, $job ); }; + if ( $@ ) { + warn "Failure running job: $@\n"; + return $class->temp_fail( $job, 'Failure running job: %s', $@ ); + } +} + +sub try_work { + my ( $class, $job ) = @_; + my $opts = $job->arg; + my $data = $class->import_data( $opts->{userid}, $opts->{import_data_id} ); + + # failure wrappers for convenience + my $fail = sub { return $class->fail( $data, 'lj_verify', $job, @_ ); }; + my $ok = sub { return $class->ok( $data, 'lj_verify', $job, @_ ); }; + my $temp_fail = sub { return $class->temp_fail( $data, 'lj_verify', $job, @_ ); }; + + # setup + my $u = LJ::load_userid( $data->{userid} ) + or return $fail->( 'Unable to load target with id %d.', $data->{userid} ); + $0 = sprintf( 'content-importer [verify: %s(%d)]', $u->user, $u->id ); + + # we verify by doing a simple tags call. yes, this means that we end up + # getting a user's tags twice... but I'm okay with that, we'll live + my $r = $class->call_xmlrpc( $data, 'getusertags' ); + + # now, we have to see if the error contains 'Invalid password' or something else + if ( $r && $r->{fault} && $r->{faultString} =~ /Invalid password/ ) { + # mark the rest of the import as aborted, since something went wrong + my $dbh = LJ::get_db_writer(); + $dbh->do( + q{UPDATE import_items SET status = 'aborted' + WHERE userid = ? AND item <> 'lj_verify' + AND import_data_id = ? AND status = 'init'}, + undef, $u->id, $opts->{import_data_id} + ); + + # this is a permanent failure. if the password is bad, we're not going to ever + # bother retrying. that's life. + return $fail->( 'Username or password rejected by ' . $data->{hostname} . '.' ); + } + + # if we got any other type of failure, call it temporary... + return $temp_fail->( 'XMLRPC failure: ' . $r->{faultString} ) + if ! $r || $r->{fault}; + + # mark the next group as ready to schedule + my $dbh = LJ::get_db_writer(); + $dbh->do( + q{UPDATE import_items SET status = 'ready' + WHERE userid = ? AND item IN ('lj_bio', 'lj_userpics', 'lj_friendgroups', 'lj_tags') + AND import_data_id = ? AND status = 'init'}, + undef, $u->id, $opts->{import_data_id} + ); + + # okay, but don't fire off a message to say it's done, this job doesn't matter to + # the user unless it fails + return $ok->( 0 ); +} + + +1; diff -r c56a6080fdcd -r 0fd5c96b9882 cgi-bin/LJ/Event/ImportStatus.pm --- a/cgi-bin/LJ/Event/ImportStatus.pm Tue Apr 14 17:34:07 2009 +0000 +++ b/cgi-bin/LJ/Event/ImportStatus.pm Wed Apr 15 02:02:34 2009 +0000 @@ -41,6 +41,7 @@ sub new { lj_friends => 4, lj_friendgroups => 5, lj_userpics => 6, + lj_verify => 7, # other import types ... }->{$type}; @@ -87,6 +88,7 @@ sub as_html { 4 => 'friends have', 5 => 'friend groups have', 6 => 'usericons have', + 7 => 'import has', }->{$self->arg1} || 'ERROR, INVALID TYPE'; # now success message diff -r c56a6080fdcd -r 0fd5c96b9882 htdocs/misc/import.bml --- a/htdocs/misc/import.bml Tue Apr 14 17:34:07 2009 +0000 +++ b/htdocs/misc/import.bml Wed Apr 15 02:02:34 2009 +0000 @@ -79,12 +79,16 @@ body<= $POST{lj_friendgroups} = 1; } + # everybody needs a verifier + $POST{lj_verify} = 1; + # default job status my @jobs = ( - ['lj_userpics', 'ready'], - ['lj_bio', 'ready'], - ['lj_tags', 'ready'], - ['lj_friendgroups', 'ready'], + ['lj_verify', 'ready'], + ['lj_userpics', 'init'], + ['lj_bio', 'init'], + ['lj_tags', 'init'], + ['lj_friendgroups', 'init'], # ['lj_friends', 'init' ], ['lj_entries', 'init' ], ['lj_comments', 'init' ], --------------------------------------------------------------------------------