[freeside-commits] freeside/FS/FS cust_pay_void.pm, 1.4, 1.5 cust_refund.pm, 1.26, 1.27 payinfo_Mixin.pm, NONE, 1.1 Record.pm, 1.127, 1.128 cust_main.pm, 1.255, 1.256 Schema.pm, 1.36, 1.37 cust_pay.pm, 1.45, 1.46

Ivan,,, ivan at wavetail.420.am
Wed Dec 13 22:00:47 PST 2006


Update of /home/cvs/cvsroot/freeside/FS/FS
In directory wavetail:/tmp/cvs-serv15602/FS/FS

Modified Files:
	cust_pay_void.pm cust_refund.pm Record.pm cust_main.pm 
	Schema.pm cust_pay.pm 
Added Files:
	payinfo_Mixin.pm 
Log Message:
encryption fixes from huntsberg & jayce

Index: cust_pay.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_pay.pm,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- cust_pay.pm	13 Sep 2006 14:53:01 -0000	1.45
+++ cust_pay.pm	14 Dec 2006 06:00:45 -0000	1.46
@@ -1,7 +1,7 @@
 package FS::cust_pay;
 
 use strict;
-use vars qw( @ISA $conf $unsuspendauto $ignore_noapply );
+use vars qw( @ISA $conf $unsuspendauto $ignore_noapply @encrypted_fields );
 use Date::Format;
 use Business::CreditCard;
 use Text::Template;
@@ -14,7 +14,7 @@
 use FS::cust_main;
 use FS::cust_pay_void;
 
- at ISA = qw( FS::cust_main_Mixin FS::Record );
+ at ISA = qw(FS::Record FS::cust_main_Mixin FS::payinfo_Mixin  );
 
 $ignore_noapply = 0;
 
@@ -24,6 +24,8 @@
   $unsuspendauto = $conf->exists('unsuspendauto');
 } );
 
+ at encrypted_fields = ('payinfo');
+
 =head1 NAME
 
 FS::cust_pay - Object methods for cust_pay objects
@@ -60,12 +62,11 @@
 =item _date - specified as a UNIX timestamp; see L<perlfunc/"time">.  Also see
 L<Time::Local> and L<Date::Parse> for conversion functions.
 
-=item payby - `CARD' (credit cards), `CHEK' (electronic check/ACH),
-`LECB' (phone bill billing), `BILL' (billing), `PREP` (prepaid card),
-`CASH' (cash), `WEST' (Western Union), `MCRD' (Manual credit card), or
-`COMP' (free)
+=item payby - Payment Type (See L<FS::payinfo_Mixin> for valid payby values)
 
-=item payinfo - card number, check #, or comp issuer (4-8 lowercase alphanumerics; think username), respectively
+=item payinfo - Payment Information (See L<FS::payinfo_Mixin> for data format)
+
+=item paymask - Masked payinfo (See L<FS::payinfo_Mixin> for how this works)
 
 =item paybatch - text field for tracking card processing
 
@@ -327,7 +328,7 @@
         'paid: $'. sprintf("%.2f", $self->paid). "\n",
         'date: '. time2str("%a %b %e %T %Y", $self->_date). "\n",
         'payby: '. $self->payby. "\n",
-        'payinfo: '. $self->payinfo. "\n",
+        'payinfo: '. $self->paymask. "\n",
         'paybatch: '. $self->paybatch. "\n",
       ],
     );
@@ -375,6 +376,7 @@
     || $self->ut_numbern('_date')
     || $self->ut_textn('paybatch')
     || $self->ut_enum('closed', [ '', 'Y' ])
+    || $self->payinfo_check()
   ;
   return $error if $error;
 
@@ -386,30 +388,6 @@
 
   $self->_date(time) unless $self->_date;
 
-  $self->payby =~ /^(CARD|CHEK|LECB|BILL|COMP|PREP|CASH|WEST|MCRD)$/
-    or return "Illegal payby";
-  $self->payby($1);
-
-  #false laziness with cust_refund::check
-  if ( $self->payby eq 'CARD' ) {
-    my $payinfo = $self->payinfo;
-    $payinfo =~ s/\D//g;
-    $self->payinfo($payinfo);
-    if ( $self->payinfo ) {
-      $self->payinfo =~ /^(\d{13,16})$/
-        or return "Illegal (mistyped?) credit card number (payinfo)";
-      $self->payinfo($1);
-      validate($self->payinfo) or return "Illegal credit card number";
-      return "Unknown card type" if cardtype($self->payinfo) eq "Unknown";
-    } else {
-      $self->payinfo('N/A');
-    }
-
-  } else {
-    $error = $self->ut_textn('payinfo');
-    return $error if $error;
-  }
-
   $self->SUPER::check;
 }
 
@@ -542,31 +520,27 @@
 
 =item payinfo_masked
 
-Returns a "masked" payinfo field with all but the last four characters replaced
-by 'x'es.  Useful for displaying credit cards.
+<DEPRICATED> Use $self->paymask
+
+Returns a "masked" payinfo field appropriate to the payment type.  Masked characters are replaced by 'x'es.  Use this to display publicly accessable account Information.
+
+Credit Cards - Mask all but the last four characters.
+Checks - Mask all but last 2 of account number and bank routing number.
+Others - Do nothing, return the unmasked string.
 
 =cut
 
 sub payinfo_masked {
   my $self = shift;
-  #some false laziness w/cust_main::paymask
-  if ( $self->payby eq 'CARD' ) {
-    my $payinfo = $self->payinfo;
-    'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4));
-  } elsif ( $self->payby eq 'CHEK' ) {
-    my( $account, $aba ) = split('@', $self->payinfo );
-    'x'x(length($account)-2). substr($account,(length($account)-2)). "@". $aba;
-  } else {
-    $self->payinfo;
-  }
+  return $self->paymask;
 }
 
+
 =back
 
 =head1 BUGS
 
-Delete and replace methods.  payinfo_masked false laziness with cust_main.pm
-and cust_refund.pm
+Delete and replace methods.  
 
 =head1 SEE ALSO
 

Index: cust_refund.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_refund.pm,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- cust_refund.pm	21 Nov 2005 10:47:11 -0000	1.26
+++ cust_refund.pm	14 Dec 2006 06:00:45 -0000	1.27
@@ -1,7 +1,7 @@
 package FS::cust_refund;
 
 use strict;
-use vars qw( @ISA );
+use vars qw( @ISA @encrypted_fields );
 use Business::CreditCard;
 use FS::Record qw( qsearch qsearchs dbh );
 use FS::UID qw(getotaker);
@@ -9,8 +9,11 @@
 use FS::cust_credit_refund;
 use FS::cust_pay_refund;
 use FS::cust_main;
+use FS::payinfo_Mixin;
 
- at ISA = qw( FS::Record );
+ at ISA = qw( FS::Record FS::payinfo_Mixin );
+
+ at encrypted_fields = ('payinfo');
 
 =head1 NAME
 
@@ -50,11 +53,11 @@
 =item _date - specified as a UNIX timestamp; see L<perlfunc/"time">.  Also see
 L<Time::Local> and L<Date::Parse> for conversion functions.
 
-=item payby - `CARD' (credit cards), `CHEK' (electronic check/ACH),
-`LECB' (Phone bill billing), `BILL' (billing), `CASH' (cash),
-`WEST' (Western Union), `MCRD' (Manual credit card), or `COMP' (free)
+=item payby - Payment Type (See L<FS::payinfo_Mixin> for valid payby values)
 
-=item payinfo - card number, P.O.#, or comp issuer (4-8 lowercase alphanumerics; think username)
+=item payinfo - Payment Information (See L<FS::payinfo_Mixin> for data format)
+
+=item paymask - Masked payinfo (See L<FS::payinfo_Mixin> for how this works)
 
 =item paybatch - text field for tracking card processing
 
@@ -212,29 +215,8 @@
     unless $self->crednum 
            || qsearchs( 'cust_main', { 'custnum' => $self->custnum } );
 
-  $self->payby =~ /^(CARD|CHEK|LECB|BILL|COMP|CASH|WEST|MCRD)$/
-    or return "Illegal payby";
-  $self->payby($1);
-
-  #false laziness with cust_pay::check
-  if ( $self->payby eq 'CARD' ) {
-    my $payinfo = $self->payinfo;
-    $payinfo =~ s/\D//g;
-    $self->payinfo($payinfo);
-    if ( $self->payinfo ) {
-      $self->payinfo =~ /^(\d{13,16})$/
-        or return "Illegal (mistyped?) credit card number (payinfo)";
-      $self->payinfo($1);
-      validate($self->payinfo) or return "Illegal credit card number";
-      return "Unknown card type" if cardtype($self->payinfo) eq "Unknown";
-    } else {
-      $self->payinfo('N/A');
-    }
-
-  } else {
-    $error = $self->ut_textn('payinfo');
-    return $error if $error;
-  }
+  $error = $self->payinfo_check;
+  return $error if $error;
 
   $self->otaker(getotaker);
 
@@ -285,10 +267,10 @@
   sprintf("%.2f", $amount );
 }
 
-
-
 =item payinfo_masked
 
+<DEPRICATED> Use $self->paymask
+
 Returns a "masked" payinfo field with all but the last four characters replaced
 by 'x'es.  Useful for displaying credit cards.
 
@@ -297,8 +279,7 @@
 
 sub payinfo_masked {
   my $self = shift;
-  my $payinfo = $self->payinfo;
-  'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4));
+  return $self->paymask;
 }
 
 

Index: cust_pay_void.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_pay_void.pm,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- cust_pay_void.pm	15 Dec 2005 04:04:50 -0000	1.4
+++ cust_pay_void.pm	14 Dec 2006 06:00:45 -0000	1.5
@@ -1,6 +1,6 @@
 package FS::cust_pay_void; 
 use strict;
-use vars qw( @ISA );
+use vars qw( @ISA @encrypted_fields );
 use Business::CreditCard;
 use FS::UID qw(getotaker);
 use FS::Record qw(qsearchs dbh fields); # qsearch );
@@ -10,7 +10,9 @@
 #use FS::cust_pay_refund;
 #use FS::cust_main;
 
- at ISA = qw( FS::Record );
+ at ISA = qw( FS::Record FS::payinfo_Mixin );
+
+ at encrypted_fields = ('payinfo');
 
 =head1 NAME
 
@@ -209,6 +211,8 @@
 
 =item payinfo_masked
 
+< DEPRICATED > Use $self->paymask
+
 Returns a "masked" payinfo field with all but the last four characters replaced
 by 'x'es.  Useful for displaying credit cards.
 
@@ -216,8 +220,7 @@
 
 sub payinfo_masked {
   my $self = shift;
-  my $payinfo = $self->payinfo;
-  'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4));
+  return $self->paymask;
 }
 
 =back

--- NEW FILE: payinfo_Mixin.pm ---
package FS::payinfo_Mixin;

use strict;
use Business::CreditCard;

=head1 NAME

FS::payinfo_Mixin - Mixin class for records in tables that contain payinfo.  

=head1 SYNOPSIS

package FS::some_table;
use vars qw(@ISA);
@ISA = qw( FS::payinfo_Mixin FS::Record );

=head1 DESCRIPTION

This is a mixin class for records that contain payinfo. 

This class handles the following functions for payinfo...

Payment Mask (Generation and Storage)
Data Validation (parent checks need to be sure to call this)
Encryption - In the Future (Pull from Record.pm)
Bad Card Stuff - In the Future (Integrate Banned Pay)
Currency - In the Future

=head1 fields

=over 4

=item payby

The following payment types (payby) are supported:

For Customers (cust_main):
'CARD' (credit card - automatic), 'DCRD' (credit card - on-demand),
'CHEK' (electronic check - automatic), 'DCHK' (electronic check - on-demand),
'LECB' (Phone bill billing), 'BILL' (billing), 'COMP' (free), or
'PREPAY' (special billing type: applies a credit - see L<FS::prepay_credit> and sets billing type to I<BILL>)

For Refunds (cust_refund):
'CARD' (credit cards), 'CHEK' (electronic check/ACH),
'LECB' (Phone bill billing), 'BILL' (billing), 'CASH' (cash),
'WEST' (Western Union), 'MCRD' (Manual credit card), 'CBAK' Chargeback, or 'COMP' (free),


For Payments (cust_pay):
'CARD' (credit cards), 'CHEK' (electronic check/ACH),
'LECB' (phone bill billing), 'BILL' (billing), 'PREP' (prepaid card),
'CASH' (cash), 'WEST' (Western Union), or 'MCRD' (Manual credit card)
'COMP' (free) is depricated as a payment type in cust_pay

=cut 
 
sub payby {
  my($self,$payby) = @_;
  if ( defined($payby) ) {
    $self->setfield('payby', $payby);
  } 
  return $self->getfield('payby')
}


=item payinfo

Payment information (payinfo) can be one of the following types:

Card Number, P.O., comp issuer (4-8 lowercase alphanumerics; think username) or prepayment identifier (see L<FS::prepay_credit>)

=cut

sub payinfo {
  my($self,$payinfo) = @_;
  if ( defined($payinfo) ) {
    $self->setfield('payinfo', $payinfo); # This is okay since we are the 'setter'
    $self->paymask($self->mask_payinfo());
  } else {
    $payinfo = $self->getfield('payinfo'); # This is okay since we are the 'getter'
    return $payinfo;
  }
}

=item paycvv

Card Verification Value, "CVV2" (also known as CVC2 or CID), the 3 or 4 digit number on the back (or front, for American Express) of the credit card

=cut

sub paycvv {
  my($self,$paycvv) = @_;
  # This is only allowed in cust_main... Even then it really shouldn't be stored...
  if ($self->table eq 'cust_main') {
    if ( defined($paycvv) ) {
      $self->setfield('paycvv', $paycvv); # This is okay since we are the 'setter'
    } else {
      $paycvv = $self->getfield('paycvv'); # This is okay since we are the 'getter'
      return $paycvv;
    }
  } else {
#    warn "This doesn't work for other tables besides cust_main
  } 
}

=item paymask

=cut

sub paymask {
  my($self,$paymask)=@_;


  if ($paymask ne '') {
    # I hate this little bit of magic...  I don't expect it to cause a problem, but who knows...
    # If the payinfo is passed in masked then ignore it and set it based on the payinfo
    # The only guy that should call this in this way is... $self->payinfo
    $self->setfield('paymask', $self->mask_payinfo());
  } else {
    $paymask=$self->getfield('paymask');
    if (!defined($paymask) || $paymask eq '') {
      # Generate it if it's blank - Note that we're not going to set it - just generate
      $paymask = $self->mask_payinfo();
    }
  }
  return $paymask;
}

=item mask_payinfo()

This method converts the payment info (credit card, bank account, etc.) into a masked string.

=cut

sub mask_payinfo {
  my $self = shift;
  my $paymask;
  my $payinfo = $self->payinfo;
  my $payby = $self->payby;
  # Check to see if it's encrypted...
  if ($self->is_encrypted($payinfo)) {
    $paymask = 'N/A';
  } else {
    # if not, mask it...
    if ($payby eq 'CARD' || $payby eq 'DCRD' || $payby eq 'MCRD') { # Credit Cards (Show first and last four)
      $paymask = substr($payinfo,0,4). 'x'x(length($payinfo)-8). substr($payinfo,(length($payinfo)-4));
    } elsif ($payby eq 'CHEK' ||
             $payby eq 'DCHK' ) { # Checks (Show last 2 @ bank)
      my( $account, $aba ) = split('@', $payinfo );
      $paymask = 'x'x(length($account)-2). substr($account,(length($account)-2))."@".$aba;
    } else { # Tie up loose ends
      $paymask = $payinfo;
    }
  }
  return $paymask;
}

=back


=head1 METHODS

=over 4

=item payinfo_check

For Customers (cust_main):
'CARD' (credit card - automatic), 'DCRD' (credit card - on-demand),
'CHEK' (electronic check - automatic), 'DCHK' (electronic check - on-demand),
'LECB' (Phone bill billing), 'BILL' (billing), 'COMP' (free), or
'PREPAY' (special billing type: applies a credit - see L<FS::prepay_credit> and sets billing type to I<BILL>)

For Refunds (cust_refund):
'CARD' (credit cards), 'CHEK' (electronic check/ACH),
'LECB' (Phone bill billing), 'BILL' (billing), 'CASH' (cash),
'WEST' (Western Union), 'MCRD' (Manual credit card), 'CBAK' (Chargeback),  or 'COMP' (free)

For Payments (cust_pay):
'CARD' (credit cards), 'CHEK' (electronic check/ACH),
'LECB' (phone bill billing), 'BILL' (billing), 'PREP' (prepaid card),
'CASH' (cash), 'WEST' (Western Union), or 'MCRD' (Manual credit card)
'COMP' (free) is depricated as a payment type in cust_pay

=cut





sub payinfo_check {
  my $self = shift;

  # Make sure it's a valid payby
  $self->payby =~ /^(CARD|DCRD|CHEK|DCHK|LECB|BILL|COMP|PREPAY|CASH|WEST|MCRD|PREP|CBAK)$/
    or return "Illegal payby (overall payinfo_check)";
  $self->payby($1);


  # Okay some aren't valid depending on table
  if ($self->table eq 'cust_main') {
    if ($self->payby =~ /^(CASH|WEST|MCRD|PREP|CBAK)$/) {
      return "Illegal payby (cust_main)";
    }
  } elsif ($self->table eq 'cust_refund') {
    if ($self->payby =~ /^(DCRD|DCHK|PREPAY|PREP)$/) {
      return "Illegal payby (cust_refund)";
    }
  } elsif ($self->table eq 'cust_pay') {
    if ($self->payby =~ /^(DCRD|DCHK|PREPAY|CBAK)$/) {
      return "Illegal payby (cust_pay)";
    }
  }

  if ( $self->payby eq 'CARD' ) {
    my $payinfo = $self->payinfo;
    $payinfo =~ s/\D//g;
    $self->payinfo($payinfo);
    if ( $self->payinfo ) {
      $self->payinfo =~ /^(\d{13,16})$/
        or return "Illegal (mistyped?) credit card number (payinfo)";
      $self->payinfo($1);
      Business::CreditCard::validate($self->payinfo) or return "Illegal credit card number";
      return "Unknown card type" if Business::CreditCard::cardtype($self->payinfo) eq "Unknown";
    } else {
      $self->payinfo('N/A');
    }
  } else {
    my $error = $self->ut_textn('payinfo');
    return $error if $error;
  }
}



=head1 BUGS

Have to add the future items...

=head1 SEE ALSO

L<FS::Record>

=cut

1;


Index: cust_main.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_main.pm,v
retrieving revision 1.255
retrieving revision 1.256
diff -u -d -r1.255 -r1.256
--- cust_main.pm	7 Dec 2006 02:40:31 -0000	1.255
+++ cust_main.pm	14 Dec 2006 06:00:45 -0000	1.256
@@ -50,8 +50,9 @@
 use FS::payment_gateway;
 use FS::agent_payment_gateway;
 use FS::banned_pay;
+use FS::payinfo_Mixin;
 
- at ISA = qw( FS::Record );
+ at ISA = qw( FS::Record FS::payinfo_Mixin );
 
 @EXPORT_OK = qw( smart_search );
 
@@ -189,81 +190,15 @@
 
 =item ship_fax - phone (optional)
 
-=item payby 
-
-I<CARD> (credit card - automatic), I<DCRD> (credit card - on-demand), I<CHEK> (electronic check - automatic), I<DCHK> (electronic check - on-demand), I<LECB> (Phone bill billing), I<BILL> (billing), I<COMP> (free), or I<PREPAY> (special billing type: applies a credit - see L<FS::prepay_credit> and sets billing type to I<BILL>)
-
-=item payinfo 
-
-Card Number, P.O., comp issuer (4-8 lowercase alphanumerics; think username) or prepayment identifier (see L<FS::prepay_credit>)
-
-=cut 
+=item payby - Payment Type (See L<FS::payinfo_Mixin> for valid payby values)
 
-sub payinfo {
-  my($self,$payinfo) = @_;
-  if ( defined($payinfo) ) {
-    $self->paymask($payinfo);
-    $self->setfield('payinfo', $payinfo); # This is okay since we are the 'setter'
-  } else {
-    $payinfo = $self->getfield('payinfo'); # This is okay since we are the 'getter'
-    return $payinfo;
-  }
-}
+=item payinfo - Payment Information (See L<FS::payinfo_Mixin> for data format)
 
+=item paymask - Masked payinfo (See L<FS::payinfo_Mixin> for how this works)
 
 =item paycvv
- 
-Card Verification Value, "CVV2" (also known as CVC2 or CID), the 3 or 4 digit number on the back (or front, for American Express) of the credit card
-
-=cut
-
-=item paymask - Masked payment type
-
-=over 4 
 
-=item Credit Cards
-
-Mask all but the last four characters.
-
-=item Checks
-
-Mask all but last 2 of account number and bank routing number.
-
-=item Others
-
-Do nothing, return the unmasked string.
-
-=back
-
-=cut 
-
-sub paymask {
-  my($self,$value)=@_;
-
-  # If it doesn't exist then generate it
-  my $paymask=$self->getfield('paymask');
-  if (!defined($value) && (!defined($paymask) || $paymask eq '')) {
-    $value = $self->payinfo;
-  }
-
-  if ( defined($value) && !$self->is_encrypted($value)) {
-    my $payinfo = $value;
-    my $payby = $self->payby;
-    if ($payby eq 'CARD' || $payby eq 'DCRD') { # Credit Cards (Show last four)
-      $paymask = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4));
-    } elsif ($payby eq 'CHEK' ||
-             $payby eq 'DCHK' ) { # Checks (Show last 2 @ bank)
-      my( $account, $aba ) = split('@', $payinfo );
-      $paymask = 'x'x(length($account)-2). substr($account,(length($account)-2))."@".$aba;
-    } else { # Tie up loose ends
-      $paymask = $payinfo;
-    }
-    $self->setfield('paymask', $paymask); # This is okay since we are the 'setter'
-  } elsif (defined($value) && $self->is_encrypted($value)) {
-    $paymask = 'N/A';
-  }
-  return $paymask;
-}
+Card Verification Value, "CVV2" (also known as CVC2 or CID), the 3 or 4 digit number on the back (or front, for American Express) of the credit card
 
 =item paydate - expiration date, mm/yyyy, m/yyyy, mm/yy or m/yy
 
@@ -1141,11 +1076,6 @@
   local $SIG{TSTP} = 'IGNORE';
   local $SIG{PIPE} = 'IGNORE';
 
-  # If the mask is blank then try to set it - if we can...
-  if (!defined($self->getfield('paymask')) || $self->getfield('paymask') eq '') {
-    $self->paymask($self->payinfo);
-  }
-
   # We absolutely have to have an old vs. new record to make this work.
   if (!defined($old)) {
     $old = qsearchs( 'cust_main', { 'custnum' => $self->custnum } );
@@ -1486,11 +1416,10 @@
     $payinfo =~ s/[^\d\@]//g;
     if ( $conf->exists('echeck-nonus') ) {
       $payinfo =~ /^(\d+)\@(\d+)$/ or return 'invalid echeck account at aba';
-      $payinfo = "$1\@$2";
     } else {
       $payinfo =~ /^(\d+)\@(\d{9})$/ or return 'invalid echeck account at aba';
-      $payinfo = "$1\@$2";
     }
+    $payinfo = "$1\@$2";
     $self->payinfo($payinfo);
     $self->paycvv('') if $self->dbdef_table->column('paycvv');
 
@@ -3405,6 +3334,8 @@
 
 =item payinfo_masked
 
+< DEPRICATED > Use $self->paymask
+
 Returns a "masked" payinfo field appropriate to the payment type.  Masked characters are replaced by 'x'es.  Use this to display publicly accessable account Information.
 
 Credit Cards - Mask all but the last four characters.

Index: Record.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/Record.pm,v
retrieving revision 1.127
retrieving revision 1.128
diff -u -d -r1.127 -r1.128
--- Record.pm	7 Dec 2006 02:40:30 -0000	1.127
+++ Record.pm	14 Dec 2006 06:00:45 -0000	1.128
@@ -2,7 +2,8 @@
 
 use strict;
 use vars qw( $AUTOLOAD @ISA @EXPORT_OK $DEBUG
-             $me %virtual_fields_cache $nowarn_identical );
+             $conf $me
+             %virtual_fields_cache $nowarn_identical );
 use Exporter;
 use Carp qw(carp cluck croak confess);
 use File::CounterFile;
@@ -36,9 +37,11 @@
 my $rsa_decrypt;
 
 FS::UID->install_callback( sub {
-  $File::CounterFile::DEFAULT_DIR = "/usr/local/etc/freeside/counters.". datasrc;
+  $conf = new FS::Conf; 
+  $File::CounterFile::DEFAULT_DIR = $conf->base_dir . "/counters.". datasrc;
 } );
 
+
 =head1 NAME
 
 FS::Record - Database record objects
@@ -442,8 +445,11 @@
     }
 
     # Check for encrypted fields and decrypt them.
-    my $conf = new FS::Conf; 
-    if ($conf->exists('encryption') && eval 'defined(@FS::'. $table . '::encrypted_fields)') {
+   ## only in the local copy, not the cached object
+    if ( $conf && $conf->exists('encryption') # $conf doesn't exist when doing
+                                              # the initial search for
+                                              # access_user
+         && eval 'defined(@FS::'. $table . '::encrypted_fields)') {
       foreach my $record (@return) {
         foreach my $field (eval '@FS::'. $table . '::encrypted_fields') {
           # Set it directly... This may cause a problem in the future...
@@ -713,11 +719,10 @@
 
   
   # Encrypt before the database
-  my $conf = new FS::Conf;
   if ($conf->exists('encryption') && defined(eval '@FS::'. $table . '::encrypted_fields')) {
     foreach my $field (eval '@FS::'. $table . '::encrypted_fields') {
       $self->{'saved'} = $self->getfield($field);
-      $self->setfield($field, $self->enrypt($self->getfield($field)));
+      $self->setfield($field, $self->encrypt($self->getfield($field)));
     }
   }
 
@@ -1006,7 +1011,7 @@
   # Encrypt for replace
   my $conf = new FS::Conf;
   my $saved = {};
-  if ($conf->exists('encryption') && defined(eval '@FS::'. $new->table . 'encrypted_fields')) {
+  if ($conf->exists('encryption') && defined(eval '@FS::'. $new->table . '::encrypted_fields')) {
     foreach my $field (eval '@FS::'. $new->table . '::encrypted_fields') {
       $saved->{$field} = $new->getfield($field);
       $new->setfield($field, $new->encrypt($new->getfield($field)));
@@ -1205,6 +1210,12 @@
     grep { defined($self->getfield($_)) && $self->getfield($_) ne "" }
     real_fields($self->table);
   ;
+
+  # If we're encrypting then don't ever store the payinfo or CVV2 in the history....
+  # You can see if it changed by the paymask...
+  if ($conf->exists('encryption') ) {
+    @fields = grep  $_ ne 'payinfo' && $_ ne 'cvv2', @fields;
+  }
   my @values = map { _quote( $self->getfield($_), $self->table, $_) } @fields;
 
   "INSERT INTO h_". $self->table. " ( ".
@@ -1869,6 +1880,17 @@
   } (fields($self->table)) );
 }
 
+=item encrypt($value)
+
+Encrypts the credit card using a combination of PK to encrypt and uuencode to armour.
+
+Returns the encrypted string.
+
+You should generally not have to worry about calling this, as the system handles this for you.
+
+=cut
+
+
 sub encrypt {
   my ($self, $value) = @_;
   my $encrypted;
@@ -1893,17 +1915,32 @@
   return $encrypted;
 }
 
+=item is_encrypted($value)
+
+Checks to see if the string is encrypted and returns true or false (1/0) to indicate it's status.
+
+=cut
+
+
 sub is_encrypted {
   my ($self, $value) = @_;
   # Possible Bug - Some work may be required here....
 
-  if (length($value) > 80) {
+  if ($value =~ /^M/ && length($value) > 80) {
     return 1;
   } else {
     return 0;
   }
 }
 
+=item decrypt($value)
+
+Uses the private key to decrypt the string. Returns the decryoted string or undef on failure.
+
+You should generally not have to worry about calling this, as the system handles this for you.
+
+=cut
+
 sub decrypt {
   my ($self,$value) = @_;
   my $decrypted = $value; # Will return the original value if it isn't encrypted or can't be decrypted.
@@ -1912,7 +1949,8 @@
     $self->loadRSA;
     if (ref($rsa_decrypt) =~ /::RSA/) {
       my $encrypted = unpack ("u*", $value);
-      $decrypted =  unpack("Z*", $rsa_decrypt->decrypt($encrypted));
+      $decrypted =  unpack("Z*", eval{$rsa_decrypt->decrypt($encrypted)});
+      if ($@) {warn "Decryption Failed"};
     }
   }
   return $decrypted;

Index: Schema.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/Schema.pm,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- Schema.pm	7 Dec 2006 02:40:30 -0000	1.36
+++ Schema.pm	14 Dec 2006 06:00:45 -0000	1.37
@@ -520,7 +520,8 @@
         'payby',    'char',   '',     4, '', '', # CARD/BILL/COMP, should be
                                                  # index into payby table
                                                  # eventually
-        'payinfo',  'varchar',   'NULL', $char_d, '', '', #see cust_main above
+        'payinfo',  'varchar',   'NULL', 512, '', '', #see cust_main above
+	'paymask', 'varchar', 'NULL', $char_d, '', '', 
         'paybatch', 'varchar',   'NULL', $char_d, '', '', #for auditing purposes.
         'closed',    'char', 'NULL', 1, '', '', 
       ],
@@ -538,7 +539,8 @@
         'payby',     'char',   '',     4, '', '', # CARD/BILL/COMP, should be
                                                   # index into payby table
                                                   # eventually
-        'payinfo',   'varchar',   'NULL', $char_d, '', '', #see cust_main above
+        'payinfo',   'varchar',   'NULL', 512, '', '', #see cust_main above
+	'paymask', 'varchar', 'NULL', $char_d, '', '', 
         'paybatch',  'varchar',   'NULL', $char_d, '', '', #for auditing purposes.
         'closed',    'char', 'NULL', 1, '', '', 
         'void_date', @date_type, '', '', 
@@ -677,7 +679,8 @@
         'payby',        'char',   '',     4, '', '', # CARD/BILL/COMP, should
                                                      # be index into payby
                                                      # table eventually
-        'payinfo',      'varchar',   'NULL', $char_d, '', '', #see cust_main above
+        'payinfo',      'varchar',   'NULL', 512, '', '', #see cust_main above
+	'paymask', 'varchar', 'NULL', $char_d, '', '', 
         'paybatch',     'varchar',   'NULL', $char_d, '', '', 
         'closed',    'char', 'NULL', 1, '', '', 
       ],



More information about the freeside-commits mailing list