--- trunk/webwork-modperl/lib/WeBWorK/CourseEnvironment.pm 2002/06/24 15:46:36 401 +++ trunk/webwork-modperl/lib/WeBWorK/CourseEnvironment.pm 2003/06/11 14:11:41 1119 @@ -1,24 +1,84 @@ +################################################################################ +# WeBWorK mod_perl (c) 2000-2002 WeBWorK Project +# $Id$ +################################################################################ + package WeBWorK::CourseEnvironment; +=head1 NAME + +WeBWorK::CourseEnvironment - Read configuration information from global.conf +and course.conf files. + +=cut + use strict; use warnings; use Safe; +use WeBWorK::Utils qw(readFile); +use Opcode qw(empty_opset); -# new($invocant, $webworkRoot, $courseName) -# $invocant implicitly set by caller -# $webworkRoot directory that contains the WeBWorK distribution -# $courseName name of the course being used +# new($invocant, $webworkRoot, $webworkURLRoot, $pgRoot, $courseName) +# $invocant implicitly set by caller +# $webworkRoot directory that contains the WeBWorK distribution +# $webworkURLRoot URL that points to the WeBWorK system +# $pgRoot directory that contains the PG distribution +# $courseName name of the course being used sub new { my $invocant = shift; my $class = ref($invocant) || $invocant; my $webworkRoot = shift; - my $courseName = shift; + my $webworkURLRoot = shift; + my $pgRoot = shift; + my $courseName = shift || ""; my $safe = Safe->new; # set up some defaults that the environment files will need $safe->reval("\$webworkRoot = '$webworkRoot'"); + $safe->reval("\$webworkURLRoot = '$webworkURLRoot'"); + $safe->reval("\$pgRoot = '$pgRoot'"); $safe->reval("\$courseName = '$courseName'"); + # Compile the "include" function with all opcodes available. + # why did this first version work (see the grep pattern?) + # my guess it's because the path on webwork.math starts with + # /ww/ !!!!!! +# my $include = 'sub include { +# my ($file) = @_; +# my $fullPath = "'.$webworkRoot.'/$file"; +# # This regex matches any string that: +# # : begins with ../ +# # : ends with /.. +# # : contains /../, or +# # : is .. +# if ($fullPath =~ m!(?:^|/)..(?:/|$)!) { +# die "Included file $file has potentially insecure path: contains \"..\""; +# } else { +# local @INC = (); +# do $fullPath; +# } +# }'; + my $include = q[ sub include { + my ($file) = @_; + my $fullPath = "].$webworkRoot.q[/$file"; + # This regex matches any string that: + # : begins with ../ + # : ends with /.. + # : contains /../, or + # : is .. + if ($fullPath =~ m!(?:^|/)\.\.(?:/|$)!) { + die "Included file $file has potentially insecure path: contains \"..\""; + } else { + local @INC = (); + do $fullPath or die "\n\n Couldn't include $fullPath. Has it been created from a distribution file?\n\n"; + } + } ]; + + my $maskBackup = $safe->mask; + $safe->mask(empty_opset); + $safe->reval($include); + $safe->mask($maskBackup); + # determine location of globalEnvironmentFile my $globalEnvironmentFile = "$webworkRoot/conf/global.conf"; @@ -71,53 +131,51 @@ return $self; } -sub hash2string { - my $hr = shift; - my $indent = shift || 0; - my $result; - foreach (keys %$hr) { - $result .= "\t"x$indent . "{$_} ="; - if (ref $hr->{$_} eq 'HASH') { - $result .= "\n"; - $result .= hash2string($hr->{$_}, $indent+1); - } elsif (ref $hr->{$_} eq 'ARRAY') { - $result .= "\n"; - $result .= array2string($hr->{$_}, $indent+1); - } else { - $result .= " " . $hr->{$_} . "\n"; - } - } - return $result; -} +1; -sub array2string { - my $ar = shift; - my $indent = shift || 0; - my $result; - foreach (0 .. @$ar-1) { - $result .= "\t"x$indent . "[$_] ="; - if (ref $ar->[$_] eq 'HASH') { - $result .= "\n"; - $result .= hash2string($ar->[$_], $indent+1); - } elsif (ref $ar->[$_] eq 'ARRAY') { - $result .= "\n"; - $result .= array2string($ar->[$_], $indent+1); - } else { - $result .= " " . $ar->[$_] . "\n"; - } - } - return $result; -} +__END__ -# ----- utils ----- +=head1 SYNOPSIS -sub readFile { - my $fileName = shift; - open INPUTFILE, "<", $fileName - or return; #die "Couldn't open environment file $fileName: $!"; - my $result = join "\n", ; - close INPUTFILE; - return $result; -} + use WeBWorK::CourseEnvironment; + $courseEnv = WeBWorK::CourseEnvironment->new($webworkRoot, $courseName); + + $timeout = $courseEnv->{sessionKeyTimeout}; + $mode = $courseEnv->{pg}->{options}->{displayMode}; + # etc... -1; +=head1 DESCRIPTION + +The WeBWorK::CourseEnvironment module reads the system-wide F and +course-specific F files used by WeBWorK to calculate and store +settings needed throughout the system. The F<.conf> files are perl source files +that can contain any code allowed under the default safe compartment opset. +After evaluation of both files, any package variables are copied out of the +safe compartment into a hash. This hash becomes the course environment. + +=head1 CONSTRUCTION + +=over + +=item new (ROOT, COURSE) + +The C method finds the file F relative to the given ROOT +directory. After reading this file, it uses the C<$courseFiles{environment}> +variable, if present, to locate the course environment file. If found, the file +is read and added to the environment. + +=back + +=head1 ACCESS + +There are no formal accessor methods. However, since the course environemnt is +a hash of hashes and arrays, is exists as the self hash of an instance +variable: + + $courseEnvironment->{someKey}->{someOtherKey}; + +=head1 AUTHOR + +Written by Sam Hathaway, sh002i (at) math.rochester.edu. + +=cut