You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(58) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(53) |
Feb
(56) |
Mar
|
Apr
|
May
(30) |
Jun
(78) |
Jul
(121) |
Aug
(155) |
Sep
(77) |
Oct
(61) |
Nov
(45) |
Dec
(94) |
2006 |
Jan
(116) |
Feb
(33) |
Mar
(11) |
Apr
(23) |
May
(60) |
Jun
(89) |
Jul
(130) |
Aug
(109) |
Sep
(124) |
Oct
(63) |
Nov
(82) |
Dec
(45) |
2007 |
Jan
(31) |
Feb
(35) |
Mar
(123) |
Apr
(36) |
May
(18) |
Jun
(134) |
Jul
(133) |
Aug
(241) |
Sep
(126) |
Oct
(31) |
Nov
(15) |
Dec
(5) |
2008 |
Jan
(11) |
Feb
(6) |
Mar
(16) |
Apr
(29) |
May
(43) |
Jun
(149) |
Jul
(27) |
Aug
(29) |
Sep
(37) |
Oct
(20) |
Nov
(4) |
Dec
(6) |
2009 |
Jan
(34) |
Feb
(30) |
Mar
(16) |
Apr
(6) |
May
(1) |
Jun
(32) |
Jul
(22) |
Aug
(7) |
Sep
(18) |
Oct
(50) |
Nov
(22) |
Dec
(8) |
2010 |
Jan
(17) |
Feb
(15) |
Mar
(10) |
Apr
(9) |
May
(67) |
Jun
(30) |
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
(1) |
Dec
|
From: Sam H. v. a. <we...@ma...> - 2005-11-16 22:05:41
|
Log Message: ----------- back out of overflow:auto feature since it makes mozilla unhappy sometimes. Modified Files: -------------- webwork2/htdocs/css: ur.css Revision Data ------------- Index: ur.css =================================================================== RCS file: /webwork/cvs/system/webwork2/htdocs/css/ur.css,v retrieving revision 1.11 retrieving revision 1.12 diff -Lhtdocs/css/ur.css -Lhtdocs/css/ur.css -u -r1.11 -r1.12 --- htdocs/css/ur.css +++ htdocs/css/ur.css @@ -15,7 +15,10 @@ div.Logo { } div.Links { font-size: small; } -div.Siblings { font-size: small; height: 10em; overflow: auto; } +/* we used to say "overflow: auto" here, but it caused problems for + * mozilla. so we're back to having a looong siblings list for the time + * being. :-( */ +div.Siblings { font-size: small; height: 10em; } div.Options { font-size: small; } /* top table cell, contains login message and path */ |
From: Mike G. v. a. <we...@ma...> - 2005-11-12 01:32:56
|
Log Message: ----------- Roll back my changes. Use Davide's method of detecting the preview Button Modified Files: -------------- pg/macros: PGanswermacros.pl Revision Data ------------- Index: PGanswermacros.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/PGanswermacros.pl,v retrieving revision 1.46 retrieving revision 1.47 diff -Lmacros/PGanswermacros.pl -Lmacros/PGanswermacros.pl -u -r1.46 -r1.47 --- macros/PGanswermacros.pl +++ macros/PGanswermacros.pl @@ -2036,18 +2036,16 @@ sub { my $rh_ans = shift; $rh_ans->{_filter_name} = "produce_equivalence_message"; - my $preview_mode_flag = $inputs_ref->{previewAnswers}; - $preview_mode_flag = defined($preview_mode_flag) and $preview_mode_flag; - # no message if no duplication - return $rh_ans unless $rh_ans->{prev_equals_current}; - - if ($preview_mode_flag) { #previews generate warning message always - $rh_ans->{ans_message} = "This answer is equivalent to the one you just submitted or previewed."; - } elsif ($rh_ans->{score} != 1) {# non correct answers generate warning message - $rh_ans->{ans_message} = "This answer is equivalent to the one you just submitted or previewed."; - } else { # correct answers in submit mode don't generate warning messages. - - } + return $rh_ans unless $rh_ans->{prev_equals_current} && + ($rh_ans->{score} != 1 || $rh_ans->{isPreview}); + # + # If the match is exact don't give an error since there may be multiple + # entry blanks and the student is trying to get one of the other ones + # right. We should only give this message when the student is actually + # working on this answer. + # + return $rh_ans if $rh_ans->{prev_ans} eq $rh_ans->{original_student_ans}; + $rh_ans->{ans_message} = "This answer is equivalent to the one you just submitted or previewed."; $rh_ans; } ); |
From: Mike G. v. a. <we...@ma...> - 2005-11-12 01:00:41
|
Log Message: ----------- Check to see if $inputs_ref->{previewAnswers} is defined. If it is then the preview button has been pressed. In this case emit a warning if the answer has been given previously regardless of whether the answer is correct or incorrect. The warning message indicates that the previous matching answer might have been either a preview or a submitted answer. Let's see how this works. Modified Files: -------------- pg/macros: PGanswermacros.pl Revision Data ------------- Index: PGanswermacros.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/PGanswermacros.pl,v retrieving revision 1.45 retrieving revision 1.46 diff -Lmacros/PGanswermacros.pl -Lmacros/PGanswermacros.pl -u -r1.45 -r1.46 --- macros/PGanswermacros.pl +++ macros/PGanswermacros.pl @@ -2036,16 +2036,18 @@ sub { my $rh_ans = shift; $rh_ans->{_filter_name} = "produce_equivalence_message"; - return $rh_ans unless $rh_ans->{prev_equals_current} && - ($rh_ans->{score} != 1 || $rh_ans->{isPreview}); - # - # If the match is exact don't give an error since there may be multiple - # entry blanks and the student is trying to get one of the other ones - # right. We should only give this message when the student is actually - # working on this answer. - # - return $rh_ans if $rh_ans->{prev_ans} eq $rh_ans->{original_student_ans}; - $rh_ans->{ans_message} = "This answer is equivalent to the one you just submitted or previewed."; + my $preview_mode_flag = $inputs_ref->{previewAnswers}; + $preview_mode_flag = defined($preview_mode_flag) and $preview_mode_flag; + # no message if no duplication + return $rh_ans unless $rh_ans->{prev_equals_current}; + + if ($preview_mode_flag) { #previews generate warning message always + $rh_ans->{ans_message} = "This answer is equivalent to the one you just submitted or previewed."; + } elsif ($rh_ans->{score} != 1) {# non correct answers generate warning message + $rh_ans->{ans_message} = "This answer is equivalent to the one you just submitted or previewed."; + } else { # correct answers in submit mode don't generate warning messages. + + } $rh_ans; } ); |
From: dpvc v. a. <we...@ma...> - 2005-11-12 00:51:50
|
Log Message: ----------- Take care of the issue where Preview could be used to gather information about whether an answer is correct by using the "this answer is the same as the previous one" message. Now if Preview is used, the warning is given whether the answer is right or not. (Maybe it is not necessary to check for correct at all, since that was there to prevent the message from being issued when there are multiple answer blanks and the student is working on other ones. But the exact match check will take care of those. Should the message be issued if the student changes a correct answer to an equivalent one?) Modified Files: -------------- pg/macros: PGanswermacros.pl Revision Data ------------- Index: PGanswermacros.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/PGanswermacros.pl,v retrieving revision 1.44 retrieving revision 1.45 diff -Lmacros/PGanswermacros.pl -Lmacros/PGanswermacros.pl -u -r1.44 -r1.45 --- macros/PGanswermacros.pl +++ macros/PGanswermacros.pl @@ -2036,10 +2036,10 @@ sub { my $rh_ans = shift; $rh_ans->{_filter_name} = "produce_equivalence_message"; - return $rh_ans unless $rh_ans->{prev_equals_current} && $rh_ans->{score} == 0; + return $rh_ans unless $rh_ans->{prev_equals_current} && + ($rh_ans->{score} != 1 || $rh_ans->{isPreview}); # - # If the match is exact don't give an error since the previous entry - # might have been from the preview button, or because there are multiple + # If the match is exact don't give an error since there may be multiple # entry blanks and the student is trying to get one of the other ones # right. We should only give this message when the student is actually # working on this answer. |
From: dpvc v. a. <we...@ma...> - 2005-11-12 00:36:16
|
Log Message: ----------- Updated a comment to make it more accurate. Modified Files: -------------- pg/macros: PGanswermacros.pl Revision Data ------------- Index: PGanswermacros.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/PGanswermacros.pl,v retrieving revision 1.43 retrieving revision 1.44 diff -Lmacros/PGanswermacros.pl -Lmacros/PGanswermacros.pl -u -r1.43 -r1.44 --- macros/PGanswermacros.pl +++ macros/PGanswermacros.pl @@ -2037,9 +2037,14 @@ my $rh_ans = shift; $rh_ans->{_filter_name} = "produce_equivalence_message"; return $rh_ans unless $rh_ans->{prev_equals_current} && $rh_ans->{score} == 0; - # the match is exact don't give an error since the previous entry - # might have been from the preview button - return $rh_ans if $rh_ans->{prev_ans} eq $rh_ans->{original_student_ans}; + # + # If the match is exact don't give an error since the previous entry + # might have been from the preview button, or because there are multiple + # entry blanks and the student is trying to get one of the other ones + # right. We should only give this message when the student is actually + # working on this answer. + # + return $rh_ans if $rh_ans->{prev_ans} eq $rh_ans->{original_student_ans}; $rh_ans->{ans_message} = "This answer is equivalent to the one you just submitted or previewed."; $rh_ans; } |
From: dpvc v. a. <we...@ma...> - 2005-11-12 00:33:07
|
Log Message: ----------- Make had the right idea, but used the wrong context (or what might be the wrong context in some circumstances). Modified Files: -------------- pg/macros: PGanswermacros.pl Revision Data ------------- Index: PGanswermacros.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/PGanswermacros.pl,v retrieving revision 1.42 retrieving revision 1.43 diff -Lmacros/PGanswermacros.pl -Lmacros/PGanswermacros.pl -u -r1.42 -r1.43 --- macros/PGanswermacros.pl +++ macros/PGanswermacros.pl @@ -2001,12 +2001,13 @@ # # Parse the previous answer, if any # - $cmp->install_pre_filter( + $cmp->install_evaluator( sub { my $rh_ans = shift; $rh_ans->{_filter_name} = "parse_previous_answer"; return $rh_ans unless defined $rh_ans->{prev_ans}; - my $oldContext = &$Context(); &$Context($context); + my $oldContext = &$Context(); + &$Context($rh_ans->{correct_value}{context}); $rh_ans->{prev_formula} = Parser::Formula($rh_ans->{prev_ans}); &$Context($oldContext); $rh_ans; |
From: dpvc v. a. <we...@ma...> - 2005-11-12 00:32:13
|
Log Message: ----------- Roll back Mike's change, since this can cause unwanted error messages in list comparisons and other situations where the equality check could compare different types of objects (for example) or where the comparison could legitimately fail. We only want to report errors here when the user-supplied checker code fails. This change would cause errors to be reported, for example, when the user (incorrectly) entered a vector one time and then a formula (correctly) the next time. When the previous answer is checked against the current one, this change would report an error rather than silently ignoring the error, as it should. Modified Files: -------------- pg/lib/Value: AnswerChecker.pm Revision Data ------------- Index: AnswerChecker.pm =================================================================== RCS file: /webwork/cvs/system/pg/lib/Value/AnswerChecker.pm,v retrieving revision 1.72 retrieving revision 1.73 diff -Llib/Value/AnswerChecker.pm -Llib/Value/AnswerChecker.pm -u -r1.72 -r1.73 --- lib/Value/AnswerChecker.pm +++ lib/Value/AnswerChecker.pm @@ -204,19 +204,14 @@ sub cmp_compare { my $self = shift; my $other = shift; my $ans = shift; my $nth = shift || ''; - my $equal = undef; - unless ( ref($ans->{checker}) eq 'CODE' ) { - $equal = eval {$self == $other} ; - } else { - $equal = eval {&{$ans->{checker}}($self,$other,$ans,$nth,@_)}; - } - if (!defined($equal) && $@ ne '' && ($$Value::context->{error}{flag} || $ans->{showAllErrors})) { - $$Value::context->setError(["<I>An error occurred while checking your$nth answer:</I>\n". - '<DIV STYLE="margin-left:1em">%s</DIV>',$@],'',undef,undef,$CMP_ERROR); - warn "Please inform your instructor that an error occurred while checking your answer"; + return eval {$self == $other} unless ref($ans->{checker}) eq 'CODE'; + my $equal = eval {&{$ans->{checker}}($self,$other,$ans,$nth,@_)}; + if (!defined($equal) && $@ ne '' && (!$$Value::context->{error}{flag} || $ans->{showAllErrors})) { + $$Value::context->setError(["<I>An error occurred while checking your$nth answer:</I>\n". + '<DIV STYLE="margin-left:1em">%s</DIV>',$@],'',undef,undef,$CMP_ERROR); + warn "Please inform your instructor that an error occurred while checking your answer"; } return $equal; - } sub cmp_list_compare {Value::List::cmp_list_compare(@_)} |
From: Mike G. v. a. <we...@ma...> - 2005-11-12 00:15:14
|
Log Message: ----------- Changes to code checking whether the previous answer is equivalent to the current answer. In this module additional code was answer to check for errors in the overloaded == in case the two Values can't be compared. In PGanswermacros.pl the filter which handles "parse_previous_answer" was modified to make sure the context is the same in the previous answer and the current answer. Modified Files: -------------- pg/lib/Value: AnswerChecker.pm pg/macros: PGanswermacros.pl Revision Data ------------- Index: AnswerChecker.pm =================================================================== RCS file: /webwork/cvs/system/pg/lib/Value/AnswerChecker.pm,v retrieving revision 1.71 retrieving revision 1.72 diff -Llib/Value/AnswerChecker.pm -Llib/Value/AnswerChecker.pm -u -r1.71 -r1.72 --- lib/Value/AnswerChecker.pm +++ lib/Value/AnswerChecker.pm @@ -204,14 +204,19 @@ sub cmp_compare { my $self = shift; my $other = shift; my $ans = shift; my $nth = shift || ''; - return eval {$self == $other} unless ref($ans->{checker}) eq 'CODE'; - my $equal = eval {&{$ans->{checker}}($self,$other,$ans,$nth,@_)}; - if (!defined($equal) && $@ ne '' && (!$$Value::context->{error}{flag} || $ans->{showAllErrors})) { - $$Value::context->setError(["<I>An error occurred while checking your$nth answer:</I>\n". - '<DIV STYLE="margin-left:1em">%s</DIV>',$@],'',undef,undef,$CMP_ERROR); - warn "Please inform your instructor that an error occurred while checking your answer"; + my $equal = undef; + unless ( ref($ans->{checker}) eq 'CODE' ) { + $equal = eval {$self == $other} ; + } else { + $equal = eval {&{$ans->{checker}}($self,$other,$ans,$nth,@_)}; + } + if (!defined($equal) && $@ ne '' && ($$Value::context->{error}{flag} || $ans->{showAllErrors})) { + $$Value::context->setError(["<I>An error occurred while checking your$nth answer:</I>\n". + '<DIV STYLE="margin-left:1em">%s</DIV>',$@],'',undef,undef,$CMP_ERROR); + warn "Please inform your instructor that an error occurred while checking your answer"; } return $equal; + } sub cmp_list_compare {Value::List::cmp_list_compare(@_)} Index: PGanswermacros.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/PGanswermacros.pl,v retrieving revision 1.41 retrieving revision 1.42 diff -Lmacros/PGanswermacros.pl -Lmacros/PGanswermacros.pl -u -r1.41 -r1.42 --- macros/PGanswermacros.pl +++ macros/PGanswermacros.pl @@ -2006,7 +2006,9 @@ my $rh_ans = shift; $rh_ans->{_filter_name} = "parse_previous_answer"; return $rh_ans unless defined $rh_ans->{prev_ans}; + my $oldContext = &$Context(); &$Context($context); $rh_ans->{prev_formula} = Parser::Formula($rh_ans->{prev_ans}); + &$Context($oldContext); $rh_ans; } ); @@ -2034,7 +2036,9 @@ my $rh_ans = shift; $rh_ans->{_filter_name} = "produce_equivalence_message"; return $rh_ans unless $rh_ans->{prev_equals_current} && $rh_ans->{score} == 0; - return $rh_ans if $rh_ans->{prev_ans} eq $rh_ans->{original_student_ans}; + # the match is exact don't give an error since the previous entry + # might have been from the preview button + return $rh_ans if $rh_ans->{prev_ans} eq $rh_ans->{original_student_ans}; $rh_ans->{ans_message} = "This answer is equivalent to the one you just submitted or previewed."; $rh_ans; } |
From: Mike G. v. a. <we...@ma...> - 2005-11-10 16:13:52
|
Log Message: ----------- Create the [HTML_TMP]/hardcopy directory if it doesn't exist. This is something of a hack done in Hardcopy.pm at the moment. I think this should be moved over to makeTempDirectory in Utils, but that would require more checking than I can do right at the moment. -- Mike Modified Files: -------------- webwork-modperl/lib/WeBWorK/ContentGenerator: Hardcopy.pm Revision Data ------------- Index: Hardcopy.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator/Hardcopy.pm,v retrieving revision 1.72 retrieving revision 1.73 diff -Llib/WeBWorK/ContentGenerator/Hardcopy.pm -Llib/WeBWorK/ContentGenerator/Hardcopy.pm -u -r1.72 -r1.73 --- lib/WeBWorK/ContentGenerator/Hardcopy.pm +++ lib/WeBWorK/ContentGenerator/Hardcopy.pm @@ -417,7 +417,13 @@ my $eUserID = $r->param("effectiveUser"); # we want to make the temp directory web-accessible, for error reporting - my $temp_dir_parent_path = $ce->{courseDirs}{html_temp} . "/hardcopy"; # makeTempDirectory will ensure that .../hardcopy exists + my $temp_dir_parent_path = $ce->{courseDirs}{html_temp} . "/hardcopy"; + #FIXME + # ensure that .../hardcopy exists + unless (-w $temp_dir_parent_path) { + mkdir "$temp_dir_parent_path" + or die "Failed to create course directory $temp_dir_parent_path: $!\n"; + } my $temp_dir_path = eval { makeTempDirectory($temp_dir_parent_path, "work") }; if ($@) { $self->add_errors(CGI::escapeHTML($@)); |
From: Sam H. v. a. <we...@ma...> - 2005-11-08 20:48:48
|
Log Message: ----------- this commit fixes quite possible the stupidest thing i've ever done. wondering where messages like this $GlobalSets[1] (ID Sec9.2ParametricEq) not defined -- skipping at /ww/webwork/webwork2/lib/WeBWorK/ContentGenerator/Hardcopy.pm line 286. were coming from? the answer is: $GlobalSets[1] = undef; which is a line i put in there for testing and never removed. i am very sorry. :-( Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator: Hardcopy.pm Revision Data ------------- Index: Hardcopy.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Hardcopy.pm,v retrieving revision 1.71 retrieving revision 1.72 diff -Llib/WeBWorK/ContentGenerator/Hardcopy.pm -Llib/WeBWorK/ContentGenerator/Hardcopy.pm -u -r1.71 -r1.72 --- lib/WeBWorK/ContentGenerator/Hardcopy.pm +++ lib/WeBWorK/ContentGenerator/Hardcopy.pm @@ -276,8 +276,6 @@ @GlobalSets = $db->getGlobalSets(@globalSetIDs); } - $GlobalSets[1] = undef; - # filter out unwanted sets my @WantedGlobalSets; foreach my $i (0 .. $#GlobalSets) { |
From: Sam H. v. a. <we...@ma...> - 2005-11-08 20:25:51
|
Log Message: ----------- fix error message for undefined global sets to print array index instead of "$i". Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator: Hardcopy.pm Revision Data ------------- Index: Hardcopy.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Hardcopy.pm,v retrieving revision 1.70 retrieving revision 1.71 diff -Llib/WeBWorK/ContentGenerator/Hardcopy.pm -Llib/WeBWorK/ContentGenerator/Hardcopy.pm -u -r1.70 -r1.71 --- lib/WeBWorK/ContentGenerator/Hardcopy.pm +++ lib/WeBWorK/ContentGenerator/Hardcopy.pm @@ -283,7 +283,7 @@ foreach my $i (0 .. $#GlobalSets) { my $Set = $GlobalSets[$i]; unless (defined $Set) { - warn "\$GlobalSets[\$i] (ID $globalSetIDs[$i]) not defined -- skipping"; + warn "\$GlobalSets[$i] (ID $globalSetIDs[$i]) not defined -- skipping"; next; } next unless $Set->open_date <= time or $perm_unopened; |
From: Sam H. v. a. <we...@ma...> - 2005-11-07 21:32:19
|
Log Message: ----------- don't override loginstatus/links (they can handle not being logged in now). also, stop using CGI::Pretty. Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator: Home.pm Revision Data ------------- Index: Home.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Home.pm,v retrieving revision 1.9 retrieving revision 1.10 diff -Llib/WeBWorK/ContentGenerator/Home.pm -Llib/WeBWorK/ContentGenerator/Home.pm -u -r1.9 -r1.10 --- lib/WeBWorK/ContentGenerator/Home.pm +++ lib/WeBWorK/ContentGenerator/Home.pm @@ -25,13 +25,13 @@ use strict; use warnings; -use CGI::Pretty qw(); +use CGI qw(); use WeBWorK::Utils qw(readFile readDirectory); use WeBWorK::Utils::CourseManagement qw/listCourses/; -sub loginstatus { "" } -sub links { "" } -sub options { "" }; +#sub loginstatus { "" } +#sub links { "" } +#sub options { "" }; sub info { my ($self) = @_; my $r = $self->r; |
From: Sam H. v. a. <we...@ma...> - 2005-11-07 21:32:00
|
Log Message: ----------- don't override loginstatus/links (they can handle not being logged in now) Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator: Error.pm Revision Data ------------- Index: Error.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Error.pm,v retrieving revision 1.5 retrieving revision 1.6 diff -Llib/WeBWorK/ContentGenerator/Error.pm -Llib/WeBWorK/ContentGenerator/Error.pm -u -r1.5 -r1.6 --- lib/WeBWorK/ContentGenerator/Error.pm +++ lib/WeBWorK/ContentGenerator/Error.pm @@ -30,8 +30,8 @@ use WeBWorK::Utils qw(ref2string); use Apache::Constants qw(:http :common); -sub loginstatus { "" } -sub links { "" } +#sub loginstatus { "" } +#sub links { "" } sub header { my $self = shift; |
From: Sam H. v. a. <we...@ma...> - 2005-11-07 21:31:01
|
Log Message: ----------- clear Authen.pm's verify cache upon logout, don't overload if_loggedin() or links() anymore. Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator: Logout.pm Revision Data ------------- Index: Logout.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Logout.pm,v retrieving revision 1.10 retrieving revision 1.11 diff -Llib/WeBWorK/ContentGenerator/Logout.pm -Llib/WeBWorK/ContentGenerator/Logout.pm -u -r1.10 -r1.11 --- lib/WeBWorK/ContentGenerator/Logout.pm +++ lib/WeBWorK/ContentGenerator/Logout.pm @@ -31,6 +31,11 @@ my ($self) = @_; my $r = $self->r; my $ce = $r->ce; + my $authen = $r->authen; + + # get rid of stored authentication info (this is kind of a hack. i have a better way + # in mind but it requires pretty much rewriting Authen/Login/Logout. :-( ) + $authen->forget_verification; my $cookie = Apache::Cookie->new($r, -name => "WeBWorKAuthentication", @@ -43,17 +48,17 @@ $r->headers_out->set("Set-Cookie" => $cookie->as_string); } -# This content generator is NOT logged in. -sub if_loggedin { - my ($self, $arg) = @_; - - return !$arg; -} - -# suppress links -sub links { - return ""; -} +## This content generator is NOT logged in. +#sub if_loggedin { +# my ($self, $arg) = @_; +# +# return !$arg; +#} +# +## suppress links +#sub links { +# return ""; +#} sub body { my ($self) = @_; |
From: Sam H. v. a. <we...@ma...> - 2005-11-07 21:30:01
|
Log Message: ----------- allow links() and loginstatus() to operate properly even if no user is logged in. uses new method was_verified() in Authen.pm. also, stop using CGI::Pretty, for speed and download size. Modified Files: -------------- webwork2/lib/WeBWorK: ContentGenerator.pm Revision Data ------------- Index: ContentGenerator.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator.pm,v retrieving revision 1.151 retrieving revision 1.152 diff -Llib/WeBWorK/ContentGenerator.pm -Llib/WeBWorK/ContentGenerator.pm -u -r1.151 -r1.152 --- lib/WeBWorK/ContentGenerator.pm +++ lib/WeBWorK/ContentGenerator.pm @@ -45,7 +45,7 @@ use warnings; use Apache::Constants qw(:response); use Carp; -use CGI::Pretty qw(*ul *li escapeHTML); +use CGI qw(*ul *li escapeHTML); use Date::Format; use URI::Escape; use WeBWorK::Debug; @@ -491,11 +491,15 @@ my ($self) = @_; my $r = $self->r; my $db = $r->db; + my $authen = $r->authen; my $authz = $r->authz; my $ce = $r->ce; my $urlpath = $r->urlpath; my $user = $r->param('user'); + # we don't currently have any links to display if the user's not logged in. this may change, though. + return unless $authen and $authen->was_verified; + # we're linking to other places in the same course, so grab the courseID from the current path my $courseID = $urlpath->arg("courseID"); @@ -713,11 +717,10 @@ sub loginstatus { my ($self) = @_; my $r = $self->r; + my $authen = $r->authen; my $urlpath = $r->urlpath; - my $key = $r->param("key"); - - if ($key) { + if ($authen and $authen->was_verified) { my $courseID = $urlpath->arg("courseID"); my $userID = $r->param("user"); my $eUserID = $r->param("effectiveUser"); @@ -726,18 +729,18 @@ params => { effectiveUser => $userID }, ); my $logoutURL = $self->systemLink($urlpath->newFromModule(__PACKAGE__ . "::Logout", courseID => $courseID)); - - print "\n<!-- BEGIN " . __PACKAGE__ . "::loginstatus -->\n"; - - print "Logged in as $userID. ", CGI::br(); - print CGI::a({href=>$logoutURL}, "Log Out"); + + my $text = "Logged in as $userID. " . CGI::br() . CGI::a({href=>$logoutURL}, "Log Out"); if ($eUserID ne $userID) { - print " | Acting as $eUserID. "; - print CGI::a({href=>$stopActingURL}, "Stop Acting"); + $text .= print " | Acting as $eUserID. " . CGI::a({href=>$stopActingURL}, "Stop Acting"); } - print "<!-- END " . __PACKAGE__ . "::loginstatus -->\n"; + #print CGI::div({class=>"LoginStatus"}, $text); # soon, my friend, soon... + print $text; + } else { + #print CGI::div({class=>"LoginStatus"}, "Not logged in."); # likewise... + print "Not logged in."; } return ""; @@ -1040,19 +1043,24 @@ If the user is currently logged in, $arg is returned. Otherwise, the inverse of $arg is returned. -The implementation in this package always returns $arg, since most content -generators are only reachable when the user is authenticated. It is up to -classes that can be reached without logging in to override this method and -provide the correct behavior. +#The implementation in this package always returns $arg, since most content +#generators are only reachable when the user is authenticated. It is up to +#classes that can be reached without logging in to override this method and +#provide the correct behavior. +# +#This is suboptimal, and may change in the future. -This is suboptimal, and may change in the future. +The implementation in this package uses WeBWorK::Authen::was_verified() to +retrieve the result of the last call to WeBWorK::Authen::verify(). =cut sub if_loggedin { my ($self, $arg) = @_; - return $arg; + #return $arg; + return 0 unless $self->r->authen; + return $self->r->authen->was_verified() ? $arg : !$arg; } =item if_submiterror($arg) |
From: Sam H. v. a. <we...@ma...> - 2005-11-07 21:23:09
|
Log Message: ----------- stop using CGI::Pretty, for speed and output size. Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator: CourseAdmin.pm Feedback.pm FixDB.pm Skeleton.pm webwork2/lib/WeBWorK/ContentGenerator/Instructor: Compare.pm Config.pm SetMaker.pm Revision Data ------------- Index: Feedback.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Feedback.pm,v retrieving revision 1.35 retrieving revision 1.36 diff -Llib/WeBWorK/ContentGenerator/Feedback.pm -Llib/WeBWorK/ContentGenerator/Feedback.pm -u -r1.35 -r1.36 --- lib/WeBWorK/ContentGenerator/Feedback.pm +++ lib/WeBWorK/ContentGenerator/Feedback.pm @@ -29,7 +29,7 @@ use strict; use warnings; use Data::Dumper; -use CGI::Pretty qw(); +use CGI qw(); use Mail::Sender; use Text::Wrap qw(wrap); use WeBWorK::Utils qw/formatDateTime decodeAnswers/; Index: CourseAdmin.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/CourseAdmin.pm,v retrieving revision 1.41 retrieving revision 1.42 diff -Llib/WeBWorK/ContentGenerator/CourseAdmin.pm -Llib/WeBWorK/ContentGenerator/CourseAdmin.pm -u -r1.41 -r1.42 --- lib/WeBWorK/ContentGenerator/CourseAdmin.pm +++ lib/WeBWorK/ContentGenerator/CourseAdmin.pm @@ -25,7 +25,7 @@ use strict; use warnings; -use CGI::Pretty qw(); +use CGI qw(); use Data::Dumper; use File::Temp qw/tempfile/; use WeBWorK::CourseEnvironment; Index: Skeleton.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Skeleton.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -Llib/WeBWorK/ContentGenerator/Skeleton.pm -Llib/WeBWorK/ContentGenerator/Skeleton.pm -u -r1.2 -r1.3 --- lib/WeBWorK/ContentGenerator/Skeleton.pm +++ lib/WeBWorK/ContentGenerator/Skeleton.pm @@ -47,7 +47,7 @@ # can use it without a corresponding "use" line. Sample lines are given below: # # You'll probably want to generate HTML code: -#use CGI::Pretty qw(); +#use CGI qw(); # # You might need some utility functions: #use WeBWorK::Utils qw(function1 function2); Index: FixDB.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/FixDB.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -Llib/WeBWorK/ContentGenerator/FixDB.pm -Llib/WeBWorK/ContentGenerator/FixDB.pm -u -r1.1 -r1.2 --- lib/WeBWorK/ContentGenerator/FixDB.pm +++ lib/WeBWorK/ContentGenerator/FixDB.pm @@ -25,7 +25,7 @@ use strict; use warnings; -use CGI::Pretty qw(); +use CGI qw(); sub title { return "Fix Database"; Index: SetMaker.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm,v retrieving revision 1.58 retrieving revision 1.59 diff -Llib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm -Llib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm -u -r1.58 -r1.59 --- lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm +++ lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm @@ -27,7 +27,7 @@ use strict; use warnings; -use CGI::Pretty qw(); +use CGI qw(); use WeBWorK::Debug; use WeBWorK::Form; use WeBWorK::Utils qw(readDirectory max sortByName); Index: Compare.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Instructor/Compare.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -Llib/WeBWorK/ContentGenerator/Instructor/Compare.pm -Llib/WeBWorK/ContentGenerator/Instructor/Compare.pm -u -r1.1 -r1.2 --- lib/WeBWorK/ContentGenerator/Instructor/Compare.pm +++ lib/WeBWorK/ContentGenerator/Instructor/Compare.pm @@ -32,7 +32,7 @@ use strict; use warnings; -use CGI::Pretty qw(); +use CGI qw(); use WeBWorK::Form; use WeBWorK::Utils qw(readDirectory max); use WeBWorK::Utils::Tasks qw(renderProblems); Index: Config.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Instructor/Config.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -Llib/WeBWorK/ContentGenerator/Instructor/Config.pm -Llib/WeBWorK/ContentGenerator/Instructor/Config.pm -u -r1.4 -r1.5 --- lib/WeBWorK/ContentGenerator/Instructor/Config.pm +++ lib/WeBWorK/ContentGenerator/Instructor/Config.pm @@ -357,7 +357,7 @@ use strict; use warnings; -use CGI::Pretty qw(); +use CGI qw(); use WeBWorK::CourseEnvironment; # Load the configuration parts defined in Constants.pm |
From: Sam H. v. a. <we...@ma...> - 2005-11-07 21:20:16
|
Log Message: ----------- store authenticator in $r. Modified Files: -------------- webwork2/lib: WeBWorK.pm Revision Data ------------- Index: WeBWorK.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK.pm,v retrieving revision 1.77 retrieving revision 1.78 diff -Llib/WeBWorK.pm -Llib/WeBWorK.pm -u -r1.77 -r1.78 --- lib/WeBWorK.pm +++ lib/WeBWorK.pm @@ -223,6 +223,7 @@ debug("...and now we can authenticate the remote user...\n"); my $authen = new WeBWorK::Authen($r); + $r->authen($authen); my $authenOK = $authen->verify; if ($authenOK) { my $userID = $r->param("user"); |
From: Sam H. v. a. <we...@ma...> - 2005-11-07 21:20:15
|
Log Message: ----------- add slot for WeBWorK::Authen object. we can use it for checking login status. Modified Files: -------------- webwork2/lib/WeBWorK: Request.pm Revision Data ------------- Index: Request.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/Request.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -Llib/WeBWorK/Request.pm -Llib/WeBWorK/Request.pm -u -r1.2 -r1.3 --- lib/WeBWorK/Request.pm +++ lib/WeBWorK/Request.pm @@ -89,6 +89,19 @@ return $self->{db}; } +=item authen([$new]) + +Return the authenticator (WeBWorK::Authen) associated with this request. If $new +is specified, set the authenticator to $new before returning the value. + +=cut + +sub authen { + my $self = shift; + $self->{authen} = shift if @_; + return $self->{authen}; +} + =item authz([$new]) Return the authorizer (WeBWorK::Authz) associated with this request. If $new is |
From: Sam H. v. a. <we...@ma...> - 2005-11-07 21:19:20
|
Log Message: ----------- add caching of verify() result, reorganize file, add docs. Modified Files: -------------- webwork2/lib/WeBWorK: Authen.pm Revision Data ------------- Index: Authen.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/Authen.pm,v retrieving revision 1.46 retrieving revision 1.47 diff -Llib/WeBWorK/Authen.pm -Llib/WeBWorK/Authen.pm -u -r1.46 -r1.47 --- lib/WeBWorK/Authen.pm +++ lib/WeBWorK/Authen.pm @@ -30,6 +30,20 @@ use constant COOKIE_LIFESPAN => 60*60*24*30; # 30 days +################################################################################ +# Public API +################################################################################ + +=head1 CONSTRUCTOR + +=over + +=item new($r) + +Instantiates a new WeBWorK::Authen object for the given WeBWorK::Requst ($r). + +=cut + sub new { my ($invocant, $r) = @_; my $class = ref($invocant) || $invocant; @@ -40,215 +54,25 @@ return $self; } -sub checkPassword($$$) { - my ($self, $userID, $possibleClearPassword) = @_; - my $db = $self->{r}->db; - - my $Password = $db->getPassword($userID); # checked - return 0 unless defined $Password; - - # check against WW password database - my $possibleCryptPassword = crypt($possibleClearPassword, $Password->password()); - return 1 if $possibleCryptPassword eq $Password->password; - - # check site-specific verification method - return 1 if $self->site_checkPassword($userID, $possibleClearPassword); - - # fail by default - return 0; -} +=back -# Site-specific password checking -# -# The site_checkPassword routine can be used to provide a hook to your institution's -# authentication system. If authentication against the course's password database, the -# method $self->site_checkPassword($userID, $clearTextPassword) is called. If this -# method returns a true value, authentication succeeds. -# -# Here is an example site_checkPassword which checks the password against the Ohio State -# popmail server: -# sub site_checkPassword($$) { -# my ($self, $userID, $clearTextPassword) = @_; -# use Net::POP3; -# my $pop = Net::POP3->new('pop.service.ohio-state.edu', Timeout => 60); -# if ($pop->login($userID, $clearTextPassword)) { -# return 1; -# } -# return 0; -# } -# -# Since you have access to the WeBWorK::Authen object, the possibilities are limitless! -# This example checks the password against the system password database and updates the -# user's password in the course database if it succeeds: -# sub site_checkPassword { -# my ($self, $userID, $clearTextPassword) = @_; -# my $realCryptPassword = (getpwnam $userID)[1] or return 0; -# my $possibleCryptPassword = crypt($possibleClearPassword, $realCryptPassword); # user real PW as salt -# if ($possibleCryptPassword eq $realCryptPassword) { -# # update WeBWorK password -# use WeBWorK::Utils qw(cryptPassword); -# my $db = $self->{r}->db; -# my $Password = $db->getPassword($userID); -# my $pass = cryptPassword($clearTextPassword); -# $Password->password($pass); -# $db->putPassword($Password); -# return 1; -# } else { -# return 0; -# } -# } -# -# -# The default site_checkPassword always fails: -sub site_checkPassword { - my ($self, $userID, $clearTextPassword) = @_; - return 0; -} +=cut -sub generateKey($$) { - my ($self, $userID) = @_; - my $ce = $self->{r}->ce; - - my @chars = @{ $ce->{sessionKeyChars} }; - my $length = $ce->{sessionKeyLength}; - - srand; - my $key = join ("", @chars[map rand(@chars), 1 .. $length]); - return WeBWorK::DB::Record::Key->new(user_id=>$userID, key=>$key, timestamp=>time); -} +=head1 METHODS -sub checkKey($$$) { - my ($self, $userID, $possibleKey) = @_; - my $ce = $self->{r}->ce; - my $db = $self->{r}->db; - - my $Key = $db->getKey($userID); # checked - return 0 unless defined $Key; - if (time <= $Key->timestamp()+$ce->{sessionKeyTimeout}) { - if ($possibleKey eq $Key->key()) { - # unexpired and matches -- update timestamp - $Key->timestamp(time); - $db->putKey($Key); - return 1; - } else { - # unexpired but doesn't match -- leave timestamp alone - # we do this to keep an attacker from keeping someone's session - # alive. (yeah, we don't match IPs.) - return 0; - } - } else { - # expired -- delete key - $db->deleteKey($userID); - return 0; - } -} +=over -sub unexpiredKeyExists($$) { - my ($self, $userID) = @_; - my $ce = $self->{r}->ce; - my $db = $self->{r}->db; - - my $Key = $db->getKey($userID); # checked - return 0 unless defined $Key; - if (time <= $Key->timestamp()+$ce->{sessionKeyTimeout}) { - # unexpired, but leave timestamp alone - return 1; - } else { - # expired -- delete key - $db->deleteKey($userID); - return 0; - } -} - -sub fetchCookie { - my ($self, $user, $key) = @_; - my $r = $self->{r}; - my $ce = $r->ce; - my $urlpath = $r->urlpath; - - my $courseID = $urlpath->arg("courseID"); - - my %cookies = Apache::Cookie->fetch; - my $cookie = $cookies{"WeBWorKCourseAuthen.$courseID"}; - - if ($cookie) { - #warn __PACKAGE__, ": fetchCookie: found a cookie for this course: \"", $cookie->as_string, "\"\n"; - #warn __PACKAGE__, ": fetchCookie: cookie has this value: \"", $cookie->value, "\"\n"; - my ($userID, $key) = split "\t", $cookie->value; - if (defined $userID and defined $key and $userID ne "" and $key ne "") { - #warn __PACKAGE__, ": fetchCookie: looks good, returning userID=$userID key=$key\n"; - return $userID, $key; - } else { - #warn __PACKAGE__, ": fetchCookie: malformed cookie. returning empty strings.\n"; - return "", ""; - } - } else { - #warn __PACKAGE__, ": fetchCookie: found no cookie for this course. returning empty strings.\n"; - return "", ""; - } -} - -sub sendCookie { - my ($self, $userID, $key) = @_; - my $r = $self->{r}; - my $ce = $r->ce; - - my $courseID = $r->urlpath->arg("courseID"); - - my $expires = time2str("%a, %d-%h-%Y %H:%M:%S %Z", time+COOKIE_LIFESPAN, "GMT"); - my $cookie = Apache::Cookie->new($r, - -name => "WeBWorKCourseAuthen.$courseID", - -value => "$userID\t$key", - -expires => $expires, - -domain => $r->hostname, - -path => $ce->{webworkURLRoot}, - -secure => 0, - ); - my $cookieString = $cookie->as_string; - - #warn __PACKAGE__, ": sendCookie: about to add Set-Cookie header with this string: \"", $cookie->as_string, "\"\n"; - $r->headers_out->set("Set-Cookie" => $cookie->as_string); -} - -sub killCookie { - my ($self) = @_; - my $r = $self->{r}; - my $ce = $r->ce; - - my $courseID = $r->urlpath->arg("courseID"); - - my $expires = time2str("%a, %d-%h-%Y %H:%M:%S %Z", time-60*60*24, "GMT"); - my $cookie = Apache::Cookie->new($r, - -name => "WeBWorKCourseAuthen.$courseID", - -value => "\t", - -expires => $expires, - -domain => $r->hostname, - -path => $ce->{webworkURLRoot}, - -secure => 0, - ); - my $cookieString = $cookie->as_string; - - #warn __PACKAGE__, ": killCookie: about to add Set-Cookie header with this string: \"", $cookie->as_string, "\"\n"; - $r->headers_out->set("Set-Cookie" => $cookie->as_string); -} +=item verify() -sub record_login($$) { - my ($self, $userID) = @_; - my $r = $self->{r}; - my $ce = $r->ce; - my $timestamp = localtime; - ($timestamp) = $timestamp =~ /^\w+\s(.*)\s/; - my $remote_host = $r->get_remote_host || "(cannot get host)"; - my $user_agent = $r->header_in("User-Agent"); - writeCourseLog($ce, "login_log", "$userID on $remote_host ($user_agent)"); -} +verify() checks several properties of the WeBWorK::Request with which it was +created to determine if a user is who they say they are. If the verification +failed because of of invalid authentication data, a note will be written in the +request explaining why it failed. If the request failed because no +authentication data was provided, however, no note will be written, as this is +expected to happen whenever someone types in a URL manually, and is not +considered an error condition. -# verify will return 1 if the person is who they say the are. If the -# verification failed because of of invalid authentication data, a note will be -# written in the request explaining why it failed. If the request failed because -# no authentication data was provided, however, no note will be written, as this -# is expected to happen whenever someone types in a URL manually, and is not -# considered an error condition. +=cut # much of the code in verify() is duplicated in verifyProctor(), below. any # changes that are made to this subroutine should be checked against @@ -486,6 +310,9 @@ $self->killCookie; } + # store verification result for fast retrevial later + $self->{was_verified} = 0; + return 0; } elsif ($failWithoutError) { # authentication failed, but we don't have any error message to report @@ -497,6 +324,9 @@ $self->killCookie; } + # store verification result for fast retrevial later + $self->{was_verified} = 0; + return 0; } else { # autentication succeeded! @@ -523,14 +353,49 @@ #warn "succeed: killing cookie"; $self->killCookie; } + + # store verification result for fast retrevial later + $self->{was_verified} = 1; + return 1; } } -# verifyProctor will return 1 if the proctor is who they say they are. It is -# essentially the same as verify(), but pulls out the proctor data from the -# form input and uses that with the appropriate database entry names to determine -# whether the proctor is valid. +=item was_verified() + +Returns true if verify() returned true the last time it was called. + +=cut + +sub was_verified { + my ($self) = @_; + + return 1 if exists $self->{was_verified} and $self->{was_verified}; + return 0; +} + +=item forget_verification() + +Future calls to was_verified() will return false, until verify() is called again and succeeds. + +=cut + +sub forget_verification { + my ($self) = @_; + + $self->{was_verified} = 0; +} + +=item verifyProctor() + +verifyProctor() checks several properties of the WeBWorK::Request with which it +was created to determine if a proctor is who they say they are. It is +essentially the same as verify(), but pulls out the proctor data from the form +input and uses that with the appropriate database entry names to determine +whether the proctor is valid. + +=cut + sub verifyProctor { my $self = shift(); my $r = $self->{r}; @@ -636,4 +501,227 @@ } } +=back + +=cut + +################################################################################ +# Password management +################################################################################ + +sub checkPassword($$$) { + my ($self, $userID, $possibleClearPassword) = @_; + my $db = $self->{r}->db; + + my $Password = $db->getPassword($userID); # checked + return 0 unless defined $Password; + + # check against WW password database + my $possibleCryptPassword = crypt($possibleClearPassword, $Password->password()); + return 1 if $possibleCryptPassword eq $Password->password; + + # check site-specific verification method + return 1 if $self->site_checkPassword($userID, $possibleClearPassword); + + # fail by default + return 0; +} + +# Site-specific password checking +# +# The site_checkPassword routine can be used to provide a hook to your institution's +# authentication system. If authentication against the course's password database, the +# method $self->site_checkPassword($userID, $clearTextPassword) is called. If this +# method returns a true value, authentication succeeds. +# +# Here is an example site_checkPassword which checks the password against the Ohio State +# popmail server: +# sub site_checkPassword($$) { +# my ($self, $userID, $clearTextPassword) = @_; +# use Net::POP3; +# my $pop = Net::POP3->new('pop.service.ohio-state.edu', Timeout => 60); +# if ($pop->login($userID, $clearTextPassword)) { +# return 1; +# } +# return 0; +# } +# +# Since you have access to the WeBWorK::Authen object, the possibilities are limitless! +# This example checks the password against the system password database and updates the +# user's password in the course database if it succeeds: +# sub site_checkPassword { +# my ($self, $userID, $clearTextPassword) = @_; +# my $realCryptPassword = (getpwnam $userID)[1] or return 0; +# my $possibleCryptPassword = crypt($possibleClearPassword, $realCryptPassword); # user real PW as salt +# if ($possibleCryptPassword eq $realCryptPassword) { +# # update WeBWorK password +# use WeBWorK::Utils qw(cryptPassword); +# my $db = $self->{r}->db; +# my $Password = $db->getPassword($userID); +# my $pass = cryptPassword($clearTextPassword); +# $Password->password($pass); +# $db->putPassword($Password); +# return 1; +# } else { +# return 0; +# } +# } +# +# +# The default site_checkPassword always fails: +sub site_checkPassword { + my ($self, $userID, $clearTextPassword) = @_; + return 0; +} + +################################################################################ +# Session key management +################################################################################ + +sub generateKey($$) { + my ($self, $userID) = @_; + my $ce = $self->{r}->ce; + + my @chars = @{ $ce->{sessionKeyChars} }; + my $length = $ce->{sessionKeyLength}; + + srand; + my $key = join ("", @chars[map rand(@chars), 1 .. $length]); + return WeBWorK::DB::Record::Key->new(user_id=>$userID, key=>$key, timestamp=>time); +} + +sub checkKey($$$) { + my ($self, $userID, $possibleKey) = @_; + my $ce = $self->{r}->ce; + my $db = $self->{r}->db; + + my $Key = $db->getKey($userID); # checked + return 0 unless defined $Key; + if (time <= $Key->timestamp()+$ce->{sessionKeyTimeout}) { + if ($possibleKey eq $Key->key()) { + # unexpired and matches -- update timestamp + $Key->timestamp(time); + $db->putKey($Key); + return 1; + } else { + # unexpired but doesn't match -- leave timestamp alone + # we do this to keep an attacker from keeping someone's session + # alive. (yeah, we don't match IPs.) + return 0; + } + } else { + # expired -- delete key + $db->deleteKey($userID); + return 0; + } +} + +sub unexpiredKeyExists($$) { + my ($self, $userID) = @_; + my $ce = $self->{r}->ce; + my $db = $self->{r}->db; + + my $Key = $db->getKey($userID); # checked + return 0 unless defined $Key; + if (time <= $Key->timestamp()+$ce->{sessionKeyTimeout}) { + # unexpired, but leave timestamp alone + return 1; + } else { + # expired -- delete key + $db->deleteKey($userID); + return 0; + } +} + +################################################################################ +# Cookie management +################################################################################ + +sub fetchCookie { + my ($self, $user, $key) = @_; + my $r = $self->{r}; + my $ce = $r->ce; + my $urlpath = $r->urlpath; + + my $courseID = $urlpath->arg("courseID"); + + my %cookies = Apache::Cookie->fetch; + my $cookie = $cookies{"WeBWorKCourseAuthen.$courseID"}; + + if ($cookie) { + #warn __PACKAGE__, ": fetchCookie: found a cookie for this course: \"", $cookie->as_string, "\"\n"; + #warn __PACKAGE__, ": fetchCookie: cookie has this value: \"", $cookie->value, "\"\n"; + my ($userID, $key) = split "\t", $cookie->value; + if (defined $userID and defined $key and $userID ne "" and $key ne "") { + #warn __PACKAGE__, ": fetchCookie: looks good, returning userID=$userID key=$key\n"; + return $userID, $key; + } else { + #warn __PACKAGE__, ": fetchCookie: malformed cookie. returning empty strings.\n"; + return "", ""; + } + } else { + #warn __PACKAGE__, ": fetchCookie: found no cookie for this course. returning empty strings.\n"; + return "", ""; + } +} + +sub sendCookie { + my ($self, $userID, $key) = @_; + my $r = $self->{r}; + my $ce = $r->ce; + + my $courseID = $r->urlpath->arg("courseID"); + + my $expires = time2str("%a, %d-%h-%Y %H:%M:%S %Z", time+COOKIE_LIFESPAN, "GMT"); + my $cookie = Apache::Cookie->new($r, + -name => "WeBWorKCourseAuthen.$courseID", + -value => "$userID\t$key", + -expires => $expires, + -domain => $r->hostname, + -path => $ce->{webworkURLRoot}, + -secure => 0, + ); + my $cookieString = $cookie->as_string; + + #warn __PACKAGE__, ": sendCookie: about to add Set-Cookie header with this string: \"", $cookie->as_string, "\"\n"; + $r->headers_out->set("Set-Cookie" => $cookie->as_string); +} + +sub killCookie { + my ($self) = @_; + my $r = $self->{r}; + my $ce = $r->ce; + + my $courseID = $r->urlpath->arg("courseID"); + + my $expires = time2str("%a, %d-%h-%Y %H:%M:%S %Z", time-60*60*24, "GMT"); + my $cookie = Apache::Cookie->new($r, + -name => "WeBWorKCourseAuthen.$courseID", + -value => "\t", + -expires => $expires, + -domain => $r->hostname, + -path => $ce->{webworkURLRoot}, + -secure => 0, + ); + my $cookieString = $cookie->as_string; + + #warn __PACKAGE__, ": killCookie: about to add Set-Cookie header with this string: \"", $cookie->as_string, "\"\n"; + $r->headers_out->set("Set-Cookie" => $cookie->as_string); +} + +################################################################################ +# Utilities +################################################################################ + +sub record_login($$) { + my ($self, $userID) = @_; + my $r = $self->{r}; + my $ce = $r->ce; + my $timestamp = localtime; + ($timestamp) = $timestamp =~ /^\w+\s(.*)\s/; + my $remote_host = $r->get_remote_host || "(cannot get host)"; + my $user_agent = $r->header_in("User-Agent"); + writeCourseLog($ce, "login_log", "$userID on $remote_host ($user_agent)"); +} + 1; |
From: Sam H. v. a. <we...@ma...> - 2005-11-07 21:18:22
|
Log Message: ----------- updated "test" template for debugging. all current template escapes are now represented, and their output is surrounded by visible DIVs. much more useful now. ;) Modified Files: -------------- webwork2/conf/templates: test.template Revision Data ------------- Index: test.template =================================================================== RCS file: /webwork/cvs/system/webwork2/conf/templates/test.template,v retrieving revision 1.3 retrieving revision 1.4 diff -Lconf/templates/test.template -Lconf/templates/test.template -u -r1.3 -r1.4 --- conf/templates/test.template +++ conf/templates/test.template @@ -21,15 +21,91 @@ --> <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"> - <head> - <title>WeBWorK Test Template</title> - </head> - <body> - <h1>#path</h1> <div><!--#path style="image" image="webwork_files/images/right_arrow.png" text=" > "--></div> - <h1>#quicklinks</h1> <div><!--#quicklinks--></div> - <h1>#siblings</h1> <div><!--#siblings--></div> - <h1>#nav</h1> <div><!--#nav style="image" imagesuffix=".png" separator=" | "--></div> - <h1>#title</h1> <div><!--#title--></div> - <h1>#body</h1> <div><!--#body--></div> - </body> +<head> +<title>WeBWorK Test Template</title> +<style type="text/css"> +div.test_box { border: 1px solid black } +</style> +<!--#head--> +</head> +<body> + +<h1>help</h1> +<div class="test_box"> +<!--#help--> +</div> + +<h1>links</h1> +<div class="test_box"> +<!--#links--> +</div> + +<h1>siblings</h1> +<div class="test_box"> +<!--#siblings--> +</div> + +<h1>options</h1> +<div class="test_box"> +<!--#options--> +</div> + +<h1>path</h1> +<div class="test_box"> +<!--#path style="text" text=" > "--> +</div> + +<h1>loginstatus</h1> +<div class="test_box"> +<!--#loginstatus--> +</div> + +<h1>nav</h1> +<div class="test_box"> +<!--#nav style="images" imageprefix="/webwork2_files/images/nav" imagesuffix=".gif" separator=" "--> +</div> + +<h1>title</h1> +<div class="test_box"> +<!--#title--> +</div> + +<h1>message</h1> +<p>used for addmessage/addgoodmessae/addbadmessage... displayed at top and bottom of page in ur.template.</p> +<div class="test_box"> +<!--#message--> +</div> + +<h1>submiterror</h1> +<p>this should go away... it is only used in three places (Grades, SendMail, ShowAnswers), and could be replaced with calls to addbadmessage.</p> +<div class="test_box"> +<!--#submiterror--> +</div> + +<h1>body</h1> +<div class="test_box"> +<!--#body--> +</div> + +<h1>warnings</h1> +<div class="test_box"> +<!--#warnings--> +</div> + +<h1>message</h1> +<div class="test_box"> +<!--#message--> +</div> + +<h1>info</h1> +<div class="test_box"> +<!--#info--> +</div> + +<h1>timestamp</h1> +<div class="test_box"> +<!--#timestamp--> +</div> + +</body> </html> |
From: Sam H. v. a. <we...@ma...> - 2005-11-07 21:17:07
|
Log Message: ----------- slight tweak to stylesheet to correct placement of loginstatus message regardless of whether it uses a <DIV> or a <SPAN>. Modified Files: -------------- webwork2/htdocs/css: ur.css Revision Data ------------- Index: ur.css =================================================================== RCS file: /webwork/cvs/system/webwork2/htdocs/css/ur.css,v retrieving revision 1.10 retrieving revision 1.11 diff -Lhtdocs/css/ur.css -Lhtdocs/css/ur.css -u -r1.10 -r1.11 --- htdocs/css/ur.css +++ htdocs/css/ur.css @@ -24,7 +24,7 @@ td.TopPanel a:visited { color: #FF9933; } -*.LoginStatus { text-align: right; font-size: small; position:absolute; right: 0; } +*.LoginStatus { text-align: right; font-size: small; position:absolute; top: 0; right: 0; } td.Timestamp { text-align: left; font-size: small; font-style: italic; } *.Path { } |
From: Sam H. v. a. <we...@ma...> - 2005-11-03 04:19:47
|
Log Message: ----------- fixed code to filter out undefined sets, improved error reporting when that happens. Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator: Hardcopy.pm Revision Data ------------- Index: Hardcopy.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Hardcopy.pm,v retrieving revision 1.69 retrieving revision 1.70 diff -Llib/WeBWorK/ContentGenerator/Hardcopy.pm -Llib/WeBWorK/ContentGenerator/Hardcopy.pm -u -r1.69 -r1.70 --- lib/WeBWorK/ContentGenerator/Hardcopy.pm +++ lib/WeBWorK/ContentGenerator/Hardcopy.pm @@ -261,27 +261,34 @@ } # get sets for selection + my @globalSetIDs; my @GlobalSets; if ($perm_multiuser) { # if we're allowed to select sets for multiple users, get all sets. - @GlobalSets = $db->getGlobalSets($db->listGlobalSets); + @globalSetIDs = $db->listGlobalSets; + @GlobalSets = $db->getGlobalSets(@globalSetIDs); } else { # otherwise, only get the sets assigned to the effective user. # note that we are getting GlobalSets, but using the list of UserSets assigned to the # effective user. this is because if we pass UserSets to ScrollingRecordList it will # give us composite IDs back, which is a pain in the ass to deal with. - @GlobalSets = $db->getGlobalSets($db->listUserSets($eUserID)); + @globalSetIDs = $db->listUserSets($eUserID); + @GlobalSets = $db->getGlobalSets(@globalSetIDs); } + $GlobalSets[1] = undef; + # filter out unwanted sets + my @WantedGlobalSets; foreach my $i (0 .. $#GlobalSets) { my $Set = $GlobalSets[$i]; unless (defined $Set) { - warn "\$GlobalSets[\$i] not defined -- skipping"; + warn "\$GlobalSets[\$i] (ID $globalSetIDs[$i]) not defined -- skipping"; next; } - splice @GlobalSets, $i, 1 unless $Set->open_date <= time or $perm_unopened; - splice @GlobalSets, $i, 1 unless $Set->published or $perm_unpublished; + next unless $Set->open_date <= time or $perm_unopened; + next unless $Set->published or $perm_unpublished; + push @WantedGlobalSets, $Set; } my $scrolling_user_list = scrollingRecordList({ @@ -302,7 +309,7 @@ default_filters => ["all"], size => 20, multiple => $perm_multiset, - }, @GlobalSets); + }, @WantedGlobalSets); # we change the text a little bit depending on whether the user has multiuser privileges my $ss = $perm_multiuser ? "s" : ""; |
From: Sam H. v. a. <we...@ma...> - 2005-11-02 18:59:41
|
Log Message: ----------- removed unmaintained templates Removed Files: ------------- webwork2/conf/templates: barebones.template classic.template system.template Revision Data ------------- --- conf/templates/classic.template +++ /dev/null @@ -1,94 +0,0 @@ -<!DOCTYPE html - PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - -<!-- -########################################################################= ######## -# WeBWorK Online Homework Delivery System -# Copyright =A9 2000-2003 The WeBWorK Project, http://openwebwork.sf.net= / -# $CVSHeader: webwork2/conf/templates/classic.template,v 1.4 2004/01/05 = 13:51:51 gage Exp $ -#=20 -# This program is free software; you can redistribute it and/or modify i= t under -# the terms of either: (a) the GNU General Public License as published b= y the -# Free Software Foundation; either version 2, or (at your option) any la= ter -# version, or (b) the "Artistic License" which comes with this package. -#=20 -# This program is distributed in the hope that it will be useful, but WI= THOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or = FITNESS -# FOR A PARTICULAR PURPOSE. See either the GNU General Public License o= r the -# Artistic License for more details. -########################################################################= ######## ---> - -<html xmlns=3D"http://www.w3.org/1999/xhtml" lang=3D"en-US"> - <head> - <title>WeBWorK - <!--#title--></title> - <!--#head--> - =20 - <style type=3D"text/css"> - <!-- - table.attemptResults { - border-style: solid;=20 - border-width: 1px;=20 - background-color: #cccccc;=20 - margin: 0px 10pt;=20 - border-spacing: 0px; - float: left - } -=09 - table.attemptResults td,table.attemptResults th { - border-style: solid;=20 - border-width: 1px;=20 - text-align: center;=20 - width: 15ex - } -=09 - div.problemHeader { - float: left - } -=09 - div.problem { - clear: both;=20 - } - //--> - </style> - </head> - <body <!--#if warnings=3D"1"-->bgcolor=3D"#ffcccc"<!--#else-->bgcolor=3D= "#efefef"<!--#endif-->> - <table border=3D"0" width=3D"100%"> - <tr> - <td align=3D"center"> - <!--#nav style=3D"images" imagesuffix=3D".gif" separator=3D" "--> - </td> - <td align=3D"right"> - <h1>WeBWorK <em>2.0</em></h1> - </td> - <td width=3D"70"> - <img src=3D"/webwork2_files/images/webwork_square.gif" height=3D"64= " width=3D"66" /> - </td> - </tr> - </table> - <hr> - <h1 style=3D"font-size: 14pt"><!--#title--></h1> - =20 - <table width=3D"100%" cellpadding=3D"10" cellspacing=3D"0" border=3D"0= "> - <tr valign=3D"top"> - <td> - <!--#body--> - </td> - <td> - <!--#info--> - </td> - </tr> - </table> - =20 - <hr /> - =20 - <table border=3D"0" width=3D"100%"> - <tr> - <h4>Links</h4> - <td align=3D"left" valign=3D"bottom"><!--#links--></td> - <td align=3D"right" valign=3D"bottom"><!--#loginstatus--></td> - </tr> - </table> - </body> -</html> --- conf/templates/system.template +++ /dev/null @@ -1,57 +0,0 @@ -<!DOCTYPE html - PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - -<!-- -########################################################################= ######## -# WeBWorK Online Homework Delivery System -# Copyright =A9 2000-2003 The WeBWorK Project, http://openwebwork.sf.net= / -# $CVSHeader: webwork2/conf/templates/system.template,v 1.3 2004/01/05 1= 3:51:51 gage Exp $ -#=20 -# This program is free software; you can redistribute it and/or modify i= t under -# the terms of either: (a) the GNU General Public License as published b= y the -# Free Software Foundation; either version 2, or (at your option) any la= ter -# version, or (b) the "Artistic License" which comes with this package. -#=20 -# This program is distributed in the hope that it will be useful, but WI= THOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or = FITNESS -# FOR A PARTICULAR PURPOSE. See either the GNU General Public License o= r the -# Artistic License for more details. -########################################################################= ######## ---> - -<html xmlns=3D"http://www.w3.org/1999/xhtml" lang=3D"en-US"> - <head> - <title>WeBWorK - <!--#title--></title> - <style type=3D"text/css"><!-- - a:link { color: red } - a:active { color: white } - a:visited { color: silver } - --></style> - </head> - <body style=3D"margin: 0px"> - <table style=3D"width: 100%; padding: 0px; margin: 0px" cellspacing=3D= "0"> - <tr> - <td style=3D"color: white; background-color: darkblue; padding: 0px;= margin: 0px"> - <img src=3D"/webwork_files/images/webwork_square.png" height=3D"64"= width=3D"66" /> - </td> - <td style=3D"color: white; background-color: darkblue; padding: 0px;= margin: 0px"> - <h1 style=3D"text-align: center; font-size: 20pt">WeBWorK II</h1> - <!--#path style=3D"image" image=3D"webwork_files/images/right_arrow= .png" text=3D" > "--> - </td> - </tr> - <tr> - <td style=3D"white-space: nowrap; color: white; background-color: da= rkblue; width: 66px"> - <div><!--#quicklinks--></div> - <div><!--#siblings--></div> - </td> - <td style=3D"color: black; background-color: white; padding-left: 2e= m; padding-right: 2em"> - <div style=3D"text-align: center"> - <!--#nav style=3D"image" imagesuffix=3D".png"--> - </div> - <h1><!--#title--></h1> - <!--#body--> - </td> - </tr> - </table> - </body> --- conf/templates/barebones.template +++ /dev/null @@ -1,127 +0,0 @@ -<!DOCTYPE html - PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - -<!-- -########################################################################= ######## -# WeBWorK Online Homework Delivery System -# Copyright =A9 2000-2003 The WeBWorK Project, http://openwebwork.sf.net= / -# $CVSHeader: webwork2/conf/templates/barebones.template,v 1.3 2004/01/0= 5 13:51:51 gage Exp $ -#=20 -# This program is free software; you can redistribute it and/or modify i= t under -# the terms of either: (a) the GNU General Public License as published b= y the -# Free Software Foundation; either version 2, or (at your option) any la= ter -# version, or (b) the "Artistic License" which comes with this package. -#=20 -# This program is distributed in the hope that it will be useful, but WI= THOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or = FITNESS -# FOR A PARTICULAR PURPOSE. See either the GNU General Public License o= r the -# Artistic License for more details. -########################################################################= ######## ---> - -<html xmlns=3D"http://www.w3.org/1999/xhtml" lang=3D"en-US"> - <head> - <title>WeBWorK - <!--#title--></title> - <!--#head--> - - <style type=3D"text/css"> - <!-- - table.attemptResults { - border-style: outset;=20 - border-width: 1px;=20 - margin: 0px 10pt;=20 - border-spacing: 1px; - float: left - } -=09 - table.attemptResults td,table.attemptResults th { - border-style: inset;=20 - border-width: 1px;=20 - text-align: center;=20 - width: 15ex - } -=09 - div.problemHeader { - float: left - } -=09 - div.problem { - clear: both;=20 - } - //--> - </style> - </head> - <body> - <table width=3D"100%" cellpadding=3D"10" cellspacing=3D"0" border=3D"1= "> - <tr valign=3D"top"> - <td align=3D"left" rowspan=3D"2"> - <img src=3D"/webwork2_files/images/webwork_square.gif" height=3D"64= " width=3D"66" /><br /> - <hr /> - =20 - <div> - <small> - <a href=3D"http://webwork3.math.rochester.edu/bugzilla/enter= _bug.cgi?product=3DWeBWorK%20mod_perl" target =3D "_bugzilla"> Report bug= s</a> - <hr /> - <!--#links--> - </small> - </div> -<!--#if can=3D"links"--> -<!--#if can=3D"siblings"--> - <hr /> -<!--#endif--> -<!--#endif--> - <div> - <small> - <!--#siblings--> - </small> - </div> - - </td> - <!--#if can=3D"path"--> - <td valign=3D"bottom" style=3D"border-right: none"> - <!--#path style=3D"text" image=3D"/webwork2_files/images/right_arro= w.png" text=3D" > "--> - </td> - <!--#endif--> - <!--#if loggedin=3D"1"--> - <td valign=3D"bottom" align=3D"right" style=3D"border-left: none"> - <!--#loginstatus--> - </td> - <!--#endif--> - </tr> - <tr valign=3D"top"> -<!--#if warnings=3D"1"--> - <td=20 - <!--#if loggedin=3D"1"--> - colspan=3D"2"=20 - <!--#endif--> - bgcolor=3D"#ffcccc"> -<!--#else--> - <td=20 - <!--#if loggedin=3D"1"--> - colspan=3D"2" - <!--#endif--> - > -<!--#endif--> - <div align=3D"center"> - <!--#nav style=3D"text" imagesuffix=3D".png" separator=3D" | "--> - </div> - <table width=3D"100%" cellpadding=3D"10" cellspacing=3D"0" border=3D= "0"> - <tr valign=3D"top"> - <td> - <h1 style=3D"font-size: 14pt"><!--#title--></h1> - <!--#if submiterror=3D"1"--> - <p><em style=3D"color: red"><!--#submiterror--></em></p> - <!--#endif-->=09 - <!--#body--> - </td> - <td> - <!--#info--> - </td> - </tr> - </table> - </td> - </tr> - </table> - </body> -</html> |
From: Mike G. v. a. <we...@ma...> - 2005-11-01 01:52:53
|
Log Message: ----------- Added rudimentary link to report problems directly. It does this by constructing a link to the bugzilla CGI that includes information on the file name of the problem and the library in which the problem is stored. This is probably still pretty fragile. A separate module could be constructed to more intelligently report bugs. -- Mike Modified Files: -------------- webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor: PGProblemEditor.pm Revision Data ------------- Index: PGProblemEditor.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm,v retrieving revision 1.61 retrieving revision 1.62 diff -Llib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm -Llib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm -u -r1.61 -r1.62 --- lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm +++ lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm @@ -406,6 +406,8 @@ unless $authz->hasPermissions($user, "modify_student_data"); + + # Gathering info my $editFilePath = $self->{editFilePath}; # path to the permanent file to be edited my $tempFilePath = $self->{tempFilePath}; # path to the file currently being worked with (might be a .tmp file) @@ -417,6 +419,17 @@ # empty string. $problemNumber = defined($problemNumber) ? $problemNumber : ''; + ######################################################################### + # Construct url for reporting bugs: + ######################################################################### + + $editFilePath =~ m|([^/]*)Library|; #find the path to the file + my $libraryName = $1; # find the library, if any exists in the path name (first library is picked) + $libraryName ='rochester' unless defined($libraryName) and $libraryName =~/\S/; # default library + + my $BUGZILLA = "http://bugs.webwork.rochester.edu/enter_bug.cgi?product=Problem%20libraries&component=$libraryName&bug_file_loc=$editFilePath"; + #FIXME # The construction of this URL is somewhat fragile. A separate module could be devoted to intelligent reporting of bugs. + ######################################################################### # Find the text for the problem, either in the tmp file, if it exists # or in the original file in the template directory @@ -479,22 +492,25 @@ $self->hidden_authen_fields, $force_field, CGI::hidden(-name=>'file_type',-default=>$self->{file_type}), - CGI::div( + CGI::div(" | ", CGI::a({-href=>'http://webwork.math.rochester.edu/docs/docs/pglanguage/manpages/',-target=>"manpage_window"}, ' Manpages ', - ), + )," | ", CGI::a({-href=>'http://devel.webwork.rochester.edu/twiki/bin/view/Webwork/PGmacrosByFile',-target=>"manpage_window"}, ' macro list ', - ), + )," | ", CGI::a({-href=>'http://devel.webwork.rochester.edu/doc/cvs/pg_HEAD/',-target=>"manpage_window"}, ' pod docs ', - ), + )," | ", + CGI::a({-href=>$BUGZILLA,-target=>"bugs_window"}, + ' report problem bugs ', + )," | ", ), CGI::p( CGI::textarea( -name => 'problemContents', -default => $problemContents, -rows => $rows, -columns => $columns, -override => 1, - ), + )," | ", ); |
From: Arnie P. v. a. <we...@ma...> - 2005-10-31 21:21:01
|
Log Message: ----------- Create an anonymous unique identifier for questionnaires in WW 2 by using $setNumber$courseName$psvnNumber in place of $psvnNumber. Modified Files: -------------- pg/macros: PGanswermacros.pl Revision Data ------------- Index: PGanswermacros.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/PGanswermacros.pl,v retrieving revision 1.40 retrieving revision 1.41 diff -Lmacros/PGanswermacros.pl -Lmacros/PGanswermacros.pl -u -r1.40 -r1.41 --- macros/PGanswermacros.pl +++ macros/PGanswermacros.pl @@ -3133,10 +3133,13 @@ my $ans_eval_template = store_ans_at(\$QUESTIONNAIRE_ANSWERS); my $psvnNumber = PG_restricted_eval(q!$main::psvnNumber!); my $probNum = PG_restricted_eval(q!$main::probNum!); + my $courseName = PG_restricted_eval(q!$main::courseName!); + my $setNumber = PG_restricted_eval(q!$main::setNumber!); + my $ans_eval = sub { my $text = shift; $text = '' unless defined($text); - my $new_text = "\n$psvnNumber-Problem-$probNum-Question-$num:\n $text "; # modify entered text + my $new_text = "\n$setNumber$courseName$psvnNumber-Problem-$probNum-Question-$num:\n $text "; # modify entered text my $out = &$ans_eval_template($new_text); # standard evaluator #warn "$QUESTIONNAIRE_ANSWERS"; $out->{student_ans} = escapeHTML($text); # restore original entered text |