[system] / branches / rel-2-4-dev / webwork-modperl / lib / WeBWorK.pm Repository:
ViewVC logotype

View of /branches/rel-2-4-dev/webwork-modperl/lib/WeBWorK.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2638 - (download) (as text) (annotate)
Wed Aug 18 01:40:44 2004 UTC (8 years, 9 months ago) by sh002i
Original Path: trunk/webwork-modperl/lib/WeBWorK.pm
File size: 10543 byte(s)
added debugging header!

    1 ################################################################################
    2 # WeBWorK Online Homework Delivery System
    3 # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/
    4 # $CVSHeader: webwork2/lib/WeBWorK.pm,v 1.63 2004/07/12 02:30:23 sh002i Exp $
    5 #
    6 # This program is free software; you can redistribute it and/or modify it under
    7 # the terms of either: (a) the GNU General Public License as published by the
    8 # Free Software Foundation; either version 2, or (at your option) any later
    9 # version, or (b) the "Artistic License" which comes with this package.
   10 #
   11 # This program is distributed in the hope that it will be useful, but WITHOUT
   12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   13 # FOR A PARTICULAR PURPOSE.  See either the GNU General Public License or the
   14 # Artistic License for more details.
   15 ################################################################################
   16 
   17 package WeBWorK;
   18 
   19 =head1 NAME
   20 
   21 WeBWorK - Dispatch requests to the appropriate content generator.
   22 
   23 =head1 SYNOPSIS
   24 
   25  my $r = Apache->request;
   26  my $result = eval { WeBWorK::dispatch($r) };
   27  die "something bad happened: $@" if $@;
   28 
   29 =head1 DESCRIPTION
   30 
   31 C<WeBWorK> is the dispatcher for the WeBWorK system. Given an Apache request
   32 object, it performs authentication and determines which subclass of
   33 C<WeBWorK::ContentGenerator> to call.
   34 
   35 =cut
   36 
   37 BEGIN { $main::VERSION = "2.0"; }
   38 
   39 use strict;
   40 use warnings;
   41 use Apache::Constants qw(:common REDIRECT DONE);
   42 
   43 # load WeBWorK::Constants before anything else
   44 # this sets package variables in several packages
   45 use WeBWorK::Constants;
   46 
   47 # the rest of these are modules that are acutally used by this one
   48 use WeBWorK::Authen;
   49 use WeBWorK::Authz;
   50 use WeBWorK::CourseEnvironment;
   51 use WeBWorK::DB;
   52 use WeBWorK::Debug;
   53 use WeBWorK::Request;
   54 use WeBWorK::Timing;
   55 use WeBWorK::Upload;
   56 use WeBWorK::URLPath;
   57 use WeBWorK::Utils qw(runtime_use);
   58 
   59 use constant AUTHEN_MODULE => "WeBWorK::ContentGenerator::Login";
   60 use constant FIXDB_MODULE => "WeBWorK::ContentGenerator::FixDB";
   61 
   62 our %SeedCE;
   63 
   64 sub dispatch($) {
   65   my ($apache) = @_;
   66   my $r = new WeBWorK::Request $apache;
   67 
   68   my $method = $r->method;
   69   my $location = $r->location;
   70   my $uri = $r->uri;
   71   my $path_info = $r->path_info | "";
   72   my $args = $r->args || "";
   73   #my $webwork_root = $r->dir_config("webwork_root");
   74   #my $pg_root = $r->dir_config("pg_root");
   75 
   76   debug("\n\n===> Begin " . __PACKAGE__ . "::dispatch() <===\n\n");
   77   debug("Hi, I'm the new dispatcher!\n");
   78   debug(("-" x 80) . "\n");
   79 
   80   debug("Okay, I got some basic information:\n");
   81   debug("The apache location is $location\n");
   82   debug("The request method is $method\n");
   83   debug("The URI is $uri\n");
   84   debug("The path-info is $path_info\n");
   85   debug("The argument string is $args\n");
   86   #debug("The WeBWorK root directory is $webwork_root\n");
   87   #debug("The PG root directory is $pg_root\n");
   88   debug(("-" x 80) . "\n");
   89 
   90   debug("The first thing we need to do is munge the path a little:\n");
   91 
   92   my ($path) = $uri =~ m/$location(.*)/;
   93   $path = "/" if $path eq ""; # no path at all
   94 
   95   debug("We can't trust the path-info, so we make our own path.\n");
   96   debug("path-info claims: $path_info\n");
   97   debug("but it's really: $path\n");
   98   debug("(if it's empty, we set it to \"/\".)\n");
   99 
  100   $path =~ s|/+|/|g;
  101   debug("...and here it is without repeated slashes: $path\n");
  102 
  103   # lookbehind assertion for "not a slash"
  104   # matches the boundary after the last char
  105   $path =~ s|(?<=[^/])$|/|;
  106   debug("...and here it is with a trailing slash: $path\n");
  107 
  108   debug(("-" x 80) . "\n");
  109 
  110   debug("Now we need to look at the path a little to figure out where we are\n");
  111 
  112   debug("-------------------- call to WeBWorK::URLPath::newFromPath\n");
  113   my $urlPath = WeBWorK::URLPath->newFromPath($path);
  114   debug("-------------------- call to WeBWorK::URLPath::newFromPath\n");
  115 
  116   unless ($urlPath) {
  117     debug("This path is invalid... see you later!\n");
  118     die "The path '$path' is not valid.\n";
  119   }
  120 
  121   my $displayModule = $urlPath->module;
  122   my %displayArgs = $urlPath->args;
  123 
  124   debug("The display module for this path is: $displayModule\n");
  125   debug("...and here are the arguments we'll pass to it:\n");
  126   foreach my $key (keys %displayArgs) {
  127     debug("\t$key => $displayArgs{$key}\n");
  128   }
  129 
  130   unless ($displayModule) {
  131     debug("The display module is empty, so we can DECLINE here.\n");
  132     die "No display module found for this path.";
  133   }
  134 
  135   my $selfPath = $urlPath->path;
  136   my $parent = $urlPath->parent;
  137   my $parentPath = $parent ? $parent->path : "<no parent>";
  138 
  139   debug("Reconstructing the original path gets us: $selfPath\n");
  140   debug("And we can generate the path to our parent, too: $parentPath\n");
  141   debug("(We could also figure out who our children are, but we'd need to supply additional arguments.)\n");
  142   debug(("-" x 80) . "\n");
  143 
  144   debug("The URLPath looks good, we'll add it to the request.\n");
  145   $r->urlpath($urlPath);
  146 
  147   debug("Now we want to look at the parameters we got.\n");
  148 
  149   debug("The raw params:\n");
  150   foreach my $key ($r->param) {
  151     debug("\t$key\n");
  152     debug("\t\t$_\n") foreach $r->param($key);
  153   }
  154 
  155   #mungeParams($r);
  156 
  157   debug("The munged params:\n");
  158   foreach my $key ($r->param) {
  159     debug("\t$key\n");
  160     debug("\t\t$_\n") foreach $r->param($key);
  161   }
  162 
  163   debug(("-" x 80) . "\n");
  164 
  165   # create a package-global timing object
  166   # FIXME: this is used by other modules!
  167   # FIXME: this is not thread-safe!
  168   my $label = defined $displayArgs{courseID} ? $displayArgs{courseID} : "ROOT";
  169   $WeBWorK::timer = WeBWorK::Timing->new($label);
  170   $WeBWorK::timer->start;
  171 
  172   debug("We need to get a course environment (with or without a courseID!)\n");
  173   my $ce = eval { new WeBWorK::CourseEnvironment({
  174     #webworkRoot => $r->dir_config("webwork_root"),
  175     #webworkURLRoot => $location,
  176     #pgRoot => $r->dir_config("pg_root"),
  177     %SeedCE,
  178     courseName => $displayArgs{courseID},
  179   }) };
  180   $@ and die "Failed to initialize course environment: $@\n";
  181   debug("Here's the course environment: $ce\n");
  182   $r->ce($ce);
  183 
  184   my @uploads = $r->upload;
  185   foreach my $u (@uploads) {
  186     # make sure it's a "real" upload
  187     next unless $u->filename;
  188 
  189     # store the upload
  190     my $upload = WeBWorK::Upload->store($u,
  191       dir => $ce->{webworkDirs}->{uploadCache}
  192     );
  193 
  194     # store the upload ID and hash in the file upload field
  195     my $id = $upload->id;
  196     my $hash = $upload->hash;
  197     $r->param($u->name => "$id $hash");
  198   }
  199 
  200   my ($db, $authz);
  201 
  202   if ($displayArgs{courseID}) {
  203     debug("We got a courseID from the URLPath, now we can do some stuff:\n");
  204 
  205     unless (-e $ce->{courseDirs}->{root}) {
  206       die "Course '$displayArgs{courseID}' not found: $!";
  207     }
  208 
  209     debug("...we can create a database object...\n");
  210     $db = new WeBWorK::DB($ce->{dbLayout});
  211     debug("(here's the DB handle: $db)\n");
  212     $r->db($db);
  213 
  214     debug("Now we check the database...\n");
  215     debug("(we can detect if a hash-style database from WW1 has not be converted properly.)\n");
  216     my ($dbOK, @dbMessages) = $db->hashDatabaseOK(0); # 0 == don't fix
  217     if (not $dbOK) {
  218       debug("hashDatabaseOK() returned $dbOK -- looks like trouble...\n");
  219       $displayModule = FIXDB_MODULE;
  220       debug("set displayModule to $displayModule\n");
  221     } else {
  222       debug("hashDatabaseOK() returned $dbOK -- leaving displayModule as-is\n");
  223     }
  224 
  225     debug("...and now we can authenticate the remote user...\n");
  226     my $authen = new WeBWorK::Authen($r);
  227     my $authenOK = $authen->verify;
  228     if ($authenOK) {
  229       debug("Hi, ", $r->param("user"), ", glad you made it.\n");
  230 
  231       debug("Authentication succeeded, so it makes sense to create an authz object...\n");
  232       $authz = new WeBWorK::Authz($r, $ce, $db);
  233       debug("(here's the authz object: $authz)\n");
  234       $r->authz($authz);
  235 
  236       debug("Now we deal with the effective user:\n");
  237       my $userID = $r->param("user");
  238       my $eUserID = $r->param("effectiveUser") || $userID;
  239       debug("userID=$userID eUserID=$eUserID\n");
  240       my $su_authorized = $authz->hasPermissions($userID, "become_student", $eUserID);
  241       if ($su_authorized) {
  242         debug("Ok, looks like you're allowed to become $eUserID. Whoopie!\n");
  243       } else {
  244         debug("Uh oh, you're not allowed to become $eUserID. Nice try!\n");
  245         $eUserID = $userID;
  246       }
  247       $r->param("effectiveUser" => $eUserID);
  248     } else {
  249       debug("Bad news: authentication failed!\n");
  250       $displayModule = AUTHEN_MODULE;
  251       debug("set displayModule to $displayModule\n");
  252     }
  253   }
  254 
  255   ## if a course ID was given in the URL and resulted in an error (as stored in $!)
  256   ## it probably means that the course does not exist or was misspelled
  257   #if ($displayArgs{courseID} and $ce->{'!'}) {
  258   # debug("Something was wrong with the courseID: \n");
  259   # debug("\t\t" . $ce->{'!'} . "\n");
  260   # debug("Time to bail!\n");
  261   # die "An error occured while accessing '$displayArgs{courseID}': '", $ce->{'!'}, "'.\n";
  262   #}
  263 
  264   debug(("-" x 80) . "\n");
  265   debug("Finally, we'll load the display module...\n");
  266 
  267   runtime_use($displayModule);
  268 
  269   debug("...instantiate it...\n");
  270 
  271   my $instance = $displayModule->new($r);
  272 
  273   debug("...and call it:\n");
  274   debug("-------------------- call to ${displayModule}::go\n");
  275 
  276   my $result = $instance->go();
  277 
  278   debug("-------------------- call to ${displayModule}::go\n");
  279 
  280   debug("returning result: " . (defined $result ? $result : "UNDEF") . "\n");
  281 
  282   $WeBWorK::timer->save();
  283 
  284   return $result;
  285 
  286 }
  287 
  288 sub mungeParams {
  289   my ($r) = @_;
  290 
  291   my @paramQueue;
  292 
  293   # remove all the params from the request, and store them in the param queue
  294   foreach my $key ($r->param) {
  295     push @paramQueue, [ $key => [ $r->param($key) ] ];
  296     $r->parms->unset($key)
  297   }
  298 
  299   # exhaust the param queue, decoding encoded params
  300   while (@paramQueue) {
  301     my ($key, $values) = @{ shift @paramQueue };
  302 
  303     if ($key =~ m/\,/) {
  304       # we have multiple params encoded in a single param
  305       # split them up and add them to the end of the queue
  306       push @paramQueue, map { [ $_, $values ] } split m/\,/, $key;
  307     } elsif ($key =~ m/\:/) {
  308       # we have a whole param encoded in a key
  309       # split it up and add it to the end of the queue
  310       my ($newKey, $newValue) = split m/\:/, $key;
  311       push @paramQueue, [ $newKey, [ $newValue ] ];
  312     } else {
  313       # this is a "normal" param
  314       # add it to the param list
  315       if (defined $r->param($key)) {
  316         # the param already exists -- append the values we have
  317         $r->param($key => [ $r->param($key), @$values ]);
  318       } else {
  319         # the param doesn't exist -- create it with the values we have
  320         $r->param($key => $values);
  321       }
  322     }
  323   }
  324 }
  325 
  326 
  327 =head1 AUTHOR
  328 
  329 Written by Dennis Lambe, malsyned at math.rochester.edu. Modified by Sam
  330 Hathaway, sh002i at math.rochester.edu.
  331 
  332 =cut
  333 
  334 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9