View | Details | Raw Unified | Return to bug 14540
Collapse All | Expand All

(-)a/C4/Auth.pm (-19 / +42 lines)
Lines 23-28 use Digest::MD5 qw(md5_base64); Link Here
23
use JSON qw/encode_json/;
23
use JSON qw/encode_json/;
24
use URI::Escape;
24
use URI::Escape;
25
use CGI::Session;
25
use CGI::Session;
26
use Scalar::Util qw(blessed);
27
use Try::Tiny;
26
28
27
require Exporter;
29
require Exporter;
28
use C4::Context;
30
use C4::Context;
Lines 226-232 sub get_template_and_user { Link Here
226
        # We are going to use the $flags returned by checkauth
228
        # We are going to use the $flags returned by checkauth
227
        # to create the template's parameters that will indicate
229
        # to create the template's parameters that will indicate
228
        # which menus the user can access.
230
        # which menus the user can access.
229
        if ( $flags && $flags->{superlibrarian} == 1 ) {
231
        if ( $flags && $flags->{superlibrarian} ) {
230
            $template->param( CAN_user_circulate        => 1 );
232
            $template->param( CAN_user_circulate        => 1 );
231
            $template->param( CAN_user_catalogue        => 1 );
233
            $template->param( CAN_user_catalogue        => 1 );
232
            $template->param( CAN_user_parameters       => 1 );
234
            $template->param( CAN_user_parameters       => 1 );
Lines 1741-1747 sub checkpw_internal { Link Here
1741
1743
1742
    my $sth =
1744
    my $sth =
1743
      $dbh->prepare(
1745
      $dbh->prepare(
1744
        "select password,cardnumber,borrowernumber,userid,firstname,surname,borrowers.branchcode,branches.branchname,flags from borrowers join branches on borrowers.branchcode=branches.branchcode where userid=?"
1746
        "select password,cardnumber,borrowernumber,userid,firstname,surname,borrowers.branchcode,branches.branchname from borrowers join branches on borrowers.branchcode=branches.branchcode where userid=?"
1745
      );
1747
      );
1746
    $sth->execute($userid);
1748
    $sth->execute($userid);
1747
    if ( $sth->rows ) {
1749
    if ( $sth->rows ) {
Lines 1801-1806 sub checkpw_hash { Link Here
1801
}
1803
}
1802
1804
1803
=head2 getuserflags
1805
=head2 getuserflags
1806
@DEPRECATED, USE THE Koha::Auth::PermissionManager
1804
1807
1805
    my $authflags = getuserflags($flags, $userid, [$dbh]);
1808
    my $authflags = getuserflags($flags, $userid, [$dbh]);
1806
1809
Lines 1813-1818 C<$authflags> is a hashref of permissions Link Here
1813
=cut
1816
=cut
1814
1817
1815
sub getuserflags {
1818
sub getuserflags {
1819
    #@DEPRECATED, USE THE Koha::Auth::PermissionManager
1816
    my $flags  = shift;
1820
    my $flags  = shift;
1817
    my $userid = shift;
1821
    my $userid = shift;
1818
    my $dbh    = @_ ? shift : C4::Context->dbh;
1822
    my $dbh    = @_ ? shift : C4::Context->dbh;
Lines 1824-1829 sub getuserflags { Link Here
1824
        no warnings 'numeric';
1828
        no warnings 'numeric';
1825
        $flags += 0;
1829
        $flags += 0;
1826
    }
1830
    }
1831
    return get_user_subpermissions($userid);
1832
1833
    #@DEPRECATED, USE THE Koha::Auth::PermissionManager
1827
    my $sth = $dbh->prepare("SELECT bit, flag, defaulton FROM userflags");
1834
    my $sth = $dbh->prepare("SELECT bit, flag, defaulton FROM userflags");
1828
    $sth->execute;
1835
    $sth->execute;
1829
1836
Lines 1847-1853 sub getuserflags { Link Here
1847
}
1854
}
1848
1855
1849
=head2 get_user_subpermissions
1856
=head2 get_user_subpermissions
1850
1857
@DEPRECATED, USE THE Koha::Auth::PermissionManager
1851
  $user_perm_hashref = get_user_subpermissions($userid);
1858
  $user_perm_hashref = get_user_subpermissions($userid);
1852
1859
1853
Given the userid (note, not the borrowernumber) of a staff user,
1860
Given the userid (note, not the borrowernumber) of a staff user,
Lines 1872-1896 necessary to check borrowers.flags. Link Here
1872
=cut
1879
=cut
1873
1880
1874
sub get_user_subpermissions {
1881
sub get_user_subpermissions {
1882
    #@DEPRECATED, USE THE Koha::Auth::PermissionManager
1875
    my $userid = shift;
1883
    my $userid = shift;
1876
1884
1877
    my $dbh = C4::Context->dbh;
1885
    use Koha::Auth::PermissionManager;
1878
    my $sth = $dbh->prepare( "SELECT flag, user_permissions.code
1886
    my $permissionManager = Koha::Auth::PermissionManager->new();
1879
                             FROM user_permissions
1887
    my $borrowerPermissions = $permissionManager->getBorrowerPermissions($userid); #Prefetch all related tables.
1880
                             JOIN permissions USING (module_bit, code)
1881
                             JOIN userflags ON (module_bit = bit)
1882
                             JOIN borrowers USING (borrowernumber)
1883
                             WHERE userid = ?" );
1884
    $sth->execute($userid);
1885
1886
    my $user_perms = {};
1888
    my $user_perms = {};
1887
    while ( my $perm = $sth->fetchrow_hashref ) {
1889
    foreach my $perm ( @$borrowerPermissions ) {
1888
        $user_perms->{ $perm->{'flag'} }->{ $perm->{'code'} } = 1;
1890
        $user_perms->{ $perm->getPermissionModule->module }->{ $perm->getPermission->code } = 1;
1889
    }
1891
    }
1892
1890
    return $user_perms;
1893
    return $user_perms;
1891
}
1894
}
1892
1895
1893
=head2 get_all_subpermissions
1896
=head2 get_all_subpermissions
1897
@DEPRECATED, USE THE Koha::Auth::PermissionManager
1894
1898
1895
  my $perm_hashref = get_all_subpermissions();
1899
  my $perm_hashref = get_all_subpermissions();
1896
1900
Lines 1903-1908 of the subpermission. Link Here
1903
=cut
1907
=cut
1904
1908
1905
sub get_all_subpermissions {
1909
sub get_all_subpermissions {
1910
    #@DEPRECATED, USE THE Koha::Auth::PermissionManager
1911
    use Koha::Auth::PermissionManager;
1912
    my $permissionManager = Koha::Auth::PermissionManager->new();
1913
    my $all_permissions = $permissionManager->listKohaPermissionsAsHASH();
1914
    foreach my $module ( keys %$all_permissions ) {
1915
        my $permissionModule = $all_permissions->{$module};
1916
        foreach my $code (keys %{$permissionModule->{permissions}}) {
1917
            my $permission = $permissionModule->{permissions}->{$code};
1918
            $all_permissions->{$module}->{$code} = $permission->{'description'};
1919
        }
1920
    }
1921
    return $all_permissions;
1922
1923
    #@DEPRECATED, USE THE Koha::Auth::PermissionManager
1906
    my $dbh = C4::Context->dbh;
1924
    my $dbh = C4::Context->dbh;
1907
    my $sth = $dbh->prepare( "SELECT flag, code, description
1925
    my $sth = $dbh->prepare( "SELECT flag, code, description
1908
                             FROM permissions
1926
                             FROM permissions
Lines 1917-1922 sub get_all_subpermissions { Link Here
1917
}
1935
}
1918
1936
1919
=head2 haspermission
1937
=head2 haspermission
1938
@DEPRECATED, USE THE Koha::Auth::PermissionManager
1920
1939
1921
  $flags = ($userid, $flagsrequired);
1940
  $flags = ($userid, $flagsrequired);
1922
1941
Lines 1928-1938 Returns member's flags or 0 if a permission is not met. Link Here
1928
=cut
1947
=cut
1929
1948
1930
sub haspermission {
1949
sub haspermission {
1950
    #@DEPRECATED, USE THE Koha::Auth::PermissionManager
1931
    my ( $userid, $flagsrequired ) = @_;
1951
    my ( $userid, $flagsrequired ) = @_;
1932
    my $sth = C4::Context->dbh->prepare("SELECT flags FROM borrowers WHERE userid=?");
1952
1933
    $sth->execute($userid);
1953
    my $flags = getuserflags( undef, $userid );
1934
    my $row = $sth->fetchrow();
1954
    #Sanitate 1 to * because we no longer have 1's from the koha.borrowers.flags.
1935
    my $flags = getuserflags( $row, $userid );
1955
    foreach my $module (%$flagsrequired) {
1956
        $flagsrequired->{$module} = '*' if $flagsrequired->{$module} && $flagsrequired->{$module} eq '1';
1957
    }
1958
1936
    if ( $userid eq C4::Context->config('user') ) {
1959
    if ( $userid eq C4::Context->config('user') ) {
1937
1960
1938
        # Super User Account from /etc/koha.conf
1961
        # Super User Account from /etc/koha.conf
Lines 1949-1955 sub haspermission { Link Here
1949
    foreach my $module ( keys %$flagsrequired ) {
1972
    foreach my $module ( keys %$flagsrequired ) {
1950
        my $subperm = $flagsrequired->{$module};
1973
        my $subperm = $flagsrequired->{$module};
1951
        if ( $subperm eq '*' ) {
1974
        if ( $subperm eq '*' ) {
1952
            return 0 unless ( $flags->{$module} == 1 or ref( $flags->{$module} ) );
1975
            return 0 unless ( ref( $flags->{$module} ) );
1953
        } else {
1976
        } else {
1954
            return 0 unless (
1977
            return 0 unless (
1955
                ( defined $flags->{$module} and
1978
                ( defined $flags->{$module} and
(-)a/C4/Members.pm (-10 / +1 lines)
Lines 230-246 sub GetMemberDetails { Link Here
230
    $borrower->{'amountoutstanding'} = $amount;
230
    $borrower->{'amountoutstanding'} = $amount;
231
    # FIXME - patronflags calls GetMemberAccountRecords... just have patronflags return $amount
231
    # FIXME - patronflags calls GetMemberAccountRecords... just have patronflags return $amount
232
    my $flags = patronflags( $borrower);
232
    my $flags = patronflags( $borrower);
233
    my $accessflagshash;
234
233
235
    $sth = $dbh->prepare("select bit,flag from userflags");
234
    $borrower->{'flags'}     = $flags; #Is this the flags-column? @DEPRECATED!
236
    $sth->execute;
237
    while ( my ( $bit, $flag ) = $sth->fetchrow ) {
238
        if ( $borrower->{'flags'} && $borrower->{'flags'} & 2**$bit ) {
239
            $accessflagshash->{$flag} = 1;
240
        }
241
    }
242
    $borrower->{'flags'}     = $flags;
243
    $borrower->{'authflags'} = $accessflagshash;
244
235
245
    # For the purposes of making templates easier, we'll define a
236
    # For the purposes of making templates easier, we'll define a
246
    # 'showname' which is the alternate form the user's first name if 
237
    # 'showname' which is the alternate form the user's first name if 
(-)a/Koha/Auth/BorrowerPermission.pm (+221 lines)
Line 0 Link Here
1
package Koha::Auth::BorrowerPermission;
2
3
# Copyright 2015 Vaara-kirjastot
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
use Scalar::Util qw(blessed);
22
23
use Koha::Auth::BorrowerPermissions;
24
use Koha::Auth::PermissionModules;
25
use Koha::Auth::Permissions;
26
use Koha::Borrowers;
27
28
use Koha::Exception::BadParameter;
29
30
use base qw(Koha::Object);
31
32
sub type {
33
    return 'BorrowerPermission';
34
}
35
sub object_class {
36
    return 'Koha::Auth::BorrowerPermission';
37
}
38
39
=head NAME
40
41
Koha::Auth::BorrowerPermission
42
43
=head SYNOPSIS
44
45
Object representation of a Permission given to a Borrower.
46
47
=head new
48
49
    my $borrowerPermission = Koha::Auth::BorrowerPermission->new({
50
                                borrowernumber => 12,
51
                                permission_module_id => 2,
52
                                permission => $Koha::Auth::Permission,
53
    });
54
    my $borrowerPermission = Koha::Auth::BorrowerPermission->new({
55
                                borrower => $Koha::Borrower,
56
                                permissionModule => $Koha::Auth::PermissionModule,
57
                                permission_id => 22,
58
    });
59
60
Remember to ->store() the returned object to persist it in the DB.
61
@PARAM1 HASHRef of constructor parameters:
62
            MANDATORY keys:
63
                borrower or borrowernumber
64
                permissionModule or permission_module_id
65
                permission or permission_id
66
            Values can be either Koha::Object derivatives or their respective DB primary keys
67
@RETURNS Koha::Auth::BorrowerPermission
68
=cut
69
70
sub new {
71
    my ($class, $params) = @_;
72
73
    _validateParams($params);
74
75
    #Check for duplicates, and update existing permission if available.
76
    my $self = Koha::Auth::BorrowerPermissions->find({borrowernumber => $params->{borrower}->borrowernumber,
77
                                                      permission_module_id => $params->{permissionModule}->permission_module_id,
78
                                                      permission_id => $params->{permission}->permission_id,
79
                                                    });
80
    $self = $class->SUPER::new() unless $self;
81
    $self->{params} = $params;
82
    $self->set({borrowernumber => $self->getBorrower()->borrowernumber,
83
                permission_id => $self->getPermission()->permission_id,
84
                permission_module_id => $self->getPermissionModule()->permission_module_id
85
                });
86
    return $self;
87
}
88
89
=head getBorrower
90
91
    my $borrower = $borrowerPermission->getBorrower();
92
93
@RETURNS Koha::Borrower
94
=cut
95
96
sub getBorrower {
97
    my ($self) = @_;
98
99
    unless ($self->{params}->{borrower}) {
100
        my $dbix_borrower = $self->_result()->borrower;
101
        my $borrower = Koha::Borrower->_new_from_dbic($dbix_borrower);
102
        $self->{params}->{borrower} = $borrower;
103
    }
104
    return $self->{params}->{borrower};
105
}
106
107
=head setBorrower
108
109
    my $borrowerPermission = $borrowerPermission->setBorrower( $borrower );
110
111
Set the Borrower.
112
When setting the DB is automatically updated as well.
113
@PARAM1 Koha::Borrower, set the given Borrower to this BorrowerPermission.
114
@RETURNS Koha::Auth::BorrowerPermission,
115
=cut
116
117
sub setBorrower {
118
    my ($self, $borrower) = @_;
119
120
    unless (blessed($borrower) && $borrower->isa('Koha::Borrower')) {
121
        Koha::Exception::BadParameter->throw(error => __PACKAGE__."->setPermissionModule():> Given parameter '\\$borrower' is not a Koha::Borrower-object!");
122
    }
123
    $self->{params}->{borrower} = $borrower;
124
    $self->set({borrowernumber => $borrower->borrowernumber()});
125
    $self->store();
126
}
127
128
=head getPermissionModule
129
130
    my $permissionModule = $borrowerPermission->getPermissionModule();
131
132
@RETURNS Koha::Auth::PermissionModule
133
=cut
134
135
sub getPermissionModule {
136
    my ($self) = @_;
137
138
    unless ($self->{params}->{permissionModule}) {
139
        my $dbix_object = $self->_result()->permission_module;
140
        my $object = Koha::Auth::PermissionModule->_new_from_dbic($dbix_object);
141
        $self->{params}->{permissionModule} = $object;
142
    }
143
    return $self->{params}->{permissionModule};
144
}
145
146
=head setPermissionModule
147
148
    my $borrowerPermission = $borrowerPermission->setPermissionModule( $permissionModule );
149
150
Set the PermissionModule.
151
When setting the DB is automatically updated as well.
152
@PARAM1 Koha::Auth::PermissionModule, set the given PermissionModule as
153
                                      the PermissionModule of this BorrowePermission.
154
@RETURNS Koha::Auth::BorrowerPermission,
155
=cut
156
157
sub setPermissionModule {
158
    my ($self, $permissionModule) = @_;
159
160
    unless (blessed($permissionModule) && $permissionModule->isa('Koha::Auth::PermissionModule')) {
161
        Koha::Exception::BadParameter->throw(error => __PACKAGE__."->setPermissionModule():> Given parameter '\$permissionModule' is not a Koha::Auth::PermissionModule-object!");
162
    }
163
    $self->{params}->{permissionModule} = $permissionModule;
164
    $self->set({permission_module_id => $permissionModule->permission_module_id()});
165
    $self->store();
166
}
167
168
=head getPermission
169
170
    my $permission = $borrowerPermission->getPermission();
171
172
@RETURNS Koha::Auth::Permission
173
=cut
174
175
sub getPermission {
176
    my ($self) = @_;
177
178
    unless ($self->{params}->{permission}) {
179
        my $dbix_object = $self->_result()->permission;
180
        my $object = Koha::Auth::Permission->_new_from_dbic($dbix_object);
181
        $self->{params}->{permission} = $object;
182
    }
183
    return $self->{params}->{permission};
184
}
185
186
=head setPermission
187
188
    my $borrowerPermission = $borrowerPermission->setPermission( $permission );
189
190
Set the Permission.
191
When setting the DB is automatically updated as well.
192
@PARAM1 Koha::Auth::Permission, set the given Permission to this BorrowerPermission.
193
@RETURNS Koha::Auth::BorrowerPermission,
194
=cut
195
196
sub setPermission {
197
    my ($self, $permission) = @_;
198
199
    unless (blessed($permission) && $permission->isa('Koha::Auth::Permission')) {
200
        Koha::Exception::BadParameter->throw(error => __PACKAGE__."->setPermission():> Given parameter '\$permission' is not a Koha::Auth::Permission-object!");
201
    }
202
    $self->{params}->{permission} = $permission;
203
    $self->set({permission_id => $permission->permission_id()});
204
    $self->store();
205
}
206
207
=head _validateParams
208
209
Validates the given constructor parameters and fetches the Koha::Objects when needed.
210
211
=cut
212
213
sub _validateParams {
214
    my ($params) = @_;
215
216
    $params->{permissionModule} = Koha::Auth::PermissionModules::castToPermissionModule( $params->{permission_module_id} || $params->{permissionModule} );
217
    $params->{permission} = Koha::Auth::Permissions::castToPermission( $params->{permission_id} || $params->{permission} );
218
    $params->{borrower} = Koha::Borrowers::castToBorrower(  $params->{borrowernumber} || $params->{borrower}  );
219
}
220
221
1;
(-)a/Koha/Auth/BorrowerPermissions.pm (+61 lines)
Line 0 Link Here
1
package Koha::Auth::BorrowerPermissions;
2
3
# Copyright 2015 Vaara-kirjastot
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
use Scalar::Util qw(blessed);
22
23
use Koha::Auth::BorrowerPermission;
24
25
use base qw(Koha::Objects);
26
27
sub type {
28
    return 'BorrowerPermission';
29
}
30
sub object_class {
31
    return 'Koha::Auth::BorrowerPermission';
32
}
33
34
sub castToBorrowerPermission {
35
    my ($input) = @_;
36
37
    unless ($input) {
38
        Koha::Exception::BadParameter->throw(error => __PACKAGE__."::castToBorrowerPermission():> No parameter given!");
39
    }
40
    if (blessed($input) && $input->isa('Koha::Auth::BorrowerPermission')) {
41
        return $input;
42
    }
43
    if (blessed($input) && $input->isa('Koha::Schema::Result::BorrowerPermission')) {
44
        return Koha::Auth::BorrowerPermission->_new_from_dbic($input);
45
    }
46
47
    my $permission;
48
    if (not(ref($input))) { #We have a scalar
49
        $permission = Koha::Auth::BorrowerPermissions->find({borrower_permission_id => $input});
50
        unless ($permission) {
51
            Koha::Exception::UnknownObject->throw(error => __PACKAGE__."::castToBorrowerPermission():> Cannot find an existing BorrowerPermission with borrower_permission_id '$input'.");
52
        }
53
    }
54
    unless ($permission) {
55
        Koha::Exception::BadParameter->throw(error => __PACKAGE__."::castToBorrowerPermission():> Cannot cast \$input '$input' to a BorrowerPermission-object.");
56
    }
57
58
    return $permission;
59
}
60
61
1;
(-)a/Koha/Auth/Permission.pm (+60 lines)
Line 0 Link Here
1
package Koha::Auth::Permission;
2
3
# Copyright 2015 Vaara-kirjastot
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use Koha::Auth::Permissions;
23
24
use Koha::Exception::BadParameter;
25
26
use base qw(Koha::Object);
27
28
sub type {
29
    return 'Permission';
30
}
31
sub object_class {
32
    return 'Koha::Auth::Permission';
33
}
34
35
sub new {
36
    my ($class, $params) = @_;
37
38
    _validateParams($params);
39
40
    my $self = Koha::Auth::Permissions->find({code => $params->{code}, module => $params->{module}});
41
    $self = $class->SUPER::new() unless $self;
42
    $self->set($params);
43
    return $self;
44
}
45
46
sub _validateParams {
47
    my ($params) = @_;
48
49
    unless ($params->{description} && length $params->{description} > 0) {
50
        Koha::Exception::BadParameter->throw(error => "Koha::Auth::Permission->new():> Parameter 'description' isn't defined or is empty.");
51
    }
52
    unless ($params->{module} && length $params->{module} > 0) {
53
        Koha::Exception::BadParameter->throw(error => "Koha::Auth::Permission->new():> Parameter 'module' isn't defined or is empty.");
54
    }
55
    unless ($params->{code} && length $params->{code} > 0) {
56
        Koha::Exception::BadParameter->throw(error => "Koha::Auth::Permission->new():> Parameter 'code' isn't defined or is empty.");
57
    }
58
}
59
60
1;
(-)a/Koha/Auth/PermissionManager.pm (+524 lines)
Line 0 Link Here
1
package Koha::Auth::PermissionManager;
2
3
# Copyright 2015 Vaara-kirjastot
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
use Scalar::Util qw(blessed);
22
use Try::Tiny;
23
24
use Koha::Database;
25
use Koha::Auth::Permission;
26
use Koha::Auth::PermissionModule;
27
use Koha::Auth::BorrowerPermission;
28
29
use Koha::Exception::BadParameter;
30
use Koha::Exception::NoPermission;
31
use Koha::Exception::UnknownProgramState;
32
33
=head NAME Koha::Auth::PermissionManager
34
35
=head SYNOPSIS
36
37
PermissionManager is a gateway to all Koha's permission operations. You shouldn't
38
need to touch individual Koha::Auth::Permission* -objects.
39
40
=head USAGE
41
42
See t::db_dependent::Koha::Auth::PermissionManager.t
43
44
=head new
45
46
    my $permissionManager = Koha::Auth::PermissionManager->new();
47
48
Instantiates a new PemissionManager.
49
50
In the future this Manager can easily be improved with Koha::Cache.
51
52
=cut
53
54
sub new {
55
    my ($class, $self) = @_;
56
    $self = {} unless $self;
57
    bless($self, $class);
58
    return $self;
59
}
60
61
=head addPermission
62
63
    $permissionManager->addPermission({ code => "end_remaining_hostilities",
64
                                        description => "All your base are belong to us",
65
    });
66
67
INSERTs or UPDATEs a Koha::Auth::Permission to the Koha DB.
68
Very handy when introducing new features that need new permissions.
69
70
@PARAM1 Koha::Auth::Permission
71
        or
72
        HASHRef of all the koha.permissions-table columns set.
73
@THROWS Koha::Exception::BadParameter
74
=cut
75
76
sub addPermission {
77
    my ($self, $permission) = @_;
78
    if (blessed($permission) && not($permission->isa('Koha::Auth::Permission'))) {
79
        Koha::Exception::BadParameter->throw(error => __PACKAGE__."::addPermission():> Given permission is not a Koha::Auth::Permission-object.");
80
    }
81
    elsif (ref($permission) eq 'HASH') {
82
        $permission = Koha::Auth::Permission->new($permission);
83
    }
84
    unless (blessed($permission)) {
85
        Koha::Exception::BadParameter->throw(error => __PACKAGE__."::addPermission():> Given permission '$permission' is not of a recognized format.");
86
    }
87
88
    $permission->store();
89
}
90
91
=head getPermission
92
93
    my $permission = $permissionManager->getPermission('edit_items'); #koha.permissions.code
94
    my $permission = $permissionManager->getPermission(12);           #koha.permissions.permission_id
95
    my $permission = $permissionManager->getPermission($dbix_Permission); #Koha::Schema::Result::Permission
96
97
@RETURNS Koha::Auth::Permission-object
98
@THROWS Koha::Exception::BadParameter
99
=cut
100
101
sub getPermission {
102
    my ($self, $permissionId) = @_;
103
104
    try {
105
        return Koha::Auth::Permissions::castToPermission($permissionId);
106
    } catch {
107
        if (blessed($_) && $_->isa('Koha::Exception::UnknownObject')) {
108
            #We catch this type of exception, and simply return nothing, since there was no such Permission
109
        }
110
        else {
111
            die $_;
112
        }
113
    };
114
}
115
116
=head delPermission
117
118
    $permissionManager->delPermission('edit_items'); #koha.permissions.code
119
    $permissionManager->delPermission(12);           #koha.permissions.permission_id
120
    $permissionManager->delPermission($dbix_Permission); #Koha::Schema::Result::Permission
121
    $permissionManager->delPermission($permission); #Koha::Auth::Permission
122
123
@THROWS Koha::Exception::UnknownObject if no given object in DB to delete.
124
=cut
125
126
sub delPermission {
127
    my ($self, $permissionId) = @_;
128
129
    my $permission = Koha::Auth::Permissions::castToPermission($permissionId);
130
    $permission->delete();
131
}
132
133
=head addPermissionModule
134
135
    $permissionManager->addPermissionModule({   module => "scotland",
136
                                                description => "William Wallace is my hero!",
137
    });
138
139
INSERTs or UPDATEs a Koha::Auth::PermissionModule to the Koha DB.
140
Very handy when introducing new features that need new permissions.
141
142
@PARAM1 Koha::Auth::PermissionModule
143
        or
144
        HASHRef of all the koha.permission_modules-table columns set.
145
@THROWS Koha::Exception::BadParameter
146
=cut
147
148
sub addPermissionModule {
149
    my ($self, $permissionModule) = @_;
150
    if (blessed($permissionModule) && not($permissionModule->isa('Koha::Auth::PermissionModule'))) {
151
        Koha::Exception::BadParameter->throw(error => __PACKAGE__."::addPermission():> Given permissionModule is not a Koha::Auth::PermissionModule-object.");
152
    }
153
    elsif (ref($permissionModule) eq 'HASH') {
154
        $permissionModule = Koha::Auth::PermissionModule->new($permissionModule);
155
    }
156
    unless (blessed($permissionModule)) {
157
        Koha::Exception::BadParameter->throw(error => __PACKAGE__."::addPermission():> Given permissionModule '$permissionModule' is not of a recognized format.");
158
    }
159
160
    $permissionModule->store();
161
}
162
163
=head getPermissionModule
164
165
    my $permission = $permissionManager->getPermissionModule('cataloguing'); #koha.permission_modules.module
166
    my $permission = $permissionManager->getPermission(12);           #koha.permission_modules.permission_module_id
167
    my $permission = $permissionManager->getPermission($dbix_Permission); #Koha::Schema::Result::PermissionModule
168
169
@RETURNS Koha::Auth::PermissionModule-object
170
@THROWS Koha::Exception::BadParameter
171
=cut
172
173
sub getPermissionModule {
174
    my ($self, $permissionModuleId) = @_;
175
176
    try {
177
        return Koha::Auth::PermissionModules::castToPermissionModule($permissionModuleId);
178
    } catch {
179
        if (blessed($_) && $_->isa('Koha::Exception::UnknownObject')) {
180
            #We catch this type of exception, and simply return nothing, since there was no such PermissionModule
181
        }
182
        else {
183
            die $_;
184
        }
185
    };
186
}
187
188
=head delPermissionModule
189
190
    $permissionManager->delPermissionModule('cataloguing'); #koha.permission_modules.module
191
    $permissionManager->delPermissionModule(12);           #koha.permission_modules.permission_module_id
192
    $permissionManager->delPermissionModule($dbix_Permission); #Koha::Schema::Result::PermissionModule
193
    $permissionManager->delPermissionModule($permissionModule); #Koha::Auth::PermissionModule
194
195
@THROWS Koha::Exception::UnknownObject if no given object in DB to delete.
196
@THROWS Koha::Exception::BadParameter
197
=cut
198
199
sub delPermissionModule {
200
    my ($self, $permissionModuleId) = @_;
201
202
    my $permissionModule = Koha::Auth::PermissionModules::castToPermissionModule($permissionModuleId);
203
    $permissionModule->delete();
204
}
205
206
=head getKohaPermissions
207
208
    my $kohaPermissions = $permissionManager->getKohaPermissions();
209
210
Gets all the PermissionModules and their related Permissions in one huge DB query.
211
@RETURNS ARRAYRef of Koha::Auth::PermissionModule-objects with related objects prefetched. 
212
=cut
213
214
sub getKohaPermissions {
215
    my ($self) = @_;
216
217
    my $schema = Koha::Database->new()->schema();
218
    my @permissionModules = $schema->resultset('PermissionModule')->search(
219
                                                            {},
220
                                                            {   join => ['permissions'],
221
                                                                prefetch => ['permissions'],
222
                                                                order_by => ['me.module', 'permissions.code'],
223
                                                            }
224
                                                        );
225
    #Cast DBIx to Koha::Object.
226
    for (my $i=0 ; $i<scalar(@permissionModules) ; $i++) {
227
        $permissionModules[$i] = Koha::Auth::PermissionModules::castToPermissionModule( $permissionModules[$i] );
228
    }
229
    return \@permissionModules;
230
}
231
232
=head listKohaPermissionsAsHASH
233
234
@RETURNS HASHRef, a HASH-representation of all the permissions and permission modules
235
in Koha. Eg:
236
                 {
237
                    acquisitions => {
238
                        description => "Yada yada",
239
                        module => 'acquisitions',
240
                        permission_module_id => 21,
241
                        permissions => {
242
                            budget_add_del => {
243
                                description => "More yada yada",
244
                                code => 'budget_add_del',
245
                                permission_id => 12,
246
                            }
247
                            budget_manage => {
248
                                description => "Yaawn yadayawn",
249
                                ...
250
                            }
251
                            ...
252
                        }
253
                    },
254
                    borrowers => {
255
                        ...
256
                    },
257
                    ...
258
                 }
259
=cut
260
261
sub listKohaPermissionsAsHASH {
262
    my ($self) = @_;
263
    my $permissionModules = $self->getKohaPermissions();
264
    my $hash = {};
265
266
    foreach my $permissionModule (sort {$a->module cmp $b->module} @$permissionModules) {
267
        my $module = $permissionModule->module;
268
269
        $hash->{$module} = $permissionModule->_result->{'_column_data'};
270
        $hash->{$module}->{permissions} = {};
271
272
        my $permissions = $permissionModule->getPermissions;
273
        foreach my $permission (sort {$a->code cmp $b->code} @$permissions) {
274
            my $code = $permission->code;
275
276
            $hash->{$module}->{permissions}->{$code} = $permission->_result->{'_column_data'};
277
        }
278
    }
279
    return $hash;
280
}
281
282
=head getBorrowerPermissions
283
284
    my $borrowerPermissions = $permissionManager->getBorrowerPermissions($borrower);     #Koha::Borrower
285
    my $borrowerPermissions = $permissionManager->getBorrowerPermissions($dbix_borrower);#Koha::Schema::Resultset::Borrower
286
    my $borrowerPermissions = $permissionManager->getBorrowerPermissions(1012);          #koha.borrowers.borrowernumber
287
    my $borrowerPermissions = $permissionManager->getBorrowerPermissions('167A0012311'); #koha.borrowers.cardnumber
288
    my $borrowerPermissions = $permissionManager->getBorrowerPermissions('bill69');      #koha.borrowers.userid
289
290
@RETURNS ARRAYRef of Koha::Auth::BorrowerPermission-objects
291
@THROWS Koha::Exception::UnknownObject, if the given $borrower cannot be casted to Koha::Borrower
292
@THROWS Koha::Exception::BadParameter
293
=cut
294
295
sub getBorrowerPermissions {
296
    my ($self, $borrower) = @_;
297
    $borrower = Koha::Borrowers::castToBorrower($borrower);
298
299
    my $schema = Koha::Database->new()->schema();
300
301
    my @borrowerPermissions = $schema->resultset('BorrowerPermission')->search({borrowernumber => $borrower->borrowernumber},
302
                                                                               {join => ['permission','permission_module'],
303
                                                                                prefetch => ['permission','permission_module'],
304
                                                                                order_by => ['permission_module.module', 'permission.code']});
305
    for (my $i=0 ; $i<scalar(@borrowerPermissions) ; $i++) {
306
        $borrowerPermissions[$i] = Koha::Auth::BorrowerPermissions::castToBorrowerPermission($borrowerPermissions[$i]);
307
    }
308
    return \@borrowerPermissions;
309
}
310
311
=head grantPermissions
312
313
    $permissionManager->grantPermissions($borrower, {borrowers => 'view_borrowers',
314
                                                     reserveforothers => ['place_holds'],
315
                                                     tools => ['edit_news', 'edit_notices'],
316
                                                     acquisition => {
317
                                                       budger_add_del => 1,
318
                                                       budget_modify => 1,
319
                                                     },
320
                                                    }
321
                                        );
322
323
Adds a group of permissions to one user.
324
@THROWS Koha::Exception::UnknownObject, if the given $borrower cannot be casted to Koha::Borrower
325
@THROWS Koha::Exception::BadParameter
326
=cut
327
328
sub grantPermissions {
329
    my ($self, $borrower, $permissionsGroup) = @_;
330
331
    while (my ($module, $permissions) = each(%$permissionsGroup)) {
332
        if (ref($permissions) eq 'ARRAY') {
333
            foreach my $permission (@$permissions) {
334
                $self->grantPermission($borrower, $module, $permission);
335
            }
336
        }
337
        elsif (ref($permissions) eq 'HASH') {
338
            foreach my $permission (keys(%$permissions)) {
339
                $self->grantPermission($borrower, $module, $permission);
340
            }
341
        }
342
        else {
343
            $self->grantPermission($borrower, $module, $permissions);
344
        }
345
    }
346
}
347
348
=head grantPermission
349
350
    my $borrowerPermission = $permissionManager->grantPermission($borrower, $permissionModule, $permission);
351
352
@PARAM1 Koha::Borrower or
353
        Scalar koha.borrowers.borrowernumber or
354
        Scalar koha.borrowers.cardnumber or
355
        Scalar koha.borrowers.userid or
356
@PARAM2 Koha::Auth::PermissionModule-object
357
        Scalar koha.permission_modules.module or
358
        Scalar koha.permission_modules.permission_module_id
359
@PARAM3 Koha::Auth::Permission-object or
360
        Scalar koha.permissions.code or
361
        Scalar koha.permissions.permission_id
362
@RETURNS Koha::Auth::BorrowerPermissions
363
@THROWS Koha::Exception::UnknownObject, if the given parameters cannot be casted to Koha::Object-subclasses
364
@THROWS Koha::Exception::BadParameter
365
=cut
366
367
sub grantPermission {
368
    my ($self, $borrower, $permissionModule, $permission) = @_;
369
370
    my $borrowerPermission = Koha::Auth::BorrowerPermission->new({borrower => $borrower, permissionModule => $permissionModule, permission => $permission});
371
    $borrowerPermission->store();
372
    return $borrowerPermission;
373
}
374
375
=head
376
377
    $permissionManager->revokePermission($borrower, $permissionModule, $permission);
378
379
Revokes a Permission from a Borrower
380
same parameters as grantPermission()
381
382
@THROWS Koha::Exception::UnknownObject, if the given parameters cannot be casted to Koha::Object-subclasses
383
@THROWS Koha::Exception::BadParameter
384
=cut
385
386
sub revokePermission {
387
    my ($self, $borrower, $permissionModule, $permission) = @_;
388
389
    my $borrowerPermission = Koha::Auth::BorrowerPermission->new({borrower => $borrower, permissionModule => $permissionModule, permission => $permission});
390
    $borrowerPermission->delete();
391
    return $borrowerPermission;
392
}
393
394
=head revokeAllPermissions
395
396
    $permissionManager->revokeAllPermissions($borrower);
397
398
@THROWS Koha::Exception::UnknownObject, if the given $borrower cannot be casted to Koha::Borrower
399
@THROWS Koha::Exception::BadParameter
400
=cut
401
402
sub revokeAllPermissions {
403
    my ($self, $borrower) = @_;
404
    $borrower = Koha::Borrowers::castToBorrower($borrower);
405
406
    my $schema = Koha::Database->new()->schema();
407
    $schema->resultset('BorrowerPermission')->search({borrowernumber => $borrower->borrowernumber})->delete_all();
408
}
409
410
=head hasPermissions
411
412
See if the given Borrower has all of the given permissions
413
@PARAM1 Koha::Borrower, or any of the koha.borrowers-table's unique identifiers.
414
@PARAM2 HASHRef of needed permissions,
415
    {
416
        borrowers => 'view_borrowers',
417
        reserveforothers => ['place_holds'],
418
        tools => ['edit_news', 'edit_notices'],
419
        acquisition => {
420
            budger_add_del => 1,
421
            budget_modify => 1,
422
        },
423
        coursereserves => '*', #Means any Permission under this PermissionModule
424
   }
425
@RETURNS see hasPermission()
426
@THROWS Koha::Exception::NoPermission, from hasPermission() if permission is missing.
427
=cut
428
429
sub hasPermissions {
430
    my ($self, $borrower, $requiredPermissions) = @_;
431
432
    foreach my $module (keys(%$requiredPermissions)) {
433
        my $permissions = $requiredPermissions->{$module};
434
        if (ref($permissions) eq 'ARRAY') {
435
            foreach my $permission (@$permissions) {
436
                $self->hasPermission($borrower, $module, $permission);
437
            }
438
        }
439
        elsif (ref($permissions) eq 'HASH') {
440
            foreach my $permission (keys(%$permissions)) {
441
                $self->hasPermission($borrower, $module, $permission);
442
            }
443
        }
444
        else {
445
            $self->hasPermission($borrower, $module, $permissions);
446
        }
447
    }
448
    return 1;
449
}
450
451
=head hasPermission
452
453
See if the given Borrower has the given permission
454
@PARAM1 Koha::Borrower, or any of the koha.borrowers-table's unique identifiers.
455
@PARAM2 Koha::Auth::PermissionModule or koha.permission_modules.module or koha.permission_modules.permission_module_id
456
@PARAM3 Koha::Auth::Permission or koha.permissions.code or koha.permissions.permission_id or
457
                               '*' if we just need any permission for the given PermissionModule.
458
@RETURNS Integer, 1 if permission check succeeded.
459
                  2 if user is a superlibrarian.
460
                  Catch Exceptions if permission check fails.
461
@THROWS Koha::Exception::NoPermission, if Borrower is missing the permission.
462
                                       Exception tells which permission is missing.
463
@THROWS Koha::Exception::UnknownObject, if the given parameters cannot be casted to Koha::Object-subclasses
464
@THROWS Koha::Exception::BadParameter
465
=cut
466
467
sub hasPermission {
468
    my ($self, $borrower, $permissionModule, $permission) = @_;
469
470
    $borrower = Koha::Borrowers::castToBorrower($borrower);
471
    $permissionModule = Koha::Auth::PermissionModules::castToPermissionModule($permissionModule);
472
    $permission = Koha::Auth::Permissions::castToPermission($permission) unless $permission eq '*';
473
474
    my $error;
475
    if ($permission eq '*') {
476
        my $borrowerPermission = Koha::Auth::BorrowerPermissions->search({borrowernumber => $borrower->borrowernumber,
477
                                                 permission_module_id => $permissionModule->permission_module_id,
478
                                                })->next();
479
        return 1 if ($borrowerPermission);
480
        $error = "Borrower '".$borrower->borrowernumber."' lacks any permission under permission module '".$permissionModule->module."'.";
481
    }
482
    else {
483
        my $borrowerPermission = Koha::Auth::BorrowerPermissions->search({borrowernumber => $borrower->borrowernumber,
484
                                                 permission_module_id => $permissionModule->permission_module_id,
485
                                                 permission_id => $permission->permission_id,
486
                                                })->next();
487
        return 1 if ($borrowerPermission);
488
        $error = "Borrower '".$borrower->borrowernumber."' lacks permission module '".$permissionModule->module."' and permission '".$permission->code."'.";
489
    }
490
491
    return 2 if not($permissionModule->module eq 'superlibrarian') && $self->_isSuperuser($borrower);
492
    return 2 if not($permissionModule->module eq 'superlibrarian') && $self->_isSuperlibrarian($borrower);
493
    Koha::Exception::NoPermission->throw(error => $error);
494
}
495
496
sub _isSuperuser {
497
    my ($self, $borrower) = @_;
498
    $borrower = Koha::Borrowers::castToBorrower($borrower);
499
500
    if ( $borrower->userid eq C4::Context->config('user') ) {
501
        return 1;
502
    }
503
    elsif ( $borrower->userid eq 'demo' && C4::Context->config('demo') ) {
504
        return 1;
505
    }
506
    return 0;
507
}
508
509
sub _isSuperlibrarian {
510
    my ($self, $borrower) = @_;
511
512
    try {
513
        return $self->hasPermission($borrower, 'superlibrarian', 'superlibrarian');
514
    } catch {
515
        if (blessed($_) && $_->isa('Koha::Exception::NoPermission')) {
516
            return 0;
517
        }
518
        else {
519
            die $_;
520
        }
521
    };
522
}
523
524
1;
(-)a/Koha/Auth/PermissionModule.pm (+78 lines)
Line 0 Link Here
1
package Koha::Auth::PermissionModule;
2
3
# Copyright 2015 Vaara-kirjastot
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use Koha::Auth::PermissionModules;
23
24
use Koha::Exception::BadParameter;
25
26
use base qw(Koha::Object);
27
28
sub type {
29
    return 'PermissionModule';
30
}
31
sub object_class {
32
    return 'Koha::Auth::PermissionModule';
33
}
34
35
sub new {
36
    my ($class, $params) = @_;
37
38
    _validateParams($params);
39
40
    my $self = Koha::Auth::PermissionModules->find({module => $params->{module}});
41
    $self = $class->SUPER::new() unless $self;
42
    $self->set($params);
43
    return $self;
44
}
45
46
sub _validateParams {
47
    my ($params) = @_;
48
49
    unless ($params->{description} && length $params->{description} > 0) {
50
        Koha::Exception::BadParameter->throw(error => "Koha::Auth::Permission->new():> Parameter 'description' isn't defined or is empty.");
51
    }
52
    unless ($params->{module} && length $params->{module} > 0) {
53
        Koha::Exception::BadParameter->throw(error => "Koha::Auth::Permission->new():> Parameter 'module' isn't defined or is empty.");
54
    }
55
}
56
57
=head getPermissions
58
59
    my $permissions = $permissionModule->getPermissions();
60
61
@RETURNS List of Koha::Auth::Permission-objects
62
=cut
63
64
sub getPermissions {
65
    my ($self) = @_;
66
67
    unless ($self->{params}->{permissions}) {
68
        $self->{params}->{permissions} = [];
69
        my @dbix_objects = $self->_result()->permissions;
70
        foreach my $dbix_object (@dbix_objects) {
71
            my $object = Koha::Auth::Permission->_new_from_dbic($dbix_object);
72
            push @{$self->{params}->{permissions}}, $object;
73
        }
74
    }
75
    return $self->{params}->{permissions};
76
}
77
78
1;
(-)a/Koha/Auth/PermissionModules.pm (+64 lines)
Line 0 Link Here
1
package Koha::Auth::PermissionModules;
2
3
# Copyright 2015 Vaara-kirjastot
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
use Scalar::Util qw(blessed);
22
23
use Koha::Auth::PermissionModule;
24
25
use base qw(Koha::Objects);
26
27
sub type {
28
    return 'PermissionModule';
29
}
30
sub object_class {
31
    return 'Koha::Auth::PermissionModule';
32
}
33
34
sub castToPermissionModule {
35
    my ($input) = @_;
36
37
    unless ($input) {
38
        Koha::Exception::BadParameter->throw(error => __PACKAGE__."::castToPermissionModule():> No parameter given!");
39
    }
40
    if (blessed($input) && $input->isa('Koha::Auth::PermissionModule')) {
41
        return $input;
42
    }
43
    if (blessed($input) && $input->isa('Koha::Schema::Result::PermissionModule')) {
44
        return Koha::Auth::PermissionModule->_new_from_dbic($input);
45
    }
46
47
    my $permissionModule;
48
    if (not(ref($input))) { #We have a scalar
49
        $permissionModule = Koha::Auth::PermissionModules->search({'-or' => [{permission_module_id => $input},
50
                                                                           {module => $input},
51
                                                                          ]
52
                                                                })->next();
53
        unless ($permissionModule) {
54
            Koha::Exception::UnknownObject->throw(error => __PACKAGE__."::castToPermissionModule():> Cannot find an existing permissionModule with permission_module_id|module '$input'.");
55
        }
56
    }
57
    unless ($permissionModule) {
58
        Koha::Exception::BadParameter->throw(error => __PACKAGE__."::castToPermissionModule():> Cannot cast \$input '$input' to a PermissionModule-object.");
59
    }
60
61
    return $permissionModule;
62
}
63
64
1;
(-)a/Koha/Auth/Permissions.pm (+67 lines)
Line 0 Link Here
1
package Koha::Auth::Permissions;
2
3
# Copyright 2015 Vaara-kirjastot
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
use Scalar::Util qw(blessed);
22
23
use Koha::Auth::Permission;
24
25
use Koha::Exception::BadParameter;
26
use Koha::Exception::UnknownObject;
27
28
use base qw(Koha::Objects);
29
30
sub type {
31
    return 'Permission';
32
}
33
sub object_class {
34
    return 'Koha::Auth::Permission';
35
}
36
37
sub castToPermission {
38
    my ($input) = @_;
39
40
    unless ($input) {
41
        Koha::Exception::BadParameter->throw(error => __PACKAGE__."::castToPermission():> No parameter given!");
42
    }
43
    if (blessed($input) && $input->isa('Koha::Auth::Permission')) {
44
        return $input;
45
    }
46
    if (blessed($input) && $input->isa('Koha::Schema::Result::Permission')) {
47
        return Koha::Auth::Permission->_new_from_dbic($input);
48
    }
49
50
    my $permission;
51
    if (not(ref($input))) { #We have a scalar
52
        $permission = Koha::Auth::Permissions->search({'-or' => [{permission_id => $input},
53
                                                                  {code => $input},
54
                                                                ]
55
                                                        })->next();
56
        unless ($permission) {
57
            Koha::Exception::UnknownObject->throw(error => __PACKAGE__."::castToPermission():> Cannot find an existing permission with permission_id|code '$input'.");
58
        }
59
    }
60
    unless ($permission) {
61
        Koha::Exception::BadParameter->throw(error => __PACKAGE__."::castToPermission():> Cannot cast \$input '$input' to a Permission-object.");
62
    }
63
64
    return $permission;
65
}
66
67
1;
(-)a/Koha/AuthUtils.pm (-1 lines)
Lines 166-172 sub _createTemporarySuperuser { Link Here
166
                       firstname  => $superuserName,
166
                       firstname  => $superuserName,
167
                       surname    => $superuserName,
167
                       surname    => $superuserName,
168
                       branchcode => 'NO_LIBRARY_SET',
168
                       branchcode => 'NO_LIBRARY_SET',
169
                       flags      => 1,
170
                       email      => C4::Context->preference('KohaAdminEmailAddress')
169
                       email      => C4::Context->preference('KohaAdminEmailAddress')
171
                    });
170
                    });
172
    return $borrower;
171
    return $borrower;
(-)a/Koha/Schema/Result/Borrower.pm (-2 / +17 lines)
Lines 753-758 __PACKAGE__->has_many( Link Here
753
  { cascade_copy => 0, cascade_delete => 0 },
753
  { cascade_copy => 0, cascade_delete => 0 },
754
);
754
);
755
755
756
=head2 borrower_permissions
757
758
Type: has_many
759
760
Related object: L<Koha::Schema::Result::BorrowerPermission>
761
762
=cut
763
764
__PACKAGE__->has_many(
765
  "borrower_permissions",
766
  "Koha::Schema::Result::BorrowerPermission",
767
  { "foreign.borrowernumber" => "self.borrowernumber" },
768
  { cascade_copy => 0, cascade_delete => 0 },
769
);
770
756
=head2 borrower_syncs
771
=head2 borrower_syncs
757
772
758
Type: has_many
773
Type: has_many
Lines 1154-1161 Composing rels: L</aqorder_users> -> ordernumber Link Here
1154
__PACKAGE__->many_to_many("ordernumbers", "aqorder_users", "ordernumber");
1169
__PACKAGE__->many_to_many("ordernumbers", "aqorder_users", "ordernumber");
1155
1170
1156
1171
1157
# Created by DBIx::Class::Schema::Loader v0.07039 @ 2015-04-27 16:08:40
1172
# Created by DBIx::Class::Schema::Loader v0.07039 @ 2015-07-11 12:59:56
1158
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Z50zYBD3Hqlv5/EnoLnyZw
1173
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZRxBjZb0KKxabonVI/2vjg
1159
1174
1160
1175
1161
# You can replace this text with custom content, and it will be preserved on regeneration
1176
# You can replace this text with custom content, and it will be preserved on regeneration
(-)a/installer/data/mysql/en/mandatory/userflags.sql (-20 / +20 lines)
Lines 1-21 Link Here
1
INSERT INTO userflags (bit, flag, flagdesc, defaulton) VALUES
1
INSERT INTO permission_modules (module, description) VALUES
2
(0,'superlibrarian','Access to all librarian functions',0),
2
('superlibrarian','Access to all librarian functions'),
3
(1,'circulate','Check out and check in items',0),
3
('circulate','Check out and check in items'),
4
(2,'catalogue','<b>Required for staff login.</b> Staff access, allows viewing of catalogue in staff client.',0),
4
('catalogue','<b>Required for staff login.</b> Staff access, allows viewing of catalogue in staff client.'),
5
(3,'parameters','Manage Koha system settings (Administration panel)',0),
5
('parameters','Manage Koha system settings (Administration panel)'),
6
(4,'borrowers','Add or modify patrons',0),
6
('borrowers','Add or modify patrons'),
7
(5,'permissions','Set user permissions',0),
7
('permissions','Set user permissions'),
8
(6,'reserveforothers','Place and modify holds for patrons',0),
8
('reserveforothers','Place and modify holds for patrons'),
9
(9,'editcatalogue','Edit catalog (Modify bibliographic/holdings data)',0),
9
('editcatalogue','Edit catalog (Modify bibliographic/holdings data)'),
10
(10,'updatecharges','Manage patrons fines and fees',0),
10
('updatecharges','Manage patrons fines and fees'),
11
(11,'acquisition','Acquisition and/or suggestion management',0),
11
('acquisition','Acquisition and/or suggestion management'),
12
(12,'management','Set library management parameters (deprecated)',0),
12
('management','Set library management parameters (deprecated)'),
13
(13,'tools','Use all tools (expand for granular tools permissions)',0),
13
('tools','Use all tools (expand for granular tools permissions)'),
14
(14,'editauthorities','Edit authorities',0),
14
('editauthorities','Edit authorities'),
15
(15,'serials','Manage serial subscriptions',0),
15
('serials','Manage serial subscriptions'),
16
(16,'reports','Allow access to the reports module',0),
16
('reports','Allow access to the reports module'),
17
(17,'staffaccess','Allow staff members to modify permissions for other staff members',0),
17
('staffaccess','Allow staff members to modify permissions for other staff members'),
18
(18,'coursereserves','Course reserves',0),
18
('coursereserves','Course reserves'),
19
(19, 'plugins', 'Koha plugins', '0'),
19
('plugins', 'Koha plugins'),
20
(20, 'lists', 'Lists', 0)
20
('lists', 'Lists')
21
;
21
;
(-)a/installer/data/mysql/en/mandatory/userpermissions.sql (-76 / +83 lines)
Lines 1-77 Link Here
1
INSERT INTO permissions (module_bit, code, description) VALUES
1
INSERT INTO permissions (module, code, description) VALUES
2
   ( 1, 'circulate_remaining_permissions', 'Remaining circulation permissions'),
2
   ( 'superlibrarian',  'superlibrarian', 'Access to all librarian functions'),
3
   ( 1, 'override_renewals', 'Override blocked renewals'),
3
   ( 'circulate',       'circulate_remaining_permissions', 'Remaining circulation permissions'),
4
   ( 1, 'overdues_report', 'Execute overdue items report'),
4
   ( 'circulate',       'override_renewals', 'Override blocked renewals'),
5
   ( 1, 'force_checkout', 'Force checkout if a limitation exists'),
5
   ( 'circulate',       'overdues_report', 'Execute overdue items report'),
6
   ( 1, 'manage_restrictions', 'Manage restrictions for accounts'),
6
   ( 'circulate',       'force_checkout', 'Force checkout if a limitation exists'),
7
   ( 3, 'parameters_remaining_permissions', 'Remaining system parameters permissions'),
7
   ( 'circulate',       'manage_restrictions', 'Manage restrictions for accounts'),
8
   ( 3, 'manage_circ_rules', 'manage circulation rules'),
8
   ( 'catalogue',       'staff_login', 'Allow staff login.'),
9
   ( 6, 'place_holds', 'Place holds for patrons'),
9
   ( 'parameters',      'parameters_remaining_permissions', 'Remaining system parameters permissions'),
10
   ( 6, 'modify_holds_priority', 'Modify holds priority'),
10
   ( 'parameters',      'manage_circ_rules', 'manage circulation rules'),
11
   ( 9, 'edit_catalogue', 'Edit catalog (Modify bibliographic/holdings data)'),
11
   ( 'borrowers',       'view_borrowers', 'Show borrower details and search for borrowers.'),
12
   ( 9, 'fast_cataloging', 'Fast cataloging'),
12
   ( 'permissions',     'set_permissions', 'Set user permissions'),
13
   ( 9, 'edit_items', 'Edit items'),
13
   ( 'reserveforothers','place_holds', 'Place holds for patrons'),
14
   ( 9, 'edit_items_restricted', 'Limit item modification to subfields defined in the SubfieldsToAllowForRestrictedEditing preference (please note that edit_item is still required)'),
14
   ( 'reserveforothers','modify_holds_priority', 'Modify holds priority'),
15
   ( 9, 'delete_all_items', 'Delete all items at once'),
15
   ( 'editcatalogue',   'edit_catalogue', 'Edit catalog (Modify bibliographic/holdings data)'),
16
   (10, 'writeoff', 'Write off fines and fees'),
16
   ( 'editcatalogue',   'fast_cataloging', 'Fast cataloging'),
17
   (10, 'remaining_permissions', 'Remaining permissions for managing fines and fees'),
17
   ( 'editcatalogue',   'edit_items', 'Edit items'),
18
   (11, 'vendors_manage', 'Manage vendors'),
18
   ( 'editcatalogue',   'edit_items_restricted', 'Limit item modification to subfields defined in the SubfieldsToAllowForRestrictedEditing preference (please note that edit_item is still required)'),
19
   (11, 'contracts_manage', 'Manage contracts'),
19
   ( 'editcatalogue',   'delete_all_items', 'Delete all items at once'),
20
   (11, 'period_manage', 'Manage periods'),
20
   ( 'updatecharges',   'writeoff', 'Write off fines and fees'),
21
   (11, 'budget_manage', 'Manage budgets'),
21
   ( 'updatecharges',   'remaining_permissions', 'Remaining permissions for managing fines and fees'),
22
   (11, 'budget_modify', 'Modify budget (can''t create lines, but can modify existing ones)'),
22
   ( 'acquisition',     'vendors_manage', 'Manage vendors'),
23
   (11, 'planning_manage', 'Manage budget plannings'),
23
   ( 'acquisition',     'contracts_manage', 'Manage contracts'),
24
   (11, 'order_manage', 'Manage orders & basket'),
24
   ( 'acquisition',     'period_manage', 'Manage periods'),
25
   (11, 'order_manage_all', 'Manage all orders and baskets, regardless of restrictions on them'),
25
   ( 'acquisition',     'budget_manage', 'Manage budgets'),
26
   (11, 'group_manage', 'Manage orders & basketgroups'),
26
   ( 'acquisition',     'budget_modify', 'Modify budget (can''t create lines, but can modify existing ones)'),
27
   (11, 'order_receive', 'Manage orders & basket'),
27
   ( 'acquisition',     'planning_manage', 'Manage budget plannings'),
28
   (11, 'budget_add_del', 'Add and delete budgets (but can''t modify budgets)'),
28
   ( 'acquisition',     'order_manage', 'Manage orders & basket'),
29
   (11, 'budget_manage_all', 'Manage all budgets'),
29
   ( 'acquisition',     'order_manage_all', 'Manage all orders and baskets, regardless of restrictions on them'),
30
   (13, 'edit_news', 'Write news for the OPAC and staff interfaces'),
30
   ( 'acquisition',     'group_manage', 'Manage orders & basketgroups'),
31
   (13, 'label_creator', 'Create printable labels and barcodes from catalog and patron data'),
31
   ( 'acquisition',     'order_receive', 'Manage orders & basket'),
32
   (13, 'edit_calendar', 'Define days when the library is closed'),
32
   ( 'acquisition',     'budget_add_del', 'Add and delete budgets (but can''t modify budgets)'),
33
   (13, 'moderate_comments', 'Moderate patron comments'),
33
   ( 'acquisition',     'budget_manage_all', 'Manage all budgets'),
34
   (13, 'edit_notices', 'Define notices'),
34
   ( 'management',      'management', 'Set library management parameters (deprecated)'),
35
   (13, 'edit_notice_status_triggers', 'Set notice/status triggers for overdue items'),
35
   ( 'tools',           'edit_news', 'Write news for the OPAC and staff interfaces'),
36
   (13, 'edit_quotes', 'Edit quotes for quote-of-the-day feature'),
36
   ( 'tools',           'label_creator', 'Create printable labels and barcodes from catalog and patron data'),
37
   (13, 'view_system_logs', 'Browse the system logs'),
37
   ( 'tools',           'edit_calendar', 'Define days when the library is closed'),
38
   (13, 'inventory', 'Perform inventory (stocktaking) of your catalog'),
38
   ( 'tools',           'moderate_comments', 'Moderate patron comments'),
39
   (13, 'stage_marc_import', 'Stage MARC records into the reservoir'),
39
   ( 'tools',           'edit_notices', 'Define notices'),
40
   (13, 'manage_staged_marc', 'Managed staged MARC records, including completing and reversing imports'),
40
   ( 'tools',           'edit_notice_status_triggers', 'Set notice/status triggers for overdue items'),
41
   (13, 'export_catalog', 'Export bibliographic and holdings data'),
41
   ( 'tools',           'edit_quotes', 'Edit quotes for quote-of-the-day feature'),
42
   (13, 'import_patrons', 'Import patron data'),
42
   ( 'tools',           'view_system_logs', 'Browse the system logs'),
43
   (13, 'edit_patrons', 'Perform batch modification of patrons'),
43
   ( 'tools',           'inventory', 'Perform inventory (stocktaking) of your catalog'),
44
   (13, 'delete_anonymize_patrons', 'Delete old borrowers and anonymize circulation history (deletes borrower reading history)'),
44
   ( 'tools',           'stage_marc_import', 'Stage MARC records into the reservoir'),
45
   (13, 'batch_upload_patron_images', 'Upload patron images in a batch or one at a time'),
45
   ( 'tools',           'manage_staged_marc', 'Managed staged MARC records, including completing and reversing imports'),
46
   (13, 'schedule_tasks', 'Schedule tasks to run'),
46
   ( 'tools',           'export_catalog', 'Export bibliographic and holdings data'),
47
   (13, 'items_batchmod', 'Perform batch modification of items'),
47
   ( 'tools',           'import_patrons', 'Import patron data'),
48
   (13, 'items_batchmod_restricted', 'Limit batch item modification to subfields defined in the SubfieldsToAllowForRestrictedBatchmod preference (please note that items_batchmod is still required)'),
48
   ( 'tools',           'edit_patrons', 'Perform batch modification of patrons'),
49
   (13, 'items_batchdel', 'Perform batch deletion of items'),
49
   ( 'tools',           'delete_anonymize_patrons', 'Delete old borrowers and anonymize circulation history (deletes borrower reading history)'),
50
   (13, 'manage_csv_profiles', 'Manage CSV export profiles'),
50
   ( 'tools',           'batch_upload_patron_images', 'Upload patron images in a batch or one at a time'),
51
   (13, 'moderate_tags', 'Moderate patron tags'),
51
   ( 'tools',           'schedule_tasks', 'Schedule tasks to run'),
52
   (13, 'rotating_collections', 'Manage rotating collections'),
52
   ( 'tools',           'items_batchmod', 'Perform batch modification of items'),
53
   (13, 'upload_local_cover_images', 'Upload local cover images'),
53
   ( 'tools',           'items_batchmod_restricted', 'Limit batch item modification to subfields defined in the SubfieldsToAllowForRestrictedBatchmod preference (please note that items_batchmod is still required)'),
54
   (13, 'manage_patron_lists', 'Add, edit and delete patron lists and their contents'),
54
   ( 'tools',           'items_batchdel', 'Perform batch deletion of items'),
55
   (13, 'records_batchmod', 'Perform batch modification of records (biblios or authorities)'),
55
   ( 'tools',           'manage_csv_profiles', 'Manage CSV export profiles'),
56
   (13, 'marc_modification_templates', 'Manage marc modification templates'),
56
   ( 'tools',           'moderate_tags', 'Moderate patron tags'),
57
   (13, 'records_batchdel', 'Perform batch deletion of records (bibliographic or authority)'),
57
   ( 'tools',           'rotating_collections', 'Manage rotating collections'),
58
   (15, 'check_expiration', 'Check the expiration of a serial'),
58
   ( 'tools',           'upload_local_cover_images', 'Upload local cover images'),
59
   (15, 'claim_serials', 'Claim missing serials'),
59
   ( 'tools',           'manage_patron_lists', 'Add, edit and delete patron lists and their contents'),
60
   (15, 'create_subscription', 'Create a new subscription'),
60
   ( 'tools',           'records_batchmod', 'Perform batch modification of records (biblios or authorities)'),
61
   (15, 'delete_subscription', 'Delete an existing subscription'),
61
   ( 'tools',           'marc_modification_templates', 'Manage marc modification templates'),
62
   (15, 'edit_subscription', 'Edit an existing subscription'),
62
   ( 'tools',           'records_batchdel', 'Perform batch deletion of records (bibliographic or authority)'),
63
   (15, 'receive_serials', 'Serials receiving'),
63
   ( 'editauthorities', 'edit_authorities', 'Edit authorities'),
64
   (15, 'renew_subscription', 'Renew a subscription'),
64
   ( 'serials',         'check_expiration', 'Check the expiration of a serial'),
65
   (15, 'routing', 'Routing'),
65
   ( 'serials',         'claim_serials', 'Claim missing serials'),
66
   (15, 'superserials', 'Manage subscriptions from any branch (only applies when IndependentBranches is used)'),
66
   ( 'serials',         'create_subscription', 'Create a new subscription'),
67
   (16, 'execute_reports', 'Execute SQL reports'),
67
   ( 'serials',         'delete_subscription', 'Delete an existing subscription'),
68
   (16, 'create_reports', 'Create SQL reports'),
68
   ( 'serials',         'edit_subscription', 'Edit an existing subscription'),
69
   (18, 'manage_courses', 'Add, edit and delete courses'),
69
   ( 'serials',         'receive_serials', 'Serials receiving'),
70
   (18, 'add_reserves', 'Add course reserves'),
70
   ( 'serials',         'renew_subscription', 'Renew a subscription'),
71
   (18, 'delete_reserves', 'Remove course reserves'),
71
   ( 'serials',         'routing', 'Routing'),
72
   (19, 'manage', 'Manage plugins ( install / uninstall )'),
72
   ( 'serials',         'superserials', 'Manage subscriptions from any branch (only applies when IndependentBranches is used)'),
73
   (19, 'tool', 'Use tool plugins'),
73
   ( 'reports',         'execute_reports', 'Execute SQL reports'),
74
   (19, 'report', 'Use report plugins'),
74
   ( 'reports',         'create_reports', 'Create SQL reports'),
75
   (19, 'configure', 'Configure plugins'),
75
   ( 'staffaccess',     'staff_access_permissions', 'Allow staff members to modify permissions for other staff members'),
76
   (20, 'delete_public_lists', 'Delete public lists')
76
   ( 'coursereserves',  'manage_courses', 'Add, edit and delete courses'),
77
   ( 'coursereserves',  'add_reserves', 'Add course reserves'),
78
   ( 'coursereserves',  'delete_reserves', 'Remove course reserves'),
79
   ( 'plugins',         'manage', 'Manage plugins ( install / uninstall )'),
80
   ( 'plugins',         'tool', 'Use tool plugins'),
81
   ( 'plugins',         'report', 'Use report plugins'),
82
   ( 'plugins',         'configure', 'Configure plugins'),
83
   ( 'lists',           'delete_public_lists', 'Delete public lists')
77
;
84
;
(-)a/installer/data/mysql/kohastructure.sql (-45 / +49 lines)
Lines 249-255 CREATE TABLE `borrowers` ( -- this table includes information about your patrons Link Here
249
  `ethnotes` varchar(255) default NULL, -- unused in Koha
249
  `ethnotes` varchar(255) default NULL, -- unused in Koha
250
  `sex` varchar(1) default NULL, -- patron/borrower's gender
250
  `sex` varchar(1) default NULL, -- patron/borrower's gender
251
  `password` varchar(60) default NULL, -- patron/borrower's encrypted password
251
  `password` varchar(60) default NULL, -- patron/borrower's encrypted password
252
  `flags` int(11) default NULL, -- will include a number associated with the staff member's permissions
253
  `userid` varchar(75) default NULL, -- patron/borrower's opac and/or staff client log in
252
  `userid` varchar(75) default NULL, -- patron/borrower's opac and/or staff client log in
254
  `opacnote` mediumtext, -- a note on the patron/borrower's account that is visible in the OPAC and staff client
253
  `opacnote` mediumtext, -- a note on the patron/borrower's account that is visible in the OPAC and staff client
255
  `contactnote` varchar(255) default NULL, -- a note related to the patron/borrower's alternate address
254
  `contactnote` varchar(255) default NULL, -- a note related to the patron/borrower's alternate address
Lines 879-885 CREATE TABLE `deletedborrowers` ( -- stores data related to the patrons/borrower Link Here
879
  `ethnotes` varchar(255) default NULL, -- unused in Koha
878
  `ethnotes` varchar(255) default NULL, -- unused in Koha
880
  `sex` varchar(1) default NULL, -- patron/borrower's gender
879
  `sex` varchar(1) default NULL, -- patron/borrower's gender
881
  `password` varchar(30) default NULL, -- patron/borrower's encrypted password
880
  `password` varchar(30) default NULL, -- patron/borrower's encrypted password
882
  `flags` int(11) default NULL, -- will include a number associated with the staff member's permissions
883
  `userid` varchar(30) default NULL, -- patron/borrower's opac and/or staff client log in
881
  `userid` varchar(30) default NULL, -- patron/borrower's opac and/or staff client log in
884
  `opacnote` mediumtext, -- a note on the patron/borrower's account that is visible in the OPAC and staff client
882
  `opacnote` mediumtext, -- a note on the patron/borrower's account that is visible in the OPAC and staff client
885
  `contactnote` varchar(255) default NULL, -- a note related to the patron/borrower's alternate address
883
  `contactnote` varchar(255) default NULL, -- a note related to the patron/borrower's alternate address
Lines 2292-2310 CREATE TABLE `tags_index` ( -- a weighted list of all tags and where they are us Link Here
2292
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
2290
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
2293
2291
2294
--
2292
--
2295
-- Table structure for table `userflags`
2296
--
2297
2298
DROP TABLE IF EXISTS `userflags`;
2299
CREATE TABLE `userflags` (
2300
  `bit` int(11) NOT NULL default 0,
2301
  `flag` varchar(30) default NULL,
2302
  `flagdesc` varchar(255) default NULL,
2303
  `defaulton` int(11) default NULL,
2304
  PRIMARY KEY  (`bit`)
2305
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
2306
2307
--
2308
-- Table structure for table `virtualshelves`
2293
-- Table structure for table `virtualshelves`
2309
--
2294
--
2310
2295
Lines 2485-2504 CREATE TABLE language_script_mapping ( Link Here
2485
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
2470
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
2486
2471
2487
--
2472
--
2488
-- Table structure for table `permissions`
2489
--
2490
2491
DROP TABLE IF EXISTS `permissions`;
2492
CREATE TABLE `permissions` (
2493
  `module_bit` int(11) NOT NULL DEFAULT 0,
2494
  `code` varchar(64) DEFAULT NULL,
2495
  `description` varchar(255) DEFAULT NULL,
2496
  PRIMARY KEY  (`module_bit`, `code`),
2497
  CONSTRAINT `permissions_ibfk_1` FOREIGN KEY (`module_bit`) REFERENCES `userflags` (`bit`)
2498
    ON DELETE CASCADE ON UPDATE CASCADE
2499
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
2500
2501
--
2502
-- Table structure for table `serialitems`
2473
-- Table structure for table `serialitems`
2503
--
2474
--
2504
2475
Lines 2513-2533 CREATE TABLE `serialitems` ( Link Here
2513
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
2484
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
2514
2485
2515
--
2486
--
2516
-- Table structure for table `user_permissions`
2517
--
2518
2519
DROP TABLE IF EXISTS `user_permissions`;
2520
CREATE TABLE `user_permissions` (
2521
  `borrowernumber` int(11) NOT NULL DEFAULT 0,
2522
  `module_bit` int(11) NOT NULL DEFAULT 0,
2523
  `code` varchar(64) DEFAULT NULL,
2524
  CONSTRAINT `user_permissions_ibfk_1` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`)
2525
    ON DELETE CASCADE ON UPDATE CASCADE,
2526
  CONSTRAINT `user_permissions_ibfk_2` FOREIGN KEY (`module_bit`, `code`) REFERENCES `permissions` (`module_bit`, `code`)
2527
    ON DELETE CASCADE ON UPDATE CASCADE
2528
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
2529
2530
--
2531
-- Table structure for table `tmp_holdsqueue`
2487
-- Table structure for table `tmp_holdsqueue`
2532
--
2488
--
2533
2489
Lines 3339-3345 CREATE TABLE IF NOT EXISTS `borrower_modifications` ( Link Here
3339
  `ethnotes` varchar(255) DEFAULT NULL,
3295
  `ethnotes` varchar(255) DEFAULT NULL,
3340
  `sex` varchar(1) DEFAULT NULL,
3296
  `sex` varchar(1) DEFAULT NULL,
3341
  `password` varchar(30) DEFAULT NULL,
3297
  `password` varchar(30) DEFAULT NULL,
3342
  `flags` int(11) DEFAULT NULL,
3343
  `userid` varchar(75) DEFAULT NULL,
3298
  `userid` varchar(75) DEFAULT NULL,
3344
  `opacnote` mediumtext,
3299
  `opacnote` mediumtext,
3345
  `contactnote` varchar(255) DEFAULT NULL,
3300
  `contactnote` varchar(255) DEFAULT NULL,
Lines 3362-3367 CREATE TABLE IF NOT EXISTS `borrower_modifications` ( Link Here
3362
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
3317
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
3363
3318
3364
--
3319
--
3320
-- Table structure for table permissions
3321
--
3322
3323
DROP TABLE IF EXISTS permissions;
3324
CREATE TABLE permissions (
3325
  permission_id int(11) NOT NULL auto_increment,
3326
  module varchar(32) NOT NULL,
3327
  code varchar(64) NOT NULL,
3328
  description varchar(255) DEFAULT NULL,
3329
  PRIMARY KEY  (permission_id),
3330
  UNIQUE KEY (code),
3331
  CONSTRAINT permissions_to_modules_ibfk1 FOREIGN KEY (module) REFERENCES permission_modules (module)
3332
    ON DELETE CASCADE ON UPDATE CASCADE
3333
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
3334
3335
--
3336
-- Table structure for table permission_modules
3337
--
3338
3339
DROP TABLE IF EXISTS permission_modules;
3340
CREATE TABLE permission_modules (
3341
  permission_module_id int(11) NOT NULL auto_increment,
3342
  module varchar(32) NOT NULL,
3343
  description varchar(255) DEFAULT NULL,
3344
  PRIMARY KEY  (permission_module_id),
3345
  UNIQUE KEY (module)
3346
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
3347
3348
--
3349
-- Table structure for table borrower_permissions
3350
--
3351
3352
DROP TABLE IF EXISTS borrower_permissions;
3353
CREATE TABLE borrower_permissions (
3354
  borrower_permission_id int(11) NOT NULL auto_increment,
3355
  borrowernumber int(11) NOT NULL,
3356
  permission_module_id int(11) NOT NULL,
3357
  permission_id int(11) NOT NULL,
3358
  PRIMARY KEY  (borrower_permission_id),
3359
  UNIQUE KEY (borrowernumber, permission_module_id, permission_id),
3360
  CONSTRAINT borrower_permissions_ibfk_1 FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber)
3361
    ON DELETE CASCADE ON UPDATE CASCADE,
3362
  CONSTRAINT borrower_permissions_ibfk_2 FOREIGN KEY (permission_id) REFERENCES permissions (permission_id)
3363
    ON DELETE CASCADE ON UPDATE CASCADE,
3364
  CONSTRAINT borrower_permissions_ibfk_3 FOREIGN KEY (permission_module_id) REFERENCES permission_modules (permission_module_id)
3365
    ON DELETE CASCADE ON UPDATE CASCADE
3366
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
3367
3368
--
3365
-- Table structure for table linktracker
3369
-- Table structure for table linktracker
3366
-- This stores clicks to external links
3370
-- This stores clicks to external links
3367
--
3371
--
(-)a/installer/data/mysql/updatedatabase.pl (+153 lines)
Lines 7823-7828 if ( CheckVersion($DBversion) ) { Link Here
7823
    SetVersion($DBversion);
7823
    SetVersion($DBversion);
7824
}
7824
}
7825
7825
7826
$DBversion = "3.21.00.XXX";
7827
if ( CheckVersion($DBversion) ) {
7828
    my $upgradeDone;
7829
    my $permissionModule = $dbh->selectrow_hashref("SELECT * FROM permission_modules LIMIT 1");
7830
    if ($permissionModule) {
7831
        print "Upgrade to $DBversion ALREADY DONE?!? (Bug 14540 - Move member-flags.pl to PermissionsManager to better manage permissions for testing.)\n";
7832
        $upgradeDone = 1;
7833
    }
7834
    unless ($upgradeDone) {
7835
        ##CREATE new TABLEs
7836
        ##CREATing instead of ALTERing existing tables because this way the changes are more easy to understand.
7837
        $dbh->do("CREATE TABLE permission_modules (
7838
                    permission_module_id int(11) NOT NULL auto_increment,
7839
                    module varchar(32) NOT NULL,
7840
                    description varchar(255) DEFAULT NULL,
7841
                    PRIMARY KEY  (permission_module_id),
7842
                    UNIQUE KEY (module)
7843
                  ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;");
7844
        $dbh->do("INSERT INTO permission_modules (permission_module_id, module, description) SELECT bit, flag, flagdesc FROM userflags WHERE bit != 0;"); #superlibrarian causes primary key conflict
7845
        $dbh->do("INSERT INTO permission_modules (permission_module_id, module, description) SELECT 21, flag, flagdesc FROM userflags WHERE bit = 0;");   #So add him by himself.
7846
7847
        $dbh->do("ALTER TABLE permissions RENAME TO permissions_old");
7848
        $dbh->do("CREATE TABLE permissions (
7849
                    permission_id int(11) NOT NULL auto_increment,
7850
                    module varchar(32) NOT NULL,
7851
                    code varchar(64) NOT NULL,
7852
                    description varchar(255) DEFAULT NULL,
7853
                    PRIMARY KEY  (permission_id),
7854
                    UNIQUE KEY (code),
7855
                    CONSTRAINT permissions_to_modules_ibfk1 FOREIGN KEY (module) REFERENCES permission_modules (module)
7856
                      ON DELETE CASCADE ON UPDATE CASCADE
7857
                  ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;");
7858
        $dbh->do("INSERT INTO permissions (module, code, description)
7859
                    SELECT userflags.flag, code, description FROM permissions_old
7860
                      LEFT JOIN userflags ON permissions_old.module_bit = userflags.bit;");
7861
7862
        $dbh->do("CREATE TABLE borrower_permissions (
7863
                    borrower_permission_id int(11) NOT NULL auto_increment,
7864
                    borrowernumber int(11) NOT NULL,
7865
                    permission_module_id int(11) NOT NULL,
7866
                    permission_id int(11) NOT NULL,
7867
                    PRIMARY KEY  (borrower_permission_id),
7868
                    UNIQUE KEY (borrowernumber, permission_module_id, permission_id),
7869
                    CONSTRAINT borrower_permissions_ibfk_1 FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber)
7870
                      ON DELETE CASCADE ON UPDATE CASCADE,
7871
                    CONSTRAINT borrower_permissions_ibfk_2 FOREIGN KEY (permission_id) REFERENCES permissions (permission_id)
7872
                      ON DELETE CASCADE ON UPDATE CASCADE,
7873
                    CONSTRAINT borrower_permissions_ibfk_3 FOREIGN KEY (permission_module_id) REFERENCES permission_modules (permission_module_id)
7874
                      ON DELETE CASCADE ON UPDATE CASCADE
7875
                  ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;");
7876
        $dbh->do("INSERT INTO borrower_permissions (borrowernumber, permission_module_id, permission_id)
7877
                    SELECT borrowernumber, user_permissions.module_bit, permissions.permission_id FROM user_permissions
7878
                    LEFT JOIN permissions ON user_permissions.code = permissions.code;");
7879
7880
        ##Add subpermissions to the stand-alone modules (modules with no subpermissions)
7881
        $dbh->do("INSERT INTO permissions (module, code, description) VALUES ('superlibrarian', 'superlibrarian', 'Access to all librarian functions.');");
7882
        $dbh->do("INSERT INTO permissions (module, code, description) VALUES ('catalogue', 'staff_login', 'Allow staff login.');");
7883
        $dbh->do("INSERT INTO permissions (module, code, description) VALUES ('borrowers', 'view_borrowers', 'Show borrower details and search for borrowers.');");
7884
        $dbh->do("INSERT INTO permissions (module, code, description) VALUES ('permissions', 'set_permissions', 'Set user permissions.');");
7885
        $dbh->do("INSERT INTO permissions (module, code, description) VALUES ('management', 'management', 'Set library management parameters (deprecated).');");
7886
        $dbh->do("INSERT INTO permissions (module, code, description) VALUES ('editauthorities', 'edit_authorities', 'Edit authorities.');");
7887
        $dbh->do("INSERT INTO permissions (module, code, description) VALUES ('staffaccess', 'staff_access_permissions', 'Allow staff members to modify permissions for other staff members.');");
7888
7889
        ##Create borrower_permissions to replace singular userflags from borrowers.flags.
7890
        use Koha::Borrowers;
7891
        my $sth = $dbh->prepare("
7892
                INSERT INTO borrower_permissions (borrowernumber, permission_module_id, permission_id)
7893
                VALUES (?,
7894
                        (SELECT permission_module_id FROM permission_modules WHERE module = ?),
7895
                        (SELECT permission_id FROM permissions WHERE code = ?)
7896
                       );
7897
                ");
7898
        my @borrowers = Koha::Borrowers->search({});
7899
        foreach my $b (@borrowers) {
7900
            next unless $b->flags;
7901
            if ( ( $b->flags & ( 2**0 ) ) ) {
7902
                $sth->execute($b->borrowernumber, 'superlibrarian', 'superlibrarian');
7903
            }
7904
            if ( ( $b->flags & ( 2**2 ) ) ) {
7905
                $sth->execute($b->borrowernumber, 'catalogue', 'staff_login');
7906
            }
7907
            if ( ( $b->flags & ( 2**4 ) ) ) {
7908
                $sth->execute($b->borrowernumber, 'borrowers', 'view_borrowers');
7909
            }
7910
            if ( ( $b->flags & ( 2**5 ) ) ) {
7911
                $sth->execute($b->borrowernumber, 'permissions', 'set_permissions');
7912
            }
7913
            if ( ( $b->flags & ( 2**12 ) ) ) {
7914
                $sth->execute($b->borrowernumber, 'management', 'management');
7915
            }
7916
            if ( ( $b->flags & ( 2**14 ) ) ) {
7917
                $sth->execute($b->borrowernumber, 'editauthorities', 'edit_authorities');
7918
            }
7919
            if ( ( $b->flags & ( 2**17 ) ) ) {
7920
                $sth->execute($b->borrowernumber, 'staffaccess', 'staff_access_permissions');
7921
            }
7922
        }
7923
7924
        ##Cleanup redundant tables.
7925
        $dbh->do("DELETE FROM userflags"); #Cascades to other tables.
7926
        $dbh->do("DROP TABLE user_permissions");
7927
        $dbh->do("DROP TABLE permissions_old");
7928
        $dbh->do("DROP TABLE userflags");
7929
        $dbh->do("ALTER TABLE borrowers DROP COLUMN flags");
7930
7931
        print "Upgrade to $DBversion done (Bug 14540 - Move member-flags.pl to PermissionsManager to better manage permissions for testing.)\n";
7932
        SetVersion($DBversion);
7933
    }
7934
}
7935
7826
$DBversion = "3.15.00.002";
7936
$DBversion = "3.15.00.002";
7827
if(CheckVersion($DBversion)) {
7937
if(CheckVersion($DBversion)) {
7828
    $dbh->do("ALTER TABLE deleteditems MODIFY materials text;");
7938
    $dbh->do("ALTER TABLE deleteditems MODIFY materials text;");
Lines 10585-10590 if ( CheckVersion($DBversion) ) { Link Here
10585
    SetVersion ($DBversion);
10695
    SetVersion ($DBversion);
10586
}
10696
}
10587
10697
10698
$DBversion = "XXX";
10699
if(CheckVersion($DBversion)) {
10700
    $dbh->do(q{
10701
        DROP TABLE IF EXISTS api_keys;
10702
    });
10703
    $dbh->do(q{
10704
        CREATE TABLE api_keys (
10705
            borrowernumber int(11) NOT NULL,
10706
            api_key VARCHAR(255) NOT NULL,
10707
            active int(1) DEFAULT 1,
10708
            PRIMARY KEY (borrowernumber, api_key),
10709
            CONSTRAINT api_keys_fk_borrowernumber
10710
              FOREIGN KEY (borrowernumber)
10711
              REFERENCES borrowers (borrowernumber)
10712
              ON DELETE CASCADE ON UPDATE CASCADE
10713
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
10714
    });
10715
10716
    print "Upgrade to $DBversion done (Bug 13920: Add API keys table)\n";
10717
    SetVersion($DBversion);
10718
}
10719
10720
$DBversion = "XXX";
10721
if(CheckVersion($DBversion)) {
10722
    $dbh->do(q{
10723
        DROP TABLE IF EXISTS api_timestamps;
10724
    });
10725
    $dbh->do(q{
10726
        CREATE TABLE api_timestamps (
10727
            borrowernumber int(11) NOT NULL,
10728
            timestamp bigint,
10729
            PRIMARY KEY (borrowernumber),
10730
            CONSTRAINT api_timestamps_fk_borrowernumber
10731
              FOREIGN KEY (borrowernumber)
10732
              REFERENCES borrowers (borrowernumber)
10733
              ON DELETE CASCADE ON UPDATE CASCADE
10734
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
10735
    });
10736
10737
    print "Upgrade to $DBversion done (Bug 13920: Add API timestamps table)\n";
10738
    SetVersion($DBversion);
10739
}
10740
10588
$DBversion = "3.21.00.008";
10741
$DBversion = "3.21.00.008";
10589
if ( CheckVersion($DBversion) ) {
10742
if ( CheckVersion($DBversion) ) {
10590
    $dbh->do(q{
10743
    $dbh->do(q{
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/member-flags.tt (-7 / +7 lines)
Lines 9-31 Link Here
9
        $("#permissionstree").treeview({animated: "fast", collapsed: true});
9
        $("#permissionstree").treeview({animated: "fast", collapsed: true});
10
10
11
        // Enforce Superlibrarian Privilege Mutual Exclusivity
11
        // Enforce Superlibrarian Privilege Mutual Exclusivity
12
        if($('input[id="flag-0"]:checked').length){
12
        if($('input[id="flag-superlibrarian"]:checked').length){
13
            if ($('input[name="flag"]:checked').length > 1){
13
            if ($('input[name="flag"]:checked').length > 1){
14
                alert('Inconsistency Detected!\n\nThe superlibrarian privilege is mutually exclusive of other privileges, as it includes them all.\n\nThis patron\'s privileges will now be reset to include only superlibrarian.');
14
                alert('Inconsistency Detected!\n\nThe superlibrarian privilege is mutually exclusive of other privileges, as it includes them all.\n\nThis patron\'s privileges will now be reset to include only superlibrarian.');
15
            }
15
            }
16
16
17
            $('input[name="flag"]').each(function() {
17
            $('input[name="flag"]').each(function() {
18
                if($(this).attr('id') != "flag-0"){
18
                if($(this).attr('id') != "flag-superlibrarian"){
19
                    $(this).attr('disabled', 'disabled');
19
                    $(this).attr('disabled', 'disabled');
20
                    $(this).removeAttr('checked', 'checked');
20
                    $(this).removeAttr('checked', 'checked');
21
                }
21
                }
22
            });
22
            });
23
        }
23
        }
24
24
25
        $('input#flag-0').click(function() {
25
        $('input#flag-superlibrarian').click(function() {
26
            if($('input[id="flag-0"]:checked').length){
26
            if($('input[id="flag-superlibrarian"]:checked').length){
27
                $('input[name="flag"]').each(function() {
27
                $('input[name="flag"]').each(function() {
28
                    if($(this).attr('id') != "flag-0"){
28
                    if($(this).attr('id') != "flag-superlibrarian"){
29
                        $(this).attr('disabled', 'disabled');
29
                        $(this).attr('disabled', 'disabled');
30
                        $(this).removeAttr('checked', 'checked');
30
                        $(this).removeAttr('checked', 'checked');
31
                    }
31
                    }
Lines 121-129 Link Here
121
        <!-- <li class="folder-close">One level down<ul> -->
121
        <!-- <li class="folder-close">One level down<ul> -->
122
    [% FOREACH loo IN loop %]
122
    [% FOREACH loo IN loop %]
123
        [% IF ( loo.expand ) %]
123
        [% IF ( loo.expand ) %]
124
        <li class="open">
124
        <li class="[% loo.flag %] open">
125
        [% ELSE %]
125
        [% ELSE %]
126
        <li>
126
        <li class="[% loo.flag %]">
127
        [% END %]
127
        [% END %]
128
			[% IF ( loo.checked ) %]
128
			[% IF ( loo.checked ) %]
129
			   <input type="checkbox" id="flag-[% loo.bit %]" name="flag" value="[% loo.flag %]" checked="checked" onclick="toggleChildren(this)" />
129
			   <input type="checkbox" id="flag-[% loo.bit %]" name="flag" value="[% loo.flag %]" checked="checked" onclick="toggleChildren(this)" />
(-)a/members/member-flags.pl (-101 / +97 lines)
Lines 14-20 use C4::Context; Link Here
14
use C4::Members;
14
use C4::Members;
15
use C4::Branch;
15
use C4::Branch;
16
use C4::Members::Attributes qw(GetBorrowerAttributes);
16
use C4::Members::Attributes qw(GetBorrowerAttributes);
17
#use C4::Acquisitions;
17
use Koha::Auth::PermissionManager;
18
19
use Koha::Exception::BadParameter;
18
20
19
use C4::Output;
21
use C4::Output;
20
22
Lines 35-155 my ($template, $loggedinuser, $cookie) = get_template_and_user({ Link Here
35
        debug           => 1,
37
        debug           => 1,
36
});
38
});
37
39
38
40
my $permissionManager = Koha::Auth::PermissionManager->new();
39
my %member2;
41
my %member2;
40
$member2{'borrowernumber'}=$member;
42
$member2{'borrowernumber'}=$member;
41
43
42
if ($input->param('newflags')) {
44
if ($input->param('newflags')) {
43
    my $dbh=C4::Context->dbh();
45
    my $dbh=C4::Context->dbh();
44
46
47
	#Cast CGI-params into a permissions HASH.
45
    my @perms = $input->param('flag');
48
    my @perms = $input->param('flag');
46
    my %all_module_perms = ();
47
    my %sub_perms = ();
49
    my %sub_perms = ();
48
    foreach my $perm (@perms) {
50
    foreach my $perm (@perms) {
49
        if ($perm !~ /:/) {
51
		if ($perm eq 'superlibrarian') {
50
            $all_module_perms{$perm} = 1;
52
			$sub_perms{superlibrarian}->{superlibrarian} = 1;
53
		}
54
        elsif ($perm !~ /:/) {
55
            #DEPRECATED, GUI still sends the module flags here even though they have been removed from the DB.
51
        } else {
56
        } else {
52
            my ($module, $sub_perm) = split /:/, $perm, 2;
57
            my ($module, $sub_perm) = split /:/, $perm, 2;
53
            push @{ $sub_perms{$module} }, $sub_perm;
58
            $sub_perms{$module}->{$sub_perm} = 1;
54
        }
59
        }
55
    }
60
    }
56
61
57
    # construct flags
62
	$permissionManager->revokeAllPermissions($member);
58
    my $module_flags = 0;
63
	$permissionManager->grantPermissions($member, \%sub_perms);
59
    my $sth=$dbh->prepare("SELECT bit,flag FROM userflags ORDER BY bit");
64
60
    $sth->execute();
61
    while (my ($bit, $flag) = $sth->fetchrow_array) {
62
        if (exists $all_module_perms{$flag}) {
63
            $module_flags += 2**$bit;
64
        }
65
    }
66
    
67
    $sth = $dbh->prepare("UPDATE borrowers SET flags=? WHERE borrowernumber=?");
68
    $sth->execute($module_flags, $member);
69
    
70
    # deal with subpermissions
71
    $sth = $dbh->prepare("DELETE FROM user_permissions WHERE borrowernumber = ?");
72
    $sth->execute($member); 
73
    $sth = $dbh->prepare("INSERT INTO user_permissions (borrowernumber, module_bit, code)
74
                        SELECT ?, bit, ?
75
                        FROM userflags
76
                        WHERE flag = ?");
77
    foreach my $module (keys %sub_perms) {
78
        next if exists $all_module_perms{$module};
79
        foreach my $sub_perm (@{ $sub_perms{$module} }) {
80
            $sth->execute($member, $sub_perm, $module);
81
        }
82
    }
83
    
84
    print $input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=$member");
65
    print $input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=$member");
85
} else {
66
} else {
86
#     my ($bor,$flags,$accessflags)=GetMemberDetails($member,'');
67
    my $all_perms  = $permissionManager->listKohaPermissionsAsHASH();
87
    my $flags = $bor->{'flags'};
68
    my $user_perms = $permissionManager->getBorrowerPermissions($member);
88
    my $accessflags = $bor->{'authflags'};
69
89
    my $dbh=C4::Context->dbh();
70
	$all_perms = markBorrowerGrantedPermissions($all_perms, $user_perms);
90
    my $all_perms  = get_all_subpermissions();
71
91
    my $user_perms = get_user_subpermissions($bor->{'userid'});
92
    my $sth=$dbh->prepare("SELECT bit,flag,flagdesc FROM userflags ORDER BY bit");
93
    $sth->execute;
94
    my @loop;
72
    my @loop;
95
    while (my ($bit, $flag, $flagdesc) = $sth->fetchrow) {
73
	#Make sure the superlibrarian module is always on top.
96
	    my $checked='';
74
	push @loop, preparePermissionModuleForDisplay($all_perms, 'superlibrarian');
97
	    if ($accessflags->{$flag}) {
75
    foreach my $module (sort(keys(%$all_perms))) {
98
	        $checked= 1;
76
		push @loop, preparePermissionModuleForDisplay($all_perms, $module) unless $module eq 'superlibrarian';
99
	    }
100
101
	    my %row = ( bit => $bit,
102
		    flag => $flag,
103
		    checked => $checked,
104
		    flagdesc => $flagdesc );
105
106
        my @sub_perm_loop = ();
107
        my $expand_parent = 0;
108
        if ($checked) {
109
            if (exists $all_perms->{$flag}) {
110
                $expand_parent = 1;
111
                foreach my $sub_perm (sort keys %{ $all_perms->{$flag} }) {
112
                    push @sub_perm_loop, {
113
                        id => "${flag}_$sub_perm",
114
                        perm => "$flag:$sub_perm",
115
                        code => $sub_perm,
116
                        description => $all_perms->{$flag}->{$sub_perm},
117
                        checked => 1
118
                    };
119
                }
120
            }
121
        } else {
122
            if (exists $user_perms->{$flag}) {
123
                $expand_parent = 1;
124
                # put selected ones first
125
                foreach my $sub_perm (sort keys %{ $user_perms->{$flag} }) {
126
                    push @sub_perm_loop, {
127
                        id => "${flag}_$sub_perm",
128
                        perm => "$flag:$sub_perm",
129
                        code => $sub_perm,
130
                        description => $all_perms->{$flag}->{$sub_perm},
131
                        checked => 1
132
                    };
133
                }
134
            }
135
            # then ones not selected
136
            if (exists $all_perms->{$flag}) {
137
                foreach my $sub_perm (sort keys %{ $all_perms->{$flag} }) {
138
                    push @sub_perm_loop, {
139
                        id => "${flag}_$sub_perm",
140
                        perm => "$flag:$sub_perm",
141
                        code => $sub_perm,
142
                        description => $all_perms->{$flag}->{$sub_perm},
143
                        checked => 0
144
                    } unless exists $user_perms->{$flag} and exists $user_perms->{$flag}->{$sub_perm};
145
                }
146
            }
147
        }
148
        $row{expand} = $expand_parent;
149
        if ($#sub_perm_loop > -1) {
150
            $row{sub_perm_loop} = \@sub_perm_loop;
151
        }
152
	    push @loop, \%row;
153
    }
77
    }
154
78
155
    if ( $bor->{'category_type'} eq 'C') {
79
    if ( $bor->{'category_type'} eq 'C') {
Lines 172-179 if (C4::Context->preference('ExtendedPatronAttributes')) { Link Here
172
}
96
}
173
97
174
# Computes full borrower address
98
# Computes full borrower address
175
my $roadtype = C4::Koha::GetAuthorisedValueByCode( 'ROADTYPE', $bor->{streettype} );
99
my $roadtype = C4::Koha::GetAuthorisedValueByCode( 'ROADTYPE', $bor->{streettype} ) || '';
176
my $address = $bor->{'streetnumber'} . " $roadtype " . $bor->{'address'};
100
my $address = ($bor->{'streetnumber'} || '') . " $roadtype " . ($bor->{'address'} || '');
177
101
178
$template->param(
102
$template->param(
179
		borrowernumber => $bor->{'borrowernumber'},
103
		borrowernumber => $bor->{'borrowernumber'},
Lines 206-208 $template->param( Link Here
206
    output_html_with_http_headers $input, $cookie, $template->output;
130
    output_html_with_http_headers $input, $cookie, $template->output;
207
131
208
}
132
}
133
134
=head markBorrowerGrantedPermissions
135
136
Adds a 'checked'-value for all subpermissions in the all-Koha-Permissions-list
137
that the current borrower has been granted.
138
@PARAM1 HASHRef of all Koha permissions and modules.
139
@PARAM1 ARRAYRef of all the granted Koha::Auth::BorrowerPermission-objects.
140
@RETURNS @PARAM1, slightly checked.
141
=cut
142
143
sub markBorrowerGrantedPermissions {
144
	my ($all_perms, $user_perms) = @_;
145
146
	foreach my $borrowerPermission (@$user_perms) {
147
		my $module = $borrowerPermission->getPermissionModule->module;
148
		my $code   = $borrowerPermission->getPermission->code;
149
		$all_perms->{$module}->{permissions}->{$code}->{checked} = 1;
150
	}
151
	return $all_perms;
152
}
153
154
=head checkIfAllModulePermissionsGranted
155
156
@RETURNS Boolean, 1 if all permissions granted.
157
=cut
158
159
sub checkIfAllModulePermissionsGranted {
160
	my ($moduleHash) = @_;
161
	foreach my $code (keys(%{$moduleHash->{permissions}})) {
162
		unless ($moduleHash->{permissions}->{$code}->{checked}) {
163
			return 0;
164
		}
165
	}
166
	return 1;
167
}
168
169
sub preparePermissionModuleForDisplay {
170
	my ($all_perms, $module) = @_;
171
172
	my $moduleHash = $all_perms->{$module};
173
	my $checked = checkIfAllModulePermissionsGranted($moduleHash);
174
175
	my %row = (
176
		bit => $module,
177
		flag => $module,
178
		checked => $checked,
179
		flagdesc => $moduleHash->{description} );
180
181
	my @sub_perm_loop = ();
182
	my $expand_parent = 0;
183
184
	if ($module ne 'superlibrarian') {
185
		foreach my $sub_perm (sort keys %{ $all_perms->{$module}->{permissions} }) {
186
			my $sub_perm_checked = $all_perms->{$module}->{permissions}->{$sub_perm}->{checked};
187
			$expand_parent = 1 if $sub_perm_checked;
188
189
			push @sub_perm_loop, {
190
				id => "${module}_$sub_perm",
191
				perm => "$module:$sub_perm",
192
				code => $sub_perm,
193
				description => $all_perms->{$module}->{permissions}->{$sub_perm}->{description},
194
				checked => $sub_perm_checked || 0,
195
			};
196
		}
197
198
		$row{expand} = $expand_parent;
199
		if ($#sub_perm_loop > -1) {
200
			$row{sub_perm_loop} = \@sub_perm_loop;
201
		}
202
	}
203
	return \%row;
204
}
(-)a/misc/devel/interactiveWebDriverShell.pl (-2 / +7 lines)
Lines 115-127 my $supportedPageObjects = { Link Here
115
    "members/moremember.pl" =>
115
    "members/moremember.pl" =>
116
    {   package     => "t::lib::Page::Members::Moremember",
116
    {   package     => "t::lib::Page::Members::Moremember",
117
        urlEndpoint => "members/moremember.pl",
117
        urlEndpoint => "members/moremember.pl",
118
        status      => "not implemented",
118
        status      => "OK",
119
        params      => ["borrowernumber"],
119
        params      => ["borrowernumber"],
120
    },
120
    },
121
    "members/member-flags.pl" =>
121
    "members/member-flags.pl" =>
122
    {   package     => "t::lib::Page::Members::MemberFlags",
122
    {   package     => "t::lib::Page::Members::MemberFlags",
123
        urlEndpoint => "members/member-flags.pl",
123
        urlEndpoint => "members/member-flags.pl",
124
        status      => "not implemented",
124
        status      => "OK",
125
        params      => ["borrowernumber"],
125
        params      => ["borrowernumber"],
126
    },
126
    },
127
################################################################################
127
################################################################################
Lines 132-137 my $supportedPageObjects = { Link Here
132
        urlEndpoint => "opac/opac-main.pl",
132
        urlEndpoint => "opac/opac-main.pl",
133
        status      => "OK",
133
        status      => "OK",
134
    },
134
    },
135
    "opac/opac-search.pl" =>
136
    {   package     => "t::lib::Page::Opac::OpacSearch",
137
        urlEndpoint => "opac/opac-search.pl",
138
        status      => "OK",
139
    },
135
};
140
};
136
################################################################################
141
################################################################################
137
  ########## END OF PAGE CONFIGURATIONS ##########
142
  ########## END OF PAGE CONFIGURATIONS ##########
(-)a/t/db_dependent/Koha/Auth.t (-5 / +35 lines)
Lines 22-28 use Modern::Perl; Link Here
22
use Test::More;
22
use Test::More;
23
use Try::Tiny; #Even Selenium::Remote::Driver uses Try::Tiny :)
23
use Try::Tiny; #Even Selenium::Remote::Driver uses Try::Tiny :)
24
24
25
use Koha::Auth::PermissionManager;
26
25
use t::lib::Page::Mainpage;
27
use t::lib::Page::Mainpage;
28
use t::lib::Page::Opac::OpacMain;
26
29
27
use t::db_dependent::TestObjects::Borrowers::BorrowerFactory;
30
use t::db_dependent::TestObjects::Borrowers::BorrowerFactory;
28
31
Lines 36-52 my $borrowers = $borrowerFactory->createTestGroup([ Link Here
36
             surname    => 'Kivi',
39
             surname    => 'Kivi',
37
             cardnumber => '1A01',
40
             cardnumber => '1A01',
38
             branchcode => 'CPL',
41
             branchcode => 'CPL',
39
             flags      => '1', #superlibrarian, not exactly a very good way of doing permission testing?
40
             userid     => 'mini_admin',
42
             userid     => 'mini_admin',
41
             password   => $password,
43
             password   => $password,
42
            },
44
            },
45
            {firstname  => 'Admin',
46
             surname    => 'Administrative',
47
             cardnumber => 'admin',
48
             branchcode => 'FPL',
49
             userid     => 'maxi_admin',
50
             password   => $password,
51
            },
43
        ], undef, $testContext);
52
        ], undef, $testContext);
44
53
54
my $permissionManager = Koha::Auth::PermissionManager->new();
55
$permissionManager->grantPermission($borrowers->{'1A01'}, 'catalogue', 'staff_login');
56
$permissionManager->grantPermission($borrowers->{'admin'}, 'superlibrarian', 'superlibrarian');
57
45
##Test context set, starting testing:
58
##Test context set, starting testing:
46
eval { #run in a eval-block so we don't die without tearing down the test context
59
eval { #run in a eval-block so we don't die without tearing down the test context
47
60
48
    testPasswordLogin();
61
    my $mainpage = t::lib::Page::Mainpage->new();
62
    testPasswordLoginLogout($mainpage);
63
    testSuperuserPasswordLoginLogout($mainpage);
64
    testSuperlibrarianPasswordLoginLogout($mainpage);
65
    $mainpage->quit();
49
66
67
    my $opacmain = t::lib::Page::Opac::OpacMain->new();
68
    testPasswordLoginLogout($opacmain);
69
    testSuperuserPasswordLoginLogout($opacmain);
70
    testSuperlibrarianPasswordLoginLogout($opacmain);
71
    $opacmain->quit();
50
};
72
};
51
if ($@) { #Catch all leaking errors and gracefully terminate.
73
if ($@) { #Catch all leaking errors and gracefully terminate.
52
    warn $@;
74
    warn $@;
Lines 66-72 sub tearDown { Link Here
66
    ###  STARTING TEST IMPLEMENTATIONS         ###
88
    ###  STARTING TEST IMPLEMENTATIONS         ###
67
######################################################
89
######################################################
68
90
69
sub testPasswordLogin {
91
sub testPasswordLoginLogout {
70
    my $mainpage = t::lib::Page::Mainpage->new();
92
    my ($mainpage) = @_;
71
    $mainpage->isPasswordLoginAvailable()->doPasswordLogin($borrowers->{'1A01'}->{userid}, $password)->quit();
93
    $mainpage->isPasswordLoginAvailable()->doPasswordLogin($borrowers->{'1A01'}->{userid}, $password)->doPasswordLogout();
94
}
95
sub testSuperuserPasswordLoginLogout {
96
    my ($mainpage) = @_;
97
    $mainpage->isPasswordLoginAvailable()->doPasswordLogin(C4::Context->config('user'), C4::Context->config('pass'))->doPasswordLogout();
98
}
99
sub testSuperlibrarianPasswordLoginLogout {
100
    my ($mainpage) = @_;
101
    $mainpage->isPasswordLoginAvailable()->doPasswordLogin($borrowers->{'admin'}->{userid}, $password)->doPasswordLogout();
72
}
102
}
(-)a/t/db_dependent/Koha/Auth/BorrowerPermission.t (+102 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2015 Vaara-kirjastot
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
use Test::More;
22
23
use Koha::Auth::BorrowerPermission;
24
use Koha::Auth::BorrowerPermissions;
25
26
use t::db_dependent::TestObjects::ObjectFactory;
27
use t::db_dependent::TestObjects::Borrowers::BorrowerFactory;
28
29
##Setting up the test context
30
my $testContext = {};
31
32
my $borrowerFactory = t::db_dependent::TestObjects::Borrowers::BorrowerFactory->new();
33
my $borrowers = $borrowerFactory->createTestGroup([
34
            {firstname  => 'Olli-Antti',
35
             surname    => 'Kivi',
36
             cardnumber => '1A01',
37
             branchcode => 'CPL',
38
            },
39
            {firstname  => 'Alli-Ontti',
40
             surname    => 'Ivik',
41
             cardnumber => '1A02',
42
             branchcode => 'CPL',
43
            },
44
        ], undef, $testContext);
45
46
##Test context set, starting testing:
47
eval { #run in a eval-block so we don't die without tearing down the test context
48
    ##Basic id-based creation.
49
    my $borrowerPermissionById = Koha::Auth::BorrowerPermission->new({borrowernumber => $borrowers->{'1A01'}->{borrowernumber}, permission_module_id => 1, permission_id => 1});
50
    $borrowerPermissionById->store();
51
    my @borrowerPermissionById = Koha::Auth::BorrowerPermissions->search({borrowernumber => $borrowers->{'1A01'}->{borrowernumber}});
52
    is(scalar(@borrowerPermissionById), 1, "BorrowerPermissions, id-based creation:> Borrower has only one permission");
53
    is($borrowerPermissionById[0]->permission_module_id, 1, "BorrowerPermissions, id-based creation:> Same permission_module_id");
54
    is($borrowerPermissionById[0]->permission_id, 1, "BorrowerPermissions, id-based creation:> Same permission_id");
55
56
    ##Basic name-based creation.
57
    my $borrowerPermissionByName = Koha::Auth::BorrowerPermission->new({borrowernumber => $borrowers->{'1A02'}->{borrowernumber}, permissionModule => 'circulate', permission => 'manage_restrictions'});
58
    $borrowerPermissionByName->store();
59
    my @borrowerPermissionByName = Koha::Auth::BorrowerPermissions->search({borrowernumber => $borrowers->{'1A02'}->{borrowernumber}});
60
    is(scalar(@borrowerPermissionByName), 1, "BorrowerPermissions, name-based creation:> Borrower has only one permission");
61
    is($borrowerPermissionByName[0]->getPermissionModule->module, 'circulate', "BorrowerPermissions, name-based creation:> Same permission_module");
62
    is($borrowerPermissionByName[0]->getPermission->code, 'manage_restrictions', "BorrowerPermissions, name-based creation:> Same permission");
63
64
    ##Testing setter/getter for Borrower
65
    my $borrower1A01 = $borrowerPermissionById->getBorrower();
66
    is($borrower1A01->cardnumber, "1A01", "BorrowerPermissions, setter/getter:> getBorrower() 1A01");
67
    my $borrower1A02 = $borrowerPermissionByName->getBorrower();
68
    is($borrower1A02->cardnumber, "1A02", "BorrowerPermissions, setter/getter:> getBorrower() 1A02");
69
70
    $borrowerPermissionById->setBorrower($borrower1A02);
71
    is($borrowerPermissionById->getBorrower()->cardnumber, "1A02", "BorrowerPermissions, setter/getter:> setBorrower() 1A02");
72
    $borrowerPermissionByName->setBorrower($borrower1A01);
73
    is($borrowerPermissionByName->getBorrower()->cardnumber, "1A01", "BorrowerPermissions, setter/getter:> setBorrower() 1A01");
74
75
    ##Testing getter for PermissionModule
76
    my $permissionModule1 = $borrowerPermissionById->getPermissionModule();
77
    is($permissionModule1->permission_module_id, 1, "BorrowerPermissions, setter/getter:> getPermissionModule() 1");
78
    my $permissionModuleCirculate = $borrowerPermissionByName->getPermissionModule();
79
    is($permissionModuleCirculate->module, "circulate", "BorrowerPermissions, setter/getter:> getPermissionModule() circulate");
80
81
    #Not testing setters because changing the module might not make any sense.
82
    #Then we would need to make sure we dont end up with bad permissionModule->permission combinations.
83
84
    ##Testing getter for Permission
85
    my $permission1 = $borrowerPermissionById->getPermission();
86
    is($permission1->permission_id, 1, "BorrowerPermissions, setter/getter:> getPermission() 1");
87
    my $permissionManage_restrictions = $borrowerPermissionByName->getPermission();
88
    is($permissionManage_restrictions->code, "manage_restrictions", "BorrowerPermissions, setter/getter:> getPermission() manage_restrictions");
89
};
90
if ($@) { #Catch all leaking errors and gracefully terminate.
91
    warn $@;
92
    tearDown();
93
    exit 1;
94
}
95
96
##All tests done, tear down test context
97
$borrowerFactory->tearDownTestContext($testContext);
98
done_testing;
99
100
sub tearDown {
101
    t::db_dependent::TestObjects::ObjectFactory->tearDownTestContext($testContext);
102
}
(-)a/t/db_dependent/Koha/Auth/PermissionManager.t (+221 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2015 Vaara-kirjastot
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
use Test::More;
22
use Try::Tiny;
23
use Scalar::Util qw(blessed);
24
25
use Koha::Auth::PermissionManager;
26
27
use t::db_dependent::TestObjects::ObjectFactory;
28
use t::db_dependent::TestObjects::Borrowers::BorrowerFactory;
29
30
31
##Setting up the test context
32
my $testContext = {};
33
34
my $borrowerFactory = t::db_dependent::TestObjects::Borrowers::BorrowerFactory->new();
35
my $borrowers = $borrowerFactory->createTestGroup([
36
            {firstname  => 'Olli-Antti',
37
             surname    => 'Kivi',
38
             cardnumber => '1A01',
39
             branchcode => 'CPL',
40
            },
41
            {firstname  => 'Alli-Ontti',
42
             surname    => 'Ivik',
43
             cardnumber => '1A02',
44
             branchcode => 'CPL',
45
            },
46
        ], undef, $testContext);
47
48
##Test context set, starting testing:
49
eval { #run in a eval-block so we don't die without tearing down the test context
50
    my $permissionManager = Koha::Auth::PermissionManager->new();
51
    my ($permissionModule, $permission, $failureCaughtFlag, $permissionsList);
52
53
    ##Test getBorrowerPermissions
54
    $permissionManager->grantPermission($borrowers->{'1A01'}, 'circulate', 'force_checkout');
55
    $permissionManager->grantPermission($borrowers->{'1A01'}, 'circulate', 'manage_restrictions');
56
    $permissionsList = $permissionManager->getBorrowerPermissions($borrowers->{'1A01'});
57
    is($permissionsList->[0]->getPermission->code, 'force_checkout', "PermissionManager, getBorrowerPermissions:> Check 1.");
58
    is($permissionsList->[1]->getPermission->code, 'manage_restrictions', "PermissionManager, getBorrowerPermissions:> Check 2.");
59
    $permissionManager->revokePermission($borrowers->{'1A01'}, 'circulate', 'force_checkout');
60
    $permissionManager->revokePermission($borrowers->{'1A01'}, 'circulate', 'manage_restrictions');
61
62
    ##Test grantPermissions && revokeAllPermissions
63
    $permissionManager->grantPermissions($borrowers->{'1A01'},
64
                                         {  borrowers => 'view_borrowers',
65
                                            reserveforothers => ['place_holds'],
66
                                            tools => ['edit_news', 'edit_notices'],
67
                                            acquisition => {
68
                                              budget_add_del => 1,
69
                                              budget_modify => 1,
70
                                            },
71
                                        });
72
    $permissionManager->hasPermission($borrowers->{'1A01'}, 'borrowers', 'view_borrowers');
73
    $permissionManager->hasPermission($borrowers->{'1A01'}, 'tools', 'edit_notices');
74
    $permissionManager->hasPermission($borrowers->{'1A01'}, 'acquisition', 'budget_modify');
75
    $permissionsList = $permissionManager->getBorrowerPermissions($borrowers->{'1A01'});
76
    is(scalar(@$permissionsList), 6, "PermissionManager, grantPermissions:> Permissions as HASH, ARRAY and Scalar.");
77
78
    $permissionManager->revokeAllPermissions($borrowers->{'1A01'});
79
    $permissionsList = $permissionManager->getBorrowerPermissions($borrowers->{'1A01'});
80
    is(scalar(@$permissionsList), 0, "PermissionManager, revokeAllPermissions:> No permissions left.");
81
82
    ##Test listKohaPermissionsAsHASH
83
    my $listedPermissions = $permissionManager->listKohaPermissionsAsHASH();
84
    ok(ref($listedPermissions->{circulate}->{permissions}->{force_checkout}) eq 'HASH', "PermissionManager, listKohaPermissionsAsHASH:> Check 1.");
85
    ok(ref($listedPermissions->{editcatalogue}->{permissions}->{edit_catalogue}) eq 'HASH', "PermissionManager, listKohaPermissionsAsHASH:> Check 2.");
86
    ok(defined($listedPermissions->{reports}->{permissions}->{create_reports}->{description}), "PermissionManager, listKohaPermissionsAsHASH:> Check 3.");
87
    ok(defined($listedPermissions->{permissions}->{description}), "PermissionManager, listKohaPermissionsAsHASH:> Check 4.");
88
89
90
91
    ###   TESTING WITH unique keys, instead of the recommended Koha::Objects. ###
92
    #Arguably this makes for more clear tests cases :)
93
    ##Add/get PermissionModule
94
    $permissionModule = $permissionManager->addPermissionModule({module => 'test', description => 'Just testing this module.'});
95
    is($permissionModule->module, "test", "PermissionManager from names, add/getPermissionModule:> Module added.");
96
    $permissionModule = $permissionManager->getPermissionModule('test');
97
    is($permissionModule->module, "test", "PermissionManager from names, add/getPermissionModule:> Module got.");
98
99
    ##Add/get Permission
100
    $permission = $permissionManager->addPermission({module => 'test', code => 'testperm', description => 'Just testing this permission.'});
101
    is($permission->code, "testperm", "PermissionManager from names, add/getPermission:> Permission added.");
102
    $permission = $permissionManager->getPermission('testperm');
103
    is($permission->code, "testperm", "PermissionManager from names, add/getPermission:> Permission got.");
104
105
    ##Grant permission
106
    $permissionManager->grantPermission($borrowers->{'1A01'}, 'test', 'testperm');
107
    ok($permissionManager->hasPermission($borrowers->{'1A01'}, 'test', 'testperm'), "PermissionManager from names, grant/hasPermission:> Borrower granted permission.");
108
109
    ##hasPermission with wildcard
110
    ok($permissionManager->hasPermission($borrowers->{'1A01'}, 'test', '*'), "PermissionManager from names, hasPermission:> Wildcard permission.");
111
112
    ##hasPermissions with wildcard
113
    ok($permissionManager->hasPermissions($borrowers->{'1A01'}, {test => ['*']}), "PermissionManager from names, hasPermission:> Wildcard permissions from array.");
114
115
    ##Revoke permission
116
    $permissionManager->revokePermission($borrowers->{'1A01'}, 'test', 'testperm');
117
    $failureCaughtFlag = 0;
118
    try {
119
        $permissionManager->hasPermission($borrowers->{'1A01'}, 'test', 'testperm');
120
    } catch {
121
        if (blessed($_) && $_->isa('Koha::Exception::NoPermission')) {
122
            $failureCaughtFlag = 1;
123
        }
124
        else {
125
            die $_; #Somekind of another problem arised and rethrow it.
126
        }
127
    };
128
    ok($failureCaughtFlag, "PermissionManager from names, revoke/hasPermission:> Borrower revoked permission.");
129
130
    ##Delete permissions and modules we just made. When we delete the module first, the permissions is ON CASCADE DELETEd
131
    $permissionManager->delPermissionModule('test');
132
    $permissionModule = $permissionManager->getPermissionModule('test');
133
    ok(not(defined($permissionModule)), "PermissionManager from names, delPermissionModule:> Module deleted.");
134
135
    $failureCaughtFlag = 0;
136
    try {
137
        #This subpermission is now deleted due to cascading delete of the parent permissionModule
138
        #We catch the exception gracefully and report test success
139
        $permissionManager->delPermission('testperm');
140
    } catch {
141
        if (blessed($_) && $_->isa('Koha::Exception::UnknownObject')) {
142
            $failureCaughtFlag = 1;
143
        }
144
        else {
145
            die $_; #Somekind of another problem arised and rethrow it.
146
        }
147
    };
148
    ok($failureCaughtFlag, "PermissionManager from names, delPermission:> Permission already deleted, exception caught.");
149
    $permission = $permissionManager->getPermission('testperm');
150
    ok(not(defined($permission)), "PermissionManager from names, delPermission:> Permission deleted.");
151
152
153
154
    ###  TESTING WITH Koha::Object parameters instead.  ###
155
    ##Add/get PermissionModule
156
    $permissionModule = $permissionManager->addPermissionModule({module => 'test', description => 'Just testing this module.'});
157
    is($permissionModule->module, "test", "PermissionManager from objects, add/getPermissionModule:> Module added.");
158
    $permissionModule = $permissionManager->getPermissionModule($permissionModule);
159
    is($permissionModule->module, "test", "PermissionManager from objects, add/getPermissionModule:> Module got.");
160
161
    ##Add/get Permission
162
    $permission = $permissionManager->addPermission({module => 'test', code => 'testperm', description => 'Just testing this permission.'});
163
    is($permission->code, "testperm", "PermissionManager from objects, add/getPermission:> Permission added.");
164
    $permission = $permissionManager->getPermission($permission);
165
    is($permission->code, "testperm", "PermissionManager from objects, add/getPermission:> Permission got.");
166
167
    ##Grant permission
168
    $permissionManager->grantPermission($borrowers->{'1A01'}, $permissionModule, $permission);
169
    ok($permissionManager->hasPermission($borrowers->{'1A01'}, $permissionModule, $permission), "PermissionManager from objects, grant/hasPermission:> Borrower granted permission.");
170
171
    ##hasPermission with wildcard
172
    ok($permissionManager->hasPermission($borrowers->{'1A01'}, $permissionModule, '*'), "PermissionManager from objects, hasPermission:> Wildcard permission.");
173
174
    ##hasPermissions with wildcard, we quite cannot use a blessed Object as a HASH key
175
    #ok($permissionManager->hasPermissions($borrowers->{'1A01'}, {$permissionModule->module() => ['*']}), "PermissionManager from objects, hasPermission:> Wildcard permissions from array.");
176
177
    ##Revoke permission
178
    $permissionManager->revokePermission($borrowers->{'1A01'}, $permissionModule, $permission);
179
    $failureCaughtFlag = 0;
180
    try {
181
        $permissionManager->hasPermission($borrowers->{'1A01'}, $permissionModule, $permission);
182
    } catch {
183
        if (blessed($_) && $_->isa('Koha::Exception::NoPermission')) {
184
            $failureCaughtFlag = 1;
185
        }
186
        else {
187
            die $_; #Somekind of another problem arised and rethrow it.
188
        }
189
    };
190
    ok($failureCaughtFlag, "PermissionManager from objects, revoke/hasPermission:> Borrower revoked permission.");
191
192
    ##Delete permissions and modules we just made
193
    $permissionManager->delPermission($permission);
194
    $permission = $permissionManager->getPermission('testperm');
195
    ok(not(defined($permission)), "PermissionManager from objects, delPermission:> Permission deleted.");
196
197
    $permissionManager->delPermissionModule($permissionModule);
198
    $permissionModule = $permissionManager->getPermissionModule('test');
199
    ok(not(defined($permissionModule)), "PermissionManager from objects, delPermissionModule:> Module deleted.");
200
201
202
203
    ##Testing superlibrarian permission
204
    $permissionManager->revokeAllPermissions($borrowers->{'1A01'});
205
    $permissionManager->grantPermission($borrowers->{'1A01'}, 'superlibrarian', 'superlibrarian');
206
    ok($permissionManager->hasPermission($borrowers->{'1A01'}, 'staffaccess', 'staff_access_permissions'), "PermissionManager, superuser permission:> Superuser has all permissions 1.");
207
    ok($permissionManager->hasPermission($borrowers->{'1A01'}, 'tools', 'batch_upload_patron_images'), "PermissionManager, superuser permission:> Superuser has all permissions 2.");
208
};
209
if ($@) { #Catch all leaking errors and gracefully terminate.
210
    warn $@;
211
    tearDown();
212
    exit 1;
213
}
214
215
##All tests done, tear down test context
216
tearDown();
217
done_testing;
218
219
sub tearDown {
220
    t::db_dependent::TestObjects::ObjectFactory->tearDownTestContext($testContext);
221
}
(-)a/t/db_dependent/Members/member-flags.t (+100 lines)
Line 0 Link Here
1
#!/usr/bin/env perl
2
3
# Copyright 2015 Open Source Freedom Fighters
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use Test::More;
23
use Try::Tiny; #Even Selenium::Remote::Driver uses Try::Tiny :)
24
use Scalar::Util qw(blessed);
25
26
use t::lib::Page::Members::MemberFlags;
27
use t::db_dependent::TestObjects::Borrowers::BorrowerFactory;
28
use Koha::Auth::PermissionManager;
29
30
31
##Setting up the test context
32
my $testContext = {};
33
34
my $password = '1234';
35
my $borrowerFactory = t::db_dependent::TestObjects::Borrowers::BorrowerFactory->new();
36
my $borrowers = $borrowerFactory->createTestGroup([
37
            {firstname  => 'Olli-Antti',
38
             surname    => 'Kivi',
39
             cardnumber => '1A01',
40
             branchcode => 'CPL',
41
             userid     => 'mini_admin',
42
             password   => $password,
43
            },
44
        ], undef, $testContext);
45
46
##Test context set, starting testing:
47
eval { #run in a eval-block so we don't die without tearing down the test context
48
49
    testGrantRevokePermissions();
50
51
};
52
if ($@) { #Catch all leaking errors and gracefully terminate.
53
    warn $@;
54
    tearDown();
55
    exit 1;
56
}
57
58
##All tests done, tear down test context
59
tearDown();
60
done_testing;
61
62
sub tearDown {
63
    t::db_dependent::TestObjects::ObjectFactory->tearDownTestContext($testContext);
64
}
65
66
sub testGrantRevokePermissions {
67
    my $permissionManager = Koha::Auth::PermissionManager->new();
68
    $permissionManager->grantPermissions($borrowers->{'1A01'}, {permissions => 'set_permissions',
69
                                                                catalogue => 'staff_login',
70
                                                                staffaccess => 'staff_access_permissions',
71
                                                                circulate => 'override_renewals',
72
                                                                borrowers => 'view_borrowers',
73
                                                              });
74
75
    my $memberflags = t::lib::Page::Members::MemberFlags->new({borrowernumber => $borrowers->{'1A01'}->{borrowernumber}});
76
77
    $memberflags->isPasswordLoginAvailable()->doPasswordLogin($borrowers->{'1A01'}->{userid}, $password)
78
                ->togglePermission('editcatalogue', 'delete_all_items') #Add this
79
                ->togglePermission('editcatalogue', 'edit_items') #Add this
80
                ->togglePermission('circulate', 'override_renewals') #Remove this permission
81
                ->submitPermissionTree();
82
83
    ok($permissionManager->hasPermissions($borrowers->{'1A01'},{editcatalogue => ['delete_all_items', 'edit_items']}),
84
    "member-flags.pl:> Granting new permissions succeeded.");
85
86
    my $failureCaughtFlag = 0;
87
    try {
88
        $permissionManager->hasPermission($borrowers->{'1A01'}, 'circulate', 'override_renewals');
89
    } catch {
90
        if (blessed($_) && $_->isa('Koha::Exception::NoPermission')) {
91
            $failureCaughtFlag = 1;
92
        }
93
        else {
94
            die $_; #Somekind of another problem arised and rethrow it.
95
        }
96
    };
97
    ok($failureCaughtFlag, "member-flags.pl:> Revoking permissions succeeded.");
98
99
    $permissionManager->revokeAllPermissions($borrowers->{'1A01'});
100
}
(-)a/t/db_dependent/Opac/opac-search.t (+79 lines)
Line 0 Link Here
1
#!/usr/bin/env perl
2
3
# Copyright 2015 Open Source Freedom Fighters
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use Test::More;
23
24
use t::lib::Page::Opac::OpacSearch;
25
use t::db_dependent::TestObjects::Borrowers::BorrowerFactory;
26
27
28
##Setting up the test context
29
my $testContext = {};
30
31
my $password = '1234';
32
my $borrowerFactory = t::db_dependent::TestObjects::Borrowers::BorrowerFactory->new();
33
my $borrowers = $borrowerFactory->createTestGroup([
34
            {firstname  => 'Olli-Antti',
35
             surname    => 'Kivi',
36
             cardnumber => '1A01',
37
             branchcode => 'CPL',
38
             userid     => 'mini_admin',
39
             password   => $password,
40
            },
41
        ], undef, $testContext);
42
43
##Test context set, starting testing:
44
eval { #run in a eval-block so we don't die without tearing down the test context
45
46
    my $opacsearch = t::lib::Page::Opac::OpacSearch->new();
47
    testAnonymousSearchHistory($opacsearch);
48
49
};
50
if ($@) { #Catch all leaking errors and gracefully terminate.
51
    warn $@;
52
    tearDown();
53
    exit 1;
54
}
55
56
##All tests done, tear down test context
57
tearDown();
58
done_testing;
59
60
sub tearDown {
61
    t::db_dependent::TestObjects::ObjectFactory->tearDownTestContext($testContext);
62
}
63
64
sub testAnonymousSearchHistory {
65
    my $opacsearch = shift;
66
67
    $opacsearch->doSetSearchFieldTerm(1, 'Author', 'nengard')->doSearchSubmit()->navigateAdvancedSearch()
68
               ->doSetSearchFieldTerm(1, 'Author', 'joubu')->doSearchSubmit()->navigateAdvancedSearch()
69
               ->doSetSearchFieldTerm(1, 'Author', 'khall')->doSearchSubmit()->navigateHome()
70
               ->doPasswordLogin($borrowers->{'1A01'}->{userid}, $password)->navigateAdvancedSearch()
71
               ->doSetSearchFieldTerm(1, 'Author', 'magnuse')->doSearchSubmit()->navigateAdvancedSearch()
72
               ->doSetSearchFieldTerm(1, 'Author', 'cait')->doSearchSubmit()->navigateSearchHistory()
73
               ->testDoSearchHistoriesExist(['nengard',
74
                                             'joubu',
75
                                             'khall',
76
                                             'magnuse',
77
                                             'cait'])
78
               ->quit();
79
}
(-)a/t/lib/Page.pm (-65 lines)
Lines 144-214 sub pause { Link Here
144
    return $self;
144
    return $self;
145
}
145
}
146
146
147
=head isPasswordLoginAvailable
148
149
    $page->isPasswordLoginAvailable();
150
151
@RETURN t::lib::Page-object
152
@CROAK if password login is unavailable.
153
=cut
154
155
sub isPasswordLoginAvailable {
156
    my $self = shift;
157
    my $d = $self->getDriver();
158
    $self->debugTakeSessionSnapshot();
159
160
    _getPasswordLoginElements($d);
161
    ok(($d->get_title() =~ /Log in to Koha/), "PasswordLogin available");
162
    return $self;
163
}
164
165
sub doPasswordLogin {
166
    my ($self, $username, $password) = @_;
167
    my $d = $self->getDriver();
168
    $self->debugTakeSessionSnapshot();
169
170
    my ($submitButton, $useridInput, $passwordInput) = _getPasswordLoginElements($d);
171
    $useridInput->send_keys($username);
172
    $passwordInput->send_keys($password);
173
    $submitButton->click();
174
    $self->debugTakeSessionSnapshot();
175
176
    my $cookies = $d->get_all_cookies();
177
    my @cgisessid = grep {$_->{name} eq 'CGISESSID'} @$cookies;
178
179
    ok(($d->get_title() !~ /Log in to Koha/ && #No longer in the login page
180
        $d->get_title() !~ /Access denied/ &&
181
        $cgisessid[0]) #Cookie CGISESSID defined!
182
       , "PasswordLogin succeeded");
183
184
    return $self; #After a succesfull password login, we are directed to the same page we tried to access.
185
}
186
187
sub _getPasswordLoginElements {
188
    my $d = shift;
189
    my $submitButton  = $d->find_element('#submit');
190
    my $useridInput   = $d->find_element('#userid');
191
    my $passwordInput = $d->find_element('#password');
192
    return ($submitButton, $useridInput, $passwordInput);
193
}
194
195
sub doPasswordLogout {
196
    my ($self, $username, $password) = @_;
197
    my $d = $self->getDriver();
198
    $self->debugTakeSessionSnapshot();
199
200
    #Click the dropdown menu to make the logout-link visible
201
    my $logged_in_identifierA = $d->find_element('#drop3'); #What a nice and descriptive HTML element name!
202
    $logged_in_identifierA->click();
203
204
    #Logout
205
    my $logoutA = $d->find_element('#logout');
206
    $logoutA->click();
207
208
    ok(($d->get_title() =~ /Log in to Koha/), "PasswordLogout succeeded");
209
    return $self; #After a succesfull password logout, we are still in the same page we did before logout.
210
}
211
212
################################################
147
################################################
213
  ##  INTRODUCING OBJECT ACCESSORS  ##
148
  ##  INTRODUCING OBJECT ACCESSORS  ##
214
################################################
149
################################################
(-)a/t/lib/Page/Intra.pm (-3 / +5 lines)
Lines 50-56 sub isPasswordLoginAvailable { Link Here
50
    my $d = $self->getDriver();
50
    my $d = $self->getDriver();
51
    $self->debugTakeSessionSnapshot();
51
    $self->debugTakeSessionSnapshot();
52
52
53
    _getPasswordLoginElements($d);
53
    $self->_getPasswordLoginElements();
54
    ok(($d->get_title() =~ /Log in to Koha/), "PasswordLogin available");
54
    ok(($d->get_title() =~ /Log in to Koha/), "PasswordLogin available");
55
    return $self;
55
    return $self;
56
}
56
}
Lines 60-66 sub doPasswordLogin { Link Here
60
    my $d = $self->getDriver();
60
    my $d = $self->getDriver();
61
    $self->debugTakeSessionSnapshot();
61
    $self->debugTakeSessionSnapshot();
62
62
63
    my ($submitButton, $useridInput, $passwordInput) = _getPasswordLoginElements($d);
63
    my ($submitButton, $useridInput, $passwordInput) = $self->_getPasswordLoginElements();
64
    $useridInput->send_keys($username);
64
    $useridInput->send_keys($username);
65
    $passwordInput->send_keys($password);
65
    $passwordInput->send_keys($password);
66
    $submitButton->click();
66
    $submitButton->click();
Lines 78-84 sub doPasswordLogin { Link Here
78
}
78
}
79
79
80
sub _getPasswordLoginElements {
80
sub _getPasswordLoginElements {
81
    my $d = shift;
81
    my ($self) = @_;
82
    my $d = $self->getDriver();
83
82
    my $submitButton  = $d->find_element('#submit');
84
    my $submitButton  = $d->find_element('#submit');
83
    my $useridInput   = $d->find_element('#userid');
85
    my $useridInput   = $d->find_element('#userid');
84
    my $passwordInput = $d->find_element('#password');
86
    my $passwordInput = $d->find_element('#password');
(-)a/t/lib/Page/Members/MemberFlags.pm (+125 lines)
Line 0 Link Here
1
package t::lib::Page::Members::MemberFlags;
2
3
# Copyright 2015 Open Source Freedom Fighters
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
use Test::More;
22
23
use t::lib::Page::Members::Moremember;
24
25
use base qw(t::lib::Page::Intra);
26
27
=head NAME t::lib::Page::Members::MemberFlags
28
29
=head SYNOPSIS
30
31
member-flags.pl PageObject providing page functionality as a service!
32
33
=cut
34
35
=head new
36
37
    my $memberflags = t::lib::Page::Members::MemberFlags->new({borrowernumber => "1"});
38
39
Instantiates a WebDriver and loads the members/member-flags.pl.
40
@PARAM1 HASHRef of optional and MANDATORY parameters
41
MANDATORY extra parameters:
42
    borrowernumber => loads the page to display Borrower matching the given borrowernumber
43
44
@RETURNS t::lib::Page::Members::MemberFlags, ready for user actions!
45
=cut
46
47
sub new {
48
    my ($class, $params) = @_;
49
    unless (ref($params) eq 'HASH') {
50
        $params = {};
51
    }
52
    $params->{resource} = '/cgi-bin/koha/members/member-flags.pl';
53
    $params->{type}     = 'staff';
54
55
    $params->{getParams} = [];
56
    #Handle MANDATORY parameters
57
    if ($params->{borrowernumber}) {
58
        push @{$params->{getParams}}, "member=".$params->{borrowernumber};
59
    }
60
    else {
61
        Koha::Exception::BadParameter->throw(error => __PACKAGE__."->new():> Parameter 'borrowernumber' is missing.");
62
    }
63
64
    my $self = $class->SUPER::new($params);
65
66
    return $self;
67
}
68
69
sub togglePermission {
70
    my ($self, $permissionModule, $permissionCode) = @_;
71
    my $d = $self->getDriver();
72
    $self->debugTakeSessionSnapshot();
73
74
    my ($moduleTreeExpansionButton, $moduleCheckbox, $permissionCheckbox) = _getPermissionTreePermissionElements($d, $permissionModule, $permissionCode);
75
    if ($moduleTreeExpansionButton->get_attribute("class") =~ /expandable-hitarea/) { #Permission checkboxes are hidden and need to be shown.
76
        $moduleTreeExpansionButton->click();
77
        $d->pause( $self->{userInteractionDelay} );
78
    }
79
80
81
    #$moduleCheckbox->click(); #Clicking this will toggle all module permissions.
82
    my $checked = $permissionCheckbox->get_attribute("checked") || ''; #Returns undef if not checked
83
    $permissionCheckbox->click();
84
    ok($checked ne ($permissionCheckbox->get_attribute("checked") || ''),
85
       "Module '$permissionModule', permission '$permissionCode', checkbox toggled");
86
    $self->debugTakeSessionSnapshot();
87
88
    return $self;
89
}
90
91
sub submitPermissionTree {
92
    my $self = shift;
93
    my $d = $self->getDriver();
94
95
    my ($submitButton, $cancelButton) = _getPermissionTreeControlElements($d);
96
    $submitButton->click();
97
    $self->debugTakeSessionSnapshot();
98
99
    ok(($d->get_title() =~ /Patron details for/), "Permissions set");
100
101
    return t::lib::Page::Members::Moremember->rebrandFromPageObject($self);
102
}
103
104
sub _getPermissionTreeControlElements {
105
    my $d = shift;
106
    my $saveButton   = $d->find_element('input[value="Save"]');
107
    my $cancelButton = $d->find_element('a.cancel');
108
    return ($saveButton, $cancelButton);
109
}
110
111
=head _getPermissionTreePermissionElements
112
113
@PARAM1 Selenium::Remote::Driver implementation
114
@PARAM2 Scalar, Koha::Auth::PermissionModule's module
115
@PARAM3 Scalar, Koha::Auth::Permission's code
116
=cut
117
118
sub _getPermissionTreePermissionElements {
119
    my ($d, $module, $code) = @_;
120
    my $moduleTreeExpansionButton = $d->find_element("div.$module-hitarea");
121
    my $moduleCheckbox   = $d->find_element("input#flag-$module");
122
    my $permissionCheckbox = $d->find_element('input#'.$module.'_'.$code);
123
    return ($moduleTreeExpansionButton, $moduleCheckbox, $permissionCheckbox);
124
}
125
1; #Make the compiler happy!
(-)a/t/lib/Page/Members/Moremember.pm (+69 lines)
Line 0 Link Here
1
package t::lib::Page::Members::Moremember;
2
3
# Copyright 2015 Open Source Freedom Fighters
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
use Scalar::Util qw(blessed);
22
23
use base qw(t::lib::Page::Intra);
24
25
use Koha::Exception::BadParameter;
26
27
=head NAME t::lib::Page::Members::Moremember
28
29
=head SYNOPSIS
30
31
moremember.pl PageObject providing page functionality as a service!
32
33
=cut
34
35
=head new
36
37
    my $moremember = t::lib::Page::Members::Moremember->new({borrowernumber => "1"});
38
39
Instantiates a WebDriver and loads the members/moremember.pl.
40
@PARAM1 HASHRef of optional and MANDATORY parameters
41
MANDATORY extra parameters:
42
    borrowernumber => loads the page to display Borrower matching the given borrowernumber
43
44
@RETURNS t::lib::Page::Members::Moremember, ready for user actions!
45
=cut
46
47
sub new {
48
    my ($class, $params) = @_;
49
    unless (ref($params) eq 'HASH' || (blessed($params) && $params->isa('t::lib::Page') )) {
50
        $params = {};
51
    }
52
    $params->{resource} = '/cgi-bin/koha/members/moremember.pl';
53
    $params->{type}     = 'staff';
54
55
    $params->{getParams} = [];
56
    #Handle MANDATORY parameters
57
    if ($params->{borrowernumber}) {
58
        push @{$params->{getParams}}, "borrowernumber=".$params->{borrowernumber};
59
    }
60
    else {
61
        Koha::Exception::BadParameter->throw(error => __PACKAGE__."->new():> Parameter 'borrowernumber' is missing.");
62
    }
63
64
    my $self = $class->SUPER::new($params);
65
66
    return $self;
67
}
68
69
1; #Make the compiler happy!
(-)a/t/lib/Page/Opac.pm (-36 / +105 lines)
Lines 23-28 use Test::More; Link Here
23
use C4::Context;
23
use C4::Context;
24
24
25
use t::lib::WebDriverFactory;
25
use t::lib::WebDriverFactory;
26
use t::lib::Page::Opac::OpacSearchHistory;
27
use t::lib::Page::Opac::OpacMain;
28
use t::lib::Page::Opac::OpacSearch;
26
29
27
use Koha::Exception::BadParameter;
30
use Koha::Exception::BadParameter;
28
use Koha::Exception::SystemCall;
31
use Koha::Exception::SystemCall;
Lines 37-100 PageObject-pattern parent class for OPAC-pages. Extend this to implement specifi Link Here
37
40
38
=cut
41
=cut
39
42
40
=head isPasswordLoginAvailable
43
sub doPasswordLogout {
44
    my ($self, $username, $password) = @_;
45
    my $d = $self->getDriver();
46
    $self->debugTakeSessionSnapshot();
41
47
42
    $page->isPasswordLoginAvailable();
48
    #Logout
49
    my $headerElements = $self->_getHeaderRegionActionElements();
50
    my $logoutA = $headerElements->{logout};
51
    $logoutA->click();
52
    $self->debugTakeSessionSnapshot();
43
53
44
@RETURN t::lib::Page-object
54
    ok(($d->get_title() =~ /Log in to your account/), "PasswordLogout succeeded");
45
@CROAK if password login is unavailable.
55
    return t::lib::Page::Opac::OpacMain->rebrandFromPageObject($self);
46
=cut
56
}
47
57
48
sub isPasswordLoginAvailable {
58
sub navigateSearchHistory {
49
    my $self = shift;
59
    my ($self) = @_;
50
    my $d = $self->getDriver();
60
    my $d = $self->getDriver();
51
    $self->debugTakeSessionSnapshot();
61
    $self->debugTakeSessionSnapshot();
52
62
53
    _getPasswordLoginElements($d);
63
    my $headerElements = $self->_getHeaderRegionActionElements();
54
    ok(1, "PasswordLogin available");
64
    my $searchHistoryA = $headerElements->{searchHistory};
55
    return $self;
65
    $searchHistoryA->click();
66
    $self->debugTakeSessionSnapshot();
67
68
    ok(($d->get_title() =~ /Your search history/), "Navigation to search history.");
69
    return t::lib::Page::Opac::OpacSearchHistory->rebrandFromPageObject($self);
56
}
70
}
57
71
58
sub doPasswordLogin {
72
sub navigateAdvancedSearch {
59
    my ($self, $username, $password) = @_;
73
    my ($self) = @_;
60
    my $d = $self->getDriver();
74
    my $d = $self->getDriver();
61
    $self->debugTakeSessionSnapshot();
75
    $self->debugTakeSessionSnapshot();
62
76
63
    my ($submitButton, $useridInput, $passwordInput) = _getPasswordLoginElements($d);
77
    my ($advancedSearchA, $authoritySearchA, $tagCloudA) = $self->_getMoresearchesElements();
64
    $useridInput->send_keys($username);
78
    $advancedSearchA->click();
65
    $passwordInput->send_keys($password);
79
66
    $submitButton->click();
67
    $self->debugTakeSessionSnapshot();
80
    $self->debugTakeSessionSnapshot();
81
    ok(($d->get_title() =~ /Advanced search/), "Navigating to advanced search.");
82
    return t::lib::Page::Opac::OpacSearch->rebrandFromPageObject($self);
83
}
68
84
69
    my $cookies = $d->get_all_cookies();
85
sub navigateHome {
70
    my @cgisessid = grep {$_->{name} eq 'CGISESSID'} @$cookies;
86
    my ($self) = @_;
87
    my $d = $self->getDriver();
88
    $self->debugTakeSessionSnapshot();
71
89
72
    my $loggedinusernameSpan = $d->find_element('span.loggedinusername');
90
    my $breadcrumbLinks = $self->_getBreadcrumbLinks();
73
    ok(($cgisessid[0]), "PasswordLogin succeeded"); #We have the element && Cookie CGISESSID defined!
91
    $breadcrumbLinks->[0]->click();
74
92
75
    return $self; #After a succesfull password login, we are directed to the same page we tried to access.
93
    $self->debugTakeSessionSnapshot();
94
    ok(($d->get_current_url() =~ /opac-main\.pl/), "Navigating to OPAC home.");
95
    return t::lib::Page::Opac::OpacMain->rebrandFromPageObject($self);
76
}
96
}
77
97
78
sub _getPasswordLoginElements {
98
sub _getMoresearchesElements {
79
    my $d = shift;
99
    my ($self) = @_;
80
    my $submitButton  = $d->find_element('form#auth input[value="Log in"]');
100
    my $d = $self->getDriver();
81
    my $useridInput   = $d->find_element('#userid');
101
82
    my $passwordInput = $d->find_element('#password');
102
    my $advancedSearchA = $d->find_element("#moresearches a[href*='opac-search.pl']");
83
    return ($submitButton, $useridInput, $passwordInput);
103
    my $authoritySearchA = $d->find_element("#moresearches a[href*='opac-authorities-home.pl']");
104
    my $tagCloudA = $d->find_element("#moresearches a[href*='opac-tags.pl']");
105
    return ($advancedSearchA, $authoritySearchA, $tagCloudA);
84
}
106
}
85
107
86
sub doPasswordLogout {
108
sub _getBreadcrumbLinks {
87
    my ($self, $username, $password) = @_;
109
    my ($self) = @_;
88
    my $d = $self->getDriver();
110
    my $d = $self->getDriver();
89
    $self->debugTakeSessionSnapshot();
90
111
91
    #Logout
112
    my $breadcrumbLinks = $d->find_elements("ul.breadcrumb a");
92
    my $logoutA = $d->find_element('#logout');
113
    return ($breadcrumbLinks);
93
    $logoutA->click();
114
}
94
    $self->debugTakeSessionSnapshot();
95
115
96
    ok(($d->get_title() =~ /Log in to your account/), "PasswordLogout succeeded");
116
=head
97
    return $self; #After a succesfull password logout, we are still in the same page we did before logout.
117
118
Returns each element providing some kind of an action from the topmost header bar in OPAC.
119
All elements are not always present on each page, so test if the return set contains your
120
desired element.
121
@PARAM1 Selenium::Remote::Driver
122
@RETURNS HASHRef of the found elements:
123
    { cart             => $cartA,
124
      lists            => $listsA,
125
      loggedinusername => $loggedinusernameA,
126
      searchHistory    => $searchHistoryA,
127
      deleteSearchHistory => $deleteSearchHistoryA,
128
      logout           => $logoutA,
129
      login            => $loginA,
130
    }
131
=cut
132
133
sub _getHeaderRegionActionElements {
134
    my ($self) = @_;
135
    my $d = $self->getDriver();
136
137
    my ($cartA, $listsA, $loggedinusernameA, $searchHistoryA, $deleteSearchHistoryA, $logoutA, $loginA);
138
    #Always visible elements
139
    $cartA = $d->find_element("#header-region a#cartmenulink");
140
    $listsA = $d->find_element("#header-region a#listsmenu");
141
    #Occasionally visible elements
142
    eval {
143
        $loggedinusernameA = $d->find_element("#header-region a[href*='opac-user.pl']");
144
    };
145
    eval {
146
        $searchHistoryA = $d->find_element("#header-region a[href*='opac-search-history.pl']");
147
    };
148
    eval {
149
        $deleteSearchHistoryA = $d->find_element("#header-region a[href*='opac-search-history.pl'] + a");
150
    };
151
    eval {
152
        $logoutA = $d->find_element("#header-region #logout");
153
    };
154
    eval {
155
        $loginA = $d->find_element("#header-region a.loginModal-trigger");
156
    };
157
158
    my $e = {};
159
    $e->{cart} = $cartA if $cartA;
160
    $e->{lists} = $listsA if $listsA;
161
    $e->{loggedinusername} = $loggedinusernameA if $loggedinusernameA;
162
    $e->{searchHistory} = $searchHistoryA if $searchHistoryA;
163
    $e->{deleteSearchHistory} = $deleteSearchHistoryA if $deleteSearchHistoryA;
164
    $e->{logout} = $logoutA if $logoutA;
165
    $e->{login} = $loginA if $loginA;
166
    return ($e);
98
}
167
}
99
168
100
1; #Make the compiler happy!
169
1; #Make the compiler happy!
(-)a/t/lib/Page/Opac/OpacHeader.pm (+166 lines)
Line 0 Link Here
1
package t::lib::Page::Opac::OpacHeader;
2
3
# Copyright 2015 Open Source Freedom Fighters
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
use Test::More;
22
23
=head NAME t::lib::Page::Opac::OpacHeader
24
25
=head SYNOPSIS
26
27
PageObject-pattern header for Opac pages. Contains all the services the header provides.
28
29
=cut
30
31
sub new {
32
    my ($class) = @_;
33
34
    my $self = {};
35
    bless($self, $class);
36
37
    return $self;
38
}
39
40
sub doPasswordLogout {
41
    my ($self, $username, $password) = @_;
42
    my $d = $self->getDriver();
43
    $self->debugTakeSessionSnapshot();
44
45
    #Logout
46
    my $headerElements = $self->_getHeaderRegionActionElements();
47
    my $logoutA = $headerElements->{logout};
48
    $logoutA->click();
49
    $self->debugTakeSessionSnapshot();
50
51
    ok(($d->get_title() =~ /Log in to your account/), "PasswordLogout succeeded");
52
    return t::lib::Page::Opac::OpacMain->rebrandFromPageObject($self);
53
}
54
55
sub navigateSearchHistory {
56
    my ($self) = @_;
57
    my $d = $self->getDriver();
58
    $self->debugTakeSessionSnapshot();
59
60
    my $headerElements = $self->_getHeaderRegionActionElements();
61
    my $searchHistoryA = $headerElements->{searchHistory};
62
    $searchHistoryA->click();
63
    $self->debugTakeSessionSnapshot();
64
65
    ok(($d->get_title() =~ /Your search history/), "Navigation to search history.");
66
    return t::lib::Page::Opac::OpacSearchHistory->rebrandFromPageObject($self);
67
}
68
69
sub navigateAdvancedSearch {
70
    my ($self) = @_;
71
    my $d = $self->getDriver();
72
    $self->debugTakeSessionSnapshot();
73
74
    my ($advancedSearchA, $authoritySearchA, $tagCloudA) = $self->_getMoresearchesElements();
75
    $advancedSearchA->click();
76
77
    $self->debugTakeSessionSnapshot();
78
    ok(($d->get_title() =~ /Advanced search/), "Navigating to advanced search.");
79
    return t::lib::Page::Opac::OpacSearch->rebrandFromPageObject($self);
80
}
81
82
sub navigateHome {
83
    my ($self) = @_;
84
    my $d = $self->getDriver();
85
    $self->debugTakeSessionSnapshot();
86
87
    my $breadcrumbLinks = $self->_getBreadcrumbLinks();
88
    $breadcrumbLinks->[0]->click();
89
90
    $self->debugTakeSessionSnapshot();
91
    ok(($d->get_current_url() =~ /opac-main\.pl/), "Navigating to OPAC home.");
92
    return t::lib::Page::Opac::OpacMain->rebrandFromPageObject($self);
93
}
94
95
sub _getMoresearchesElements {
96
    my ($self) = @_;
97
    my $d = $self->getDriver();
98
99
    my $advancedSearchA = $d->find_element("#moresearches a[href*='opac-search.pl']");
100
    my $authoritySearchA = $d->find_element("#moresearches a[href*='opac-authorities-home.pl']");
101
    my $tagCloudA = $d->find_element("#moresearches a[href*='opac-tags.pl']");
102
    return ($advancedSearchA, $authoritySearchA, $tagCloudA);
103
}
104
105
sub _getBreadcrumbLinks {
106
    my ($self) = @_;
107
    my $d = $self->getDriver();
108
109
    my $breadcrumbLinks = $d->find_elements("ul.breadcrumb a");
110
    return ($breadcrumbLinks);
111
}
112
113
=head
114
115
Returns each element providing some kind of an action from the topmost header bar in OPAC.
116
All elements are not always present on each page, so test if the return set contains your
117
desired element.
118
@PARAM1 Selenium::Remote::Driver
119
@RETURNS HASHRef of the found elements:
120
    { cart             => $cartA,
121
      lists            => $listsA,
122
      loggedinusername => $loggedinusernameA,
123
      searchHistory    => $searchHistoryA,
124
      deleteSearchHistory => $deleteSearchHistoryA,
125
      logout           => $logoutA,
126
      login            => $loginA,
127
    }
128
=cut
129
130
sub _getHeaderRegionActionElements {
131
    my ($self) = @_;
132
    my $d = $self->getDriver();
133
134
    my ($cartA, $listsA, $loggedinusernameA, $searchHistoryA, $deleteSearchHistoryA, $logoutA, $loginA);
135
    #Always visible elements
136
    $cartA = $d->find_element("#header-region a#cartmenulink");
137
    $listsA = $d->find_element("#header-region a#listsmenu");
138
    #Occasionally visible elements
139
    eval {
140
        $loggedinusernameA = $d->find_element("#header-region a[href*='opac-user.pl']");
141
    };
142
    eval {
143
        $searchHistoryA = $d->find_element("#header-region a[href*='opac-search-history.pl']");
144
    };
145
    eval {
146
        $deleteSearchHistoryA = $d->find_element("#header-region a[href*='opac-search-history.pl'] + a");
147
    };
148
    eval {
149
        $logoutA = $d->find_element("#header-region #logout");
150
    };
151
    eval {
152
        $loginA = $d->find_element("#header-region a.loginModal-trigger");
153
    };
154
155
    my $e = {};
156
    $e->{cart} = $cartA if $cartA;
157
    $e->{lists} = $listsA if $listsA;
158
    $e->{loggedinusername} = $loggedinusernameA if $loggedinusernameA;
159
    $e->{searchHistory} = $searchHistoryA if $searchHistoryA;
160
    $e->{deleteSearchHistory} = $deleteSearchHistoryA if $deleteSearchHistoryA;
161
    $e->{logout} = $logoutA if $logoutA;
162
    $e->{login} = $loginA if $loginA;
163
    return ($e);
164
}
165
166
1; #Make the compiler happy!
(-)a/t/lib/Page/Opac/OpacMain.pm (+51 lines)
Lines 19-24 package t::lib::Page::Opac::OpacMain; Link Here
19
19
20
use Modern::Perl;
20
use Modern::Perl;
21
use Scalar::Util qw(blessed);
21
use Scalar::Util qw(blessed);
22
use Test::More;
23
24
use t::lib::Page::Opac::OpacUser;
22
25
23
use base qw(t::lib::Page::Opac);
26
use base qw(t::lib::Page::Opac);
24
27
Lines 57-60 sub new { Link Here
57
    return $self;
60
    return $self;
58
}
61
}
59
62
63
=head isPasswordLoginAvailable
64
65
    $page->isPasswordLoginAvailable();
66
67
@RETURN t::lib::Page-object
68
@CROAK if password login is unavailable.
69
=cut
70
71
sub isPasswordLoginAvailable {
72
    my $self = shift;
73
    my $d = $self->getDriver();
74
    $self->debugTakeSessionSnapshot();
75
76
    $self->_getPasswordLoginElements();
77
    ok(1, "PasswordLogin available");
78
    return $self;
79
}
80
81
sub doPasswordLogin {
82
    my ($self, $username, $password) = @_;
83
    my $d = $self->getDriver();
84
    $self->debugTakeSessionSnapshot();
85
86
    my ($submitButton, $useridInput, $passwordInput) = $self->_getPasswordLoginElements();
87
    $useridInput->send_keys($username);
88
    $passwordInput->send_keys($password);
89
    $submitButton->click();
90
    $self->debugTakeSessionSnapshot();
91
92
    my $cookies = $d->get_all_cookies();
93
    my @cgisessid = grep {$_->{name} eq 'CGISESSID'} @$cookies;
94
95
    my $loggedinusernameSpan = $d->find_element('span.loggedinusername');
96
    ok(($cgisessid[0]), "PasswordLogin succeeded"); #We have the element && Cookie CGISESSID defined!
97
98
    return t::lib::Page::Opac::OpacUser->rebrandFromPageObject($self);
99
}
100
101
sub _getPasswordLoginElements {
102
    my ($self) = @_;
103
    my $d = $self->getDriver();
104
105
    my $submitButton  = $d->find_element('form#auth input[type="submit"]');
106
    my $useridInput   = $d->find_element('#userid');
107
    my $passwordInput = $d->find_element('#password');
108
    return ($submitButton, $useridInput, $passwordInput);
109
}
110
60
1; #Make the compiler happy!
111
1; #Make the compiler happy!
(-)a/t/lib/Page/Opac/OpacSearch.pm (+127 lines)
Line 0 Link Here
1
package t::lib::Page::Opac::OpacSearch;
2
3
# Copyright 2015 Open Source Freedom Fighters
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
use Scalar::Util qw(blessed);
22
use Test::More;
23
24
use t::lib::Page::PageUtils;
25
use t::lib::Page::Opac::OpacMain;
26
use t::lib::Page::Opac::OpacSearchHistory;
27
28
use base qw(t::lib::Page::Opac);
29
30
use Koha::Exception::BadParameter;
31
32
=head NAME t::lib::Page::Opac::OpacSearch
33
34
=head SYNOPSIS
35
36
PageObject providing page functionality as a service!
37
38
=cut
39
40
=head new
41
42
    my $opacsearch = t::lib::Page::Opac::OpacSearch->new();
43
44
Instantiates a WebDriver and loads the opac/opac-search.pl.
45
@PARAM1 HASHRef of optional and MANDATORY parameters
46
MANDATORY extra parameters:
47
    none atm.
48
49
@RETURNS t::lib::Page::Opac::OpacSearch, ready for user actions!
50
=cut
51
52
sub new {
53
    my ($class, $params) = @_;
54
    unless (ref($params) eq 'HASH' || (blessed($params) && $params->isa('t::lib::Page') )) {
55
        $params = {};
56
    }
57
    $params->{resource} = '/cgi-bin/koha/opac-search.pl';
58
    $params->{type}     = 'opac';
59
60
    my $self = $class->SUPER::new($params);
61
62
    return $self;
63
}
64
65
=head doSetSearchFieldTerm
66
67
Sets the search index and term for one of the (by default) three search fields.
68
@PARAM1, Integer, which search field to put the parameters into?
69
                  Starts from 0 == the topmost search field.
70
@PARAM2, String, the index to use. Undef if you want to use whatever there is.
71
                 Use the english index full name, eg. "Keyword", "Title", "Author".
72
@PARAM3, String, the search term. This replaces any existing search terms in the search field.
73
=cut
74
75
sub doSetSearchFieldTerm {
76
    my ($self, $searchField, $selectableIndex, $term) = @_;
77
    $searchField = '0' unless $searchField; #Trouble with Perl interpreting 0
78
    my $d = $self->getDriver();
79
    $self->debugTakeSessionSnapshot();
80
81
    my ($indexSelect, $termInput, $searchSubmit) = $self->_findSearchFieldElements($searchField);
82
83
    if ($selectableIndex) {
84
        t::lib::Page::PageUtils::displaySelectsOptions($d, $indexSelect);
85
        my $optionElement = t::lib::Page::PageUtils::getSelectElementsOptionByName($d, $indexSelect, $selectableIndex);
86
        $optionElement->click();
87
    }
88
89
    if ($term) {
90
        $termInput->clear();
91
        $termInput->send_keys($term);
92
    }
93
    else {
94
        Koha::Exception::BadParameter->throw("doSetSearchFieldTerm():> Parameter \$main is mandatory but is missing? Parameters as follow\n: @_");
95
    }
96
97
    $selectableIndex = '' unless $selectableIndex;
98
    ok(1, "SearchField parameters '$selectableIndex' and '$term' set.");
99
    $self->debugTakeSessionSnapshot();
100
    return $self;
101
}
102
103
sub _findSearchFieldElements {
104
    my ($self, $searchField) = @_;
105
    my $d = $self->getDriver();
106
    $searchField = '0' unless $searchField;
107
108
    my $indexSelect = $d->find_element("#search-field_$searchField");
109
    my $termInput = $d->find_element("#search-field_$searchField + input[name='q']");
110
    my $searchSubmit = $d->find_element("input[type='submit'].btn-success"); #Returns the first instance.
111
    return ($indexSelect, $termInput, $searchSubmit);
112
}
113
114
sub doSearchSubmit {
115
    my ($self) = @_;
116
    my $d = $self->getDriver();
117
    $self->debugTakeSessionSnapshot();
118
119
    my ($indexSelect, $termInput, $searchSubmit) = $self->_findSearchFieldElements(0); #We just want the submit button
120
    $searchSubmit->click();
121
    $self->debugTakeSessionSnapshot();
122
123
    ok(($d->get_title() =~ /Results of search/), "SearchField search.");
124
    return $self;
125
}
126
127
1; #Make the compiler happy!
(-)a/t/lib/Page/Opac/OpacSearchHistory.pm (+107 lines)
Line 0 Link Here
1
package t::lib::Page::Opac::OpacSearchHistory;
2
3
# Copyright 2015 Open Source Freedom Fighters
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
use Test::More;
22
23
use base qw(t::lib::Page::Opac);
24
25
use Koha::Exception::FeatureUnavailable;
26
27
=head NAME t::lib::Page::Opac::OpacSearchHistory
28
29
=head SYNOPSIS
30
31
PageObject providing page functionality as a service!
32
33
=cut
34
35
=head new
36
37
YOU CANNOT GET HERE WITHOUT LOGGING IN FIRST!
38
39
=cut
40
41
sub new {
42
    Koha::Exception::FeatureUnavailable->throw(error => __PACKAGE__."->new():> You must login first to navigate to this page!");
43
}
44
45
=head testDoSearchHistoriesExist
46
47
    $opacsearchhistory->testDoSearchHistoriesExist([ 'maximus',
48
                                                     'julius',
49
                                                     'titus',
50
                                                  ]);
51
@PARAM1 ARRAYRef of search strings shown in the opac-search-history.pl -page.
52
                 These search strings need only be contained in the displayed values.
53
=cut
54
55
sub testDoSearchHistoriesExist {
56
    my ($self, $searchStrings) = @_;
57
    my $d = $self->getDriver();
58
    $self->debugTakeSessionSnapshot();
59
60
    my $histories = $self->_getAllSearchHistories();
61
    foreach my $s (@$searchStrings) {
62
63
        my $matchFound;
64
        foreach my $h (@$histories) {
65
            if ($h->{searchStringA}->get_text() =~ /$s/) {
66
                $matchFound = $h->{searchStringA}->get_text();
67
                last();
68
            }
69
        }
70
        ok($matchFound =~ /$s/, "SearchHistory $s exists.");
71
    }
72
    return $self;
73
}
74
75
sub _getAllSearchHistories {
76
    my ($self) = @_;
77
    my $d = $self->getDriver();
78
79
    $self->pause(500); #Wait for datatables to load the page.
80
    my $histories = $d->find_elements("table.historyt tr");
81
    #First index has the table header, so skip that.
82
    shift @$histories;
83
    for (my $i=0 ; $i<scalar(@$histories) ; $i++) {
84
        $histories->[$i] = $self->_castSearchHistoryRowToHash($histories->[$i]);
85
    }
86
    return $histories;
87
}
88
89
sub _castSearchHistoryRowToHash {
90
    my ($self, $historyRow) = @_;
91
    my $d = $self->getDriver();
92
93
    my $checkbox = $d->find_child_element($historyRow, "input[type='checkbox']","css");
94
    my $date = $d->find_child_element($historyRow, "span[title]","css");
95
    $date = $date->get_text();
96
    my $searchStringA = $d->find_child_element($historyRow, "a + a","css");
97
    my $resultsCount = $d->find_child_element($historyRow, "td + td + td + td","css");
98
99
    my $sh = {  checkbox => $checkbox,
100
                date => $date,
101
                searchStringA => $searchStringA,
102
                resultsCount => $resultsCount,
103
              };
104
    return $sh;
105
}
106
107
1; #Make the compiler happy!
(-)a/t/lib/Page/Opac/OpacUser.pm (+44 lines)
Line 0 Link Here
1
package t::lib::Page::Opac::OpacUser;
2
3
# Copyright 2015 Open Source Freedom Fighters
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use base qw(t::lib::Page::Opac);
23
24
use Koha::Exception::FeatureUnavailable;
25
26
=head NAME t::lib::Page::Opac::OpacUser
27
28
=head SYNOPSIS
29
30
PageObject providing page functionality as a service!
31
32
=cut
33
34
=head new
35
36
YOU CANNOT GET HERE WITHOUT LOGGING IN FIRST!
37
Navigate here from opac-main.pl for example.
38
=cut
39
40
sub new {
41
    Koha::Exception::FeatureUnavailable->throw(error => __PACKAGE__."->new():> You must login first to navigate to this page!");
42
}
43
44
1; #Make the compiler happy!
(-)a/t/lib/Page/PageUtils.pm (-1 / +69 lines)
Line 0 Link Here
0
- 
1
package t::lib::Page::PageUtils;
2
3
# Copyright 2015 Open Source Freedom Fighters
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use Koha::Exception::UnknownObject;
23
24
=head NAME t::lib::Page::PageUtils
25
26
=head SYNOPSIS
27
28
Contains all kinds of helper functions used all over the PageObject testing framework.
29
30
=cut
31
32
sub getSelectElementsOptionByName {
33
    my ($d, $selectElement, $optionName) = @_;
34
35
    my $options = $d->find_child_elements($selectElement, "option", 'css');
36
    my $correctOption;
37
    foreach my $option (@$options) {
38
        if ($option->get_text() eq $optionName) {
39
            $correctOption = $option;
40
            last();
41
        }
42
    }
43
44
    return $correctOption if $correctOption;
45
46
    ##Throw Exception because we didn't find the option element.
47
    my @availableOptions;
48
    foreach my $option (@$options) {
49
        push @availableOptions, $option->get_tag_name() .', value: '. $option->get_value() .', text: '. $option->get_text();
50
    }
51
    Koha::Exception::UnknownObject->throw(error =>
52
        "getSelectElementsOptionByName():> Couldn't find the given option-element using '$optionName'. Available options:\n".
53
        join("\n", @availableOptions));
54
}
55
56
sub displaySelectsOptions {
57
    my ($d, $selectElement) = @_;
58
59
    my $options = $d->find_child_elements($selectElement, "option", 'css');
60
    if (scalar(@$options)) {
61
        $selectElement->click() if $options->[0]->is_hidden();
62
    }
63
    else {
64
        Koha::Exception::UnknownObject->throw(error =>
65
            "_displaySelectsOptions():> element: ".$selectElement->get_tag_name()-', class: '.$selectElement->get_attribute("class").", doesn't have any option-elements?");
66
    }
67
}
68
69
1;

Return to bug 14540