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

(-)a/C4/Auth.pm (-1 lines)
Lines 168-174 sub get_template_and_user { Link Here
168
        $in->{'template_name'},
168
        $in->{'template_name'},
169
        $in->{'type'},
169
        $in->{'type'},
170
        $in->{'query'},
170
        $in->{'query'},
171
        $in->{'is_plugin'}
172
    );
171
    );
173
172
174
    if ( $in->{'template_name'} !~ m/maintenance/ ) {
173
    if ( $in->{'template_name'} !~ m/maintenance/ ) {
(-)a/C4/Templates.pm (-4 / +4 lines)
Lines 164-172 sub _get_template_file { Link Here
164
    my ($theme, $lang, $availablethemes) = themelanguage($htdocs, $tmplbase, $interface, $query);
164
    my ($theme, $lang, $availablethemes) = themelanguage($htdocs, $tmplbase, $interface, $query);
165
    $lang //= 'en';
165
    $lang //= 'en';
166
    $theme //= '';
166
    $theme //= '';
167
    my $filename = "$htdocs/$theme/$lang/modules/$tmplbase";
167
    $tmplbase = "$htdocs/$theme/$lang/modules/$tmplbase" if $tmplbase !~ /^\//;
168
        # do not prefix an absolute path
168
169
169
    return ($htdocs, $theme, $lang, $filename);
170
    return ( $htdocs, $theme, $lang, $tmplbase );
170
}
171
}
171
172
172
=head2 badtemplatecheck
173
=head2 badtemplatecheck
Lines 201-211 sub badtemplatecheck { Link Here
201
}
202
}
202
203
203
sub gettemplate {
204
sub gettemplate {
204
    my ( $tmplbase, $interface, $query, $is_plugin ) = @_;
205
    my ( $tmplbase, $interface, $query ) = @_;
205
    ($query) or warn "no query in gettemplate";
206
    ($query) or warn "no query in gettemplate";
206
    my ($htdocs, $theme, $lang, $filename)
207
    my ($htdocs, $theme, $lang, $filename)
207
       =  _get_template_file($tmplbase, $interface, $query);
208
       =  _get_template_file($tmplbase, $interface, $query);
208
    $filename = $tmplbase if ( $is_plugin );
209
    badtemplatecheck( $filename ); # single trip for bad templates
209
    badtemplatecheck( $filename ); # single trip for bad templates
210
    my $template = C4::Templates->new($interface, $filename, $tmplbase, $query);
210
    my $template = C4::Templates->new($interface, $filename, $tmplbase, $query);
211
211
(-)a/Koha/Plugins/Base.pm (-2 / +5 lines)
Lines 106-117 sub get_template { Link Here
106
106
107
    require C4::Auth;
107
    require C4::Auth;
108
108
109
    my $template_name = $args->{'file'} // '';
110
    # if not absolute, call mbf_path, which dies if file does not exist
111
    $template_name = $self->mbf_path( $template_name )
112
        if $template_name !~ m/^\//;
109
    my ( $template, $loggedinuser, $cookie ) = C4::Auth::get_template_and_user(
113
    my ( $template, $loggedinuser, $cookie ) = C4::Auth::get_template_and_user(
110
        {   template_name   => abs_path( $self->mbf_path( $args->{'file'} ) ),
114
        {   template_name   => $template_name,
111
            query           => $self->{'cgi'},
115
            query           => $self->{'cgi'},
112
            type            => "intranet",
116
            type            => "intranet",
113
            authnotrequired => 1,
117
            authnotrequired => 1,
114
            is_plugin       => 1,
115
        }
118
        }
116
    );
119
    );
117
120
(-)a/opac/maintenance.pl (-1 / +1 lines)
Lines 25-31 use C4::Templates qw/gettemplate/; Link Here
25
use Koha;
25
use Koha;
26
26
27
my $query = new CGI;
27
my $query = new CGI;
28
my $template = C4::Templates::gettemplate( 'maintenance.tt', 'opac', $query, 0 );
28
my $template = C4::Templates::gettemplate( 'maintenance.tt', 'opac', $query );
29
29
30
my $koha_db_version = C4::Context->preference('Version');
30
my $koha_db_version = C4::Context->preference('Version');
31
my $kohaversion     = Koha::version();
31
my $kohaversion     = Koha::version();
(-)a/t/db_dependent/Auth.t (-1 / +1 lines)
Lines 192-198 my $hash2 = hash_password('password'); Link Here
192
                }
192
                }
193
            );
193
            );
194
        };
194
        };
195
        like ( $@, qr(^bad template path), 'The file $template_name should not be accessible' );
195
        like ( $@, qr(^bad template path), "The file $template_name should not be accessible" );
196
    }
196
    }
197
    ( $template, $loggedinuser, $cookies ) = get_template_and_user(
197
    ( $template, $loggedinuser, $cookies ) = get_template_and_user(
198
        {
198
        {
(-)a/t/db_dependent/Plugins.t (-3 / +24 lines)
Lines 2-13 Link Here
2
2
3
use Modern::Perl;
3
use Modern::Perl;
4
4
5
use Test::More tests => 28;
5
use Test::More tests => 29;
6
use CGI;
6
use File::Basename;
7
use File::Basename;
7
use File::Temp qw( tempdir );
8
use File::Spec;
9
use File::Temp qw( tempdir tempfile );
8
use FindBin qw($Bin);
10
use FindBin qw($Bin);
9
use Archive::Extract;
11
use Archive::Extract;
10
use Module::Load::Conditional qw(can_load);
12
use Module::Load::Conditional qw(can_load);
13
use Test::MockModule;
11
14
12
use C4::Context;
15
use C4::Context;
13
use t::lib::Mocks;
16
use t::lib::Mocks;
Lines 21-29 BEGIN { Link Here
21
    use_ok('Koha::Plugin::Test');
24
    use_ok('Koha::Plugin::Test');
22
}
25
}
23
26
27
my $mock_plugin = Test::MockModule->new( 'Koha::Plugin::Test' );
28
$mock_plugin->mock( 'test_template', sub {
29
    my ( $self, $file ) = @_;
30
    my $template = $self->get_template({ file => $file });
31
    $template->param( filename => $file );
32
    return $template->output;
33
});
34
24
ok( can_load( modules => { "Koha::Plugin::Test" => undef } ), 'Test can_load' );
35
ok( can_load( modules => { "Koha::Plugin::Test" => undef } ), 'Test can_load' );
25
36
26
my $plugin = Koha::Plugin::Test->new({ enable_plugins => 1});
37
my $plugin = Koha::Plugin::Test->new({ enable_plugins => 1, cgi => CGI->new });
27
38
28
isa_ok( $plugin, "Koha::Plugin::Test", 'Test plugin class' );
39
isa_ok( $plugin, "Koha::Plugin::Test", 'Test plugin class' );
29
isa_ok( $plugin, "Koha::Plugins::Base", 'Test plugin parent class' );
40
isa_ok( $plugin, "Koha::Plugins::Base", 'Test plugin parent class' );
Lines 43-48 is( $metadata->{'name'}, 'Test Plugin', 'Test $plugin->get_metadata()' ); Link Here
43
is( $plugin->get_qualified_table_name('mytable'), 'koha_plugin_test_mytable', 'Test $plugin->get_qualified_table_name()' );
54
is( $plugin->get_qualified_table_name('mytable'), 'koha_plugin_test_mytable', 'Test $plugin->get_qualified_table_name()' );
44
is( $plugin->get_plugin_http_path(), '/plugin/Koha/Plugin/Test', 'Test $plugin->get_plugin_http_path()' );
55
is( $plugin->get_plugin_http_path(), '/plugin/Koha/Plugin/Test', 'Test $plugin->get_plugin_http_path()' );
45
56
57
# test absolute path change in get_template with Koha::Plugin::Test
58
# using the mock set before
59
# we also add tmpdir as an approved template dir
60
t::lib::Mocks::mock_config( 'pluginsdir', [ File::Spec->tmpdir ] );
61
my ( $fh, $fn ) = tempfile( SUFFIX => '.tt', UNLINK => 1 );
62
print $fh 'I am [% filename %]';
63
close $fh;
64
my $classname = ref($plugin);
65
like( $plugin->test_template($fn), qr/^I am $fn/, 'Template works' );
66
46
# testing GetPlugins
67
# testing GetPlugins
47
my @plugins = Koha::Plugins->new({ enable_plugins => 1 })->GetPlugins({
68
my @plugins = Koha::Plugins->new({ enable_plugins => 1 })->GetPlugins({
48
    method => 'report'
69
    method => 'report'
(-)a/t/db_dependent/Templates.t (-6 / +29 lines)
Lines 19-31 use Modern::Perl; Link Here
19
19
20
use CGI;
20
use CGI;
21
21
22
use Test::More tests => 7;
22
use Test::More tests => 8;
23
use Test::Deep;
23
use Test::Deep;
24
use Test::MockModule;
24
use Test::MockModule;
25
use Test::Warn;
25
use Test::Warn;
26
use File::Spec;
27
use File::Temp qw/tempfile/;
26
28
27
use t::lib::Mocks;
29
use t::lib::Mocks;
28
30
31
use C4::Auth qw//;
32
29
BEGIN {
33
BEGIN {
30
    use_ok( 'C4::Templates' );
34
    use_ok( 'C4::Templates' );
31
    can_ok( 'C4::Templates',
35
    can_ok( 'C4::Templates',
Lines 102-114 subtest 'Testing gettemplate/badtemplatecheck' => sub { Link Here
102
106
103
    my $cgi = CGI->new;
107
    my $cgi = CGI->new;
104
    my $template;
108
    my $template;
105
    warning_like { eval { $template = C4::Templates::gettemplate( '/etc/passwd', 'opac', $cgi, 1 ) }; warn $@ if $@; } qr/bad template/, 'Bad template check';
109
    warning_like { eval { $template = C4::Templates::gettemplate( '/etc/passwd', 'opac', $cgi ) }; warn $@ if $@; } qr/bad template/, 'Bad template check';
106
    is( $template ? $template->output: '', '', 'Check output' );
110
    is( $template ? $template->output: '', '', 'Check output' );
107
111
108
    # Test a few more bad paths to gettemplate triggering badtemplatecheck
112
    # Test a few more bad paths to gettemplate triggering badtemplatecheck
109
    warning_like { eval { C4::Templates::gettemplate( '../topsecret.tt', 'opac', $cgi, 1 ) }; warn $@ if $@; } qr/bad template/, 'No safe chars';
113
    warning_like { eval { C4::Templates::gettemplate( '../topsecret.tt', 'opac', $cgi ) }; warn $@ if $@; } qr/bad template/, 'No safe chars';
110
    warning_like { eval { C4::Templates::gettemplate( '/noaccess/topsecret.tt', 'opac', $cgi, 1 ) }; warn $@ if $@; } qr/bad template/, 'Directory not allowed';
114
    warning_like { eval { C4::Templates::gettemplate( '/noaccess/topsecret.tt', 'opac', $cgi ) }; warn $@ if $@; } qr/bad template/, 'Directory not allowed';
111
    warning_like { eval { C4::Templates::gettemplate( C4::Context->config('intrahtdocs') . '2/prog/en/modules/about.tt', 'intranet', $cgi, 1 ) }; warn $@ if $@; } qr/bad template/, 'Directory not allowed too';
115
    warning_like { eval { C4::Templates::gettemplate( C4::Context->config('intrahtdocs') . '2/prog/en/modules/about.tt', 'intranet', $cgi ) }; warn $@ if $@; } qr/bad template/, 'Directory not allowed too';
112
116
113
    # Allow templates from /tmp
117
    # Allow templates from /tmp
114
    t::lib::Mocks::mock_config( 'pluginsdir', [ '/tmp' ] );
118
    t::lib::Mocks::mock_config( 'pluginsdir', [ '/tmp' ] );
Lines 117-119 subtest 'Testing gettemplate/badtemplatecheck' => sub { Link Here
117
    warning_like { eval { C4::Templates::badtemplatecheck( '/tmp/about.tmpl' ) }; warn $@ if $@; } qr/bad template/, 'Warn on bad extension';
121
    warning_like { eval { C4::Templates::badtemplatecheck( '/tmp/about.tmpl' ) }; warn $@ if $@; } qr/bad template/, 'Warn on bad extension';
118
};
122
};
119
123
120
- 
124
subtest "Absolute path change in _get_template_file" => sub {
125
    plan tests => 1;
126
127
    # We create a simple template in /tmp.
128
    # We simulate an anonymous OPAC session; the OPACBaseURL template variable
129
    # should be filled by get_template_and_user.
130
    t::lib::Mocks::mock_config( 'pluginsdir', [ File::Spec->tmpdir ] );
131
    t::lib::Mocks::mock_preference( 'OPACBaseURL', 'without any doubt' );
132
    my ( $fh, $fn ) = tempfile( SUFFIX => '.tt', UNLINK => 1 );
133
    print $fh q|I am a [% quality %] template [% OPACBaseURL %]|;
134
    close $fh;
135
    my ( $template, $login, $cookie ) = C4::Auth::get_template_and_user({
136
        template_name => $fn,
137
        query => CGI::new,
138
        type => "opac",
139
        authnotrequired => 1,
140
    });
141
    $template->param( quality => 'good-for-nothing' );
142
    like( $template->output, qr/a good.+template.+doubt/, 'Testing a template with an absolute path' );
143
};

Return to bug 17989