--- loncom/auth/lonroles.pm 2008/05/14 22:26:48 1.190
+++ loncom/auth/lonroles.pm 2013/05/09 05:24:42 1.284
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# User Roles Screen
#
-# $Id: lonroles.pm,v 1.190 2008/05/14 22:26:48 www Exp $
+# $Id: lonroles.pm,v 1.284 2013/05/09 05:24:42 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -27,6 +27,102 @@
#
###
+=pod
+
+=head1 NAME
+
+Apache::lonroles - User Roles Screen
+
+=head1 SYNOPSIS
+
+Invoked by /etc/httpd/conf/srm.conf:
+
+
+ PerlAccessHandler Apache::lonacc
+ SetHandler perl-script
+ PerlHandler Apache::lonroles
+ ErrorDocument 403 /adm/login
+ 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.
+
+=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
+operate under (instructor, student, teaching assistant, course
+coordinator, etc). These roles are pre-established by the actions
+of upper-level users.
+
+This is part of the LearningOnline Network with CAPA project
+described at http://www.lon-capa.org.
+
+=head1 HANDLER SUBROUTINE
+
+This routine is called by Apache and mod_perl.
+
+=over 4
+
+=item *
+
+Roles Initialization (yes/no)
+
+=item *
+
+Get Error Message from Environment
+
+=item *
+
+Who is this?
+
+=item *
+
+Generate Page Output
+
+=item *
+
+Choice or no choice
+
+=item *
+
+Table
+
+=item *
+
+Privileges
+
+=back
+
+=cut
+
+
package Apache::lonroles;
use strict;
@@ -41,26 +137,27 @@ use Apache::lonannounce;
use Apache::lonlocal;
use Apache::lonpageflip();
use Apache::lonnavdisplay();
+use Apache::loncoursequeueadmin;
+use Apache::longroup;
+use Apache::lonrss;
use GDBM_File;
use LONCAPA qw(:DEFAULT :match);
-
+use HTML::Entities;
+
sub redirect_user {
- my ($r,$title,$url,$msg,$launch_nav) = @_;
+ my ($r,$title,$url,$msg) = @_;
$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();
- }
+
+ # Breadcrumbs
+ my $brcrum = [{'href' => $url,
+ 'text' => 'Switching Role'},];
my $start_page = &Apache::loncommon::start_page('Switching Role',undef,
- {'redirect' => [1,$url],});
+ {'redirect' => [1,$url],
+ 'bread_crumbs' => $brcrum,});
my $end_page = &Apache::loncommon::end_page();
# Note to style police:
@@ -68,11 +165,7 @@ sub redirect_user {
$url=~s/ /\%20/g;
$r->print(<
-$swinfo
-
-$navwindow
-
$msg
+
$msg
$end_page
ENDREDIR
return;
@@ -84,13 +177,25 @@ sub error_page {
&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:').
+ # Breadcrumbs
+ my $brcrum = [{'href' => $dest,
+ 'text' => 'Problems during Course Initialization'},];
+ $r->print(&Apache::loncommon::start_page('Problems during Course Initialization',
+ undef,
+ {'bread_crumbs' => $brcrum,})
+ );
+ $r->print(
+ ''.
+ '
'.&mt('The following problems occurred:').
+ ' '.
$error.
- '
'
+ .&Apache::loncommon::end_data_table_empty_row()
+ );
+ }
+ $r->print($output);
+ }
+ }
}
- my $tremark='';
- my $tfont='#003300';
- if ($env{'request.role'} eq 'cm') {
- $r->print('
');
- $tremark=&mt('Currently selected. ');
- $tfont='#002200';
+}
+
+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('
');
+ $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.').' ');
}
- unless ($nochoose) {
- if ($env{'request.role'} ne 'cm') {
- $r->print('
');
- } else {
- $r->print('
');
- }
- }
- $r->print('
'.&mt('No role specified').
- '
'.$tremark.
- '
'."\n");
+ $r->print('
'.&mt('Self-Enrollment').'
'.
+ '
'.&mt('The [_1]Course/Community Catalog[_2] provides information about all [_3] classes for which LON-CAPA courses have been created, as well as any communities in the domain.','','',$domdesc).' ');
+ $r->print(&mt('You can search for courses and communities which permit self-enrollment, if you would like to enroll in one.').'
'.&mt('Use the [_1]request form[_2] to submit a request for creation of a new course or community.','','').'');
+ }
}
- $r->print(&Apache::loncommon::end_page());
- return OK;
+ return;
}
sub privileges_info {
@@ -853,7 +1503,7 @@ sub privileges_info {
$ttype='System';
$twhere='/';
}
- $output .= "\n
".$ttype.': '.$twhere.'
'."\n
";
+ $output .= "\n
".&mt($ttype).': '.$twhere.'
'."\n
";
foreach my $priv (sort(split(/:/,$env{$envkey}))) {
next if (!$priv);
@@ -873,34 +1523,9 @@ sub privileges_info {
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 ($trolecode,$tdom,$trest,$tstatus,$tryagain,$advanced,$tremark,$tbg,$trole,$twhere,$tpstart,$tpend,$nochoose,$button,$switchserver,$reinit,$switchwarning) = @_;
+ my ($roletext,$roletext_end);
my $is_dc=($trolecode =~ m/^dc\./);
my $rowspan=($is_dc) ? ''
: ' rowspan="2" ';
@@ -910,75 +1535,104 @@ sub build_roletext {
$buttonname=~s/\W//g;
if (!$button) {
if ($switchserver) {
- $roletext.='
'.
+ ''.
+ ''.
+ ''.
+ &mt('Your section has changed for your current [_1] role in [_2].',$rolename,$coursedesc).' ';
+ my $button = '';
+ if ($newsec[0] eq 'none') {
+ $msg .= &mt('[_1] to continue with your new section-less role.',$button);
+ } else {
+ $msg .= &mt('[_1] to continue with your new role in section ([_2]).',$button,$newsec[0]);
+ }
+ $msg .= '';
+ }
+ } elsif ($currrole_expired) {
+ $msg .= '
';
+ if (&Apache::loncommon::show_course()) {
+ $msg .= &mt('Your role in the current course has expired.');
+ } else {
+ $msg .= &mt('Your current role has expired.');
+ }
+ $msg .= ' '.&mt('However you can continue to use this role until you logout, click the "Re-Select" button, or your session has been idle for more than 24 hours.').'
';
+ }
+ &Apache::lonnet::set_userprivs(\%userroles,\%allroles,\%allgroups,\%groups_roles);
+ my ($curr_is_adv,$curr_role_adv,$curr_author,$curr_role_author);
+ $curr_author = $env{'user.author'};
+ if (($env{'request.role'} =~/^au/) || ($env{'request.role'} =~/^ca/) ||
+ ($env{'request.role'} =~/^aa/)) {
+ $curr_role_author=1;
+ }
+ $curr_is_adv = $env{'user.adv'};
+ $curr_role_adv = $env{'request.role.adv'};
+ if (keys(%userroles) > 0) {
+ foreach my $role (@changed_roles) {
+ unless(grep(/^\Q$role\E$/,@rolecodes)) {
+ push(@rolecodes,$role);
+ }
+ }
+ unless(grep(/^\Qcm\E$/,@rolecodes)) {
+ push(@rolecodes,'cm');
+ }
+ &Apache::lonnet::appenv(\%userroles,\@rolecodes);
+ }
+ my %newenv;
+ if (&Apache::lonnet::is_advanced_user($env{'user.domain'},$env{'user.name'})) {
+ unless ($curr_is_adv) {
+ $newenv{'user.adv'} = 1;
+ }
+ } elsif ($curr_is_adv && !$curr_role_adv) {
+ &Apache::lonnet::delenv('user.adv');
+ }
+ my %authorroleshash =
+ &Apache::lonnet::get_my_roles('','','userroles',['active'],['au','ca','aa']);
+ if (keys(%authorroleshash)) {
+ unless ($curr_author) {
+ $newenv{'user.author'} = 1;
+ }
+ } elsif ($curr_author && !$curr_role_author) {
+ &Apache::lonnet::delenv('user.author');
+ }
+ if ($env{'request.course.id'}) {
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ my (@activecrsgroups,$crsgroupschanged);
+ if ($env{'request.course.groups'}) {
+ @activecrsgroups = split(/:/,$env{'request.course.groups'});
+ foreach my $item (keys(%deletedroles)) {
+ if ($item =~ m{^gr\./\Q$cdom\E/\Q$cnum\E/(\w+)$}) {
+ if (grep(/^\Q$1\E$/,@activecrsgroups)) {
+ $crsgroupschanged = 1;
+ last;
+ }
+ }
+ }
+ }
+ unless ($crsgroupschanged) {
+ foreach my $item (keys(%newgroup)) {
+ if ($item =~ m{^gr\./\Q$cdom\E/\Q$cnum\E/(\w+)$}) {
+ if ($newgroup{$item} eq 'active') {
+ $crsgroupschanged = 1;
+ last;
+ }
+ }
+ }
+ }
+ if ((ref($changed_groups{$env{'request.course.id'}}) eq 'HASH') ||
+ (ref($groupchange{"/$cdom/$cnum"}) eq 'HASH') ||
+ ($crsgroupschanged)) {
+ my %grouproles = &Apache::lonnet::get_my_roles('','','userroles',
+ ['active'],['gr'],[$cdom],1);
+ my @activegroups;
+ foreach my $item (keys(%grouproles)) {
+ next unless($item =~ /^\Q$cnum\E:\Q$cdom\E/);
+ my $group;
+ my ($crsn,$crsd,$role,$remainder) = split(/:/,$item,4);
+ if ($remainder =~ /:/) {
+ (my $other,$group) = ($remainder =~ /^([\w:]+):([^:]+)$/);
+ } else {
+ $group = $remainder;
+ }
+ if ($group ne '') {
+ push(@activegroups,$group);
+ }
+ }
+ $newenv{'request.course.groups'} = join(':',@activegroups);
+ }
+ }
+ if (keys(%newenv)) {
+ &Apache::lonnet::appenv(\%newenv);
+ }
+ if (!@changed_roles || !(keys(%changed_groups))) {
+ my ($rolesmsg,$groupsmsg);
+ if (!@changed_roles) {
+ if (&Apache::loncommon::show_course()) {
+ $rolesmsg = &mt('No new courses or communities');
+ } else {
+ $rolesmsg = &mt('No role changes');
+ }
+ }
+ if ($hasgroups && !(keys(%changed_groups)) && !(grep(/gr/,@changed_roles))) {
+ $groupsmsg = &mt('No changes in course/community groups');
+ }
+ if (!@changed_roles && !(keys(%changed_groups))) {
+ if (($msg ne '') || ($groupsmsg ne '')) {
+ $msg .= '
';
+ if ($rolesmsg) {
+ $msg .= '
'.$rolesmsg.'
';
+ }
+ if ($groupsmsg) {
+ $msg .= '
'.$groupsmsg.'
';
+ }
+ $msg .= '
';
+ } else {
+ $msg = ' '.$rolesmsg.' ';
+ }
+ return $msg;
+ }
+ }
+ my $changemsg;
+ if (@changed_roles > 0) {
+ if (keys(%newgroup) > 0) {
+ my $groupmsg;
+ my (%curr_groups,%groupdescs,$currcrs);
+ foreach my $item (sort(keys(%newgroup))) {
+ if (&is_active_course($item,$refresh,$update,\%roleshash)) {
+ if ($item =~ m{^gr\./($match_domain/$match_courseid)/(\w+)$}) {
+ my ($cdom,$cnum) = split(/\//,$1);
+ my $group = $2;
+ if ($currcrs ne $cdom.'_'.$cnum) {
+ if ($currcrs) {
+ $groupmsg .= '
';
+ }
+ if ($env{'environment.canrequest.author'}) {
+ unless (&Apache::loncoursequeueadmin::is_active_author()) {
+ my $requestauthor;
+ my ($status,$timestamp) = split(/:/,$env{'environment.requestauthorqueued'});
+ if (($status eq 'approval') || ($status eq 'approved')) {
+ $output .= '
'.&mt('Author role request').' ';
+ if ($status eq 'approval') {
+ $output .= &mt('A request for authoring space submitted on [_1] is awaiting approval',
+ &Apache::lonlocal::locallocaltime($timestamp));
+ } elsif ($status eq 'approved') {
+ my %roleshash =
+ &Apache::lonnet::get_my_roles($env{'user.name'},$env{'user.domain'},'userroles',
+ ['active'],['au'],[$env{'user.domain'}]);
+ if (keys(%roleshash)) {
+ $output .= ''.
+ &mt('Your request for an author role has been approved.').' '.
+ &mt('Use the "Check for changes" link to update your list of roles.').
+ '';
+ }
+ }
+ $output .= '
';
+ }
+ }
+ }
+ unless ($output) {
+ if ($env{'environment.canrequest.author'} || $env{'environment.canrequest.official'} ||
+ $env{'environment.canrequest.unofficial'} || $env{'environment.canrequest.community'}) {
+ $output = &mt('No requests for courses, communities or authoring currently queued');
+ } else {
+ $output = &mt('No enrollment requests currently queued awaiting approval');
+ }
+ }
+ return ' ';
+}
+
1;
__END__
@@ -1250,8 +2826,7 @@ course they should act on, etc. Both in
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.
+what they were trying to do.
=begin latex