Lines 15-27
Link Here
|
15 |
# with Koha; if not, see <http://www.gnu.org/licenses>. |
15 |
# with Koha; if not, see <http://www.gnu.org/licenses>. |
16 |
|
16 |
|
17 |
use Modern::Perl; |
17 |
use Modern::Perl; |
18 |
use Test::More tests => 5; |
18 |
use Test::More tests => 3; |
19 |
|
19 |
|
20 |
use C4::Context; |
20 |
use C4::Context; |
21 |
use C4::Log; |
21 |
use C4::Log; |
22 |
use C4::Auth qw/checkpw/; |
22 |
use C4::Auth qw/checkpw/; |
23 |
use Koha::Database; |
23 |
use Koha::Database; |
24 |
use Koha::DateUtils; |
24 |
use Koha::DateUtils; |
|
|
25 |
use Koha::ActionLogs; |
25 |
|
26 |
|
26 |
use t::lib::Mocks qw/mock_preference/; # to mock CronjobLog |
27 |
use t::lib::Mocks qw/mock_preference/; # to mock CronjobLog |
27 |
use t::lib::TestBuilder; |
28 |
use t::lib::TestBuilder; |
Lines 32-38
$schema->storage->txn_begin;
Link Here
|
32 |
our $dbh = C4::Context->dbh; |
33 |
our $dbh = C4::Context->dbh; |
33 |
|
34 |
|
34 |
subtest 'Existing tests' => sub { |
35 |
subtest 'Existing tests' => sub { |
35 |
plan tests => 6; |
36 |
plan tests => 3; |
36 |
|
37 |
|
37 |
my $success; |
38 |
my $success; |
38 |
eval { |
39 |
eval { |
Lines 45-77
subtest 'Existing tests' => sub {
Link Here
|
45 |
}; |
46 |
}; |
46 |
ok($success, "logaction seemed to work"); |
47 |
ok($success, "logaction seemed to work"); |
47 |
|
48 |
|
48 |
eval { |
|
|
49 |
# FIXME: US formatted date hardcoded into test for now |
50 |
$success = scalar(@{GetLogs("","","",undef,undef,"","")}); |
51 |
} or do { |
52 |
diag($@); |
53 |
$success = 0; |
54 |
}; |
55 |
ok($success, "GetLogs returns results for an open search"); |
56 |
|
57 |
eval { |
58 |
# FIXME: US formatted date hardcoded into test for now |
59 |
my $date = output_pref( { dt => dt_from_string, dateonly => 1, dateformat => 'iso' } ); |
60 |
$success = scalar(@{GetLogs( $date, $date, "", undef, undef, "", "") } ); |
61 |
} or do { |
62 |
diag($@); |
63 |
$success = 0; |
64 |
}; |
65 |
ok($success, "GetLogs accepts dates in an All-matching search"); |
66 |
|
67 |
eval { |
68 |
$success = scalar(@{GetLogs("","","",["MEMBERS"],["MODIFY"],1,"")}); |
69 |
} or do { |
70 |
diag($@); |
71 |
$success = 0; |
72 |
}; |
73 |
ok($success, "GetLogs seemed to find ".$success." like our test record in a tighter search"); |
74 |
|
75 |
# We want numbers to be the same between runs. |
49 |
# We want numbers to be the same between runs. |
76 |
$dbh->do("DELETE FROM action_logs;"); |
50 |
$dbh->do("DELETE FROM action_logs;"); |
77 |
|
51 |
|
Lines 86-107
subtest 'Existing tests' => sub {
Link Here
|
86 |
is($cronJobCount,1,"Cronjob logged as expected."); |
60 |
is($cronJobCount,1,"Cronjob logged as expected."); |
87 |
}; |
61 |
}; |
88 |
|
62 |
|
89 |
subtest "GetLogs should return all logs if dates are not set" => sub { |
|
|
90 |
plan tests => 2; |
91 |
my $today = dt_from_string->add(minutes => -1); |
92 |
my $yesterday = dt_from_string->add( days => -1 ); |
93 |
$dbh->do(q| |
94 |
INSERT INTO action_logs (timestamp, user, module, action, object, info) |
95 |
VALUES |
96 |
(?, 42, 'CATALOGUING', 'MODIFY', 4242, 'Record 42 has been modified by patron 4242 yesterday'), |
97 |
(?, 43, 'CATALOGUING', 'MODIFY', 4242, 'Record 43 has been modified by patron 4242 today') |
98 |
|, undef, output_pref({dt =>$yesterday, dateformat => 'iso'}), output_pref({dt => $today, dateformat => 'iso'})); |
99 |
my $logs = GetLogs( undef, undef, undef, ['CATALOGUING'], ['MODIFY'], 4242 ); |
100 |
is( scalar(@$logs), 2, 'GetLogs should return all logs regardless the dates' ); |
101 |
$logs = GetLogs( output_pref($today), undef, undef, ['CATALOGUING'], ['MODIFY'], 4242 ); |
102 |
is( scalar(@$logs), 1, 'GetLogs should return the logs for today' ); |
103 |
}; |
104 |
|
105 |
subtest 'logaction(): interface is correctly logged' => sub { |
63 |
subtest 'logaction(): interface is correctly logged' => sub { |
106 |
|
64 |
|
107 |
plan tests => 4; |
65 |
plan tests => 4; |
Lines 110-165
subtest 'logaction(): interface is correctly logged' => sub {
Link Here
|
110 |
$dbh->do("DELETE FROM action_logs;"); |
68 |
$dbh->do("DELETE FROM action_logs;"); |
111 |
C4::Context->interface( 'commandline' ); |
69 |
C4::Context->interface( 'commandline' ); |
112 |
logaction( "MEMBERS", "MODIFY", 1, "test operation"); |
70 |
logaction( "MEMBERS", "MODIFY", 1, "test operation"); |
113 |
my $logs = GetLogs(); |
71 |
my $log = Koha::ActionLogs->search->next; |
114 |
is( @{$logs}[0]->{ interface }, 'commandline', 'Interface correctly deduced (commandline)'); |
72 |
is( $log->interface, 'commandline', 'Interface correctly deduced (commandline)'); |
115 |
|
73 |
|
116 |
# No interface passed, using C4::Context->interface |
74 |
# No interface passed, using C4::Context->interface |
117 |
$dbh->do("DELETE FROM action_logs;"); |
75 |
$dbh->do("DELETE FROM action_logs;"); |
118 |
C4::Context->interface( 'opac' ); |
76 |
C4::Context->interface( 'opac' ); |
119 |
logaction( "MEMBERS", "MODIFY", 1, "test operation"); |
77 |
logaction( "MEMBERS", "MODIFY", 1, "test operation"); |
120 |
$logs = GetLogs(); |
78 |
$log = Koha::ActionLogs->search->next; |
121 |
is( @{$logs}[0]->{ interface }, 'opac', 'Interface correctly deduced (opac)'); |
79 |
is( $log->interface, 'opac', 'Interface correctly deduced (opac)'); |
122 |
|
80 |
|
123 |
# Explicit interfaces |
81 |
# Explicit interfaces |
124 |
$dbh->do("DELETE FROM action_logs;"); |
82 |
$dbh->do("DELETE FROM action_logs;"); |
125 |
C4::Context->interface( 'intranet' ); |
83 |
C4::Context->interface( 'intranet' ); |
126 |
logaction( "MEMBERS", "MODIFY", 1, 'test info', 'intranet'); |
84 |
logaction( "MEMBERS", "MODIFY", 1, 'test info', 'intranet'); |
127 |
$logs = GetLogs(); |
85 |
$log = Koha::ActionLogs->search->next; |
128 |
is( @{$logs}[0]->{ interface }, 'intranet', 'Passed interface is respected (intranet)'); |
86 |
is( $log->interface, 'intranet', 'Passed interface is respected (intranet)'); |
129 |
|
87 |
|
130 |
# Explicit interfaces |
88 |
# Explicit interfaces |
131 |
$dbh->do("DELETE FROM action_logs;"); |
89 |
$dbh->do("DELETE FROM action_logs;"); |
132 |
C4::Context->interface( 'sip' ); |
90 |
C4::Context->interface( 'sip' ); |
133 |
logaction( "MEMBERS", "MODIFY", 1, 'test info', 'sip'); |
91 |
logaction( "MEMBERS", "MODIFY", 1, 'test info', 'sip'); |
134 |
$logs = GetLogs(); |
92 |
$log = Koha::ActionLogs->search->next; |
135 |
is( @{$logs}[0]->{ interface }, 'sip', 'Passed interface is respected (sip)'); |
93 |
is( $log->interface, 'sip', 'Passed interface is respected (sip)'); |
136 |
}; |
|
|
137 |
|
138 |
subtest 'GetLogs() respects interface filters' => sub { |
139 |
|
140 |
plan tests => 5; |
141 |
|
142 |
$dbh->do("DELETE FROM action_logs;"); |
143 |
|
144 |
logaction( 'MEMBERS', 'MODIFY', 1, 'opac info', 'opac'); |
145 |
logaction( 'MEMBERS', 'MODIFY', 1, 'sip info', 'sip'); |
146 |
logaction( 'MEMBERS', 'MODIFY', 1, 'intranet info', 'intranet'); |
147 |
logaction( 'MEMBERS', 'MODIFY', 1, 'commandline info', 'commandline'); |
148 |
|
149 |
my $logs = scalar @{ GetLogs() }; |
150 |
is( $logs, 4, 'If no filter on interfaces is passed, all logs are returned'); |
151 |
|
152 |
$logs = GetLogs(undef,undef,undef,undef,undef,undef,undef,['opac']); |
153 |
is( @{$logs}[0]->{ interface }, 'opac', 'Interface correctly filtered (opac)'); |
154 |
|
155 |
$logs = GetLogs(undef,undef,undef,undef,undef,undef,undef,['sip']); |
156 |
is( @{$logs}[0]->{ interface }, 'sip', 'Interface correctly filtered (sip)'); |
157 |
|
158 |
$logs = GetLogs(undef,undef,undef,undef,undef,undef,undef,['intranet']); |
159 |
is( @{$logs}[0]->{ interface }, 'intranet', 'Interface correctly filtered (intranet)'); |
160 |
|
161 |
$logs = GetLogs(undef,undef,undef,undef,undef,undef,undef,['commandline']); |
162 |
is( @{$logs}[0]->{ interface }, 'commandline', 'Interface correctly filtered (commandline)'); |
163 |
}; |
94 |
}; |
164 |
|
95 |
|
165 |
subtest 'GDPR logging' => sub { |
96 |
subtest 'GDPR logging' => sub { |
Lines 170-177
subtest 'GDPR logging' => sub {
Link Here
|
170 |
|
101 |
|
171 |
t::lib::Mocks::mock_userenv({ patron => $patron }); |
102 |
t::lib::Mocks::mock_userenv({ patron => $patron }); |
172 |
logaction( 'AUTH', 'FAILURE', $patron->id, '', 'opac' ); |
103 |
logaction( 'AUTH', 'FAILURE', $patron->id, '', 'opac' ); |
173 |
my $logs = GetLogs( undef, undef, $patron->id, ['AUTH'], ['FAILURE'], $patron->id ); |
104 |
my $logs = Koha::ActionLogs->search( |
174 |
is( @$logs, 1, 'We should find one auth failure' ); |
105 |
{ |
|
|
106 |
user => $patron->id, |
107 |
module => 'AUTH', |
108 |
action => 'FAILURE', |
109 |
object => $patron->id, |
110 |
} |
111 |
); |
112 |
is( $logs->count, 1, 'We should find one auth failure' ); |
175 |
|
113 |
|
176 |
t::lib::Mocks::mock_preference('AuthFailureLog', 1); |
114 |
t::lib::Mocks::mock_preference('AuthFailureLog', 1); |
177 |
my $strong_password = 'N0tStr0ngAnyM0reN0w:)'; |
115 |
my $strong_password = 'N0tStr0ngAnyM0reN0w:)'; |
Lines 179-196
subtest 'GDPR logging' => sub {
Link Here
|
179 |
my @ret = checkpw( $dbh, $patron->userid, 'WrongPassword', undef, undef, 1); |
117 |
my @ret = checkpw( $dbh, $patron->userid, 'WrongPassword', undef, undef, 1); |
180 |
is( $ret[0], 0, 'Authentication failed' ); |
118 |
is( $ret[0], 0, 'Authentication failed' ); |
181 |
# Look for auth failure but NOT on patron id, pass userid in info parameter |
119 |
# Look for auth failure but NOT on patron id, pass userid in info parameter |
182 |
$logs = GetLogs( undef, undef, 0, ['AUTH'], ['FAILURE'], undef, $patron->userid ); |
120 |
$logs = Koha::ActionLogs->search( |
183 |
is( @$logs, 1, 'We should find one auth failure with this userid' ); |
121 |
{ |
|
|
122 |
module => 'AUTH', |
123 |
action => 'FAILURE', |
124 |
info => { -like => '%'.$patron->userid.'%' }, |
125 |
} |
126 |
); |
127 |
is( $logs->count, 1, 'We should find one auth failure with this userid' ); |
184 |
t::lib::Mocks::mock_preference('AuthFailureLog', 0); |
128 |
t::lib::Mocks::mock_preference('AuthFailureLog', 0); |
185 |
@ret = checkpw( $dbh, $patron->userid, 'WrongPassword', undef, undef, 1); |
129 |
@ret = checkpw( $dbh, $patron->userid, 'WrongPassword', undef, undef, 1); |
186 |
$logs = GetLogs( undef, undef, 0, ['AUTH'], ['FAILURE'], undef, $patron->userid ); |
130 |
$logs = Koha::ActionLogs->search( |
187 |
is( @$logs, 1, 'Still only one failure with this userid' ); |
131 |
{ |
|
|
132 |
module => 'AUTH', |
133 |
action => 'FAILURE', |
134 |
info => { -like => '%'.$patron->userid.'%' }, |
135 |
} |
136 |
); |
137 |
is( $logs->count, 1, 'Still only one failure with this userid' ); |
188 |
t::lib::Mocks::mock_preference('AuthSuccessLog', 1); |
138 |
t::lib::Mocks::mock_preference('AuthSuccessLog', 1); |
189 |
@ret = checkpw( $dbh, $patron->userid, $strong_password, undef, undef, 1); |
139 |
@ret = checkpw( $dbh, $patron->userid, $strong_password, undef, undef, 1); |
190 |
is( $ret[0], 1, 'Authentication succeeded' ); |
140 |
is( $ret[0], 1, 'Authentication succeeded' ); |
191 |
# Now we can look for patron id |
141 |
# Now we can look for patron id |
192 |
$logs = GetLogs( undef, undef, $patron->id, ['AUTH'], ['SUCCESS'], $patron->id ); |
142 |
$logs = Koha::ActionLogs->search( |
193 |
is( @$logs, 1, 'We expect only one auth success line for this patron' ); |
143 |
{ |
|
|
144 |
user => $patron->id, |
145 |
module => 'AUTH', |
146 |
action => 'SUCCESS', |
147 |
object => $patron->id, |
148 |
} |
149 |
); |
150 |
|
151 |
is( $logs->count, 1, 'We expect only one auth success line for this patron' ); |
194 |
}; |
152 |
}; |
195 |
|
153 |
|
196 |
$schema->storage->txn_rollback; |
154 |
$schema->storage->txn_rollback; |
197 |
- |
|
|