--- loncom/auth/lonroles.pm 2006/06/02 13:58:37 1.153
+++ loncom/auth/lonroles.pm 2009/09/23 19:42:20 1.209.4.2
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# User Roles Screen
#
-# $Id: lonroles.pm,v 1.153 2006/06/02 13:58:37 raeburn Exp $
+# $Id: lonroles.pm,v 1.209.4.2 2009/09/23 19:42:20 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -40,8 +40,10 @@ use Apache::lonhtmlcommon;
use Apache::lonannounce;
use Apache::lonlocal;
use Apache::lonpageflip();
+use Apache::lonnavdisplay();
use GDBM_File;
-use LONCAPA;
+use LONCAPA qw(:DEFAULT :match);
+use HTML::Entities;
sub redirect_user {
@@ -53,8 +55,8 @@ sub redirect_user {
my $swinfo=&Apache::lonmenu::rawconfig();
my $navwindow;
if ($launch_nav eq 'on') {
- $navwindow.=&Apache::lonnavmaps::launch_win('now',undef,undef,
- ($url =~ m-^/adm/whatsnew-));
+ $navwindow.=&Apache::lonnavdisplay::launch_win('now',undef,undef,
+ ($url =~ m-^/adm/whatsnew-));
} else {
$navwindow.=&Apache::lonnavmaps::close();
}
@@ -88,7 +90,7 @@ sub error_page {
&Apache::lonmenu::rawconfig().''.
'
'.&mt('The following problems occurred:').
$error.
- '
'.&mt('Continue').''.
&Apache::loncommon::end_page());
}
@@ -105,29 +107,90 @@ sub handler {
# ================================================================== Roles Init
if ($env{'form.selectrole'}) {
+
+ my $locknum=&Apache::lonnet::get_locks();
+ if ($locknum) { return 409; }
+
if ($env{'form.newrole'}) {
$env{'form.'.$env{'form.newrole'}}=1;
}
if ($env{'request.course.id'}) {
+ # Check if user is CC trying to select a course role
+ if ($env{'form.switchrole'}) {
+ if (!defined($env{'user.role.'.$env{'form.switchrole'}})) {
+ &adhoc_course_role($then);
+ }
+ }
my %temp=('logout_'.$env{'request.course.id'} => time);
&Apache::lonnet::put('email_status',\%temp);
&Apache::lonnet::delenv('user.state.'.$env{'request.course.id'});
}
- &Apache::lonnet::appenv("request.course.id" => '',
- "request.course.fn" => '',
- "request.course.uri" => '',
- "request.course.sec" => '',
- "request.role" => 'cm',
- "request.role.adv" => $env{'user.adv'},
- "request.role.domain" => $env{'user.domain'});
-
-# Check if user is a DC trying to enter a course and needs privs to be created
+ &Apache::lonnet::appenv({"request.course.id" => '',
+ "request.course.fn" => '',
+ "request.course.uri" => '',
+ "request.course.sec" => '',
+ "request.role" => 'cm',
+ "request.role.adv" => $env{'user.adv'},
+ "request.role.domain" => $env{'user.domain'}});
+# Check if user is a DC trying to enter a course or author space and needs privs to be created
if ($numdc > 0) {
foreach my $envkey (keys %env) {
+# Is this an ad-hoc CC-role?
if (my ($domain,$coursenum) =
- ($envkey =~ m-^form\.cc\./(\w+)/(\w+)$-)) {
+ ($envkey =~ m-^form\.cc\./($match_domain)/($match_courseid)$-)) {
if ($dcroles{$domain}) {
- &check_privs($domain,$coursenum,$then,$now);
+ &check_privs($domain,$coursenum,$then,$now,'cc');
+ }
+ last;
+ }
+# Is this an ad-hoc CA-role?
+ if (my ($domain,$user) =
+ ($envkey =~ m-^form\.ca\./($match_domain)/($match_username)$-)) {
+ if (($domain eq $env{'user.domain'}) && ($user eq $env{'user.name'})) {
+ delete($env{$envkey});
+ $env{'form.au./'.$domain.'/'} = 1;
+ my ($server_status,$home) = &check_author_homeserver($user,$domain);
+ if ($server_status eq 'switchserver') {
+ my $trolecode = 'au./'.$domain.'/';
+ my $switchserver = '/adm/switchserver?otherserver='.$home.'&role='.$trolecode;
+ $r->internal_redirect($switchserver);
+ }
+ last;
+ }
+ if (my ($castart,$caend) = ($env{'user.role.ca./'.$domain.'/'.$user} =~ /^(\d*)\.(\d*)$/)) {
+ if (((($castart) && ($castart < $now)) || !$castart) &&
+ ((!$caend) || (($caend) && ($caend > $now)))) {
+ my ($server_status,$home) = &check_author_homeserver($user,$domain);
+ if ($server_status eq 'switchserver') {
+ my $trolecode = 'ca./'.$domain.'/'.$user;
+ my $switchserver = '/adm/switchserver?otherserver='.$home.'&role='.$trolecode;
+ $r->internal_redirect($switchserver);
+ }
+ last;
+ }
+ }
+ # Check if author blocked ca-access
+ my %blocked=&Apache::lonnet::get('environment',['domcoord.author'],$domain,$user);
+ if ($blocked{'domcoord.author'} eq 'blocked') {
+ delete($env{$envkey});
+ $env{'user.error.msg'}=':::1:User '.$user.' in domain '.$domain.' blocked domain coordinator access';
+ last;
+ }
+ if ($dcroles{$domain}) {
+ my ($server_status,$home) = &check_author_homeserver($user,$domain);
+ if (($server_status eq 'ok') || ($server_status eq 'switchserver')) {
+ &check_privs($domain,$user,$then,$now,'ca');
+ if ($server_status eq 'switchserver') {
+ my $trolecode = 'ca./'.$domain.'/'.$user;
+ my $switchserver = '/adm/switchserver?'
+ .'otherserver='.$home.'&role='.$trolecode;
+ $r->internal_redirect($switchserver);
+ }
+ } else {
+ delete($env{$envkey});
+ }
+ } else {
+ delete($env{$envkey});
}
last;
}
@@ -149,8 +212,10 @@ sub handler {
# store role if recent_role list being kept
if ($env{'environment.recentroles'}) {
+ my %frozen_roles =
+ &Apache::lonhtmlcommon::get_recent_frozen('roles',$env{'environment.recentrolesn'});
&Apache::lonhtmlcommon::store_recent('roles',
- $trolecode,' ');
+ $trolecode,' ',$frozen_roles{$trolecode});
}
@@ -162,7 +227,7 @@ sub handler {
my $authnum=$cnum;
if ($env{'course.'.$cdom.'_'.$cnum.'.keyauth'}) {
($authnum,$authdom)=
- split(/\W/,$env{'course.'.$cdom.'_'.$cnum.'.keyauth'});
+ split(/:/,$env{'course.'.$cdom.'_'.$cnum.'.keyauth'});
}
# check with key authority
unless (&Apache::lonnet::validate_access_key(
@@ -187,8 +252,11 @@ sub handler {
$cdom,$cnum,
$env{'user.domain'},
$env{'user.name'},
- 'Assigned from '.$ENV{'REMOTE_ADDR'}.' at '.localtime().' for '.
- $trolecode);
+ &mt('Assigned from [_1] at [_2] for [_3]'
+ ,$ENV{'REMOTE_ADDR'}
+ ,&Apache::lonlocal::locallocaltime()
+ ,$trolecode)
+ );
unless ($assignresult eq 'ok') {
$assignresult=~s/^error\:\s*//;
$message=&mt($assignresult).
@@ -198,7 +266,7 @@ sub handler {
}
$r->print(<
+
\n");
+ $r->rflush();
+ $r->print('');
+ $r->print(&Apache::loncommon::end_page());
+ return OK;
+ }
+ if ($needs_switchserver) {
+ $r->print("
".&mt('Server Switch Required')."
\n".
+ &mt('Construction Space access is only available from '.
+ 'the home server of the corresponding Author.').' '.
+ &mt("Click the 'Switch Server' link to go there.").' ');
+ }
}
-# More than one possible role
# ----------------------------------------------------------------------- Table
- unless (($advanced) || ($nochoose)) {
- $r->print("
');
+ }
+ $r->print(&Apache::loncommon::end_page());
+ return OK;
+}
- foreach $envkey (sort keys %env) {
- if ($envkey=~/^user\.priv\.$env{'request.role'}\./) {
- my $where=$envkey;
- $where=~s/^user\.priv\.$env{'request.role'}\.//;
- my $ttype;
- my $twhere;
- my ($tdom,$trest,$tsec)=
- split(/\//,Apache::lonnet::declutter($where));
- if ($trest) {
- if ($env{'course.'.$tdom.'_'.$trest.'.description'} eq 'ca') {
- $ttype='Construction Space';
- $twhere='User: '.$trest.', Domain: '.$tdom;
- } else {
- $ttype='Course';
- if (defined($env{'course.'.$tdom.'_'.$trest.'.type'})) {
- $ttype = $env{'course.'.$tdom.'_'.$trest.'.type'};
+sub role_timezone {
+ my ($where,$timezones) = @_;
+ my $timezone;
+ if (ref($timezones) eq 'HASH') {
+ if ($where =~ m{^/($match_domain)/($match_courseid)}) {
+ my $cdom = $1;
+ my $cnum = $2;
+ if ($cdom && $cnum) {
+ if (!exists($timezones->{$cdom.'_'.$cnum})) {
+ my %timehash =
+ &Apache::lonnet::get('environment',['timezone'],$cdom,$cnum);
+ if ($timehash{'timezone'} eq '') {
+ if (!exists($timezones->{$cdom})) {
+ my %domdefaults =
+ &Apache::lonnet::get_domain_defaults($cdom);
+ if ($domdefaults{'timezone_def'} eq '') {
+ $timezones->{$cdom} = 'local';
+ } else {
+ $timezones->{$cdom} = $domdefaults{'timezone_def'};
+ }
}
- $twhere=$env{'course.'.$tdom.'_'.$trest.'.description'};
- if ($tsec) {
- $twhere.=' (Section: '.$tsec.')';
- }
- }
- } elsif ($tdom) {
- $ttype='Domain';
- $twhere=$tdom;
- } else {
- $ttype='System';
- $twhere='/';
- }
- $r->print("\n
".$ttype.': '.$twhere.'
');
- foreach (sort split(/:/,$env{$envkey})) {
- if ($_) {
- my ($prv,$restr)=split(/\&/,$_);
- my $trestr='';
- if ($restr ne 'F') {
- my $i;
- $trestr.=' (';
- for ($i=0;$iprint('
'."\n");
+ $doheaders=-1;
+ my @roletypes = &roletypes();
+ foreach my $type (@roletypes) {
+ my $haverole=0;
+ foreach my $which (sort {uc($a) cmp uc($b)} (keys(%{$sortrole}))) {
+ if ($roleclass->{$sortrole->{$which}} =~ /^\Q$type\E/) {
+ $haverole=1;
+ }
+ }
+ if ($haverole) { $doheaders++; }
+ }
+ }
+ return $doheaders;
+}
+
+sub roletypes {
+ my @types = ('Domain','Construction Space','Course','Unavailable','System');
+ return @types;
+}
+
+sub print_rolerows {
+ my ($r,$doheaders,$roleclass,$sortrole,$dcroles,$roletext) = @_;
+ if ((ref($roleclass) eq 'HASH') && (ref($sortrole) eq 'HASH')) {
+ my @types = &roletypes();
+ foreach my $type (@types) {
+ my $output;
+ foreach my $which (sort {uc($a) cmp uc($b)} (keys(%{$sortrole}))) {
+ if ($roleclass->{$sortrole->{$which}} =~ /^\Q$type\E/) {
+ if (ref($roletext) eq 'HASH') {
+ $output.=$roletext->{$sortrole->{$which}};
+ if ($sortrole->{$which} =~ m-dc\./($match_domain)/-) {
+ if (ref($dcroles) eq 'HASH') {
+ if ($dcroles->{$1}) {
+ $output .= &adhoc_roles_row($1,'');
+ }
+ }
+ }
+ }
+ }
+ }
+ if ($output) {
+ if ($doheaders > 0) {
+ $r->print("
".
+ "
".
+ &mt($type)."
");
+ }
+ $r->print($output);
+ }
+ }
+ }
+}
+
+sub findcourse_advice {
+ my ($r,$numcourses) = @_;
+ my $domdesc = &Apache::lonnet::domain($env{'user.domain'},'description');
+ my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&');
+ if (&Apache::lonnet::auto_run(undef,$env{'user.domain'})) {
+ $r->print(&mt('If you were expecting to see an active role listed for a particular course in the [_1] domain, it may be missing for one of the following reasons:',$domdesc).'
+
+
'.&mt('The course has yet to be created.').'
+
'.&mt('Automatic enrollment of registered students has not been enabled for the course.').'
+
'.&mt('You are in a section of course for which automatic enrollment in the corresponding LON-CAPA course is not active.').'
+
'.&mt('The start date for automated enrollment has yet to be reached.').'
+
'.&mt('You registered for the course recently and there is a time lag between the time you register, and the time this information becomes available for the update of LON-CAPA course rosters.').'
+
');
+ } else {
+ $r->print(&mt('If you were expecting to see an active role listed for a particular course, that course may not have been created yet.').' ');
+ }
+ my $queuetotal = &queued_selfenrollment($r);
+ if (($numcourses - $queuetotal) > 0) {
+ $r->print('
'.&mt('The [_1]Course Catalog[_2] provides information about all [_3] classes for which LON-CAPA courses have been created.','','',$domdesc).' ');
+ $r->print(&mt('You can search the course catalog for courses which permit self-enrollment, if you would like to enroll in a course.').'
');
+ }
+ return;
+}
+
+sub queued_selfenrollment {
+ my ($r) = @_;
+ my %selfenrollrequests = &Apache::lonnet::dump('selfenrollrequests');
+ my %reqs_by_date;
+ my $queuetotal = 0;
+ foreach my $item (keys(%selfenrollrequests)) {
+ if (ref($selfenrollrequests{$item}) eq 'HASH') {
+ if ($selfenrollrequests{$item}{'status'} eq 'request') {
+ if ($selfenrollrequests{$item}{'timestamp'}) {
+ push(@{$reqs_by_date{$selfenrollrequests{$item}{'timestamp'}}},$item);
+ }
+ }
+ }
+ }
+ if (keys(%reqs_by_date)) {
+ my $rolename = &Apache::lonnet::plaintext('st');
+ $r->print(''.&mt('Enrollment requests pending Course Coordinator approval').' '.
+ &Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().
+ '
'.&mt('Date requested').'
'.&mt('Course title').'
'.
+ '
'.&mt('User role').'
'.&mt('Section').'
'.
+ &Apache::loncommon::end_data_table_header_row());
+ my @sorted = sort { $a <=> $b } (keys(%reqs_by_date));
+ foreach my $item (@sorted) {
+ if (ref($reqs_by_date{$item}) eq 'ARRAY') {
+ foreach my $crs (@{$reqs_by_date{$item}}) {
+ my %courseinfo = &Apache::lonnet::coursedescription($crs);
+ my $usec = $selfenrollrequests{$crs}{'section'};
+ if ($usec eq '') {
+ $usec = &mt('No section');
+ }
+ $r->print(&Apache::loncommon::start_data_table_row().
+ '
'.&Apache::lonlocal::locallocaltime($item).'
'.
+ '
'.$courseinfo{'description'}.'
'.
+ '
'.$rolename.'
'.$usec.'
'.
+ &Apache::loncommon::end_data_table_row());
+ $queuetotal ++;
+ }
+ }
+ }
+ $r->print(&Apache::loncommon::end_data_table());
+ }
+ return $queuetotal;
+}
+
+sub privileges_info {
+ my ($which) = @_;
+ my $output;
+
+ $which ||= $env{'request.role'};
+
+ foreach my $envkey (sort(keys(%env))) {
+ next if ($envkey!~/^user\.priv\.\Q$which\E\.(.*)/);
+
+ my $where=$1;
+ my $ttype;
+ my $twhere;
+ my (undef,$tdom,$trest,$tsec)=split(m{/},$where);
+ if ($trest) {
+ if ($env{'course.'.$tdom.'_'.$trest.'.description'} eq 'ca') {
+ $ttype='Construction Space';
+ $twhere='User: '.$trest.', Domain: '.$tdom;
+ } else {
+ $ttype= &Apache::loncommon::course_type($tdom.'_'.$trest);
+ $twhere=$env{'course.'.$tdom.'_'.$trest.'.description'};
+ if ($tsec) {
+ my $sec_type = 'Section';
+ if (exists($env{"user.role.gr.$where"})) {
+ $sec_type = 'Group';
}
+ $twhere.=' ('.$sec_type.': '.$tsec.')';
}
- $r->print('');
}
+ } elsif ($tdom) {
+ $ttype='Domain';
+ $twhere=$tdom;
+ } else {
+ $ttype='System';
+ $twhere='/';
}
+ $output .= "\n
".&mt($ttype).': '.$twhere.'
'."\n
";
+ foreach my $priv (sort(split(/:/,$env{$envkey}))) {
+ next if (!$priv);
+
+ my ($prv,$restr)=split(/\&/,$priv);
+ my $trestr='';
+ if ($restr ne 'F') {
+ $trestr.=' ('.
+ join(', ',
+ map { &Apache::lonnet::plaintext($_) }
+ (split('',$restr))).') ';
+ }
+ $output .= "\n\t".
+ '
'.&Apache::lonnet::plaintext($prv).$trestr.'
';
+ }
+ $output .= "\n".'
';
}
- $r->print(&Apache::lonnet::getannounce());
- if ($advanced) {
- $r->print('
This is LON-CAPA '.
- $r->dir_config('lonVersion').' '.
- ''.&mt('Logout').'
');
- }
- $r->print(&Apache::loncommon::end_page());
- return OK;
+ return $output;
}
sub role_status {
@@ -821,8 +1129,8 @@ sub role_status {
}
sub build_roletext {
- my ($trolecode,$tdom,$trest,$tstatus,$tryagain,$advanced,$tremark,$tbg,$tfont,$trole,$twhere,$tpstart,$tpend,$nochoose,$button,$switchserver) = @_;
- my $roletext='
';
+ my ($trolecode,$tdom,$trest,$tstatus,$tryagain,$advanced,$tremark,$tbg,$tfont,$trole,$twhere,$tpstart,$tpend,$nochoose,$button,$switchserver,$reinit) = @_;
+ my $roletext='
';
my $is_dc=($trolecode =~ m/^dc\./);
my $rowspan=($is_dc) ? ''
: ' rowspan="2" ';
@@ -832,55 +1140,99 @@ sub build_roletext {
$buttonname=~s/\W//g;
if (!$button) {
if ($switchserver) {
- $roletext.='