--- loncom/homework/grades.pm	2003/06/18 18:59:20	1.101
+++ loncom/homework/grades.pm	2003/06/20 21:45:20	1.105
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # The LON-CAPA Grading handler
 #
-# $Id: grades.pm,v 1.101 2003/06/18 18:59:20 albertel Exp $
+# $Id: grades.pm,v 1.105 2003/06/20 21:45:20 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -49,6 +49,7 @@ use Apache::Constants qw(:common);
 use String::Similarity;
 
 my %oldessays=();
+my %perm=();
 
 # ----- These first few routines are general use routines.----
 #
@@ -135,53 +136,60 @@ sub getclasslist {
 	    }
 	}
 	$section = ($section ne '' ? $section : 'no');
-	if ($getsec eq 'all' || $getsec eq $section) {
-            $sections{$section}++;
-            $fullnames{$_}=$fullname;
-        } else {
-            delete($classlist->{$_});
-        }
+	if (1 || &canview($section)) {
+	    if ($getsec eq 'all' || $getsec eq $section) {
+		$sections{$section}++;
+		$fullnames{$_}=$fullname;
+	    } else {
+		delete($classlist->{$_});
+	    }
+	} else {
+	    delete($classlist->{$_});
+	}
     }
     my %seen = ();
     my @sections = sort(keys(%sections));
     return ($classlist,\@sections,\%fullnames);
 }
 
-#find user domain
-sub finduser {
-    my ($name) = @_;
-    my $domain = '';
-    if ( $Apache::grades::viewgrades eq 'F' ) {
-	my %classlist=&Apache::lonnet::dump('classlist',
-					    $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
-					    $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
-	my (@fields) = grep /^$name:/, keys %classlist;
-	($name, $domain) = split(/:/,$fields[0]);
-	return ($name,$domain);
-    } else {
-	return ($ENV{'user.name'},$ENV{'user.domain'});
+sub canmodify {
+    my ($sec)=@_;
+    if ($perm{'mgr'}) {
+	if (!defined($perm{'mgr_section'})) {
+	    # can modify whole class
+	    return 1;
+	} else {
+	    if ($sec eq $perm{'mgr_section'}) {
+		#can modify the requested section
+		return 1;
+	    } else {
+		# can't modify the request section
+		return 0;
+	    }
+	}
     }
+    #can't modify
+    return 0;
 }
 
-#--- Prompts a user to enter a username.
-sub moreinfo {
-    my ($request,$reason) = @_;
-    $request->print("Unable to process request: $reason");
-    if ( $Apache::grades::viewgrades eq 'F' ) {
-	$request->print('<form action="/adm/grades" method="post">'."\n");
-	if ($ENV{'form.url'}) {
-	    $request->print('<input type="hidden" name="url" value="'.$ENV{'form.url'}.'" />'."\n");
-	}
-	if ($ENV{'form.symb'}) {
-	    $request->print('<input type="hidden" name="symb" value="'.$ENV{'form.symb'}.'" />'."\n");
-	}
-	$request->print('<input type="hidden" name="command" value="'.$ENV{'form.command'}.'" />'."\n");
-	$request->print("Student:".'<input type="text" name="student" value="'.$ENV{'form.student'}.'" />'."<br />\n");
-	$request->print("Domain:".'<input type="text" name="domain" value="'.$ENV{'user.domain'}.'" />'."<br />\n");
-	$request->print('<input type="submit" name="submit" value="ReSubmit" />'."<br />\n");
-	$request->print('</form>');
+sub canview {
+    my ($sec)=@_;
+    if ($perm{'vgr'}) {
+	if (!defined($perm{'vgr_section'})) {
+	    # can modify whole class
+	    return 1;
+	} else {
+	    if ($sec eq $perm{'vgr_section'}) {
+		#can modify the requested section
+		return 1;
+	    } else {
+		# can't modify the request section
+		return 0;
+	    }
+	}
     }
-    return '';
+    #can't modify
+    return 0;
 }
 
 #--- Retrieve the grade status of a student for all the parts
@@ -446,7 +454,7 @@ LISTJAVASCRIPT
 	next if ($statusflg eq '' && $submitonly eq 'yes');
 
 	$ctr++;
-	if ( $Apache::grades::viewgrades eq 'F' ) {
+	if ( $perm{'vgr'} eq 'F' ) {
 	    $gradeTable.='<tr bgcolor="#ffffe6">'.
 		'<td align="center"><input type=checkbox name="stuinfo" value="'.
 		$student.':'.$$fullname{$student}.'"></td>'."\n".
@@ -1050,11 +1058,18 @@ sub submission {
 
     (my $url=$ENV{'form.url'})=~s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
     my ($uname,$udom)     = ($ENV{'form.student'},$ENV{'form.userdom'});
-    ($uname,$udom)        = &finduser($uname) if $udom eq '';
+    my $usec = &Apache::lonnet::getsection($udom,$uname,$ENV{'request.course.id'});
     $ENV{'form.fullname'} = &get_fullname ($uname,$udom) if $ENV{'form.fullname'} eq '';
 
     my $symb=($ENV{'form.symb'} ne '' ? $ENV{'form.symb'} : (&Apache::lonnet::symbread($url)));
     if ($symb eq '') { $request->print("Unable to handle ambiguous references:$url:."); return ''; }
+
+    if (!&canview($usec)) {
+	$request->print('<font color="red">Unable to view requested student.('.$uname.$udom.$usec.$ENV{'request.course.id'}.')</font>');
+	$request->print(&show_grading_menu_form($symb,$url));
+	return;
+    }
+
     my $last = ($ENV{'form.lastSub'} eq 'last' ? 'last' : '');
 
     # header info
@@ -1288,7 +1303,7 @@ KEYWORDS
     }
     
     # return if view submission with no grading option
-    if ($ENV{'form.showgrading'} eq '') {
+    if ($ENV{'form.showgrading'} eq '' || (!&canmodify($usec))) {
 	$request->print('</td></tr></table></td></tr></table></form>'."\n");
 	$request->print(&show_grading_menu_form($symb,$url)) 
 	    if (($ENV{'form.command'} eq 'submission') || 
@@ -1432,6 +1447,11 @@ sub processHandGrade {
 		$ctr++;
 		next;
 	    }
+	    if ($errorflag eq 'not_allowed') {
+		$request->print("<font color=\"red\">Not allowed to modify grades for $uname:$udom</font>");
+		$ctr++;
+		next;
+	    }
 	    my $includemsg = $ENV{'form.includemsg'.$ctr};
 	    my ($subject,$message,$msgstatus) = ('','','');
 	    if ($includemsg =~ /savemsg|newmsg\Q$ctr\E/) {
@@ -1451,12 +1471,16 @@ sub processHandGrade {
 	    if ($ENV{'form.collaborator'.$ctr}) {
 		my (@collaborators) = split(/:/,$ENV{'form.collaborator'.$ctr});
 		foreach (@collaborators) {
-		    &saveHandGrade($request,$url,$symb,$_,$udom,$ctr,
-				   $ENV{'form.unamedom'.$ctr});
-		    if ($message ne '') {
-			$msgstatus = &Apache::lonmsg::user_normal_msg ($_,$udom,
-								       $ENV{'form.msgsub'},
-								       $message);
+		    my ($errorflag,$pts,$wgt) = &saveHandGrade($request,$url,$symb,$_,$udom,$ctr,$ENV{'form.unamedom'.$ctr});
+		    if ($errorflag eq 'not_allowed') {
+			$request->print("<font color=\"red\">Not allowed to modify grades for $_:$udom</font>");
+			next;
+		    } else {
+			if ($message ne '') {
+			    $msgstatus = &Apache::lonmsg::user_normal_msg ($_,$udom,
+									   $ENV{'form.msgsub'},
+									   $message);
+			}
 		    }
 		}
 	    }
@@ -1589,6 +1613,9 @@ sub processHandGrade {
 #---- Save the score and award for each student, if changed
 sub saveHandGrade {
     my ($request,$url,$symb,$stuname,$domain,$newflg,$submitter) = @_;
+    my $usec = &Apache::lonnet::getsection($domain,$stuname,
+					   $ENV{'request.course.id'});
+    if (!&canmodify($usec)) { return('not_allowed'); }
     my %record     = &Apache::lonnet::restore($symb,$ENV{'request.course.id'},$domain,$stuname);
     my %newrecord  = ();
     my ($pts,$wgt) = ('','');
@@ -1820,7 +1847,7 @@ sub viewgrades {
 
     #beginning of class grading form
     $result.= '<form action="/adm/grades" method="post" name="classgrade">'."\n".
-	'<input type="hidden" name="symb"    value="'.$symb.'" />'."\n".
+	'<input type="hidden" name="symb"    value="'.$symb.'" /resu\n".
 	'<input type="hidden" name="url"     value="'.$url.'" />'."\n".
 	'<input type="hidden" name="command" value="editgrades" />'."\n".
 	'<input type="hidden" name="section" value="'.$ENV{'form.section'}.'" />'."\n".
@@ -2053,10 +2080,15 @@ sub editgrades {
 	my ($uname,$udom)=split(/_/,$user);
 	my %newrecord;
 	my $updateflag = 0;
-
 	$line .= '<tr bgcolor="#ffffde"><td>'.$uname.'&nbsp;</td><td>'.
 	    $udom.'&nbsp;</td><td>'.
 		$$fullname{$usercolon}.'&nbsp;</td>';
+	my $usec=%$classlist->{"$uname:$udom"}[5];
+	if (!&canmodify($usec)) {
+	    my $numcols=scalar(@partid)*(scalar(@parts)-1)*2;
+	    $noupdate.=$line."<td colspan=\"$numcols\"><font color=\"red\">Not allowed to modify student</font></td></tr>";
+	    next;
+	}
 	foreach (@partid) {
 	    my $old_aw    = $ENV{'form.GD_'.$user.'_'.$_.'_awarded_s'};
 	    my $old_part_pcr = $old_aw/($weight{$_} ne '0' ? $weight{$_}:1);
@@ -2114,7 +2146,8 @@ sub editgrades {
 	}
     }
     if ($noupdate) {
-	$result .= '<tr bgcolor="#ffffff"><td align="center" colspan="7">No Changes Occured For the Students Below</td></tr>'.$noupdate;
+	my $numcols=(scalar(@partid)*(scalar(@parts)-1)*2)+3;
+	$result .= '<tr bgcolor="#ffffff"><td align="center" colspan="'.$numcols.'">No Changes Occured For the Students Below</td></tr>'.$noupdate;
     }
     $result .= '</table></td></tr></table>'."\n".
 	&show_grading_menu_form ($symb,$url);
@@ -2523,6 +2556,7 @@ LISTJAVASCRIPT
 	'<input type="radio" name="lastSub" value="all" /> all details'."\n";
 
     $result.='<input type="hidden" name="section"     value="'.$getsec.'" />'."\n".
+	'<input type="hidden" name="status"     value="'.$ENV{'form.status'}.'" />'."\n".
 	'<input type="hidden" name="command" value="displayPage" />'."\n".
 	'<input type="hidden" name="url"     value="'.$url.'" />'."\n".
 	'<input type="hidden" name="symb"    value="'.$symb.'" />'."\n".
@@ -2630,9 +2664,14 @@ sub displayPage {
     my $cnum      = $ENV{"course.$ENV{'request.course.id'}.num"};
     my $getsec    = $ENV{'form.section'} eq '' ? 'all' : $ENV{'form.section'};
     my $pageTitle = $ENV{'form.page'};
-    my (undef,undef,$fullname) = &getclasslist($getsec,'1');
+    my ($classlist,undef,$fullname) = &getclasslist($getsec,'1');
     my ($uname,$udom) = split(/:/,$ENV{'form.student'});
-
+    my $usec=$classlist->{$ENV{'form.student'}}[5];
+    if (!&canview($usec)) {
+	$request->print('<font color="red">Unable to view requested student.('.$ENV{'form.student'}.')</font>');
+	$request->print(&show_grading_menu_form($symb,$url));
+	return;
+    }
     my $result='<h3><font color="#339933">&nbsp;'.$ENV{'form.title'}.'</font></h3>';
     $result.='<h3>&nbsp;Student: '.$$fullname{$ENV{'form.student'}}.
 	'<font color="#999999"> ('.$uname.($udom eq $cdom ? '':':'.$udom).')</font></h3>'."\n";
@@ -2745,15 +2784,16 @@ sub displayPage {
 									'','.submission');
  
 	    }
-
-	    foreach my $partid (@{$parts}) {
-		$studentTable.=&gradeBox($request,$symbx,$uname,$udom,$question,$partid,\%record);
-		$studentTable.='<input type="hidden" name="q_'.$question.'" value="'.$partid.'" />'."\n";
-		$question++;
+	    if (&canmodify($usec)) {
+		foreach my $partid (@{$parts}) {
+		    $studentTable.=&gradeBox($request,$symbx,$uname,$udom,$question,$partid,\%record);
+		    $studentTable.='<input type="hidden" name="q_'.$question.'" value="'.$partid.'" />'."\n";
+		    $question++;
+		}
 	    }
 	    $studentTable.='</td></tr>';
 
-       }
+	}
         $curRes = $iterator->next();
     }
 
@@ -2776,9 +2816,14 @@ sub updateGradeByPage {
     my $cnum      = $ENV{"course.$ENV{'request.course.id'}.num"};
     my $getsec    = $ENV{'form.section'} eq '' ? 'all' : $ENV{'form.section'};
     my $pageTitle = $ENV{'form.page'};
-    my (undef,undef,$fullname) = &getclasslist($getsec,'1');
+    my ($classlist,undef,$fullname) = &getclasslist($getsec,'1');
     my ($uname,$udom) = split(/:/,$ENV{'form.student'});
-
+    my $usec=$classlist->{$ENV{'form.student'}}[5];
+    if (!&canmodify($usec)) {
+	$request->print('<font color="red">Unable to modify requested student.('.$ENV{'form.student'}.'</font>');
+	$request->print(&show_grading_menu_form($ENV{'form.symb'},$ENV{'form.url'}));
+	return;
+    }
     my $result='<h3><font color="#339933">&nbsp;'.$ENV{'form.title'}.'</font></h3>';
     $result.='<h3>&nbsp;Student: '.$$fullname{$ENV{'form.student'}}.
 	'<font color="#999999"> ('.$uname.($udom eq $cdom ? '':':'.$udom).')</font></h3>'."\n";
@@ -3396,7 +3441,8 @@ GRADINGMENUJS
 
 sub handler {
     my $request=$_[0];
-    
+
+    undef(%perm);
     if ($ENV{'browser.mathml'}) {
 	$request->content_type('text/xml');
     } else {
@@ -3441,24 +3487,41 @@ sub handler {
 	    }
 	}
     } else {
-	$Apache::grades::viewgrades=&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'});
-	if ($command eq 'submission') {
+	if (!($perm{'vgr'}=&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'}))) {
+	    if ($perm{'vgr'}=&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'}.'/'.$ENV{'request.course.sec'})) {
+		$perm{'vgr_section'}=$ENV{'request.course.sec'};
+	    } else {
+		delete($perm{'vgr'});
+	    }
+	}
+	if (!($perm{'mgr'}=&Apache::lonnet::allowed('mgr',$ENV{'request.course.id'}))) {
+	    if ($perm{'mgr'}=&Apache::lonnet::allowed('mgr',$ENV{'request.course.id'}.'/'.$ENV{'request.course.sec'})) {
+		$perm{'mgr_section'}=$ENV{'request.course.sec'};
+	    } else {
+		delete($perm{'mgr'});
+	    }
+	}
+	#delete($perm{'mgr'});
+	#$Apache::lonxml::debug=1;
+	#&Apache::lonxml::debug("command is $command");
+
+	if ($command eq 'submission' && $perm{'vgr'}) {
 	    ($ENV{'form.student'} eq '' ? &listStudents($request) : &submission($request,0,0));
-	} elsif ($command eq 'pickStudentPage') {
+	} elsif ($command eq 'pickStudentPage' && $perm{'vgr'}) {
 	    &pickStudentPage($request);
-	} elsif ($command eq 'displayPage') {
+	} elsif ($command eq 'displayPage' && $perm{'vgr'}) {
 	    &displayPage($request);
-	} elsif ($command eq 'gradeByPage') {
+	} elsif ($command eq 'gradeByPage' && $perm{'mgr'}) {
 	    &updateGradeByPage($request);
-	} elsif ($command eq 'processGroup') {
+	} elsif ($command eq 'processGroup' && $perm{'vgr'}) {
 	    &processGroup($request);
-	} elsif ($command eq 'gradingmenu') {
+	} elsif ($command eq 'gradingmenu' && $perm{'vgr'}) {
 	    $request->print(&gradingmenu($request));
-	} elsif ($command eq 'viewgrades') {
+	} elsif ($command eq 'viewgrades' && $perm{'vgr'}) {
 	    $request->print(&viewgrades($request));
-	} elsif ($command eq 'handgrade') {
+	} elsif ($command eq 'handgrade' && $perm{'mgr'}) {
 	    $request->print(&processHandGrade($request));
-	} elsif ($command eq 'editgrades') {
+	} elsif ($command eq 'editgrades' && $perm{'mgr'} ) {
 	    $request->print(&editgrades($request));
 	} elsif ($command eq 'verify') {
 	    $request->print(&verifyreceipt($request));