Make sure points are integer values, add form-auth check for points 
purchase, enforce personal bans for points. Some localization and variable 
cleanup. Fix a warning in the logs.

        Patch by kareila. 

diffs (312 lines):

diff -r 4bb19bbdda27 -r 9d5f77944cfc bin/upgrading/en.dat
--- a/bin/upgrading/en.dat      Thu Jan 27 17:16:54 2011 +0000
+++ b/bin/upgrading/en.dat      Tue Feb 15 11:28:31 2011 +0800
@@ -3723,8 +3723,14 @@ shop.item.account.name.perm=[[points]] p
 
 shop.item.account.randomuser=Random active free user
 
+shop.item.points.canbeadded.banned=You are restricted from making purchases 
for this journal.
+
+shop.item.points.canbeadded.insufficient=You do not have enough points to do 
that.
+
 shop.item.points.canbeadded.invalidjournaltype=You can only buy points for a 
personal journal.
 
+shop.item.points.canbeadded.itemerror=Could not add item to cart.
+
 shop.item.points.canbeadded.notauser=You can only buy points for an active 
account.
 
 shop.item.points.canbeadded.outofrange=Minimum purchase is 30 points, maximum 
is 5000.
@@ -3740,6 +3746,8 @@ shop.item.rename.name.hastoken=Rename To
 shop.item.rename.name.hastoken=Rename Token <a [[aopts]]>[[token]]</a>
 
 shop.item.rename.name.hastoken.text=Rename Token [[token]]
+
+shop.unavailable=The shop is currently disabled.
 
 sitescheme.accountlinks.account=Account
 
diff -r 4bb19bbdda27 -r 9d5f77944cfc cgi-bin/DW/Controller/Shop.pm
--- a/cgi-bin/DW/Controller/Shop.pm     Thu Jan 27 17:16:54 2011 +0000
+++ b/cgi-bin/DW/Controller/Shop.pm     Tue Feb 15 11:28:31 2011 +0800
@@ -15,8 +15,6 @@
 #
 
 package DW::Controller::Shop;
-
-# FIXME: lots of english stripping needs to be done
 
 use strict;
 use warnings;
@@ -41,7 +39,7 @@ sub _shop_controller {
     # if payments are disabled, do nothing
     unless ( LJ::is_enabled( 'payments' ) ) {
         $r->redirect( "$LJ::SITEROOT/" );
-        return ( 0, 'The shop is currently disabled.' );
+        return ( 0, LJ::Lang::ml( 'shop.unavailable' ) );
     }
 
     # if they're banned ...
@@ -82,35 +80,45 @@ sub shop_transfer_points_handler {
     my ( $ok, $rv ) = _shop_controller();
     return $rv unless $ok;
 
+    my $remote = $rv->{remote};
     my %errs;
     $rv->{errs} = \%errs;
-    $rv->{has_points} = $rv->{remote}->shop_points;
+    $rv->{has_points} = $remote->shop_points;
 
     my $r = DW::Request->get;
     if ( LJ::did_post() ) {
         my $args = $r->post_args;
         die "invalid auth\n" unless LJ::check_form_auth( $args->{lj_form_auth} 
);
 
-        # error check the user
-        my $u = LJ::load_user( $args->{foruser} )
-            or $errs{foruser} = 'Invalid account.';
-        if ( $u ) {
-            if ( $u->is_visible && $u->is_person ) {
+        my $u = LJ::load_user( $args->{foruser} );
+        my $points = int( $args->{points} + 0 );
+
+        if ( !$u ) {
+            $errs{foruser} = LJ::Lang::ml( 
'shop.item.points.canbeadded.notauser' );
+
+        } elsif ( my $item = DW::Shop::Item::Points->new( target_userid => 
$u->id, from_userid => $remote->id, points => $points, transfer => 1 ) ) {
+            # provisionally create the item to access object methods
+
+            # error check the user
+            if ( $item->can_be_added_user( errref => \$errs{foruser} ) ) {
                 $rv->{foru} = $u;
-            } else {
-                $errs{foruser} = 'Account must be active and a personal 
account.';
+                delete $errs{foruser};  # undefined
             }
+
+            # error check the points
+            if ( $item->can_be_added_points( errref => \$errs{points} ) ) {
+                # remote must have enough points to transfer
+                if ( $remote->shop_points < $points ) {
+                    $errs{points} = LJ::Lang::ml( 
'shop.item.points.canbeadded.insufficient' );
+                } else {
+                    $rv->{points} = $points;
+                    delete $errs{points};  # undefined
+                }
+            }
+
+        } else {
+            $errs{foruser} = LJ::Lang::ml( 
'shop.item.points.canbeadded.itemerror' );
         }
-
-        # error check the points
-        my $points = $args->{points} + 0;
-        $errs{points} = 'Points must be in range 1 to 5,000.'
-            unless $points >= 1 && $points <= 5000;
-        $rv->{points} = $points;
-
-        # remove must have enough points
-        $errs{points} = 'You do not have enough points to do that.'
-            unless $rv->{remote}->shop_points >= $points;
 
         # copy down anon value
         $rv->{anon} = $args->{anon} ? 1 : 0;
@@ -118,15 +126,15 @@ sub shop_transfer_points_handler {
         # if this is a confirmation page, then confirm if there are no errors
         if ( $args->{confirm} && ! scalar keys %errs ) {
             # first add the points to the other person... wish we had 
transactions here!
-            $u->give_shop_points( amount => $points, reason => sprintf( 
'transfer from %s(%d)', $rv->{remote}->user, $rv->{remote}->id ) );
-            $rv->{remote}->give_shop_points( amount => -$points, reason => 
sprintf( 'transfer to %s(%d)', $u->user, $u->id ) );
+            $u->give_shop_points( amount => $points, reason => sprintf( 
'transfer from %s(%d)', $remote->user, $remote->id ) );
+            $remote->give_shop_points( amount => -$points, reason => sprintf( 
'transfer to %s(%d)', $u->user, $u->id ) );
 
             # send notification ...
             my $e = $rv->{anon} ? 'anon' : 'user';
             my $body = LJ::Lang::get_text( $u->prop( 'browselang' ), 
"esn.receivedpoints.$e.body", undef, {
                     user => $u->display_username,
                     points => $points,
-                    from => $rv->{remote}->display_username,
+                    from => $remote->display_username,
                     sitename => $LJ::SITENAMESHORT,
                     store => "$LJ::SITEROOT/shop/",
                 } );
@@ -150,8 +158,7 @@ sub shop_transfer_points_handler {
         
     } else {
         if ( my $for = $r->get_args->{for} ) {
-            my $fu = LJ::load_user( $for );
-            $rv->{foru} = $fu if $fu;
+            $rv->{foru} = LJ::load_user( $for );
         }
 
         if ( my $points = $r->get_args->{points} ) {
@@ -168,36 +175,42 @@ sub shop_points_handler {
     my ( $ok, $rv ) = _shop_controller();
     return $rv unless $ok;
 
+    my $remote = $rv->{remote};
     my %errs;
     $rv->{errs} = \%errs;
 
     my $r = DW::Request->get;
     if ( LJ::did_post() ) {
         my $args = $r->post_args;
+        die "invalid auth\n" unless LJ::check_form_auth( $args->{lj_form_auth} 
);
 
-        # error check the user
-        my $u = LJ::load_user( $args->{foruser} )
-            or $errs{foruser} = 'Invalid account.';
-        if ( $u ) {
-            if ( $u->is_visible && $u->is_person ) {
+        my $u = LJ::load_user( $args->{foruser} );
+        my $points = int( $args->{points} + 0 );
+        my $item;  # provisionally create the item to access object methods
+
+        if ( !$u ) {
+            $errs{foruser} = LJ::Lang::ml( 
'shop.item.points.canbeadded.notauser' );
+
+        } elsif ( $item = DW::Shop::Item::Points->new( target_userid => 
$u->id, from_userid => $remote->id, points => $points ) ) {
+            # error check the user
+            if ( $item->can_be_added_user( errref => \$errs{foruser} ) ) {
                 $rv->{foru} = $u;
-            } else {
-                $errs{foruser} = 'Account must be active and a personal 
account.';
+                delete $errs{foruser};  # undefined
             }
+
+            # error check the points
+            if ( $item->can_be_added_points( errref => \$errs{points} ) ) {
+                $rv->{points} = $points;
+                delete $errs{points};  # undefined
+            }
+
+        } else {
+            $errs{foruser} = LJ::Lang::ml( 
'shop.item.points.canbeadded.itemerror' );
         }
-
-        # error check the points
-        my $points = $args->{points} + 0;
-        $errs{points} = 'Points must be in range 30 to 5,000.'
-            unless $points >= 30 && $points <= 5000;
-        $rv->{points} = $points;
 
         # looks good, add it!
         unless ( keys %errs ) {
-            $rv->{cart}->add_item(
-                DW::Shop::Item::Points->new( target_userid => $u->id, 
from_userid => $rv->{remote}->id, points => $points )
-            );
-        
+            $rv->{cart}->add_item( $item );
             return $r->redirect( "$LJ::SITEROOT/shop" );
         }
         
@@ -205,10 +218,9 @@ sub shop_points_handler {
         my $for = $r->get_args->{for};
 
         if ( ! $for || $for eq 'self' ) {
-            $rv->{foru} = $rv->{remote};
-        } elsif ( $for ) {
-            my $fu = LJ::load_user( $for );
-            $rv->{foru} = $fu if $fu;
+            $rv->{foru} = $remote;
+        } else {
+            $rv->{foru} = LJ::load_user( $for );
         }
     }
 
diff -r 4bb19bbdda27 -r 9d5f77944cfc cgi-bin/DW/Shop/Item.pm
--- a/cgi-bin/DW/Shop/Item.pm   Thu Jan 27 17:16:54 2011 +0000
+++ b/cgi-bin/DW/Shop/Item.pm   Tue Feb 15 11:28:31 2011 +0800
@@ -96,10 +96,15 @@ sub new {
     }
 
     # looks good
+    my $confargs = $LJ::SHOP{$args{type}};  # arrayref
+
+    # points and vgifts have empty args, which will cause undef warnings
+    $confargs = [0,0,0,0] unless scalar @$confargs;
+
     return bless {
         # user supplied arguments (close enough)
-        cost_cash   => $LJ::SHOP{$args{type}}->[0] + 0.00,
-        cost_points => $LJ::SHOP{$args{type}}->[3] + 0,
+        cost_cash   => $confargs->[0] + 0.00,
+        cost_points => $confargs->[3] + 0,
         %args,
 
         # internal things we use to track the state of this item,
diff -r 4bb19bbdda27 -r 9d5f77944cfc cgi-bin/DW/Shop/Item/Points.pm
--- a/cgi-bin/DW/Shop/Item/Points.pm    Thu Jan 27 17:16:54 2011 +0000
+++ b/cgi-bin/DW/Shop/Item/Points.pm    Tue Feb 15 11:28:31 2011 +0800
@@ -47,7 +47,10 @@ sub new {
     my $self = $class->SUPER::new( %args, type => 'points' );
     return unless $self;
 
-    if ( $self ) {
+    if ( $args{transfer} ) {
+        $self->{cost_cash} = 0;
+        $self->{cost_points} = $self->{points};
+    } else {
         $self->{cost_cash} = $self->{points} / 10;
         $self->{cost_points} = 0;
     }
@@ -139,6 +142,15 @@ sub can_be_added {
 sub can_be_added {
     my ( $self, %opts ) = @_;
 
+    return 0 unless $self->can_be_added_user( %opts );
+    return 0 unless $self->can_be_added_points( %opts );
+
+    return 1;
+}
+
+sub can_be_added_user {
+    my ( $self, %opts ) = @_;
+
     my $errref = $opts{errref};
 
     # if not a valid account, error
@@ -154,9 +166,30 @@ sub can_be_added {
         return 0;
     }
 
-    # sanity check that the points are in-range and less than 5000, but only 
if they're being
-    # purchased.  otherwise, we allow anything if it's a 0.00 cost item.
-    if ( $self->cost_cash > 0.00 && ( $self->points < 30 || $self->points > 
5000 ) ) {
+    # make sure no sysban is in effect here
+    my $fromu = LJ::load_userid( $self->from_userid );
+    if ( $fromu && $target_u->has_banned( $fromu ) ) {
+        $$errref = LJ::Lang::ml( 'shop.item.points.canbeadded.banned' );
+        return 0;
+    }
+
+    return 1;
+}
+
+sub can_be_added_points {
+    my ( $self, %opts ) = @_;
+
+    my $errref = $opts{errref};
+
+    # sanity check that the points are positive and not more than 5000
+    unless ( $self->points > 0 && $self->points <= 5000 ) {
+        $$errref = LJ::Lang::ml( 'shop.item.points.canbeadded.outofrange' );
+        return 0;
+    }
+
+    # sanity check that the points are above the purchase minimum, but only
+    # if they're being purchased.  we allow small point transfers at no cost.
+    if ( $self->cost_cash > 0.00 && $self->points < 30 ) {
         $$errref = LJ::Lang::ml( 'shop.item.points.canbeadded.outofrange' );
         return 0;
     }
diff -r 4bb19bbdda27 -r 9d5f77944cfc views/shop/points.tt
--- a/views/shop/points.tt      Thu Jan 27 17:16:54 2011 +0000
+++ b/views/shop/points.tt      Tue Feb 15 11:28:31 2011 +0800
@@ -5,6 +5,7 @@
 <p>[% '.about' | ml(sitename = site.nameshort) %]</p>
 
 <form method='post'>
+[% dw.form_auth %]
 <table summary='' class='shop-table-gift'>
 [% IF foru %]
     <tr><td>[% '.buying.for' | ml %]</td><td>[% foru.ljuser_display %]
_______________________________________________
dw-changelog mailing list
[email protected]
http://lists.dwscoalition.org/mailman/listinfo/dw-changelog

Reply via email to