[system] / branches / rel-2-3-dev / webwork2 / lib / WeBWorK / Authz.pm Repository:
ViewVC logotype

View of /branches/rel-2-3-dev/webwork2/lib/WeBWorK/Authz.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4396 - (download) (as text) (annotate)
Thu Aug 24 21:07:52 2006 UTC (6 years, 9 months ago)
File size: 7127 byte(s)
This commit was manufactured by cvs2svn to create branch 'rel-2-3-dev'.

    1 ################################################################################
    2 # WeBWorK Online Homework Delivery System
    3 # Copyright © 2000-2006 The WeBWorK Project, http://openwebwork.sf.net/
    4 # $CVSHeader$
    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::Authz;
   18 
   19 =head1 NAME
   20 
   21 WeBWorK::Authz - check user permissions.
   22 
   23 =head1 SYNOPSIS
   24 
   25  # create new authorizer -- $r is a WeBWorK::Request object.
   26  my $authz = new WeBWorK::Authz($r);
   27 
   28  # tell authorizer to cache permission level of user spammy.
   29  $authz->setCachedUser("spammy");
   30 
   31  # this call will use the cached data.
   32  if ($authz->hasPermissions("spammy", "eat_breakfast")) {
   33   eat_breakfast();
   34  }
   35 
   36  # this call will not use the cached data, and will cause a database lookup.
   37  if ($authz->hasPermissions("hammy", "go_to_bed")) {
   38   go_to_bed();
   39  }
   40 
   41 =head1 DESCRIPTION
   42 
   43 WeBWorK::Authen determines if a user is authorized to perform a specific
   44 activity, based on the user's PermissionLevel record in the WeBWorK database and
   45 the contents of the %permissionLevels hash in the course environment.
   46 
   47 =head2 Format of the %permissionLevels hash
   48 
   49 %permissionLevels maps text strings describing activities to numeric permission
   50 levels. The definitive list of activities is contained in the default version of
   51 %permissionLevels, in the file F<conf/global.conf.dist>.
   52 
   53 A user is able to engage in an activity if their permission level is greater
   54 than or equal to the level associated with the activity. If the level associated
   55 with an activity is undefiend, then no user is permitted to perform the
   56 activity, regardless of their permission level.
   57 
   58 =cut
   59 
   60 use strict;
   61 use warnings;
   62 use Carp qw/croak/;
   63 
   64 ################################################################################
   65 
   66 =head1 CONSTRUCTOR
   67 
   68 =over
   69 
   70 =item WeBWorK::Authz->new($r)
   71 
   72 Creates a new authorizer instance. $r is a WeBWorK::Request object. It must
   73 already have its C<ce> and C<db> fields set.
   74 
   75 =cut
   76 
   77 sub new {
   78   my ($invocant, $r) = @_;
   79   my $class = ref($invocant) || $invocant;
   80   my $self = {
   81     r => $r,
   82   };
   83 
   84   bless $self, $class;
   85   return $self;
   86 }
   87 
   88 =back
   89 
   90 =cut
   91 
   92 ################################################################################
   93 
   94 =head1 METHODS
   95 
   96 =over
   97 
   98 =item setCachedUser($userID)
   99 
  100 Caches the PermissionLevel of the user $userID in an existing authorizer. If a
  101 user's PermissionLevel is cached, it will be used whenever hasPermissions() is
  102 called on the same user. Only one user can be cached at a time. This is used by
  103 WeBWorK to cache the "real" user.
  104 
  105 =cut
  106 
  107 sub setCachedUser {
  108   my ($self, $userID) = @_;
  109   my $r = $self->{r};
  110   my $db = $r->db;
  111 
  112   delete $self->{userID};
  113   delete $self->{PermissionLevel};
  114 
  115   if (defined $userID) {
  116     $self->{userID} = $userID;
  117     my $PermissionLevel = $db->getPermissionLevel($userID); # checked
  118     if (defined $PermissionLevel) {
  119       # store permission level record in database to avoid later database calls
  120       $self->{PermissionLevel} = $PermissionLevel;
  121     }
  122   } else {
  123     warn "setCachedUser() called with userID undefined.";
  124   }
  125 }
  126 
  127 =item hasPermissions($userID, $activity)
  128 
  129 Checks the %permissionLevels hash in the course environment to determine if the
  130 user $userID has permission to engage in the activity $activity. If the user's
  131 permission level is greater than or equal to the level associated with $activty,
  132 a true value is returned. Otherwise, a false value is returned.
  133 
  134 If $userID has been cached using the setCachedUser() call, the cached data is
  135 used. Otherwise, the user's PermissionLevel is looked up in the WeBWorK
  136 database.
  137 
  138 If the user does not have a PermissionLevel record, the permission level record
  139 is empty, or the activity does not appear in %permissionLevels, hasPermissions()
  140 assumes that the user does not have permission.
  141 
  142 =cut
  143 
  144 # This currently only uses two of it's arguments, but it accepts any number, in
  145 # case in the future calculating certain permissions requires more information.
  146 sub hasPermissions {
  147   if (@_ != 3) {
  148     shift @_; # get rid of self
  149     my $nargs = @_;
  150     croak "hasPermissions called with $nargs arguments instead of the expected 2: '@_'"
  151   }
  152 
  153   my ($self, $userID, $activity) = @_;
  154   my $r = $self->{r};
  155   my $ce = $r->ce;
  156   my $db = $r->db;
  157 
  158   # this may need to be changed if we get other permission level data sources
  159   return 0 unless defined $db;
  160 
  161   # this may need to be changed if we want to control what unauthenticated users
  162   # can do with the permissions system
  163   return 0 unless defined $userID and $userID ne "";
  164 
  165   my $PermissionLevel;
  166 
  167   my $cachedUserID = $self->{userID};
  168   if (defined $cachedUserID and $cachedUserID ne "" and $cachedUserID eq $userID) {
  169     # this is the same user -- we can skip the database call
  170     $PermissionLevel = $self->{PermissionLevel};
  171   } else {
  172     # a different user, or no user was defined before
  173     #my $prettyCachedUserID = defined $cachedUserID ? "'$cachedUserID'" : "undefined";
  174     #warn "hasPermissions called with user '$userID', but cached user is $prettyCachedUserID. Accessing database.\n";
  175     $PermissionLevel = $db->getPermissionLevel($userID); # checked
  176   }
  177 
  178   my $permission_level;
  179 
  180   if (defined $PermissionLevel) {
  181     $permission_level = $PermissionLevel->permission;
  182   } else {
  183     # uh, oh. this user has no permission level record!
  184     warn "User '$userID' has no PermissionLevel record -- assuming no permission.";
  185     return 0;
  186   }
  187 
  188   unless (defined $permission_level and $permission_level ne "") {
  189     warn "User '$userID' has empty permission level -- assuming no permission.";
  190     return 0;
  191   }
  192 
  193   my $userRoles = $ce->{userRoles};
  194   my $permissionLevels = $ce->{permissionLevels};
  195 
  196   if (exists $permissionLevels->{$activity}) {
  197     my $activity_role = $permissionLevels->{$activity};
  198     if (defined $activity_role) {
  199       if (exists $userRoles->{$activity_role}) {
  200         my $role_permlevel = $userRoles->{$activity_role};
  201         if (defined $role_permlevel) {
  202           return $permission_level >= $role_permlevel;
  203         } else {
  204           warn "Role '$activity_role' has undefined permisison level -- assuming no permission.";
  205           return 0;
  206         }
  207       } else {
  208         warn "Role '$activity_role' for activity '$activity' not found in \%userRoles -- assuming no permission.";
  209         return 0;
  210       }
  211     } else {
  212       return 0; # undefiend $activity_role, no one has permission to perform $activity
  213     }
  214   } else {
  215     warn "Activity '$activity' not found in \%permissionLevels -- assuming no permission.";
  216     return 0;
  217   }
  218 }
  219 
  220 =back
  221 
  222 =cut
  223 
  224 =head1 AUTHOR
  225 
  226 Written by Dennis Lambe, malsyned at math.rochester.edu. Modified by Sam
  227 Hathaway, sh002i at math.rochester.edu.
  228 
  229 =cut
  230 
  231 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9