73085: Enable credit card/ach encryption on a live system [v3 merge]
[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 => 14;
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_main 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 ### upgrade test db schema
20 $err = system('freeside-upgrade','-s','admin');
21 ok( !$err, 'schema upgrade ran' ) or BAIL_OUT('Error string: '.$!);
22
23 ### we need to unencrypt our test db before we can test turning it on
24
25 # temporarily load all payinfo into memory
26 my %payinfo = ();
27 foreach my $table (@tables) {
28   $payinfo{$table} = {};
29   foreach my $record ($fs->qsearch({ table => $table })) {
30     next unless grep { $record->payby eq $_ } @FS::Record::encrypt_payby;
31     $payinfo{$table}{$record->get($record->primary_key)} = $record->get('payinfo');
32   }
33 }
34
35 # turn off encryption
36 foreach my $config ( qw(encryption encryptionmodule encryptionpublickey encryptionprivatekey) ) {
37   $conf->delete($config);
38   ok( !$conf->exists($config), "deleted $config" ) or BAIL_OUT('');
39 }
40 $FS::Record::conf_encryption           = $conf->exists('encryption');
41 $FS::Record::conf_encryptionmodule     = $conf->config('encryptionmodule');
42 $FS::Record::conf_encryptionpublickey  = join("\n",$conf->config('encryptionpublickey'));
43 $FS::Record::conf_encryptionprivatekey = join("\n",$conf->config('encryptionprivatekey'));
44
45 # save unencrypted values
46 foreach my $table (@tables) {
47   local $FS::payinfo_Mixin::allow_closed_replace = 1;
48   local $FS::Record::no_update_diff = 1;
49   local $FS::UID::AutoCommit = 1;
50   my $tclass = 'FS::'.$table;
51   foreach my $key (keys %{$payinfo{$table}}) {
52     my $record = $tclass->by_key($key);
53     $record->payinfo($payinfo{$table}{$key});
54     $err = $record->replace;
55     last if $err;
56   }
57 }
58 ok( !$err, "save unencrypted values" ) or BAIL_OUT($err);
59
60 # make sure it worked
61 CHECKDECRYPT:
62 foreach my $table (@tables) {
63   my $tclass = 'FS::'.$table;
64   foreach my $key (sort {$a <=> $b} keys %{$payinfo{$table}}) {
65     my $sql = 'SELECT * FROM '.$table.
66               ' WHERE payinfo LIKE \'M%\''.
67               ' AND char_length(payinfo) > 80'.
68               ' AND '.$tclass->primary_key.' = '.$key;
69     my $sth = dbh->prepare($sql) or BAIL_OUT(dbh->errstr);
70     $sth->execute or BAIL_OUT($sth->errstr);
71     if (my $hashrec = $sth->fetchrow_hashref) {
72       $err = $table.' '.$key.' encrypted';
73       last CHECKDECRYPT;
74     }
75   }
76 }
77 ok( !$err, "all values unencrypted" ) or BAIL_OUT($err);
78
79 ### now, run upgrade
80 $err = system('freeside-upgrade','admin');
81 ok( !$err, 'upgrade ran' ) or BAIL_OUT('Error string: '.$!);
82
83 # check that confs got set
84 foreach my $config ( qw(encryption encryptionmodule encryptionpublickey encryptionprivatekey) ) {
85   ok( $conf->exists($config), "$config was set" ) or BAIL_OUT('');
86 }
87
88 # check that known records got encrypted
89 CHECKENCRYPT:
90 foreach my $table (@tables) {
91   my $tclass = 'FS::'.$table;
92   foreach my $key (sort {$a <=> $b} keys %{$payinfo{$table}}) {
93     my $sql = 'SELECT * FROM '.$table.
94               ' WHERE payinfo LIKE \'M%\''.
95               ' AND char_length(payinfo) > 80'.
96               ' AND '.$tclass->primary_key.' = '.$key;
97     my $sth = dbh->prepare($sql) or BAIL_OUT(dbh->errstr);
98     $sth->execute or BAIL_OUT($sth->errstr);
99     unless ($sth->fetchrow_hashref) {
100       $err = $table.' '.$key.' not encrypted';
101       last CHECKENCRYPT;
102     }
103   }
104 }
105 ok( !$err, "all values encrypted" ) or BAIL_OUT($err);
106
107 exit;
108
109 1;
110