mark: A photo of Mark kneeling on top of the Taal Volcano in the Philippines. It was a long hike. (Default)
Mark Smith ([staff profile] mark) wrote in [site community profile] changelog2012-01-17 08:18 am

[dw-free] ability to "claim" your OpenID and update imported posts/comments as coming from

[commit: http://hg.dwscoalition.org/dw-free/rev/b8a9b2c3c047]

http://bugs.dwscoalition.org/show_bug.cgi?id=4201

Initial support for claiming an OpenID account.

The only shortcoming of this, right now, is that it doesn't update talkleft.
This means that the "you've posted 2349822 comments" text will be wrong on
the profile pages. I'm not sure how I want to fix that yet.

The actual content will be fine, though.

Patch by [staff profile] mark.

Files modified:
  • bin/upgrading/update-db-general.pl
  • bin/worker/change-poster-id
  • cgi-bin/DW/Controller/OpenID.pm
  • cgi-bin/DW/User/OpenID.pm
  • cgi-bin/DW/Worker/ChangePosterId.pm
  • cgi-bin/DW/Worker/ContentImporter/LiveJournal.pm
  • cgi-bin/LJ/Sendmail.pm
  • cgi-bin/LJ/User.pm
  • views/openid/claim.tt
  • views/openid/claim.tt.text
  • views/openid/claim_confirm.tt
  • views/openid/claim_confirm.tt.text
  • views/openid/claim_sent.tt
  • views/openid/claim_sent.tt.text
--------------------------------------------------------------------------------
diff -r bd7b2d844877 -r b8a9b2c3c047 bin/upgrading/update-db-general.pl
--- a/bin/upgrading/update-db-general.pl	Tue Jan 10 19:51:34 2012 +0800
+++ b/bin/upgrading/update-db-general.pl	Tue Jan 17 08:24:55 2012 +0000
@@ -3095,7 +3095,6 @@
 )
 EOC
 
-
 register_tablecreate('renames', <<'EOC');
 CREATE TABLE renames (
     renid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
@@ -3122,6 +3121,16 @@
 )
 EOC
 
+register_tablecreate("openid_claims", <<'EOC');
+CREATE TABLE openid_claims (
+    userid          INT UNSIGNED NOT NULL,
+    claimed_userid  INT UNSIGNED NOT NULL,
+
+    PRIMARY KEY (userid),
+    INDEX (claimed_userid)
+)
+EOC
+
 # NOTE: new table declarations go ABOVE here ;)
 
 ### changes
diff -r bd7b2d844877 -r b8a9b2c3c047 bin/worker/change-poster-id
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/worker/change-poster-id	Tue Jan 17 08:24:55 2012 +0000
@@ -0,0 +1,26 @@
+#!/usr/bin/perl
+#
+# bin/worker/change-poster-id
+#
+# Worker that updates the poster of content in the database.
+#
+# Authors:
+#     Mark Smith <mark@dreamwidth.org>
+#
+# Copyright (c) 2012 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 warnings;
+
+use lib "$ENV{LJHOME}/cgi-bin";
+use LJ::Worker::TheSchwartz;
+use DW::Worker::ChangePosterId;
+
+schwartz_decl( $_ )
+    foreach ( DW::Worker::ChangePosterId->schwartz_capabilities );
+
+schwartz_work(); # Never returns.
diff -r bd7b2d844877 -r b8a9b2c3c047 cgi-bin/DW/Controller/OpenID.pm
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cgi-bin/DW/Controller/OpenID.pm	Tue Jan 17 08:24:55 2012 +0000
@@ -0,0 +1,181 @@
+#!/usr/bin/perl
+#
+# DW::Controller::OpenID
+#
+# This controller is for OpenID related pages.
+#
+# Authors:
+#      Mark Smith <mark@dreamwidth.org>
+#
+# Copyright (c) 2011 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::Controller::OpenID;
+
+use strict;
+use warnings;
+use DW::Routing;
+use DW::Controller;
+use DW::Template;
+
+DW::Routing->register_string( '/openid/claim', \&openid_claim_handler, app => 1 );
+DW::Routing->register_string( '/openid/claimed', \&openid_claimed_handler, app => 1 );
+DW::Routing->register_string( '/openid/claim_confirm', \&openid_claim_confirm_handler, app => 1 );
+
+sub openid_claim_handler {
+    my $opts = shift;
+    my $r = DW::Request->get;
+    my ( $ok, $rv ) = controller();
+    return $rv unless $ok;
+
+    my $err = sub {
+        my @errors = map { $_ =~ /^\./ ? LJ::Lang::ml( "/openid/claim.tt$_" ) : $_ } @_;
+        return DW::Template->render_template( 'openid/claim.tt', { error_list => \@errors } );
+    };
+
+    return $err->( '.error.no_openid' )
+        unless LJ::OpenID::consumer_enabled();
+
+    my $u = $rv->{remote};
+    my @claims = $u->get_openid_claims;
+    return DW::Template->render_template( 'openid/claim.tt', { claims => \@claims } )
+        unless $r->did_post;
+
+    # at this point, the user did a POST, so we want to try to perform an OpenID
+    # login on the given URL.
+    my $args = $r->post_args;
+    my $url = LJ::trim( $args->{openid_url} );
+    return $err->( '.error.required' ) unless $url;
+    return $err->( '.error.invalidchars' ) if $url =~ /[\<\>\s]/;
+
+    my $csr = LJ::OpenID::consumer();
+    my $tried_local_ref = LJ::OpenID::blocked_hosts( $csr );
+
+    my $claimed_id = eval { $csr->claimed_identity($url); };
+    return $err->( $@ ) if $@;
+
+    unless ( $claimed_id ) {
+        return $err->( LJ::Lang::ml( '/openid/claim.tt.error.cantuseownsite', { sitename => $LJ::SITENAMESHORT } ) )
+            if $$tried_local_ref;
+        return $err->( $csr->err );
+    }
+
+    my $check_url = $claimed_id->check_url(
+        return_to => "$LJ::SITEROOT/openid/claimed",
+        trust_root => "$LJ::SITEROOT/",
+        delayed_return => 1,
+    );
+    return $r->redirect( $check_url );
+}
+
+sub openid_claimed_handler {
+    my $opts = shift;
+    my $r = DW::Request->get;
+    my ( $ok, $rv ) = controller();
+    return $rv unless $ok;
+
+    my $err = sub {
+        my @errors = map { $_ =~ /^\./ ? LJ::Lang::ml( "/openid/claim.tt$_" ) : $_ } @_;
+        return DW::Template->render_template( 'openid/claim.tt', { error_list => \@errors } );
+    };
+
+    return $err->( '.error.no_openid' )
+        unless LJ::OpenID::consumer_enabled();
+
+    # attempt to verify the user
+    my $u = $rv->{remote};
+    my $args = $r->get_args;
+    return $r->redirect( "$LJ::SITEROOT/openid/claim" )
+        unless exists $args->{'openid.mode'};
+
+    my $csr = LJ::OpenID::consumer( $args->as_hashref );
+    return $r->redirect( "$LJ::SITEROOT/openid/claim" )
+        if $csr->user_cancel;
+
+    my $setup = $csr->user_setup_url;
+    return $r->redirect( $setup ) if $setup;
+
+    my $return_to = "$LJ::SITEROOT/openid/claimed";
+    return $r->redirect( "$LJ::SITEROOT/openid/claim" )
+        if $args->{'openid.return_to'} && $args->{'openid.return_to'} !~ /^\Q$return_to\E/;
+
+    my $vident = eval { $csr->verified_identity; };
+    return $err->( $@ ) if $@;
+    return $err->( $csr->err ) unless $vident;
+
+    my $url = $vident->url;
+    return $err->( '.error.invalidchars' ) if $url =~ /[\<\>\s]/;
+
+    my $ou = LJ::User::load_identity_user( 'O', $url, $vident );
+    return $err->( '.error.failed_vivification' ) unless $ou;
+
+    # generate the authaction
+    my $aa = LJ::register_authaction( $u->id, 'claimopenid', $ou->id )
+        or return $err->( 'Internal error generating authaction.' );
+    my $confirm_url = "$LJ::SITEROOT/openid/claim_confirm?auth=$aa->{aaid}.$aa->{authcode}";
+
+    # great, let's send them an email to confirm
+    my $email = LJ::Lang::ml( '/openid/claim.tt.email', {
+        sitename      => $LJ::SITENAME,
+        sitenameshort => $LJ::SITENAMESHORT,
+        remote        => $u->display_name,
+        openid        => $ou->display_name,
+        confirm_url   => $confirm_url,
+    } );
+    LJ::send_mail( {
+        to      => $u->email_raw,
+        from    => $LJ::ADMIN_EMAIL,
+        subject => LJ::Lang::ml( '/openid/claim.tt.email.subject', { sitename => $LJ::SITENAME } ),
+        body    => $email,
+        delay   => 1800,
+    } );
+
+    # now give them the conf page
+    return DW::Template->render_template( 'openid/claim_sent.tt' );
+}
+
+sub openid_claim_confirm_handler {
+    my $opts = shift;
+    my $r = DW::Request->get;
+    my ( $ok, $rv ) = controller();
+    return $rv unless $ok;
+
+    my $err = sub {
+        my @errors = map { $_ =~ /^\./ ? LJ::Lang::ml( "/openid/claim_confirm.tt$_" ) : $_ } @_;
+        return DW::Template->render_template( 'openid/claim_confirm.tt', { error_list => \@errors } );
+    };
+
+    my $u = $rv->{remote};
+    my @claims = $u->get_openid_claims;
+    my $args = $r->get_args;
+
+    # verify that the link they followed is good
+    my ( $aaid, $authcode ) = ( $1, $2 )
+        if $args->{auth} =~ /^(\d+)\.(\w+)$/;
+    my $aa = LJ::is_valid_authaction( $aaid, $authcode );
+    return $err->( '.error.invalid_auth' )
+        unless $aa && ref $aa eq 'HASH' && $aa->{used} eq 'N' && $aa->{action} eq 'claimopenid';
+    return $err->( '.error.wrong_account' )
+        if $aa->{userid} != $u->id;
+
+    # now make sure nobody has since claimed that account
+    my $ou = LJ::load_userid( $aa->{arg1}+0 );
+    return $err->( '.error.invalid_account' )
+        unless $ou && $ou->is_identity;
+    if ( my $cbu = $ou->claimed_by ) {
+        return $err->( '.error.already_claimed_self' )
+            if $cbu->equals( $u );
+        return $err->( '.error.already_claimed_other' );
+    }
+
+    # now start the claim process
+    $u->claim_identity( $ou );
+
+    return DW::Template->render_template( 'openid/claim_confirm.tt' ); 
+}
+
+1;
diff -r bd7b2d844877 -r b8a9b2c3c047 cgi-bin/DW/User/OpenID.pm
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cgi-bin/DW/User/OpenID.pm	Tue Jan 17 08:24:55 2012 +0000
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+#
+# DW::User::OpenID
+#
+# Adds OpenID claim functionality.
+#
+# Authors:
+#      Mark Smith <mark@dreamwidth.org>
+#
+# Copyright (c) 2012 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::User::OpenID;
+use strict;
+
+# get the claims that a user has. this returns an array of user objects for
+# the relevant OpenID accounts.
+sub get_openid_claims {
+    my $u = LJ::want_user( $_[0] )
+        or die "need a user!\n";
+
+    my $dbh = LJ::get_db_writer()
+        or die "need database\n";
+    my $claims = $dbh->selectall_arrayref(
+        'SELECT userid, claimed_userid FROM openid_claims WHERE userid = ?',
+        undef, $u->id
+    );
+    return () unless $claims && ref $claims eq 'ARRAY';
+    return map { LJ::load_userid( $_->[1] ) } @$claims;
+}
+*LJ::User::get_openid_claims = \&get_openid_claims;
+
+# if we're claimed, return a user object of the claimant
+sub claimed_by {
+    my $u = LJ::want_user( $_[0] )
+        or die "need a user!\n";
+    return undef unless $u->is_identity;
+
+    my $dbh = LJ::get_db_writer()
+        or die "need database\n";
+    my $userid = $dbh->selectrow_array(
+        'SELECT userid FROM openid_claims WHERE claimed_userid = ?',
+        undef, $u->id
+    );
+    return undef unless $userid;
+    return LJ::load_userid( $userid );
+}
+*LJ::User::claimed_by = \&claimed_by;
+
+# do a claim
+sub claim_identity {
+    my $u = LJ::want_user( $_[0] )
+        or die "need a user!\n";
+    my $ou = LJ::want_user( $_[1] )
+        or die "need an identity!\n";
+
+    die "account types not right in claiming\n"
+        unless $u->is_person && $ou->is_identity;
+
+    # Insert this into the database. We do this first in case it fails,
+    # then we don't want to kick off the job below.
+    my $dbh = LJ::get_db_writer()
+        or die "need database\n";
+    $dbh->do( 'INSERT INTO openid_claims (userid, claimed_userid) VALUES (?, ?)',
+               undef, $u->id, $ou->id );
+    die "database error claiming: " . $dbh->errstr . "\n"
+        if $dbh->err;
+
+    # Now we need to kick off the job that actually goes and reclaims things.
+    my $sclient = LJ::theschwartz()
+        or die "openid claiming requires TheSchwartz\n";
+    $sclient->insert('DW::Worker::ChangePosterId',
+            { from_userid => $ou->id, to_userid => $u->id } );
+    return 1;
+}
+*LJ::User::claim_identity = \&claim_identity;
+
+1;
diff -r bd7b2d844877 -r b8a9b2c3c047 cgi-bin/DW/Worker/ChangePosterId.pm
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cgi-bin/DW/Worker/ChangePosterId.pm	Tue Jan 17 08:24:55 2012 +0000
@@ -0,0 +1,146 @@
+#!/usr/bin/perl
+#
+# DW::Worker::ChangePosterId
+#
+# Does the heavy lifting of changing a poster.
+#
+# Authors:
+#     Mark Smith <mark@dreamwidth.org>
+#
+# Copyright (c) 2012 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 warnings;
+
+package DW::Worker::ChangePosterId;
+use base 'TheSchwartz::Worker';
+use LJ::User;
+
+sub schwartz_capabilities { return ('DW::Worker::ChangePosterId'); }
+sub max_retries { 5 }
+sub retry_delay { return (10, 30, 60, 300, 600)[$_[1]]; }
+sub keep_exit_status_for { 86400 }
+sub grab_for { 86400 }
+
+sub work {
+    my ( $class, $job ) = @_;
+
+    my %arg = %{$job->arg};
+    my $fu = LJ::load_userid( delete $arg{from_userid} );
+    my $tu = LJ::load_userid( delete $arg{to_userid} );
+    return $job->failed( 'Failed to load the involved users.' )
+        unless $fu && $tu;
+    return $job->permanent_failure( 'Unknown keys: ' . join( ', ', keys %arg ))
+        if keys %arg;
+    return $job->permanent_failure( 'Makes no sense! The users are the same?!' )
+        if $fu->id == $tu->id;
+
+    # Basically, all this job is doing is reparenting comments and posts that
+    # have been made by a particular user. We try to be gentle to the database by
+    # only updating a few rows at a time, but there's no way this isn't going to
+    # pound the system on large users. Memcache complicates things, too, since we
+    # might cache things and then update them underneath it.
+
+    foreach my $cid ( @LJ::CLUSTERS ) {
+        my $dbcm = LJ::get_cluster_master( $cid )
+            or return $job->failed( "Temporary failure connecting to cluster $cid." );
+
+        eval {
+            fix_entries( $dbcm, $fu, $tu );
+            fix_comments( $dbcm, $fu, $tu );
+        };
+        return $job->failed( "Temporary failure fixing things: $@" ) if $@;
+    }
+    $job->completed;
+
+    # we're done and happy
+    $0 = 'change-poster-id [bored]';
+}
+
+sub fix_entries {
+    my ( $dbcm, $fu, $tu ) = @_;
+
+    my $total = $dbcm->selectrow_array( 'SELECT COUNT(*) FROM log2 WHERE posterid = ?', undef, $fu->id );
+    title( $fu, $tu, 'entries', 0, $total );
+
+    my $ct = 0;
+    while ( 1 ) {
+        my $rows = $dbcm->selectall_arrayref(
+            'SELECT journalid, jitemid FROM log2 WHERE posterid = ? LIMIT 100',
+            undef, $fu->id
+        );
+        die $dbcm->errstr if $dbcm->err;
+        last unless $rows && @$rows;
+
+        foreach my $row ( @$rows ) {
+            my ( $jid, $jitemid ) = @$row;
+
+            $ct++;
+            title( $fu, $tu, 'entries', $ct, $total );
+
+            # update the db
+            $dbcm->do( 'UPDATE log2 SET posterid = ? ' .
+                'WHERE journalid = ? AND jitemid = ? AND posterid = ? LIMIT 1',
+                undef, $tu->id, $jid, $jitemid, $fu->id
+            );
+            die $dbcm->errstr if $dbcm->err;
+
+            # now nuke the memcache
+            LJ::MemCache::delete( [ $jid, "log2:$jid:$jitemid" ] );
+            LJ::MemCache::delete( [ $jid, "log2lt:$jid" ] );
+        }
+    }
+}
+
+sub fix_comments {
+    my ( $dbcm, $fu, $tu ) = @_;
+
+    my $total = $dbcm->selectrow_array( 'SELECT COUNT(*) FROM talk2 WHERE posterid = ?', undef, $fu->id );
+    title( $fu, $tu, 'comments', 0, $total );
+
+    my $ct = 0;
+    while ( 1 ) {
+        my $rows = $dbcm->selectall_arrayref(
+            'SELECT journalid, jtalkid, nodetype, nodeid ' .
+            'FROM talk2 WHERE posterid = ? LIMIT 100',
+            undef, $fu->id
+        );
+        die $dbcm->errstr if $dbcm->err;
+        last unless $rows && @$rows;
+
+        foreach my $row ( @$rows ) {
+            my ( $jid, $jtalkid, $nodetype, $nodeid ) = @$row;
+
+            $ct++;
+            title( $fu, $tu, 'comments', $ct, $total );
+
+            # update the db
+            $dbcm->do( 'UPDATE talk2 SET posterid = ? ' .
+                'WHERE journalid = ? AND jtalkid = ? AND posterid = ? LIMIT 1',
+                undef, $tu->id, $jid, $jtalkid, $fu->id
+            );
+            die $dbcm->errstr if $dbcm->err;
+
+            # now nuke the memcache
+            LJ::MemCache::delete( [ $jid, "talk2:$jid:$nodetype:$nodeid" ] );
+            LJ::MemCache::delete( [ $jid, "talk2row:$jid:$jtalkid" ] );
+        }
+    }
+
+    # fix the "comments posted" entry on the profile
+    LJ::MemCache::delete( [ $fu->id, "talkleftct:" . $fu->id ] );
+    LJ::MemCache::delete( [ $tu->id, "talkleftct:" . $tu->id ] );
+}
+
+sub title {
+    my ( $fu, $tu, $which, $cur, $total ) = @_;
+    my $title = sprintf( 'change-poster-id [%s :: %s -> %s :: %d/%d :: %0.2f%%]',
+            $which, $fu->display_name, $tu->display_name, $cur, $total, $cur/$total*100 );
+    $0 = $title;
+}
+
+1;
diff -r bd7b2d844877 -r b8a9b2c3c047 cgi-bin/DW/Worker/ContentImporter/LiveJournal.pm
--- a/cgi-bin/DW/Worker/ContentImporter/LiveJournal.pm	Tue Jan 10 19:51:34 2012 +0800
+++ b/cgi-bin/DW/Worker/ContentImporter/LiveJournal.pm	Tue Jan 17 08:24:55 2012 +0000
@@ -193,8 +193,15 @@
 
     $dbh->do( 'REPLACE INTO import_usermap (hostname, username, identity_userid, feed_userid) VALUES (?, ?, ?, ?)',
               undef, $data->{hostname}, $user, $oid, $fid );
+
+    # load this user and determine if they've been claimed. if so, we want to post
+    # all content as from the claimant.
+    my $ou = LJ::load_userid( $oid );
+    if ( my $cu = $ou->claimed_by ) {
+        $oid = $cu->id;
+    }
+
     $MAPS{$data->{hostname}}->{$user} = [ $oid, $fid ];
-
     return ( $oid, $fid );
 }
 
diff -r bd7b2d844877 -r b8a9b2c3c047 cgi-bin/LJ/Sendmail.pm
--- a/cgi-bin/LJ/Sendmail.pm	Tue Jan 10 19:51:34 2012 +0800
+++ b/cgi-bin/LJ/Sendmail.pm	Tue Jan 17 08:24:55 2012 +0000
@@ -183,6 +183,7 @@
                                             data     => $msg->as_string,
                                         },
                                         coalesce => $host,
+                                        run_after => $opt->{delay} ? time() + $opt->{delay} : undef,
                                         );
         my $h = $sclient->insert($job);
 
diff -r bd7b2d844877 -r b8a9b2c3c047 cgi-bin/LJ/User.pm
--- a/cgi-bin/LJ/User.pm	Tue Jan 10 19:51:34 2012 +0800
+++ b/cgi-bin/LJ/User.pm	Tue Jan 17 08:24:55 2012 +0000
@@ -42,6 +42,7 @@
 use DW::Pay;
 use DW::User::ContentFilters;
 use DW::User::Edges;
+use DW::User::OpenID;
 use DW::InviteCodes::Promo;
 use DW::SiteScheme;
 use DW::Template;
diff -r bd7b2d844877 -r b8a9b2c3c047 views/openid/claim.tt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/openid/claim.tt	Tue Jan 17 08:24:55 2012 +0000
@@ -0,0 +1,43 @@
+[%# claim.tt
+
+The page for claiming an OpenID account.
+
+Authors:
+    Mark Smith <mark@dreamwidth.org>
+
+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'.
+%]
+
+[%- sections.title = '.title' | ml -%]
+
+[% IF error_list %]
+    <div class='error-box'>
+    <p>[% '.error.header' | ml %]</p>
+    <ul class='error-list'>
+        [% FOREACH error = error_list %]
+            <li>[% error %] </li>
+        [% END %]
+    </ul>
+    </div>
+[% END %]
+
+<p>[% '.about' | ml %]</p>
+
+[% IF claims.0 %]
+    <p>[% '.claimed' | ml %]</p>
+    <ul>
+    [% FOR claim IN claims %]
+        <li>[% claim.ljuser_display %]</li>
+    [% END %]
+    </ul>
+[% END %]
+
+<p><form method="post" action="[% site.root %]/openid/claim">
+    [% dw.form_auth() %]
+    <label for="openid_url">[% '.openid' | ml %]</label> <input type="text" name="openid_url" aria-required="true" />
+    <input type="submit" value="[% '.submit' | ml %]" />
+</form></p>
+
+<p>[% '.delay' | ml %]</p>
diff -r bd7b2d844877 -r b8a9b2c3c047 views/openid/claim.tt.text
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/openid/claim.tt.text	Tue Jan 17 08:24:55 2012 +0000
@@ -0,0 +1,46 @@
+;; -*- coding: utf-8 -*-
+.about=Use this tool to claim an OpenID account. When you claim an account, all comments that are owned by that account will now be owned by you. This is effectively an account merge and is not reversible.
+
+.claimed=You have claimed the following OpenID accounts:
+
+.delay=An email will be sent to the email address we have on file for your account. You will need to read this email and then confirm that you wish to merge your OpenID account. The email will take approximately one hour to arrive.
+
+.email<<
+Hi [[remote]],
+
+You have requested to merge the following OpenID account into your [[sitenameshort]] account:
+
+    [[openid]]
+
+Claiming this account will merge all of the comments and entries that are currently owned by the OpenID account into your account. This action is immediate and irreversible -- we will not be able to unmerge them.
+
+If you are sure you want to do this, please click this link:
+
+    [[confirm_url]]
+
+If you did not request this, please delete this email.
+
+
+Regards,
+[[sitename]]
+.
+
+.email.subject=Your [[sitename]] Request
+
+.error.cantuseownsite=You can't claim a [[sitename]] account!
+
+.error.failed_vivification=We failed to load a user account for that OpenID. Please try again and if it continues to fail, report this error.
+
+.error.header=There were errors in your request:
+
+.error.invalidchars=The URL you entered appears to be invalid.
+
+.error.no_openid=OpenID is not enabled on this site.
+
+.error.required=You must enter the URL of your account on the remote site.
+
+.openid=Claim a new OpenID URL:
+
+.title=Claim OpenID Account
+
+.submit=Claim Account
diff -r bd7b2d844877 -r b8a9b2c3c047 views/openid/claim_confirm.tt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/openid/claim_confirm.tt	Tue Jan 17 08:24:55 2012 +0000
@@ -0,0 +1,24 @@
+[%# claim_confirm.tt
+
+The confirmation page for claiming an OpenID account.
+
+Authors:
+    Mark Smith <mark@dreamwidth.org>
+
+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'.
+%]
+
+[%- sections.title = '.title' | ml -%]
+
+[% IF error_list %]
+    <p>[% '.error.header' | ml %]</p>
+    <ul class='error-list'>
+        [% FOREACH error = error_list %]
+            <li>[% error %] </li>
+        [% END %]
+    </ul>
+[% ELSE %]
+    <p>[% '.confirmed' | ml %]</p>
+[% END %]
diff -r bd7b2d844877 -r b8a9b2c3c047 views/openid/claim_confirm.tt.text
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/openid/claim_confirm.tt.text	Tue Jan 17 08:24:55 2012 +0000
@@ -0,0 +1,16 @@
+;; -*- coding: utf-8 -*-
+.confirmed=Your claim has been confirmed. All comments and posts that were previously attributed to the OpenID account will now be reattributed to you. <strong>This process may take several hours or longer to complete.</strong>
+
+.error.already_claimed_other=The OpenID account you have attempted to claim has already been claimed.
+
+.error.already_claimed_self=You have already claimed this OpenID account. If comments and posts have not been updated yet, and it has been at least 24 hours from the time you first claimed this account, please let us know.
+
+.error.header=There were errors in your request:
+
+.error.invalid_account=The account being claimed is not an OpenID account. This should never happen. Please try again or report this error.
+
+.error.invalid_auth=The claim you attempted has timed out or the link you followed is invalid. Please try again.
+
+.error.wrong_account=You are not logged in with the same account. Please check your email and make sure you are logged in to the right account before claiming this OpenID.
+
+.title=Claim OpenID Account
diff -r bd7b2d844877 -r b8a9b2c3c047 views/openid/claim_sent.tt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/openid/claim_sent.tt	Tue Jan 17 08:24:55 2012 +0000
@@ -0,0 +1,15 @@
+[%# claim_sent.tt
+
+The confirmation page for claiming an OpenID account.
+
+Authors:
+    Mark Smith <mark@dreamwidth.org>
+
+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'.
+%]
+
+[%- sections.title = '.title' | ml -%]
+
+<p>[% '.body' | ml %]</p>
diff -r bd7b2d844877 -r b8a9b2c3c047 views/openid/claim_sent.tt.text
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/openid/claim_sent.tt.text	Tue Jan 17 08:24:55 2012 +0000
@@ -0,0 +1,4 @@
+;; -*- coding: utf-8 -*-
+.body=Your request has been submitted. Please watch your email for confirmation. You will need to confirm the request by following the directions in the email.
+
+.title=Claim Confirmation Sent
--------------------------------------------------------------------------------

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org