[LON-CAPA-cvs] cvs: modules /msu/sentinel sentinel.conf_frag sentinelonly.pm loncom/auth lonacc.pm loncom/interface coursecatalog.pm
raeburn
lon-capa-cvs@mail.lon-capa.org
Mon, 08 Jan 2007 15:56:32 -0000
Index: loncom/auth/lonacc.pm
diff -u loncom/auth/lonacc.pm:1.103 loncom/auth/lonacc.pm:1.104
--- loncom/auth/lonacc.pm:1.103 Mon Dec 11 09:06:04 2006
+++ loncom/auth/lonacc.pm Mon Jan 8 10:54:23 2007
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Cookie Based Access Handler
#
-# $Id: lonacc.pm,v 1.103 2006/12/11 14:06:04 raeburn Exp $
+# $Id: lonacc.pm,v 1.104 2007/01/08 15:54:23 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -184,6 +184,8 @@
}
return OK;
} elsif (defined($r->dir_config('lonSSOUserUnknownRedirect'))) {
+ $r->subprocess_env->set('SSOUserUnknown' => $user);
+ $r->subprocess_env->set('SSOUserDomain' => $domain);
$r->internal_redirect($r->dir_config('lonSSOUserUnknownRedirect'));
$r->set_handlers('PerlHandler'=> undef);
return OK;
Index: loncom/interface/coursecatalog.pm
diff -u loncom/interface/coursecatalog.pm:1.14 loncom/interface/coursecatalog.pm:1.15
--- loncom/interface/coursecatalog.pm:1.14 Sat Jan 6 15:12:19 2007
+++ loncom/interface/coursecatalog.pm Mon Jan 8 10:54:56 2007
@@ -365,6 +365,7 @@
my ($domain) = @_;
my $output;
my %courses;
+ my $knownuser = &user_is_known();
if ($env{'form.coursenum'} ne '') {
%courses = &Apache::lonnet::courseiddump($domain,'.',1,'.','.',
$env{'form.coursenum'},
@@ -379,19 +380,29 @@
$output = &mt('No courses match the criteria you selected.');
return $output;
}
- if (&user_is_known()) {
+ if ($knownuser) {
$output = &mt('<b>Note for students:</b> If you are officially enrolled in a course but the course is not listed in your LON-CAPA courses, click the "Show more details" link for the specific course and check the default access dates and/or automated enrollment settings.<br /><br />');
}
}
- $output .= &Apache::loncommon::start_data_table().
- &Apache::loncommon::start_data_table_header_row();
- my @coltitles = ('Code','Sections','Crosslisted','Title','Owner');
+ $output .= &construct_data_table($knownuser,\%courses,$env{'form.coursenum'});
+ $output .= &Apache::lonhtmlcommon::echo_form_input(['coursenum','state','catalogfilter','sortby']);
+ return $output;
+}
+
+sub construct_data_table {
+ my ($knownuser,$courses,$details,$usersections) = @_;
my %sortname;
- if ($env{'form.coursenum'} eq '') {
+ if ($details eq '') {
$sortname{'Code'} = 'code';
$sortname{'Title'} = 'title';
$sortname{'Owner'} = 'owner';
}
+ my $output = &Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row();
+ my @coltitles = ('Code','Sections','Crosslisted','Title','Owner');
+ if (ref($usersections) eq 'HASH') {
+ $coltitles[1] = 'Your Section';
+ }
foreach my $item (@coltitles) {
$output .= '<th>';
if (defined($sortname{$item})) {
@@ -401,20 +412,21 @@
}
$output .= '</th>';
}
- if (&user_is_known()) {
- if ($env{'form.coursenum'} eq '') {
- $output .= '<th> </th>';
- } else {
+ if ($knownuser) {
+ if ($details) {
$output .=
'<th>'.&mt('Default Access Dates for Students').'</th>'.
'<th>'.&mt('Student Counts').'</th>'.
'<th>'.&mt('Auto-enrollment of <br />registered students').'</th>';
+ } else {
+ $output .= '<th> </th>';
}
}
&Apache::loncommon::end_data_table_header_row();
- my %courseinfo = &build_courseinfo_hash(%courses);
+ my %courseinfo = &build_courseinfo_hash($courses,$knownuser,$details,
+ $usersections);
my %Sortby;
- foreach my $course (sort(keys(%courses))) {
+ foreach my $course (sort(keys(%{$courses}))) {
if ($env{'form.sortby'} eq 'code') {
push(@{$Sortby{$courseinfo{$course}{'code'}}},$course);
} elsif ($env{'form.sortby'} eq 'owner') {
@@ -432,33 +444,31 @@
foreach my $item (@sorted_courses) {
foreach my $course (@{$Sortby{$item}}) {
$output.=&Apache::loncommon::start_data_table_row();
- $output.=&courseinfo_row($courseinfo{$course});
+ $output.=&courseinfo_row($courseinfo{$course},$knownuser,$details);
$output.=&Apache::loncommon::end_data_table_row();
}
}
$output .= &Apache::loncommon::end_data_table();
- my $echo = &Apache::lonhtmlcommon::echo_form_input(['coursenum','state','catalogfilter','sortby']);
- $output .= $echo;
return $output;
}
sub build_courseinfo_hash {
- my (%courses) = @_;
+ my ($courses,$knownuser,$details,$usersections) = @_;
my %courseinfo;
my $now = time;
- foreach my $course (keys(%courses)) {
+ foreach my $course (keys(%{$courses})) {
my $descr;
- if ($courses{$course} =~ m/^([^:]*):/i) {
+ if ($courses->{$course} =~ m/^([^:]*):/i) {
$descr = &unescape($1);
} else {
- $descr = &unescape($courses{$course});
+ $descr = &unescape($courses->{$course});
}
my $cleandesc=&HTML::Entities::encode($descr,'<>&"');
$cleandesc=~s/'/\\'/g;
$cleandesc =~ s/^\s+//;
my ($cdom,$cnum)=split(/\_/,$course);
- my ($desc,$instcode,$owner,$ttype) = split(/:/,$courses{$course});
+ my ($desc,$instcode,$owner,$ttype) = split(/:/,$courses->{$course});
$owner = &unescape($owner);
my ($ownername,$ownerdom);
if ($owner =~ /:/) {
@@ -483,41 +493,47 @@
my %coursehash = &Apache::lonnet::dump('environment',$cdom,$cnum);
my @classids;
my @crosslistings;
- my $seclist = &identify_sections($coursehash{'internal.sectionnums'});
+ my ($seclist,$numsec) =
+ &identify_sections($coursehash{'internal.sectionnums'});
+ if (ref($usersections) eq 'HASH') {
+ if (ref($usersections->{$course}) eq 'ARRAY') {
+ $seclist = join(', ',@{$usersections->{$course}});
+ }
+ }
$courseinfo{$course}{'seclist'} = $seclist;
- my $xlist_items = &identify_sections($coursehash{'internal.crosslistings'});
+ my ($xlist_items,$numxlist) =
+ &identify_sections($coursehash{'internal.crosslistings'});
my $showsyllabus = 1; # default is to include a syllabus link
if (defined($coursehash{'showsyllabus'})) {
$showsyllabus = $coursehash{'showsyllabus'};
}
$courseinfo{$course}{'showsyllabus'} = $showsyllabus;
- if (defined($env{'form.coursenum'})) {
- if ($cnum eq $env{'form.coursenum'}) {
- $courseinfo{$course}{'counts'} = &count_students($cdom,$cnum);
- $courseinfo{$course}{'autoenrollment'} =
- &autoenroll_info(\%coursehash,$now,$seclist,$xlist_items,
- $instcode,$owner,$cdom,$cnum);
-
- my $startaccess = '';
- my $endaccess = '';
- my $accessdates;
- if ( defined($coursehash{'default_enrollment_start_date'}) ) {
- $startaccess = &Apache::lonlocal::locallocaltime($coursehash{'default_enrollment_start_date'});
- }
- if ( defined($coursehash{'default_enrollment_end_date'}) ) {
- $endaccess = &Apache::lonlocal::locallocaltime($coursehash{'default_enrollment_end_date'});
- if ($coursehash{'default_enrollment_end_date'} == 0) {
- $endaccess = "No ending date";
- }
- }
- if ($startaccess) {
- $accessdates .= &mt('<i>From:</i> ').$startaccess.'<br />';
- }
- if ($endaccess) {
- $accessdates .= &mt('<i>To:</i> ').$endaccess.'<br />';
- }
- $courseinfo{$course}{'access'} = $accessdates;
+ if (((defined($env{'form.coursenum'}) && ($cnum eq $env{'form.coursenum'}))) ||
+ ($knownuser && ($details == 1))) {
+ $courseinfo{$course}{'counts'} = &count_students($cdom,$cnum,$numsec);
+ $courseinfo{$course}{'autoenrollment'} =
+ &autoenroll_info(\%coursehash,$now,$seclist,$xlist_items,
+ $instcode,$owner,$cdom,$cnum);
+
+ my $startaccess = '';
+ my $endaccess = '';
+ my $accessdates;
+ if ( defined($coursehash{'default_enrollment_start_date'}) ) {
+ $startaccess = &Apache::lonlocal::locallocaltime($coursehash{'default_enrollment_start_date'});
+ }
+ if ( defined($coursehash{'default_enrollment_end_date'}) ) {
+ $endaccess = &Apache::lonlocal::locallocaltime($coursehash{'default_enrollment_end_date'});
+ if ($coursehash{'default_enrollment_end_date'} == 0) {
+ $endaccess = "No ending date";
+ }
+ }
+ if ($startaccess) {
+ $accessdates .= &mt('<i>From:</i> ').$startaccess.'<br />';
}
+ if ($endaccess) {
+ $accessdates .= &mt('<i>To:</i> ').$endaccess.'<br />';
+ }
+ $courseinfo{$course}{'access'} = $accessdates;
}
if ($xlist_items eq '') {
$xlist_items = &mt('No');
@@ -528,7 +544,7 @@
}
sub count_students {
- my ($cdom,$cnum) = @_;
+ my ($cdom,$cnum,$numsec) = @_;
my $classlist = &Apache::loncoursedata::get_classlist($cdom,$cnum);
my %student_count = (
Active => 0,
@@ -547,7 +563,7 @@
$student_count{$data->[$idx{'status'}]} ++;
}
- my $countslist;
+ my $countslist = &mt('[quant,_1,section]',$numsec).':<br />';
foreach my $status ('Active','Future') {
$countslist .= '<nobr>'.$status_title{$status}.': '.
$student_count{$status}.'</nobr><br />';
@@ -556,7 +572,7 @@
}
sub courseinfo_row {
- my ($info) = @_;
+ my ($info,$knownuser,$details) = @_;
my ($cdom,$cnum,$title,$ownerlast,$code,$owner,$seclist,$xlist_items,
$accessdates,$showsyllabus,$counts,$autoenrollment,$output);
if (ref($info) eq 'HASH') {
@@ -588,14 +604,14 @@
}
$output .= '</font></td>'.
'<td>'.$ownerlast.'</td>';
- if (&user_is_known()) {
- if ($env{'form.coursenum'} eq '') {
- $output .= "<td><a href=\"javascript:setCourseId('$cnum')\">".&mt('Show more details').'</a></td>';
- } else {
+ if ($knownuser) {
+ if ($details) {
$output .=
'<td>'.$accessdates.'</td>'.
'<td>'.$counts.'</td>'.
'<td>'.$autoenrollment.'</td>';
+ } else {
+ $output .= "<td><a href=\"javascript:setCourseId('$cnum')\">".&mt('Show more details').'</a></td>';
}
}
return $output;
@@ -620,7 +636,8 @@
}
@secnums = sort {$a <=> $b} @secnums;
my $seclist = join(', ',@secnums);
- return $seclist;
+ my $numsec = @secnums;
+ return ($seclist,$numsec);
}
sub get_valid_classes {
Index: modules/msu/sentinel/sentinelonly.pm
+++ modules/msu/sentinel/sentinelonly.pm
# Display informative page to MSU users when SSO-based authentication
# is successful but there is no corresponding account in the
# MSU LON-CAPA domain.
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
package Apache::sentinelonly;
use strict;
use lib qw(/home/httpd/lib/perl);
use Apache::Constants qw(:common);
use Apache::loncommon;
use Apache::lonnet;
use Apache::lonlocal;
use Apache::lonacc;
use Apache::coursecatalog;
use HTTP::Request::Common;
use LWP::UserAgent;
sub handler {
my ($r) = @_;
&Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
if ($r->header_only) {
return OK;
}
# &Apache::lonacc::get_posted_cgi($r);
&Apache::lonlocal::get_language_handle($r);
my $username = $r->subprocess_env->get('REDIRECT_SSOUserUnknown');
my $domain = $r->subprocess_env->get('REDIRECT_SSOUserDomain');
my $domdesc = $Apache::lonnet::domaindescription{$domain};
my %add_entries = (topmargin => "0",
marginheight => "0",);
my $start_page =
&Apache::loncommon::start_page("MSU Single SignOn",'',
{
'add_entries' => \%add_entries,
'no_inline_link' => 1,});
$r->print($start_page);
$r->print(&mt("You successfully logged in via <b>Sentinel</b>, the MSUNet ID login service at <b>[_1]</b>, with a username of <b>[_2]</b>.",$domdesc,$username).'<br />'.&mt('However, LON-CAPA does <b>not</b> recognize your username as valid.').'<br /><br />'.&mt('If you are MSU <b>faculty</b> or <b>staff</b> this may be because you use a LON-CAPA account which is different from your MSUNet ID.').' '.&mt('If so, please login <a href="[_1]">here</a>.','/adm/login').'<br /><br />'.&mt('If you are an MSU <b>student</b> ...').'<br />');
$r->rflush();
my $usercourses = &query_LC_classlists($username);
if ($usercourses != -1) {
if ($usercourses eq '') {
$r->print(&mt('You are <b>not</b> a registered student in any official [_1] courses from the last two years, which are using LON-CAPA.',$domdesc).'<br />'.&mt('As a result a LON-CAPA user account has <b>not</b> been created for you.'));
} else {
$usercourses =~tr/A-Z/a-z/;
my $output = &check_courses($domain,$usercourses);
if ($output) {
$r->print(&mt('The following is a list of your section affiliation in all official courses which used LON-CAPA in the last two years in which you were a registered student.').'<br /><br />');
$r->print($output);
} else {
$r->print(&mt('You are not currently in any sections of courses for which automatic enrollment in the corresponding LON-CAPA course is configured.').'<br />'.&mt('As a result a LON-CAPA user account has <b>not</b> yet been created for you.'));
}
}
$r->print('<br /><br />');
}
&Apache::lonnet::logthis("No LON-CAPA account for $username:$domain authenticated by SSO");
my $catalogurl = '/adm/coursecatalog';
my $ssologout = 'https://login.msu.edu/Logout.asp';
$r->print(&mt('If you are registered in a course at MSU which will be using LON-CAPA, an account for your MSUNet ID may be lacking for one of the following reasons:').'
<ul>
<li>'.&mt('The course has yet to be created.').'</li>
<li>'.&mt('Automatic enrollment of registered students has not been enabled for the course.').'</li>
<li>'.&mt('You are in a section of course for which automatic enrollment in the corresponding LON-CAPA course is not active.').'</li>
<li>'.&mt('The start date for automated enrollment has yet to be reached.').'</li>
<li>'.&mt('You registered for the course within the last 48 hours - there is a time lag between the time you register, and the time this information becomes available for the nightly update of LON-CAPA course rosters.').'</li>
</ul>'.&mt("The <a href=\"[_1]\"/>Course Catalog</a> provides information about all MSU courses for which LON-CAPA courses have been created.",$catalogurl));
$r->print('<br /><br />'.&mt("<a href=\"[_1]\">Logout from Single SignOn</a>?",$ssologout));
$r->print(&Apache::loncommon::end_page());
return OK;
}
sub query_LC_classlists {
my ($user) = @_;
my $URL = "http://s10.lite.msu.edu/cgi-bin/LC_classlist_check.pl?username=$user";
my $request = new HTTP::Request;
$request = GET $URL;
my $res = LWP::UserAgent->new->request($request);
if ($res->is_success) {
my $dump = $res->content;
return $dump;
} else {
&Apache::lonnet::logthis("An error occurred checking the classlist database: $res->error");
return -1;
}
}
sub check_courses {
my ($dom,$usercourses) = @_;
my ($output,%matches,%stucourse,@lines,%matchedsec);
my ($instcodes,$allcourses);
if ($usercourses =~ /\n/s) {
@lines = split/\n/,$usercourses;
} else {
@lines = ($usercourses);
}
if (@lines > 0) {
($instcodes,$allcourses) = &get_official_courses($dom);
foreach my $item (@lines) {
my ($code,$seclist) = split(/=/,$item);
my @sections = split(/:/,$seclist);
if (defined($instcodes->{$code})) {
my @sections = split(/:/,$seclist);
if (ref($stucourse{$code}) eq 'ARRAY') {
foreach my $sec (@sections) {
if (!grep(/^\Q$sec\E$/,@{$stucourse{$code}{sections}})) {
push(@{$stucourse{$code}{sections}},$sec);
}
}
} else {
@{$stucourse{$code}{sections}} = @sections;
}
}
}
}
if (keys(%stucourse) > 0) {
foreach my $code (keys(%stucourse)) {
if (ref($instcodes) eq 'HASH') {
foreach my $cid (@{$instcodes->{$code}}) {
my %courseinfo =
&Apache::lonnet::coursedescription($cid,{'one_time' => 1});
my ($instseclist,$numsec) =
&Apache::coursecatalog::identify_sections($courseinfo{'internal.sectionnums'});
my @instsecs = split(/, /,$instseclist);
foreach my $stusec (@{$stucourse{$code}{sections}}) {
if (grep(/^\Q$stusec\E$/,@instsecs)) {
$matches{$cid} = $allcourses->{$cid};
push(@{$matchedsec{$cid}},$stusec);
}
}
}
}
}
}
if (keys(%matches) > 0) {
$output = &Apache::coursecatalog::construct_data_table(1,\%matches,1,\%matchedsec);
}
return $output;
}
sub get_official_courses {
my ($dom) = @_;
my %allcourses =
&Apache::lonnet::courseiddump($dom,'.',1,'.','.','.',undef,undef,'Course');
my %instcodes;
foreach my $cid (keys(%allcourses)) {
my ($description,$code,$other) = split(/:/,$allcourses{$cid},3);
if ($code ne '') {
push(@{$instcodes{$code}},$cid);
}
}
return (\%instcodes,\%allcourses);
}
1;
Index: modules/msu/sentinel/sentinel.conf_frag
+++ modules/msu/sentinel/sentinel.conf_frag
<LocationMatch "^/adm/sso_failed_login">
SetHandler perl-script
PerlHandler Apache::sentinelonly
ErrorDocument 500 /adm/errorhandler
</LocationMatch>