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] changelog2009-06-14 08:27 pm

[dw-free] invite code blacklisting

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

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

Add sysban types for the invite code system, so we can prevent people from
getting more invite codes if they're abusing the system. (Name grabbing,
etc.)

Patch by [personal profile] afuna.

Files modified:
  • cgi-bin/DW/BusinessRules/InviteCodeRequests.pm
  • cgi-bin/DW/InviteCodeRequests.pm
  • cgi-bin/DW/Worker/DistributeInvites.pm
  • cgi-bin/sysban.pl
  • htdocs/admin/invites/requests.bml
  • htdocs/admin/sysban.bml
  • htdocs/manage/circle/invite.bml
  • htdocs/manage/circle/invite.bml.text
--------------------------------------------------------------------------------
diff -r 7b476361b2dd -r 387de3306546 cgi-bin/DW/BusinessRules/InviteCodeRequests.pm
--- a/cgi-bin/DW/BusinessRules/InviteCodeRequests.pm	Sun Jun 14 20:20:17 2009 +0000
+++ b/cgi-bin/DW/BusinessRules/InviteCodeRequests.pm	Sun Jun 14 20:27:07 2009 +0000
@@ -36,7 +36,8 @@ DW::BusinessRules::InviteCodeRequests - 
 =head2 C<< DW::BusinessRules::InviteCodeRequests::can_request( user => $u ) >> 
 
 Return whether the user can make a request for more invite codes. Default implementation allows the user
-to make a new request if they have no unused invite codes, and they have no pending requests for review.
+to make a new request if they have no unused invite codes, they have no pending requests for review, and
+are not sysbanned from using the invites system.
 
 =cut
 
@@ -44,13 +45,15 @@ sub can_request {
     my (%opts)  = @_;
     return 0 unless $opts{user}->is_person;
     my $userid = $opts{user}->id;
-    
+
     my $unused_count = DW::InviteCodes->unused_count( userid => $userid );
     return 0 if $unused_count;
 
     my $outstanding_count = DW::InviteCodeRequests->outstanding_count( userid => $userid );
     return 0 if $outstanding_count;
-    
+
+    return 0 if DW::InviteCodeRequests->invite_sysbanned( user => $opts{user} );
+
     return 1;
 }
 
diff -r 7b476361b2dd -r 387de3306546 cgi-bin/DW/InviteCodeRequests.pm
--- a/cgi-bin/DW/InviteCodeRequests.pm	Sun Jun 14 20:20:17 2009 +0000
+++ b/cgi-bin/DW/InviteCodeRequests.pm	Sun Jun 14 20:27:07 2009 +0000
@@ -188,6 +188,23 @@ sub outstanding {
     return @outstanding;
 }
 
+=head2 C<< $class->invite_sysbanned( user => $u ) >>
+
+Return whether this user is sysbanned from the invite codes system.
+Accepts a user object.
+
+=cut
+
+sub invite_sysbanned {
+    my ( $class, %opts ) = @_;
+    my $u = $opts{user};
+
+    return 1 if LJ::sysban_check( "invite_user", $u->user );
+    return 1 if LJ::sysban_check( "invite_email", $u->email_raw );
+
+    return 0;
+}
+
 =head2 C<< $object->accept( [num_invites => $num_invites ] ) >>
 
 Accept this request.
diff -r 7b476361b2dd -r 387de3306546 cgi-bin/DW/Worker/DistributeInvites.pm
--- a/cgi-bin/DW/Worker/DistributeInvites.pm	Sun Jun 14 20:20:17 2009 +0000
+++ b/cgi-bin/DW/Worker/DistributeInvites.pm	Sun Jun 14 20:27:07 2009 +0000
@@ -23,10 +23,11 @@ package DW::Worker::DistributeInvites;
 package DW::Worker::DistributeInvites;
 use base 'TheSchwartz::Worker';
 use DW::InviteCodes;
+use DW::InviteCodeRequests;
 use DW::BusinessRules::InviteCodes;
 use LJ::User;
 
-BEGIN { require "ljlang.pl"; require "ljmail.pl"; }
+BEGIN { require "ljlang.pl"; require "ljmail.pl"; require "sysban.pl"; }
 
 sub schwartz_capabilities { return ('DW::Worker::DistributeInvites'); }
 
@@ -102,24 +103,7 @@ sub work {
     } else {
         my $adj_ninv
             = DW::BusinessRules::InviteCodes::adj_invites( $ninv, $inv_nusers );
-
-        if ($adj_ninv == 0) {
-            $reqemail_body = 'cantadjust';
-            $reqemail_vars = { numusers => $inv_nusers };
-        } elsif ( $adj_ninv < $ninv ) {
-            $reqemail_body = 'adjustdown';
-            $reqemail_vars = { actinvites => $adj_ninv,
-                               remainder => $ninv - $adj_ninv,
-                               numusers => $inv_nusers };
-        } elsif ( $adj_ninv > $ninv ) {
-            $reqemail_body = 'adjustup';
-            $reqemail_vars = { actinvites => $adj_ninv,
-                               additional => $adj_ninv - $ninv,
-                               numusers => $inv_nusers };
-        } else {
-            $reqemail_body = 'keptsame';
-            $reqemail_vars = { numusers => $inv_nusers };
-        }
+        my $num_sysbanned = 0;
 
         if ( $adj_ninv > 0 ) {
             # Here, we know we'll be generating invites, so get cracking.
@@ -133,6 +117,13 @@ sub work {
                     : $inv_nusers - 1;
                 my $inv_uhash = LJ::load_userids( @{$inv_uids}[$start..$end] );
                 foreach my $inv_user (values %$inv_uhash) {
+
+                    # skip sysbanned users; we may send a few less invites than we thought we could
+                    if ( DW::InviteCodeRequests->invite_sysbanned( user => $inv_user ) ) {
+                        $num_sysbanned++;
+                        next;
+                    }
+
                     my @ics = DW::InviteCodes->generate( count => $inv_peruser,
                                                          owner => $inv_user,
                                                          reason => $reason );
@@ -168,6 +159,29 @@ sub work {
                 }
             }
         }
+
+        # adjust the numbers to reflect how many we actually managed to distribute
+        # accounting for sysbanned users (which we only know post-distribution)
+        $inv_nusers -= $num_sysbanned;
+        $adj_ninv -=  $num_sysbanned * $reqemail_vars->{peruser};
+
+        if ( $adj_ninv == 0 ) {
+            $reqemail_body = 'cantadjust';
+            $reqemail_vars = { numusers => $inv_nusers };
+        } elsif ( $adj_ninv < $ninv ) {
+            $reqemail_body = 'adjustdown';
+            $reqemail_vars = { actinvites => $adj_ninv,
+                               remainder => $ninv - $adj_ninv,
+                               numusers => $inv_nusers };
+        } elsif ( $adj_ninv > $ninv ) {
+            $reqemail_body = 'adjustup';
+            $reqemail_vars = { actinvites => $adj_ninv,
+                               additional => $adj_ninv - $ninv,
+                               numusers => $inv_nusers };
+        } else {
+            $reqemail_body = 'keptsame';
+            $reqemail_vars = { numusers => $inv_nusers };
+        }
     }
 
     $req_email{body} .= LJ::Lang::get_text( $req_lang,
diff -r 7b476361b2dd -r 387de3306546 cgi-bin/sysban.pl
--- a/cgi-bin/sysban.pl	Sun Jun 14 20:20:17 2009 +0000
+++ b/cgi-bin/sysban.pl	Sun Jun 14 20:27:07 2009 +0000
@@ -473,6 +473,8 @@ sub sysban_validate {
                'lostpassword' => 'user',
                'talk_ip_test' => 'ip',
                'contentflag' => 'user',
+               'invite_user' => 'user',
+               'invite_email' => 'email',
                );
 
     while (my ($new, $existing) = splice(@map, 0, 2)) {
diff -r 7b476361b2dd -r 387de3306546 htdocs/admin/invites/requests.bml
--- a/htdocs/admin/invites/requests.bml	Sun Jun 14 20:20:17 2009 +0000
+++ b/htdocs/admin/invites/requests.bml	Sun Jun 14 20:27:07 2009 +0000
@@ -45,6 +45,10 @@ body<=
     $ret .= "<tr><th>User</th><th>Time Generated</th><th>Ct</th><th>Give</th><th>Reason</th></tr>";
     foreach my $outstanding ( @outstanding ) {
         my $u = $users->{$outstanding->userid};
+        
+        # don't include in table if they're sysbanned
+        next if DW::InviteCodeRequests->invite_sysbanned( user => $u );
+
         $ret .= "<tr>";
         $ret .= "<td>" . $u->ljuser_display . "</td>";
         $ret .= "<td>" . LJ::time_to_http( $outstanding->timegenerate ) . "</td>";
diff -r 7b476361b2dd -r 387de3306546 htdocs/admin/sysban.bml
--- a/htdocs/admin/sysban.bml	Sun Jun 14 20:20:17 2009 +0000
+++ b/htdocs/admin/sysban.bml	Sun Jun 14 20:27:07 2009 +0000
@@ -32,7 +32,8 @@ body<=
     my $priv = 'sysban';
     my @all_sb_args = qw( ip uniq email email_domain user pay_cc msisdn 
                           pay_user pay_email pay_uniq support_user 
-                          support_uniq lostpassword  talk_ip_test contentflag );
+                          support_uniq lostpassword  talk_ip_test contentflag
+                          invite_user invite_email );
 
     my $remote = LJ::get_remote();
     return "<?needlogin?>" unless $remote;
diff -r 7b476361b2dd -r 387de3306546 htdocs/manage/circle/invite.bml
--- a/htdocs/manage/circle/invite.bml	Sun Jun 14 20:20:17 2009 +0000
+++ b/htdocs/manage/circle/invite.bml	Sun Jun 14 20:27:07 2009 +0000
@@ -37,7 +37,9 @@
         }
 
         unless ( @invitecodes ) {
-            $body = BML::ml('.error.noinvitecodes', { aopts => "href='$LJ::SITEROOT/manage/invitecodes.bml'" });
+            $body = $ML{'.msg.noinvitecodes'};
+            $body .= " " . BML::ml( '.msg.noinvitecodes.requestmore', { aopts => "href='$LJ::SITEROOT/manage/invitecodes'" } )
+                if DW::BusinessRules::InviteCodeRequests::can_request( user => $u );
             return;
         }
 
diff -r 7b476361b2dd -r 387de3306546 htdocs/manage/circle/invite.bml.text
--- a/htdocs/manage/circle/invite.bml.text	Sun Jun 14 20:20:17 2009 +0000
+++ b/htdocs/manage/circle/invite.bml.text	Sun Jun 14 20:27:07 2009 +0000
@@ -20,8 +20,6 @@ The [[sitenameshort]] Team
 .error.noemail=Please enter your friend's email address.
 
 .error.noimagesallowed=Images are not allowed in this message.
-
-.error.noinvitecodes=You have no invite codes available. Please go to <a [[aopts]]>your manage invite codes page</a> to request new ones.
 
 .error.noname=Please enter your friend's name.
 
@@ -94,6 +92,10 @@ The [[sitename]] Team
 [[siteroot]]
 .
 
+.msg.noinvitecodes=You don't have any invite codes available.
+
+.msg.noinvitecodes.requestmore=You can request more on your <a [[aopts]]>Manage Invite Codes</a> page.
+
 .msg_subject=[[username]] has invited you to join [[sitenameshort]]!
 
 .msg_subject.header=Subject:
--------------------------------------------------------------------------------