fu: Close-up of Fu, bringing a scoop of water to her mouth (Default)
fu ([personal profile] fu) wrote in [site community profile] changelog2012-02-10 12:50 pm

[dw-free] need way for users to create pre-paid account if invites are off

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

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

If user tries to apply a code with paid time while invites are off, apply it
immediately after account creation.

Patch by [personal profile] fu.

Files modified:
  • cgi-bin/DW/InviteCodes.pm
  • cgi-bin/LJ/User.pm
  • cgi-bin/LJ/Widget/CreateAccount.pm
  • cgi-bin/LJ/Widget/CreateAccountEnterCode.pm
  • htdocs/create.bml
--------------------------------------------------------------------------------
diff -r 4e5463fc7b55 -r f09622111ce2 cgi-bin/DW/InviteCodes.pm
--- a/cgi-bin/DW/InviteCodes.pm	Fri Feb 10 20:02:59 2012 +0800
+++ b/cgi-bin/DW/InviteCodes.pm	Fri Feb 10 20:49:14 2012 +0800
@@ -171,6 +171,24 @@
     return 1;
 }
 
+=head2 C<< $class->check_rate >>
+
+Rate limit code input; only allow one code every five seconds.
+
+Return 1 if rate is okay, return 0 if too fast.
+
+=cut
+
+sub check_rate {
+    my $ip = LJ::get_remote_ip();
+    if ( LJ::MemCache::get( "invite_code_try_ip:$ip" ) ) {
+        LJ::MemCache::set( "invite_code_try_ip:$ip", 1, 5 );
+        return 0;
+    }
+    LJ::MemCache::set( "invite_code_try_ip:$ip", 1, 5 );
+    return 1;
+}
+
 =head2 C<< $class->paid_status( code => $code ) >>
 
 Checks whether this code comes loaded with a paid account. Returns a DW::Shop::Item::Account 
diff -r 4e5463fc7b55 -r f09622111ce2 cgi-bin/LJ/User.pm
--- a/cgi-bin/LJ/User.pm	Fri Feb 10 20:02:59 2012 +0800
+++ b/cgi-bin/LJ/User.pm	Fri Feb 10 20:49:14 2012 +0800
@@ -258,10 +258,10 @@
     }
 
     # apply any paid time that this account should get
-    if ( $LJ::USE_ACCT_CODES && $opts{code} ) {
+    if ( $opts{code} ) {
         my $code = $opts{code};
         my $itemidref;
-        my $promo_code = DW::InviteCodes::Promo->load( code => $code );
+        my $promo_code = $LJ::USE_ACCT_CODES ? DW::InviteCodes::Promo->load( code => $code ) : undef;
         if ( $promo_code ) {
             $promo_code->apply_for_user( $u );
         } elsif ( my $cart = DW::Shop::Cart->get_from_invite( $code, itemidref => \$itemidref ) ) {
diff -r 4e5463fc7b55 -r f09622111ce2 cgi-bin/LJ/Widget/CreateAccount.pm
--- a/cgi-bin/LJ/Widget/CreateAccount.pm	Fri Feb 10 20:02:59 2012 +0800
+++ b/cgi-bin/LJ/Widget/CreateAccount.pm	Fri Feb 10 20:49:14 2012 +0800
@@ -280,7 +280,7 @@
     $ret .= "</div> <!-- relative-container -->\n";
 
     $ret .= $class->html_hidden( from => $from ) if $from;
-    $ret .= $class->html_hidden( code => $code ) if $LJ::USE_ACCT_CODES;
+    $ret .= $class->html_hidden( code => $code ) if $code;
 
     $ret .= $class->end_form;
 
@@ -418,7 +418,7 @@
             inviter => $post->{from},
             extra_props => $opts{extra_props},
             status_history => $opts{status_history},
-            code => $code,
+            code => DW::InviteCodes->check_code( code => $code ) ? $code : undef,
         );
         return $class->ml('widget.createaccount.error.cannotcreate') unless $nu;
 
@@ -452,11 +452,20 @@
 
         $nu->make_login_session;
 
-        # we're all done; mark the invite code as used
-        if ( $LJ::USE_ACCT_CODES && $code ) {
-            if ( my $pc = DW::InviteCodes::Promo->load( code => $code ) ) {
-                $pc->use_code;
-            } else {
+        # we're all done
+        if ( $code ) {
+            # unconditionally mark the invite code as used
+            if ( $LJ::USE_ACCT_CODES ) {
+                if ( my $pc = DW::InviteCodes::Promo->load( code => $code ) ) {
+                    $pc->use_code;
+                } else {
+                    my $invitecode = DW::InviteCodes->new( code => $code );
+                    $invitecode->use_code( user => $nu );
+                }
+
+            # user is now paid, let's assume that this came from the invite code
+            # so mark the invite code as used
+            } elsif ( DW::Pay::get_current_account_status( $nu ) ) {
                 my $invitecode = DW::InviteCodes->new( code => $code );
                 $invitecode->use_code( user => $nu );
             }
diff -r 4e5463fc7b55 -r f09622111ce2 cgi-bin/LJ/Widget/CreateAccountEnterCode.pm
--- a/cgi-bin/LJ/Widget/CreateAccountEnterCode.pm	Fri Feb 10 20:02:59 2012 +0800
+++ b/cgi-bin/LJ/Widget/CreateAccountEnterCode.pm	Fri Feb 10 20:49:14 2012 +0800
@@ -20,12 +20,19 @@
 use base qw(LJ::Widget);
 use Carp qw(croak);
 
+use DW::InviteCodes;
+
 sub need_res { qw( stc/widgets/createaccountentercode.css ) }
 
 sub render_body {
     my $class = shift;
     my %opts = @_;
 
+    # we can still use invite codes to create new paid accounts
+    # so display this in case they hit the rate limit, even without USE_ACCT_CODES
+    return "<p>" . $class->ml( 'widget.createaccountentercode.error.toofast' ) . "</p>"
+        unless $opts{rate_ok};
+
     return "" unless $LJ::USE_ACCT_CODES;
 
     my $get = $opts{get};
@@ -41,16 +48,8 @@
     };
 
     # if we're in this widget with a code defined, then it's invalid
-    # rate limit code input; only allow one code every five seconds
-    if ( $code ) {
-        my $ip = LJ::get_remote_ip();
-        if ( LJ::MemCache::get( "invite_code_try_ip:$ip" ) ) {
-            LJ::MemCache::set( "invite_code_try_ip:$ip", 1, 5 );
-            return "<p>" . $class->ml( 'widget.createaccountentercode.error.toofast' ) . "</p>";
-        }
-        LJ::MemCache::set( "invite_code_try_ip:$ip", 1, 5 );
-        $errors->{code} = $class->ml( 'widget.createaccountentercode.error.invalidcode' );
-    }
+    $errors->{code} = $class->ml( 'widget.createaccountentercode.error.invalidcode' )
+        if $code;
 
     my $ret;
 
diff -r 4e5463fc7b55 -r f09622111ce2 htdocs/create.bml
--- a/htdocs/create.bml	Fri Feb 10 20:02:59 2012 +0800
+++ b/htdocs/create.bml	Fri Feb 10 20:49:14 2012 +0800
@@ -37,22 +37,31 @@
     my %from_post;
     my $code_valid = $LJ::USE_ACCT_CODES ? 0 : 1;
     my $code;
+    my $rate_ok;
     if ( LJ::did_post() ) {
         LJ::Widget->use_specific_form_fields( post => \%POST, widget => "CreateAccount", fields => [ DW::Captcha->form_fields ] )
             if DW::Captcha->enabled( 'create' );
         %from_post = LJ::Widget->handle_post( \%POST, ( 'CreateAccount' ) );
-    } elsif ( $LJ::USE_ACCT_CODES ) {
+    } else {
+        # we always need the code, because it might contain paid time
         $code = LJ::trim( $GET{code} );
-        $code_valid = DW::InviteCodes->check_code( code => $code );
+
+        # but we don't always need to block the registration
+        $code_valid = DW::InviteCodes->check_code( code => $code )
+            if $LJ::USE_ACCT_CODES;
+
+        # rate limiting
+        $rate_ok = DW::InviteCodes->check_rate;
     }
 
     my $ret;
 
     $ret .= "<div id='create-page'>";
     $ret .= LJ::Widget::CreateAccountProgressMeter->render( step => 1, code => $code );
-    if ( !$code_valid && !$from_post{code_valid} ) {
+    if ( ! $rate_ok || ( !$code_valid && !$from_post{code_valid} ) ) {
         $ret .= LJ::Widget::CreateAccountEnterCode->render(
-            get         => \%GET,);
+            get         => \%GET,
+            rate_ok     => $rate_ok );
     } else {
         $ret .= LJ::Widget::CreateAccount->render(
             post        => LJ::Widget::CreateAccount->post_fields( \%POST ),
--------------------------------------------------------------------------------