--- loncom/auth/lonroles.pm 2021/10/26 14:25:09 1.352 +++ loncom/auth/lonroles.pm 2021/11/30 15:55:40 1.359 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # User Roles Screen # -# $Id: lonroles.pm,v 1.352 2021/10/26 14:25:09 raeburn Exp $ +# $Id: lonroles.pm,v 1.359 2021/11/30 15:55:40 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -158,12 +158,21 @@ sub start_loading_course { my $brcrum = [{'href' => '', 'text' => $title},]; my $start_page = &Apache::loncommon::start_page($title,undef, - {'bread_crumbs' => $brcrum,}); + {'bread_crumbs' => $brcrum, + 'bread_crumbs_nomenu' => 1, + 'links_disabled' => 1}); $r->print(< // ENDREDIR @@ -172,8 +181,7 @@ ENDREDIR sub finish_loading_course { my ($r,$msg,$url) = @_; -#FIXME add continue link, and add jquery to enable menu links when page is loaded - my $link; + my $link = ''; my $end_page = &Apache::loncommon::end_page(); my $js_url = &js_escape($url); $r->print(< // a').removeAttr("aria-disabled"); + \$('.isDisabled').removeClass("isDisabled"); var url = "$js_url"; \$(location).attr('href',url); }); @@ -266,7 +277,8 @@ sub handler { $update = $then; } - my $norolelist; + my ($norolelist,$blocked_by_ip,$blocked_type,$clientip); + $clientip = &Apache::lonnet::get_requestor_ip($r); if (($env{'request.course.id'}) && ($env{'request.deeplink.login'})) { my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; @@ -303,6 +315,89 @@ sub handler { } } + if ($env{'form.selectrole'}) { + my ($role,$cdom,$cnum,$rest); + if ($env{'form.switchrole'} =~ m{^(co|cc|in|ta|ep|ad|st|cr).*?\./($match_domain)/($match_courseid)(/(\w+)|$)}) { + ($role,$cdom,$cnum,$rest) = ($1,$2,$3,$4); + } elsif ($env{'form.newrole'} =~ m{^(co|cc|in|ta|ep|ad|st|cr).*?\./($match_domain)/($match_courseid)(/(\w+)|$)}) { + ($role,$cdom,$cnum,$rest) = ($1,$2,$3,$4); + } + if ($cdom ne '') { + my ($has_evb,$check_ipaccess,$showrole); + $showrole = 1; + my $checkrole = "cm./$cdom/$cnum"; + if ($rest ne '') { + $checkrole .= "/$rest"; + } + if ((&Apache::lonnet::allowed('evb',undef,undef,$checkrole)) && + ($role ne 'st')) { + $has_evb = 1; + } + unless ($has_evb) { + my @machinedoms = &Apache::lonnet::current_machine_domains(); + my $udom = $env{'user.domain'}; + if ($udom eq $cdom) { + $check_ipaccess = 1; + } elsif (($udom ne '') && (grep(/^\Q$udom\E$/,@machinedoms))) { + $check_ipaccess = 1; + } else { + my $lonhost = $Apache::lonnet::perlvar{'lonHostID'}; + my $internet_names = &Apache::lonnet::get_internet_names($lonhost); + my $cprim = &Apache::lonnet::domain($cdom,'primary'); + my $cintdom = &Apache::lonnet::internet_dom($cprim); + if (($cintdom ne '') && (ref($internet_names) eq 'ARRAY')) { + if (grep(/^\Q$cintdom\E$/,@{$internet_names})) { + $check_ipaccess = 1; + } + } + } + if ($check_ipaccess) { + my ($ipaccessref,$cached)=&Apache::lonnet::is_cached_new('ipaccess',$cdom); + unless (defined($cached)) { + my %domconfig = + &Apache::lonnet::get_dom('configuration',['ipaccess'],$cdom); + $ipaccessref = &Apache::lonnet::do_cache_new('ipaccess',$cdom,$domconfig{'ipaccess'},1800); + } + if (ref($ipaccessref) eq 'HASH') { + foreach my $id (keys(%{$ipaccessref})) { + if (ref($ipaccessref->{$id}) eq 'HASH') { + my $range = $ipaccessref->{$id}->{'ip'}; + if ($range) { + my $type = 'exclude'; + if (&Apache::lonnet::ip_match($clientip,$range)) { + $type = 'include'; + } + if (ref($ipaccessref->{$id}->{'courses'}) eq 'HASH') { + if ($ipaccessref->{$id}->{'courses'}{$cdom.'_'.$cnum}) { + if ($type eq 'include') { + $showrole = 1; + last; + } else { + $showrole = 0; + } + } else { + if ($type eq 'include') { + $showrole = 0; + } else { + $showrole = 1; + } + } + } + } + } + } + } + } + } + unless ($showrole) { + $blocked_by_ip = 1; + $blocked_type = &Apache::loncommon::course_type($cdom.'_'.$cnum); + delete($env{'form.selectrole'}); + delete($env{'form.newrole'}); + } + } + } + $registered_cleanup=0; @{$rosterupdates}=(); &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}); @@ -685,7 +780,7 @@ ENDCLOSE $r->rflush(); my ($msg,$blockcrit,$critmsg_check); $critmsg_check = 1; - $blockcrit = &Apache::loncommon::blocking_status('alert',$cnum,$cdom,undef,1); + $blockcrit = &Apache::loncommon::blocking_status('alert',$clientip,$cnum,$cdom,undef,1); if ($blockcrit) { my $checkrole = "cm./$cdom/$cnum"; if ($csec ne '') { @@ -912,6 +1007,9 @@ ENDCLOSE $dest .= (($dest =~/\?/)? '&':'?').'symb='.$esc_symb; } } + if ($env{'form.ttoken'}) { + $dest .= (($dest =~/\?/)? '&':'?').'ttoken='.$env{'form.ttoken'}; + } unless ($env{'request.lti.login'}) { $msg = '

'.&mt('Entering [_1] ...', $env{'course.'.$cdom.'_'.$cnum.'.description'}). @@ -1054,6 +1152,10 @@ ENDCLOSE $recent = &mt('Recent Courses'); $standby = &mt('Course selected. Please stand by.'); } + if (($norolelist) && ((split(/:/,$env{'user.error.msg'}))[2])) { + $crumbtext = 'Access Denied'; + $pagetitle = 'Unauthorized'; + } my $brcrum =[{href=>"/adm/roles",text=>$crumbtext}]; my %roles_in_env; @@ -1090,11 +1192,13 @@ ENDCLOSE $start_page=&Apache::loncommon::start_page($pagetitle,undef, {bread_crumbs=>$brcrum,crstype=>'Placement'}); } else { - $funcs = &get_roles_functions($showcount,$cattype); my $crumbsright; - if ($env{'browser.mobile'}) { - $crumbsright = $funcs; - undef($funcs); + unless (($norolelist) && ((split(/:/,$env{'user.error.msg'}))[2])) { + $funcs = &get_roles_functions($showcount,$cattype); + if ($env{'browser.mobile'}) { + $crumbsright = $funcs; + undef($funcs); + } } $start_page=&Apache::loncommon::start_page($pagetitle,undef,{bread_crumbs=>$brcrum, bread_crumbs_component=>$crumbsright}); @@ -1202,8 +1306,16 @@ ENDHEADER } if ($nochoose) { $r->print("

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

\n". - &mt('This action is currently not authorized.').''. - &Apache::loncommon::end_page()); + &mt('This action is currently not authorized.').''); + if ($error && $norolelist) { + $r->print('

'. + &mt('As your session was launched from a web page external to LON-CAPA some course content may be unavailable, including the resource you were trying to access.'). + '

'. + '

'. + &mt('You may need to login to LON-CAPA directly, or re-launch from a different external system.'). + '

'); + } + $r->print(&Apache::loncommon::end_page()); return OK; } else { if ($updateresult || $reqauthor || $hotlist) { @@ -1232,6 +1344,16 @@ ENDHEADER $r->print(''); $r->print(''); $r->print(''); + if ($blocked_by_ip) { + my $blocked_role = 'student'; + if ($blocked_type eq 'Community') { + $blocked_role = 'member'; + } + $r->print('

'. + &mt('The [_1] you selected is not available for access with a [_2] role from your current IP address: [_3].', + lc($blocked_type),$blocked_role,$clientip). + '

'); + } } $r->rflush();