default to a session cookie instead of setting an explicit timeout, weird timezone...
[freeside.git] / FS / t / suite / 15-activate_encryption.t
1 #!/usr/bin/perl
2
3 use strict;
4 use FS::Test;
5 use Test::More tests => 15;
6 use FS::Conf;
7 use FS::UID qw( dbh );
8 use DateTime;
9 use FS::cust_main; # to load all other tables
10
11 my $fs = FS::Test->new( user => 'admin' );
12 my $conf = FS::Conf->new;
13 my $err;
14 my @tables = qw(cust_payby cust_pay_pending cust_pay cust_pay_void cust_refund);
15
16 ### can only run on test database (company name "Freeside Test")
17 like( $conf->config('company_name'), qr/^Freeside Test/, 'using test database' ) or BAIL_OUT('');
18
19 ### remove gateway overrides and set non-tokenizing default gateway
20 ### so that we play nicely with tokenization upgrades
21 ### (though really, should just get rid of cardtype overrides in test db)
22 # these will just get in the way for now
23 foreach my $apg ($fs->qsearch('agent_payment_gateway')) {
24   $err = $apg->delete;
25   last if $err;
26 }
27 ok( !$err, 'removing agent gateway overrides' ) or BAIL_OUT($err);
28
29 my $bopconf = 
30 'IPPay
31 TESTTERMINAL';
32 $conf->set('business-onlinepayment' => $bopconf);
33 is( join("\n",$conf->config('business-onlinepayment')), $bopconf, "set default gateway" ) or BAIL_OUT('');
34
35 ### we need to unencrypt our test db before we can test turning it on
36
37 # temporarily load all payinfo into memory
38 my %payinfo = ();
39 foreach my $table (@tables) {
40   $payinfo{$table} = {};
41   foreach my $record ($fs->qsearch({ table => $table })) {
42     next unless grep { $record->payby eq $_ } @FS::Record::encrypt_payby;
43     $payinfo{$table}{$record->get($record->primary_key)} = $record->get('payinfo');
44   }
45 }
46
47 # turn off encryption
48 foreach my $config ( qw(encryption encryptionmodule encryptionpublickey encryptionprivatekey) ) {
49   $conf->delete($config);
50   ok( !$conf->exists($config), "deleted $config" ) or BAIL_OUT('');
51 }
52 $FS::Record::conf_encryption           = $conf->exists('encryption');
53 $FS::Record::conf_encryptionmodule     = $conf->config('encryptionmodule');
54 $FS::Record::conf_encryptionpublickey  = join("\n",$conf->config('encryptionpublickey'));
55 $FS::Record::conf_encryptionprivatekey = join("\n",$conf->config('encryptionprivatekey'));
56
57 # save unencrypted values
58 foreach my $table (@tables) {
59   local $FS::payinfo_Mixin::allow_closed_replace = 1;
60   local $FS::Record::no_update_diff = 1;
61   local $FS::UID::AutoCommit = 1;
62   my $tclass = 'FS::'.$table;
63   foreach my $key (keys %{$payinfo{$table}}) {
64     my $record = $tclass->by_key($key);
65     $record->payinfo($payinfo{$table}{$key});
66     $err = $record->replace;
67     last if $err;
68   }
69 }
70 ok( !$err, "save unencrypted values" ) or BAIL_OUT($err);
71
72 # make sure it worked
73 CHECKDECRYPT:
74 foreach my $table (@tables) {
75   my $tclass = 'FS::'.$table;
76   foreach my $key (sort {$a <=> $b} keys %{$payinfo{$table}}) {
77     my $sql = 'SELECT * FROM '.$table.
78               ' WHERE payinfo LIKE \'M%\''.
79               ' AND char_length(payinfo) > 80'.
80               ' AND '.$tclass->primary_key.' = '.$key;
81     my $sth = dbh->prepare($sql) or BAIL_OUT(dbh->errstr);
82     $sth->execute or BAIL_OUT($sth->errstr);
83     if (my $hashrec = $sth->fetchrow_hashref) {
84       $err = $table.' '.$key.' encrypted';
85       last CHECKDECRYPT;
86     }
87   }
88 }
89 ok( !$err, "all values unencrypted" ) or BAIL_OUT($err);
90
91 ### now, run upgrade
92 $err = system('freeside-upgrade','admin');
93 ok( !$err, 'upgrade ran' ) or BAIL_OUT('Error string: '.$!);
94
95 # check that confs got set
96 foreach my $config ( qw(encryption encryptionmodule encryptionpublickey encryptionprivatekey) ) {
97   ok( $conf->exists($config), "$config was set" ) or BAIL_OUT('');
98 }
99
100 # check that known records got encrypted
101 CHECKENCRYPT:
102 foreach my $table (@tables) {
103   my $tclass = 'FS::'.$table;
104   foreach my $key (sort {$a <=> $b} keys %{$payinfo{$table}}) {
105     my $sql = 'SELECT * FROM '.$table.
106               ' WHERE payinfo LIKE \'M%\''.
107               ' AND char_length(payinfo) > 80'.
108               ' AND '.$tclass->primary_key.' = '.$key;
109     my $sth = dbh->prepare($sql) or BAIL_OUT(dbh->errstr);
110     $sth->execute or BAIL_OUT($sth->errstr);
111     unless ($sth->fetchrow_hashref) {
112       $err = $table.' '.$key.' not encrypted';
113       last CHECKENCRYPT;
114     }
115   }
116 }
117 ok( !$err, "all values encrypted" ) or BAIL_OUT($err);
118
119 exit;
120
121 1;
122