--- loncom/auth/lonroles.pm 2003/03/24 14:45:09 1.54 +++ loncom/auth/lonroles.pm 2008/08/22 17:46:52 1.204 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # User Roles Screen # -# $Id: lonroles.pm,v 1.54 2003/03/24 14:45:09 www Exp $ +# $Id: lonroles.pm,v 1.204 2008/08/22 17:46:52 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -25,503 +25,1310 @@ # # http://www.lon-capa.org/ # -# (Directory Indexer -# (Login Screen -# YEAR=1999 -# 5/21/99,5/22,5/25,5/26,5/31,6/2,6/10,7/12,7/14 Gerd Kortemeyer) -# 11/23 Gerd Kortemeyer) -# YEAR=2000 -# 1/14,03/06,06/01,07/22,07/24,07/25, -# 09/04,09/06,09/28,09/29,09/30,10/2,10/5,10/26,10/28, -# 12/08,12/28, -# YEAR=2001 -# 01/15/01 Gerd Kortemeyer -# 03/02,05/03,05/25,05/30,06/01,07/06,08/06 Gerd Kortemeyer -# 12/29 Gerd Kortemeyer -# ### package Apache::lonroles; use strict; -use Apache::lonnet(); +use Apache::lonnet; use Apache::lonuserstate(); use Apache::Constants qw(:common); use Apache::File(); use Apache::lonmenu; use Apache::loncommon; +use Apache::lonhtmlcommon; +use Apache::lonannounce; +use Apache::lonlocal; +use Apache::lonpageflip(); +use Apache::lonnavdisplay(); +use GDBM_File; +use LONCAPA qw(:DEFAULT :match); +use HTML::Entities; + + +sub redirect_user { + my ($r,$title,$url,$msg,$launch_nav) = @_; + $msg = $title if (! defined($msg)); + &Apache::loncommon::content_type($r,'text/html'); + &Apache::loncommon::no_cache($r); + $r->send_http_header; + my $swinfo=&Apache::lonmenu::rawconfig(); + my $navwindow; + if ($launch_nav eq 'on') { + $navwindow.=&Apache::lonnavdisplay::launch_win('now',undef,undef, + ($url =~ m-^/adm/whatsnew-)); + } else { + $navwindow.=&Apache::lonnavmaps::close(); + } + my $start_page = &Apache::loncommon::start_page('Switching Role',undef, + {'redirect' => [1,$url],}); + my $end_page = &Apache::loncommon::end_page(); + +# Note to style police: +# This must only replace the spaces, nothing else, or it bombs elsewhere. + $url=~s/ /\%20/g; + $r->print(< +$swinfo + +$navwindow +

$msg

+$end_page +ENDREDIR + return; +} + +sub error_page { + my ($r,$error,$dest)=@_; + &Apache::loncommon::content_type($r,'text/html'); + &Apache::loncommon::no_cache($r); + $r->send_http_header; + return OK if $r->header_only; + $r->print(&Apache::loncommon::start_page('Problems during Course Initialization'). + ''. + '

'.&mt('The following problems occurred:'). + $error. + '


'.&mt('Continue').''. + &Apache::loncommon::end_page()); +} sub handler { my $r = shift; my $now=time; - my $then=$ENV{'user.login.time'}; + my $then=$env{'user.login.time'}; my $envkey; - + my %dcroles = (); + my $numdc = &check_fordc(\%dcroles,$then); + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}); # ================================================================== Roles Init + if ($env{'form.selectrole'}) { - if ($ENV{'form.selectrole'}) { - if ($ENV{'request.course.id'}) { - my %temp=('logout_'.$ENV{'request.course.id'} => time); + 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 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\./($match_domain)/($match_courseid)$-)) { + if ($dcroles{$domain}) { + &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)$-)) { + # 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; + } + } } - &Apache::lonnet::appenv("request.course.id" => '', - "request.course.fn" => '', - "request.course.uri" => '', - "request.course.sec" => '', - "request.role" => 'cm', - "request.role.domain" => $ENV{'user.domain'}); - foreach $envkey (keys %ENV) { + + foreach $envkey (keys %env) { next if ($envkey!~/^user\.role\./); - my (undef,undef,$role,@pwhere)=split(/\./,$envkey); - my $where=join('.',@pwhere); - my $trolecode=$role.'.'.$where; - if ($ENV{'form.'.$trolecode}) { - my ($tstart,$tend)=split(/\./,$ENV{$envkey}); - my $tstatus='is'; - if ($tstart) { - if ($tstart>$then) { - $tstatus='future'; - } - } - if ($tend) { - if ($tend<$then) { $tstatus='expired'; } - if ($tend<$now) { $tstatus='will_not'; } - } - if ($tstatus eq 'is') { - $where=~s/^\///; - my ($cdom,$cnum,$csec)=split(/\//,$where); + my ($where,$trolecode,$role,$tstatus,$tend,$tstart); + &role_status($envkey,$then,$now,\$role,\$where,\$trolecode,\$tstatus,\$tstart,\$tend); + if ($env{'form.'.$trolecode}) { + if ($tstatus eq 'is') { + $where=~s/^\///; + my ($cdom,$cnum,$csec)=split(/\//,$where); +# check for course groups + my %coursegroups = &Apache::lonnet::get_active_groups( + $env{'user.domain'},$env{'user.name'},$cdom, $cnum); + my $cgrps = join(':',keys(%coursegroups)); + +# 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,' ',$frozen_roles{$trolecode}); + } + + # check for keyed access - if (($role eq 'st') && - ($ENV{'course.'.$cdom.'_'.$cnum.'.keyaccess'} eq 'yes')) { - unless (&Apache::lonnet::validate_access_key( - $ENV{'environment.key.'.$cdom.'_'.$cnum}, - $cdom,$cnum)) { + if (($role eq 'st') && + ($env{'course.'.$cdom.'_'.$cnum.'.keyaccess'} eq 'yes')) { +# who is key authority? + my $authdom=$cdom; + my $authnum=$cnum; + if ($env{'course.'.$cdom.'_'.$cnum.'.keyauth'}) { + ($authnum,$authdom)= + split(/:/,$env{'course.'.$cdom.'_'.$cnum.'.keyauth'}); + } +# check with key authority + unless (&Apache::lonnet::validate_access_key( + $env{'environment.key.'.$cdom.'_'.$cnum}, + $authdom,$authnum)) { # there is no valid key - if ($ENV{'form.newkey'}) { + if ($env{'form.newkey'}) { # student attempts to register a new key - } else { + &Apache::loncommon::content_type($r,'text/html'); + &Apache::loncommon::no_cache($r); + $r->send_http_header; + my $swinfo=&Apache::lonmenu::rawconfig(); + my $start_page=&Apache::loncommon::start_page + ('Verifying Access Key to Unlock this Course'); + my $end_page=&Apache::loncommon::end_page(); + my $buttontext=&mt('Enter Course'); + my $message=&mt('Successfully registered key'); + my $assignresult= + &Apache::lonnet::assign_access_key( + $env{'form.newkey'}, + $authdom,$authnum, + $cdom,$cnum, + $env{'user.domain'}, + $env{'user.name'}, + &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). + '
'. + &mt('Logout').''; + $buttontext=&mt('Re-Enter Key'); + } + $r->print(< +$swinfo + +
+ + +$message
+ +
+$end_page +ENDENTEREDKEY + return OK; + } else { # print form to enter a new key - $r->content_type('text/html'); - &Apache::loncommon::no_cache($r); - $r->send_http_header; - my $swinfo=&Apache::lonmenu::rawconfig(); - my $bodytag=&Apache::loncommon::bodytag - ('Enter Access Key to Unlock this Course'); - $r->print(<Entering Course Access Key - - -$bodytag -
- - + + +
- +$end_page ENDENTERKEY - return OK; - } - } - } - &Apache::lonnet::appenv('request.role' => $trolecode, - 'request.role.domain' => $cdom, - 'request.course.sec' => $csec); - my $msg='Entering course ...'; - if (($cnum) && ($role ne 'ca')) { - my ($furl,$ferr)= - &Apache::lonuserstate::readmap($cdom.'/'.$cnum); - if (($ENV{'form.orgurl'}) && - ($ENV{'form.orgurl'}!~/^\/adm\/flip/)) { - $r->internal_redirect($ENV{'form.orgurl'}); - return OK; - } else { - unless ($ENV{'request.course.id'}) { - &Apache::lonnet::appenv( - "request.course.id" => $cdom.'_'.$cnum); - $furl='/adm/notfound.html'; - $msg= - '

Could not initialize top-level map.

'; - } - $r->content_type('text/html'); - &Apache::loncommon::no_cache($r); - $r->send_http_header; - my $swinfo=&Apache::lonmenu::rawconfig(); - my $bodytag=&Apache::loncommon::bodytag('Switching Role'); - print (<Entering Course - - - -$bodytag - -

$msg

- - -ENDREDIR - return OK; - } - } - } - } + return OK; + } + } + } + &Apache::lonnet::log($env{'user.domain'}, + $env{'user.name'}, + $env{'user.home'}, + "Role ".$trolecode); + + &Apache::lonnet::appenv( + {'request.role' => $trolecode, + 'request.role.domain' => $cdom, + 'request.course.sec' => $csec, + 'request.course.groups' => $cgrps}); + my $tadv=0; + + if (($cnum) && ($role ne 'ca') && ($role ne 'aa')) { + my $msg; + my ($furl,$ferr)= + &Apache::lonuserstate::readmap($cdom.'/'.$cnum); + if (($env{'form.orgurl'}) && + ($env{'form.orgurl'}!~/^\/adm\/flip/)) { + my $dest=$env{'form.orgurl'}; + if (&Apache::lonnet::allowed('adv') eq 'F') { $tadv=1; } + &Apache::lonnet::appenv({'request.role.adv'=>$tadv}); + if (($ferr) && ($tadv)) { + &error_page($r,$ferr,$dest); + } else { + $r->internal_redirect($dest); + } + return OK; + } else { + if (!$env{'request.course.id'}) { + &Apache::lonnet::appenv( + {"request.course.id" => $cdom.'_'.$cnum}); + $furl='/adm/roles?tryagain=1'; + $msg= + '

'. + &mt('Could not initialize [_1] at this time.', + $env{'course.'.$cdom.'_'.$cnum.'.description'}). + '

'.&mt('Please try again.').'

'.$ferr; + } + if (&Apache::lonnet::allowed('adv') eq 'F') { $tadv=1; } + &Apache::lonnet::appenv({'request.role.adv'=>$tadv}); + + if (($ferr) && ($tadv)) { + &error_page($r,$ferr,$furl); + } else { + # Check to see if the user is a CC entering a course + # for the first time + my (undef, undef, $role, $courseid) = split(/\./, $envkey); + if (substr($courseid, 0, 1) eq '/') { + $courseid = substr($courseid, 1); + } + $courseid =~ s/\//_/; + if ($role eq 'cc' && $env{'course.' . $courseid . + '.course.helper.not.run'}) { + $furl = "/adm/helper/course.initialization.helper"; + # Send the user to the course they selected + } elsif ($env{'request.course.id'}) { + if ($env{'form.destinationurl'}) { + my $dest = $env{'form.destinationurl'}; + if ($env{'form.destsymb'} ne '') { + my $esc_symb = &HTML::Entities::encode($env{'form.destsymb'},'"<>&'); + $dest .= '?symb='.$esc_symb; + } + &redirect_user($r,&mt('Entering [_1]', + $env{'course.'.$courseid.'.description'}), + $dest,$msg, + $env{'environment.remotenavmap'}); + return OK; + } + if (&Apache::lonnet::allowed('whn', + $env{'request.course.id'}) + || &Apache::lonnet::allowed('whn', + $env{'request.course.id'}.'/' + .$env{'request.course.sec'}) + ) { + my $startpage = &courseloadpage($courseid); + unless ($startpage eq 'firstres') { + $msg = &mt('Entering [_1] ...', + $env{'course.'.$courseid.'.description'}); + &redirect_user($r,&mt('New in course'), + '/adm/whatsnew?refpage=start',$msg, + $env{'environment.remotenavmap'}); + return OK; + } + } + } +# Are we allowed to look at the first resource? + if ($furl !~ m|^/adm/|) { +# Guess not ... + $furl=&Apache::lonpageflip::first_accessible_resource(); + } + $msg = &mt('Entering [_1] ...', + $env{'course.'.$courseid.'.description'}); + &redirect_user($r,&mt('Entering [_1]', + $env{'course.'.$courseid.'.description'}), + $furl,$msg, + $env{'environment.remotenavmap'}); + } + return OK; + } + } + # + # Send the user to the construction space they selected + if ($role =~ /^(au|ca|aa)$/) { + my $redirect_url = '/priv/'; + if ($role eq 'au') { + $redirect_url.=$env{'user.name'}; + } else { + $where =~ /\/(.*)$/; + $redirect_url .= $1; + } + $redirect_url .= '/'; + &redirect_user($r,&mt('Entering Construction Space'), + $redirect_url); + return OK; + } + if ($role eq 'dc') { + my $redirect_url = '/adm/menu/'; + &redirect_user($r,&mt('Loading Domain Coordinator Menu'), + $redirect_url); + return OK; + } + } + } } } # =============================================================== No Roles Init - $r->content_type('text/html'); + &Apache::loncommon::content_type($r,'text/html'); &Apache::loncommon::no_cache($r); $r->send_http_header; return OK if $r->header_only; my $swinfo=&Apache::lonmenu::rawconfig(); - my $bodytag=&Apache::loncommon::bodytag('User Roles'); - my $helptag=&Apache::loncommon::help_open_topic - ("General_Intro","Click here for help"); + my $start_page=&Apache::loncommon::start_page('User Roles'); + my $standby=&mt('Role selected. Please stand by.'); + $standby=~s/\n/\\n/g; + my $noscript=''.&mt('Use of LON-CAPA requires Javascript to be enabled in your web browser.').'
'.&mt('As this is not the case, most functionality in the system will be unavailable.').'

'; + $r->print(< - -LON-CAPA User Roles - -$bodytag -$helptag
- ENDHEADER # ------------------------------------------ Get Error Message from Environment - my ($fn,$priv,$nochoose,$error,$msg)=split(/:/,$ENV{'user.error.msg'}); - if ($ENV{'user.error.msg'}) { - $r->log_reason( - "$msg for $ENV{'user.name'} domain $ENV{'user.domain'} access $priv",$fn); + my ($fn,$priv,$nochoose,$error,$msg)=split(/:/,$env{'user.error.msg'}); + if ($env{'user.error.msg'}) { + $r->log_reason( + "$msg for $env{'user.name'} domain $env{'user.domain'} access $priv",$fn); } -# ---------------------------------------------------------------- Who is this? +# ------------------------------------------------- Can this user re-init, etc? - my $advanced=0; - foreach $envkey (keys %ENV) { - if ($envkey=~/^user\.role\./) { - my (undef,undef,$role,@pwhere)=split(/\./,$envkey); - if ($role ne 'st') { $advanced=1; } - } - } + my $advanced=$env{'user.adv'}; + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['tryagain']); + my $tryagain=$env{'form.tryagain'}; # -------------------------------------------------------- Generate Page Output # --------------------------------------------------------------- Error Header? if ($error) { - $r->print("

LON-CAPA Access Control

"); - $r->print("
Access  : ".
-                  Apache::lonnet::plaintext($priv)."\n");
-        $r->print("Resource: $fn\n");
-        $r->print("Action  : $msg\n

"); + $r->print("

".&mt('LON-CAPA Access Control')."

"); + $r->print("
");
+	if ($priv ne '') {
+            $r->print(&mt('Access  : ').&Apache::lonnet::plaintext($priv)."\n");
+	}
+	if ($fn ne '') {
+            $r->print(&mt('Resource: ').&Apache::lonenc::check_encrypt($fn)."\n");
+	}
+	if ($msg ne '') {
+            $r->print(&mt('Action  : ').$msg."\n");
+	}
+	$r->print("

"); + my $url=$fn; + my $last; + if (tie(my %hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db', + &GDBM_READER(),0640)) { + $last=$hash{'last_known'}; + untie(%hash); + } + if ($last) { $fn.='?symb='.&escape($last); } + + &Apache::londocs::changewarning($r,undef,'You have modified your course recently, [_1] may fix this access problem.', + &Apache::lonenc::check_encrypt($fn)); } else { - if ($ENV{'user.error.msg'}) { + if ($env{'user.error.msg'}) { $r->print( - '

You need to choose another user role or '. - 'enter a specific course for this function

'); + '

'. + &mt('You need to choose another user role or enter a specific course for this function').'

'); } } # -------------------------------------------------------- Choice or no choice? if ($nochoose) { - if ($advanced) { - $r->print("

Assigned User Roles

\n"); - } else { - $r->print("

Sorry ...

\nThis resource might be part of"); - if ($ENV{'request.course.id'}) { - $r->print(' another'); - } else { - $r->print(' a certain'); - } - $r->print(' course.'); - return OK; - } + $r->print("

".&mt('Sorry ...')."

\n". + &mt('This action is currently not authorized.').''. + &Apache::loncommon::end_page()); + return OK; } else { - if ($advanced) { - $r->print("Your home server is ". - $Apache::lonnet::hostname{&Apache::lonnet::homeserver - ($ENV{'user.name'},$ENV{'user.domain'})}. - "
\n"); - $r->print("Author and Co-Author roles may not be available on ". - "servers other than your home server."); - } else { - $r->print("

Enter a Course

\n"); - } if (($ENV{'REDIRECT_QUERY_STRING'}) && ($fn)) { $fn.='?'.$ENV{'REDIRECT_QUERY_STRING'}; } - $r->print('
'); - $r->print(''); - $r->print(''); - } - $r->print('
Show all roles: print(' checked'); } - $r->print('>
'); -# ----------------------------------------------------------------------- Table - $r->print(''); - unless ($nochoose) { $r->print(''); } - $r->print(''. - ''."\n"); - - foreach $envkey (sort keys %ENV) { + $r->print(''); + $r->print(''); + $r->print(''); + $r->print(''); + } + my (%roletext,%sortrole,%roleclass); + my $countactive=0; + my $countfuture=0; + my $countwill=0; + my $inrole=0; + my $possiblerole=''; + my %futureroles; + my %roles_nextlogin; + foreach $envkey (sort keys %env) { my $button = 1; my $switchserver=''; + my $roletext; + my $sortkey; if ($envkey=~/^user\.role\./) { - my (undef,undef,$role,@pwhere)=split(/\./,$envkey); - next if (!defined($role) || $role eq ''); - my $where=join('.',@pwhere); - my $trolecode=$role.'.'.$where; - my ($tstart,$tend)=split(/\./,$ENV{$envkey}); - my $tremark=''; - my $tstatus='is'; - my $tpstart=' '; - my $tpend=' '; - my $tfont='#000000'; + my ($role,$where,$trolecode,$tstart,$tend,$tremark,$tstatus,$tpstart,$tpend,$tfont); + &role_status($envkey,$then,$now,\$role,\$where,\$trolecode,\$tstatus,\$tstart,\$tend); + next if (!defined($role) || $role eq '' || $role =~ /^gr/); + $tremark=''; + $tpstart=' '; + $tpend=' '; + $tfont='#000000'; if ($tstart) { - if ($tstart>$then) { - $tstatus='future'; - if ($tstart<$now) { $tstatus='will'; } - } - $tpstart=localtime($tstart); + $tpstart=&Apache::lonlocal::locallocaltime($tstart); } if ($tend) { - if ($tend<$then) { - $tstatus='expired'; - } elsif ($tend<$now) { - $tstatus='will_not'; - } - $tpend=localtime($tend); + $tpend=&Apache::lonlocal::locallocaltime($tend); } - if ($ENV{'request.role'} eq $trolecode) { + if ($env{'request.role'} eq $trolecode) { $tstatus='selected'; } my $tbg; - if (($tstatus eq 'is') || ($tstatus eq 'selected') || - ($ENV{'form.showall'})) { + if (($tstatus eq 'is') + || ($tstatus eq 'selected') + || ($tstatus eq 'will') + || ($tstatus eq 'future') + || ($env{'form.showall'})) { if ($tstatus eq 'is') { $tbg='#77FF77'; $tfont='#003300'; + $possiblerole=$trolecode; + $countactive++; } elsif ($tstatus eq 'future') { $tbg='#FFFF77'; $button=0; + $futureroles{$trolecode} = $tstart.':'.$tend; + $countfuture ++; } elsif ($tstatus eq 'will') { $tbg='#FFAA77'; - $tremark.='Active at next login. '; + $tremark.=&mt('Active at next login.').' '; + $roles_nextlogin{$trolecode} = $tstart.':'.$tend; + $countwill ++; } elsif ($tstatus eq 'expired') { $tbg='#FF7777'; $tfont='#330000'; $button=0; } elsif ($tstatus eq 'will_not') { $tbg='#AAFF77'; - $tremark.='Expired after logout. '; + $tremark.=&mt('Expired after logout.').' '; } elsif ($tstatus eq 'selected') { $tbg='#11CC55'; $tfont='#002200'; - $tremark.='Currently selected. '; + $inrole=1; + $countactive++; + $tremark.=&mt('Currently selected.').' '; } my $trole; if ($role =~ /^cr\//) { my ($rdummy,$rdomain,$rauthor,$rrole)=split(/\//,$role); - $tremark.='
Defined by '.$rauthor.' at '.$rdomain.'.'; - $trole=$rrole; - } else { - $trole=Apache::lonnet::plaintext($role); - } + if ($tremark) { $tremark.='
'; } + $tremark.=&mt('Defined by [_1] at [_2].',$rauthor,$rdomain); + } + $trole=Apache::lonnet::plaintext($role); my $ttype; my $twhere; my ($tdom,$trest,$tsection)= split(/\//,Apache::lonnet::declutter($where)); # First, Co-Authorship roles - if ($role eq 'ca') { + if (($role eq 'ca') || ($role eq 'aa')) { my $home = &Apache::lonnet::homeserver($trest,$tdom); - if ($home ne $r->dir_config('lonHostID')) { + my $allowed=0; + my @ids=&Apache::lonnet::current_machine_ids(); + foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } } + if (!$allowed) { $button=0; - $switchserver=&Apache::lonnet::escape('http://'. - $Apache::lonnet::hostname{$home}. - '/adm/login?domain='.$ENV{'user.domain'}. - '&username='.$ENV{'user.name'}. - '&firsturl=/priv/'.$trest); + $switchserver='otherserver='.$home.'&role='.$trolecode; } #next if ($home eq 'no_host'); - $home = $Apache::lonnet::hostname{$home}; + $home = &Apache::lonnet::hostname($home); $ttype='Construction Space'; - $twhere='User: '.$trest.'
Domain: '.$tdom.'
'. - ' Server: '.$home; - $ENV{'course.'.$tdom.'_'.$trest.'.description'}='ca'; + $twhere=&mt('User').': '.$trest.'
'.&mt('Domain'). + ': '.$tdom.'
'. + ' '.&mt('Server').': '.$home; + $env{'course.'.$tdom.'_'.$trest.'.description'}='ca'; + $tremark.=&Apache::lonhtmlcommon::authorbombs('/res/'.$tdom.'/'.$trest.'/'); + $sortkey=$role."$trest:$tdom"; } elsif ($role eq 'au') { # Authors my $home = &Apache::lonnet::homeserver - ($ENV{'user.name'},$ENV{'user.domain'}); - if ($home ne $r->dir_config('lonHostID')) { + ($env{'user.name'},$env{'user.domain'}); + my $allowed=0; + my @ids=&Apache::lonnet::current_machine_ids(); + foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } } + if (!$allowed) { $button=0; - $switchserver=&Apache::lonnet::escape('http://'. - $Apache::lonnet::hostname{$home}. - '/adm/login?domain='.$ENV{'user.domain'}. - '&username='.$ENV{'user.name'}. - '&firsturl=/priv/'.$ENV{'user.name'}); + $switchserver='otherserver='.$home.'&role='.$trolecode; } #next if ($home eq 'no_host'); - $home = $Apache::lonnet::hostname{$home}; + $home = &Apache::lonnet::hostname($home); $ttype='Construction Space'; - $twhere='Domain: '.$tdom.'
Server: '.$home; - $ENV{'course.'.$tdom.'_'.$trest.'.description'}='ca'; + $twhere=&mt('Domain').': '.$tdom.'
'.&mt('Server'). + ': '.$home; + $env{'course.'.$tdom.'_'.$trest.'.description'}='ca'; + $tremark.=&Apache::lonhtmlcommon::authorbombs('/res/'.$tdom.'/'.$env{'user.name'}.'/'); + $sortkey=$role; } elsif ($trest) { - $ttype='Course'; - if ($tsection) { - $ttype.='
Section/Group: '.$tsection; - } my $tcourseid=$tdom.'_'.$trest; - if ($ENV{'course.'.$tcourseid.'.description'}) { - $twhere=$ENV{'course.'.$tcourseid.'.description'}; - unless ($twhere eq 'Currently not available') { - $twhere.=' '. - &Apache::loncommon::syllabuswrapper('Syllabus',$trest,$tdom,$tfont). + $ttype = &Apache::loncommon::course_type($tcourseid); + $trole = &Apache::lonnet::plaintext($role,$ttype); + if ($env{'course.'.$tcourseid.'.description'}) { + $twhere=$env{'course.'.$tcourseid.'.description'}; + $sortkey=$role."\0".$tdom."\0".$twhere."\0".$envkey; + unless ($twhere eq &mt('Currently not available')) { + $twhere.=' '. + &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom,$tfont). ''; - } + } } else { - my %newhash=Apache::lonnet::coursedescription - ($tcourseid); + my %newhash=&Apache::lonnet::coursedescription($tcourseid); if (%newhash) { + $sortkey=$role."\0".$tdom."\0".$newhash{'description'}. + "\0".$envkey; $twhere=$newhash{'description'}. ' '. - &Apache::loncommon::syllabuswrapper('Syllabus',$trest,$tdom,$tfont). + &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$trest,$tdom,$tfont). ''; + $ttype = $newhash{'type'}; + $trole = &Apache::lonnet::plaintext($role,$ttype); } else { - $twhere='Currently not available'; - $ENV{'course.'.$tcourseid.'.description'}=$twhere; + $twhere=&mt('Currently not available'); + $env{'course.'.$tcourseid.'.description'}=$twhere; + $sortkey=$role."\0".$tdom."\0".$twhere."\0".$envkey; + $ttype = 'Unavailable'; } } - if ($role ne 'st') { $twhere.="
Domain:".$tdom; } + if ($tsection) { + $twhere.='
'.&mt('Section').': '.$tsection; + } + if ($role ne 'st') { $twhere.="
".&mt('Domain').":".$tdom; } } elsif ($tdom) { $ttype='Domain'; $twhere=$tdom; + $sortkey=$role.$twhere; } else { $ttype='System'; - $twhere='system wide'; + $twhere=&mt('system wide'); + $sortkey=$role.$twhere; } - -# ----- do not trust the indention below here ----- - $r->print('
'); - unless ($nochoose) { - if (!$button) { - if ($switchserver) { - $r->print(''); - } else { - $r->print(''); - } - } elsif ($tstatus eq 'is') { - $r->print(''); - } elsif ($ENV{'user.adv'}) { - $r->print - (''); - } else { - $r->print(''); - } - } - $r->print(''."\n"); - } + $roletext.=&build_roletext($trolecode,$tdom,$trest,$tstatus,$tryagain,$advanced,$tremark,$tbg,$tfont,$trole,$twhere,$tpstart,$tpend,$nochoose,$button,$switchserver); + $roletext{$envkey}=$roletext; + if (!$sortkey) {$sortkey=$twhere."\0".$envkey;} + $sortrole{$sortkey}=$envkey; + $roleclass{$envkey}=$ttype; + } } } - my $tremark=''; - my $tfont='#003300'; - if ($ENV{'request.role'} eq 'cm') { - $r->print(''); - $tremark='Currently selected.'; - $tfont='#002200'; + if ($env{'user.adv'}) { + $r->print( + '
'); } else { - $r->print('
'); + if ($countactive > 0) { + my $domdesc = &Apache::lonnet::domain($env{'user.domain'},'description'); + my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&'); + $r->print('

'.&mt('[_1]Visit the [_2]Course Catalog[_3] to view all [_4] LON-CAPA courses.','','','',$domdesc).'
'.&mt('If a course is [_1]not[_2] in your list of current courses below, you may be able to enroll if self-enrollment is permitted.','','').'

'); + } + } + +# No active roles + if ($countactive==0) { + if ($inrole) { + $r->print('

'.&mt('Currently no additional roles or courses').'

'); + } else { + $r->print('

'.&mt('Currently no active roles or courses').'

'); + } + &findcourse_advice($r); + $r->print(''); + if ($countfuture) { + $r->print(&mt('The following [quant,_1,role,roles] will become active in the future:',$countfuture)); + my $doheaders = &roletable_headers($r,\%roleclass,\%sortrole, + $nochoose); + &print_rolerows($r,$doheaders,\%roleclass,\%sortrole,\%dcroles, + \%roletext); + my $tremark=''; + my $tfont='#003300'; + if ($env{'request.role'} eq 'cm') { + $r->print('
'); + $tremark=&mt('Currently selected.').' '; + $tfont='#002200'; + } else { + $r->print(''); + } + $r->print(''."\n"); + + $r->print('
 User RoleExtentStartEndRemark
Switch Server  '.$trole. - ''.$ttype. - ''.$twhere. - ''.$tpstart. - ''.$tpend. - ''.$tremark. - ' 
'.&mt('No role specified'). + ''.$tremark. + ' 
'); + } + $r->print(&Apache::loncommon::end_page()); + return OK; +# Is there only one choice? + } elsif ($countactive==1) { + my $needs_switchserver; + if ($env{'user.author'}) { + $needs_switchserver = &check_needs_switchserver($possiblerole); + } + if ((!$needs_switchserver) && ($env{'request.role'} eq 'cm')) { + $r->print('

'.&mt('Please stand by.').'

'. + ''. + ''); + $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 ((!&Apache::lonmenu::show_course()) || ($nochoose) || ($countactive==1)) { + $r->print("

".&mt('Select a Course to Enter')."

\n"); + } + my $doheaders = &roletable_headers($r,\%roleclass,\%sortrole,$nochoose); + if ($env{'environment.recentroles'}) { + my %recent_roles = + &Apache::lonhtmlcommon::get_recent('roles',$env{'environment.recentrolesn'}); + my $output=''; + foreach (sort(keys(%recent_roles))) { + if (defined($roletext{'user.role.'.$_})) { + $output.=$roletext{'user.role.'.$_}; + if ($_ =~ m-dc\./($match_domain)/- + && $dcroles{$1}) { + $output .= &adhoc_roles_row($1,'recent'); + } + } elsif ($numdc > 0) { + unless ($_ =~/^error\:/) { + $output.=&display_cc_role('user.role.'.$_); + } + } + } + if ($output) { + $r->print("". + &mt('Recent Roles').""); + $r->print($output); + $doheaders ++; + } } - unless ($nochoose) { - if ($ENV{'request.role'} ne 'cm') { - $r->print(''); - } else { - $r->print(' '); - } - } - $r->print('No role specified'. - ''.$tremark. - ' '."\n"); + if ($numdc > 0) { + $r->print(&coursepick_jscript()); + $r->print(&Apache::loncommon::coursebrowser_javascript(). + &Apache::loncommon::authorbrowser_javascript()); + } + &print_rolerows($r,$doheaders,\%roleclass,\%sortrole,\%dcroles,\%roletext); + if ($countactive > 1) { + my $tremark=''; + my $tfont='#003300'; + if ($env{'request.role'} eq 'cm') { + $r->print(''); + $tremark=&mt('Currently selected.').' '; + $tfont='#002200'; + } else { + $r->print(''); + } + unless ($nochoose) { + if ($env{'request.role'} ne 'cm') { + $r->print(''); + } else { + $r->print(' '); + } + } + $r->print(''.&mt('No role specified'). + ''.$tremark. + ' '."\n"); + } $r->print(''); unless ($nochoose) { $r->print("\n"); } # ------------------------------------------------------------ Privileges Info - if (($advanced) && (($ENV{'user.error.msg'}) || ($error))) { - $r->print('

Current Privileges

'); + if (($advanced) && (($env{'user.error.msg'}) || ($error))) { + $r->print('

Current Privileges

'); + $r->print(&privileges_info()); + } + $r->print(&Apache::lonnet::getannounce()); + if ($advanced) { + my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&'); + $r->print('

' + .&mt('This is LON-CAPA [_1]',$r->dir_config('lonVersion')) + .'
' + .''.&mt('Logout').'  ' + .'' + .&mt('Course Catalog') + .'

'); + } + $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'; - $twhere=$ENV{'course.'.$tdom.'_'.$trest.'.description'}; - if ($tsec) { - $twhere.=' (Section/Group: '.$tsec.')'; - } - } - } elsif ($tdom) { - $ttype='Domain'; - $twhere=$tdom; +sub roletable_headers { + my ($r,$roleclass,$sortrole,$nochoose) = @_; + my $doheaders; + if ((ref($sortrole) eq 'HASH') && (ref($roleclass) eq 'HASH')) { + $r->print('
'); + if (!$nochoose) { $r->print(''); } + $r->print(''."\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("". + ""); + } + $r->print($output); + } + } + } +} + +sub findcourse_advice { + my ($r) = @_; + 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.').'
'); + } + $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 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.')'; + } + } + } 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".'
'; + } + return $output; +} + +sub role_status { + my ($rolekey,$then,$now,$role,$where,$trolecode,$tstatus,$tstart,$tend) = @_; + my @pwhere = (); + if (exists($env{$rolekey}) && $env{$rolekey} ne '') { + (undef,undef,$$role,@pwhere)=split(/\./,$rolekey); + unless (!defined($$role) || $$role eq '') { + $$where=join('.',@pwhere); + $$trolecode=$$role.'.'.$$where; + ($$tstart,$$tend)=split(/\./,$env{$rolekey}); + $$tstatus='is'; + if ($$tstart && $$tstart>$then) { + $$tstatus='future'; + if ($$tstart<$now) { $$tstatus='will'; } + } + if ($$tend) { + if ($$tend<$then) { + $$tstatus='expired'; + } elsif ($$tend<$now) { + $$tstatus='will_not'; + } + } + } + } +} + +sub build_roletext { + my ($trolecode,$tdom,$trest,$tstatus,$tryagain,$advanced,$tremark,$tbg,$tfont,$trole,$twhere,$tpstart,$tpend,$nochoose,$button,$switchserver) = @_; + my $roletext=''; + my $is_dc=($trolecode =~ m/^dc\./); + my $rowspan=($is_dc) ? '' + : ' rowspan="2" '; + + unless ($nochoose) { + my $buttonname=$trolecode; + $buttonname=~s/\W//g; + if (!$button) { + if ($switchserver) { + $roletext.=''.&mt('Switch Server').''; } else { - $ttype='System'; - $twhere='/'; + $roletext.=(' '); } - $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('
  • '.Apache::lonnet::plaintext($prv).$trestr. - '
  • '); - } + } elsif ($tstatus eq 'is') { + $roletext.=''; + } elsif ($tryagain) { + $roletext.= + ''; + } elsif ($advanced) { + $roletext.= + ''; + } else { + $roletext.=' '; + } + } + if ($trolecode !~ m/^(dc|ca|au|aa)\./) { + $tremark.=&Apache::lonannounce::showday(time,1, + &Apache::lonannounce::readcalendar($tdom.'_'.$trest)); + } + $roletext.='
'; + if (!$is_dc) { + $roletext.=''."\n"; + } + return $roletext; +} + +sub check_needs_switchserver { + my ($possiblerole) = @_; + my $needs_switchserver; + my ($role,$where) = split(/\./,$possiblerole,2); + my (undef,$tdom,$twho) = split(/\//,$where); + my ($server_status,$home); + if (($role eq 'ca') || ($role eq 'aa')) { + ($server_status,$home) = &check_author_homeserver($twho,$tdom); + } else { + ($server_status,$home) = &check_author_homeserver($env{'user.name'}, + $env{'user.domain'}); + } + if ($server_status eq 'switchserver') { + $needs_switchserver = 1; + } + return $needs_switchserver; +} + +sub check_author_homeserver { + my ($uname,$udom)=@_; + if (($uname eq '') || ($udom eq '')) { + return ('fail',''); + } + my $home = &Apache::lonnet::homeserver($uname,$udom); + if (&Apache::lonnet::host_domain($home) ne $udom) { + return ('fail',$home); + } + my @ids=&Apache::lonnet::current_machine_ids(); + if (grep(/^\Q$home\E$/,@ids)) { + return ('ok',$home); + } else { + return ('switchserver',$home); + } +} + +sub check_privs { + my ($cdom,$cnum,$then,$now,$checkrole) = @_; + my $cckey = 'user.role.'.$checkrole.'./'.$cdom.'/'.$cnum; + if ($env{$cckey}) { + my ($role,$where,$trolecode,$tstart,$tend,$tremark,$tstatus,$tpstart,$tpend,$tfont); + &role_status($cckey,$then,$now,\$role,\$where,\$trolecode,\$tstatus,\$tstart,\$tend); + unless (($tstatus eq 'is') || ($tstatus eq 'will_not')) { + &set_privileges($cdom,$cnum,$checkrole); + } + } else { + &set_privileges($cdom,$cnum,$checkrole); + } +} + +sub check_fordc { + my ($dcroles,$then) = @_; + my $numdc = 0; + if ($env{'user.adv'}) { + foreach my $envkey (sort keys %env) { + if ($envkey=~/^user\.role\.dc\.\/($match_domain)\/$/) { + my $dcdom = $1; + my $livedc = 1; + my ($tstart,$tend)=split(/\./,$env{$envkey}); + if ($tstart && $tstart>$then) { $livedc = 0; } + if ($tend && $tend <$then) { $livedc = 0; } + if ($livedc) { + $$dcroles{$dcdom} = $envkey; + $numdc++; + } } - $r->print(''); } } - } + return $numdc; +} - $r->print("\n"); - return OK; -} +sub adhoc_course_role { + my ($then) = @_; + my ($cdom,$cnum); + $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + if (&check_forcc($cdom,$cnum,$then)) { + my $setprivs; + if (!defined($env{'user.role.'.$env{'form.switchrole'}})) { + $setprivs = 1; + } else { + my ($start,$end) = split(/\./,$env{'user.role.'.$env{'form.switchrole'}}); + if (($start && ($start>$then || $start == -1)) || + ($end && $end<$then)) { + $setprivs = 1; + } + } + if ($setprivs) { + if ($env{'form.switchrole'} =~ m-^(in|ta|ep|ad|st|cr)([\w/]*)\./\Q$cdom\E/\Q$cnum\E/?(\w*)$-) { + my $role = $1; + my $custom_role = $2; + my $usec = $3; + if ($role eq 'cr') { + if ($custom_role =~ m-^/$match_domain/$match_username/\w+$-) { + $role .= $custom_role; + } else { + return; + } + } + my (%userroles,%newrole,%newgroups); + my $area = '/'.$cdom.'/'.$cnum; + my $spec = $role.'.'.$area; + if ($usec ne '') { + $spec .= '/'.$usec; + $area .= '/'.$usec; + } + &Apache::lonnet::standard_roleprivs(\%newrole,$role,$cdom,$spec,$cnum,$area); + &Apache::lonnet::set_userprivs(\%userroles,\%newrole,%newgroups); + my $adhocstart = $then-1; + $userroles{'user.role.'.$spec} = $adhocstart.'.'; + &Apache::lonnet::appenv(\%userroles,[$role,'cm']); + } + } + } + return; +} + +sub check_forcc { + my ($cdom,$cnum,$then) = @_; + my $is_cc; + if ($cdom ne '' && $cnum ne '') { + if (&Apache::lonnet::is_course($cdom,$cnum)) { + my $envkey = 'user.role.cc./'.$cdom.'/'.$cnum; + if (defined($env{$envkey})) { + $is_cc = 1; + my ($tstart,$tend)=split(/\./,$env{$envkey}); + if ($tstart && $tstart>$then) { $is_cc = 0; } + if ($tend && $tend <$then) { $is_cc = 0; } + } + } + } + return $is_cc; +} + +sub courselink { + my ($dcdom,$rowtype) = @_; + my $courseform=&Apache::loncommon::selectcourse_link + ('rolechoice','dccourse'.$rowtype.'_'.$dcdom, + 'dcdomain'.$rowtype.'_'.$dcdom,'coursedesc'.$rowtype.'_'. + $dcdom,$dcdom,undef); + my $hiddenitems = ''. + ''. + ''. + ''; + return $courseform.$hiddenitems; +} + +sub coursepick_jscript { + my %lt = &Apache::lonlocal::texthash( + plsu => "Please use the 'Select Course' link to open a separate pick course window where you may select the course you wish to enter.", + youc => 'You can only use this screen to select courses in the current domain.', + ); + my $verify_script = <<"END"; + +END + return $verify_script; +} + +sub coauthorlink { + my ($dcdom,$rowtype) = @_; + my $coauthorform=&Apache::loncommon::selectauthor_link('rolechoice',$dcdom); + my $hiddenitems = ''; + return $coauthorform.$hiddenitems; +} + +sub display_cc_role { + my $rolekey = shift; + my $roletext; + my $advanced = $env{'user.adv'}; + my $tryagain = $env{'form.tryagain'}; + unless ($rolekey =~/^error\:/) { + if ($rolekey =~ m-^user\.role.cc\./($match_domain)/($match_courseid)$-) { + my $tcourseid = $1.'_'.$2; + my $trolecode = 'cc./'.$1.'/'.$2; + my $twhere; + my $ttype; + my $tbg='#77FF77'; + my $tfont='#003300'; + my %newhash=&Apache::lonnet::coursedescription($tcourseid); + if (%newhash) { + $twhere=$newhash{'description'}. + ' '. + &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$2,$1,$tfont). + ''; + $ttype = $newhash{'type'}; + } else { + $twhere=&mt('Currently not available'); + $env{'course.'.$tcourseid.'.description'}=$twhere; + } + my $trole = &Apache::lonnet::plaintext('cc',$ttype); + $twhere.="
".&mt('Domain').":".$1; + $roletext = &build_roletext($trolecode,$1,$2,'is',$tryagain,$advanced,'',$tbg,$tfont,$trole,$twhere,'','','',1,''); + } + } + return ($roletext); +} + +sub adhoc_roles_row { + my ($dcdom,$rowtype) = @_; + my $output = ''. + ' '. + ''."\n"; + return $output; +} + +sub recent_filename { + my $area=shift; + return 'nohist_recent_'.&escape($area); +} + +sub set_privileges { +# role can be cc or ca + my ($dcdom,$pickedcourse,$role) = @_; + my $area = '/'.$dcdom.'/'.$pickedcourse; + my $spec = $role.'.'.$area; + my %userroles = &Apache::lonnet::set_arearole($role,$area,'','', + $env{'user.domain'}, + $env{'user.name'}); + my %ccrole = (); + &Apache::lonnet::standard_roleprivs(\%ccrole,$role,$dcdom,$spec,$pickedcourse,$area); + my ($author,$adv)= &Apache::lonnet::set_userprivs(\%userroles,\%ccrole); + &Apache::lonnet::appenv(\%userroles,[$role,'cm']); + + &Apache::lonnet::log($env{'user.domain'}, + $env{'user.name'}, + $env{'user.home'}, + "Role ".$role); + &Apache::lonnet::appenv( + {'request.role' => $spec, + 'request.role.domain' => $dcdom, + 'request.course.sec' => ''}); + my $tadv=0; + if (&Apache::lonnet::allowed('adv') eq 'F') { $tadv=1; } + &Apache::lonnet::appenv({'request.role.adv' => $tadv}); +} + +sub courseloadpage { + my ($courseid) = @_; + my $startpage; + my %entry_settings = &Apache::lonnet::get('nohist_whatsnew', + [$courseid.':courseinit']); + my ($tmp) = %entry_settings; + unless ($tmp =~ /^error: 2 /) { + $startpage = $entry_settings{$courseid.':courseinit'}; + } + if ($startpage eq '') { + if (exists($env{'environment.course_init_display'})) { + $startpage = $env{'environment.course_init_display'}; + } + } + return $startpage; +} 1; __END__ @@ -542,6 +1349,36 @@ Invoked by /etc/httpd/conf/srm.conf: ErrorDocument 500 /adm/errorhandler +=head1 OVERVIEW + +=head2 Choosing Roles + +C is a handler that allows a user to switch roles in +mid-session. LON-CAPA attempts to work with "No Role Specified", the +default role that a user has before selecting a role, as widely as +possible, but certain handlers for example need specification which +course they should act on, etc. Both in this scenario, and when the +handler determines via C's C<&allowed> function that a certain +action is not allowed, C is used as error handler. This +allows the user to select another role which may have permission to do +what they were trying to do. C can also be accessed via the +B button in the Remote Control. + +=begin latex + +\begin{figure} +\begin{center} +\includegraphics[width=0.45\paperwidth,keepaspectratio]{Sample_Roles_Screen} + \caption{\label{Sample_Roles_Screen}Sample Roles Screen} +\end{center} +\end{figure} + +=end latex + +=head2 Role Initialization + +The privileges for a user are established at login time and stored in the session environment. As a consequence, a new role does not become active till the next login. Handlers are able to query for privileges using C's C<&allowed> function. When a user first logs in, their role is the "common" role, which means that they have the sum of all of their privileges. During a session it might become necessary to choose a particular role, which as a consequence also limits the user to only the privileges in that particular role. + =head1 INTRODUCTION This module enables a user to select what role he wishes to
 '.&mt('User Role').''.&mt('Extent') + .''.&mt('Start').''.&mt('End') + .'
". + &mt($type)."
'.$trole. + ''.$twhere. + ''.$tpstart. + ''.$tpend. + '
'.$tremark. + ' 
' + .&mt('[_1]Ad hoc[_2] roles in domain [_3] --', + '','',$dcdom).''; + my $selectcclink = &courselink($dcdom,$rowtype); + my $ccrole = &Apache::lonnet::plaintext('cc'); + my $carole = &Apache::lonnet::plaintext('ca'); + my $selectcalink = &coauthorlink($dcdom,$rowtype); + $output.= ''. + &mt('[_1]: [_2]',$ccrole,$selectcclink). + '
  '. + &mt('[_1]: [_2]',$carole,$selectcalink). + '