version 1.370, 2020/02/07 20:42:50
|
version 1.378, 2021/02/01 15:58:41
|
Line 176 use Locale::Language;
|
Line 176 use Locale::Language;
|
use DateTime::TimeZone; |
use DateTime::TimeZone; |
use DateTime::Locale; |
use DateTime::Locale; |
use Time::HiRes qw( sleep ); |
use Time::HiRes qw( sleep ); |
|
use Net::CIDR; |
|
|
my $registered_cleanup; |
my $registered_cleanup; |
my $modified_urls; |
my $modified_urls; |
Line 219 sub handler {
|
Line 220 sub handler {
|
'serverstatuses','requestcourses','helpsettings', |
'serverstatuses','requestcourses','helpsettings', |
'coursedefaults','usersessions','loadbalancing', |
'coursedefaults','usersessions','loadbalancing', |
'requestauthor','selfenrollment','inststatus', |
'requestauthor','selfenrollment','inststatus', |
'ltitools','ssl','trust','lti','privacy','passwords'],$dom); |
'ltitools','ssl','trust','lti','privacy','passwords', |
|
'proctoring','wafproxy'],$dom); |
my %encconfig = |
my %encconfig = |
&Apache::lonnet::get_dom('encconfig',['ltitools','lti'],$dom); |
&Apache::lonnet::get_dom('encconfig',['ltitools','lti','proctoring'],$dom); |
if (ref($domconfig{'ltitools'}) eq 'HASH') { |
if (ref($domconfig{'ltitools'}) eq 'HASH') { |
if (ref($encconfig{'ltitools'}) eq 'HASH') { |
if (ref($encconfig{'ltitools'}) eq 'HASH') { |
foreach my $id (keys(%{$domconfig{'ltitools'}})) { |
foreach my $id (keys(%{$domconfig{'ltitools'}})) { |
Line 246 sub handler {
|
Line 248 sub handler {
|
} |
} |
} |
} |
} |
} |
my @prefs_order = ('rolecolors','login','defaults','passwords','quotas','autoenroll', |
if (ref($domconfig{'proctoring'}) eq 'HASH') { |
'autoupdate','autocreate','directorysrch','contacts','privacy', |
if (ref($encconfig{'proctoring'}) eq 'HASH') { |
'usercreation','selfcreation','usermodification','scantron', |
foreach my $provider (keys(%{$domconfig{'proctoring'}})) { |
'requestcourses','requestauthor','coursecategories', |
if ((ref($domconfig{'proctoring'}{$provider}) eq 'HASH') && |
'serverstatuses','helpsettings','coursedefaults', |
(ref($encconfig{'proctoring'}{$provider}) eq 'HASH')) { |
'ltitools','selfenrollment','usersessions','ssl','trust','lti'); |
foreach my $item ('key','secret') { |
|
$domconfig{'proctoring'}{$provider}{$item} = $encconfig{'proctoring'}{$provider}{$item}; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
my @prefs_order = ('rolecolors','login','defaults','wafproxy','passwords','quotas', |
|
'autoenroll','autoupdate','autocreate','directorysrch', |
|
'contacts','privacy','usercreation','selfcreation', |
|
'usermodification','scantron','requestcourses','requestauthor', |
|
'coursecategories','serverstatuses','helpsettings','coursedefaults', |
|
'ltitools','proctoring','selfenrollment','usersessions','ssl', |
|
'trust','lti'); |
my %existing; |
my %existing; |
if (ref($domconfig{'loadbalancing'}) eq 'HASH') { |
if (ref($domconfig{'loadbalancing'}) eq 'HASH') { |
%existing = %{$domconfig{'loadbalancing'}}; |
%existing = %{$domconfig{'loadbalancing'}}; |
Line 296 sub handler {
|
Line 311 sub handler {
|
print => \&print_defaults, |
print => \&print_defaults, |
modify => \&modify_defaults, |
modify => \&modify_defaults, |
}, |
}, |
|
'wafproxy' => |
|
{ text => 'Web Application Firewall/Reverse Proxy', |
|
help => 'Domain_Configuration_WAF_Proxy', |
|
header => [{col1 => 'Domain server', |
|
col2 => 'Alias for WAF/Reverse Proxy', |
|
}, |
|
{col1 => 'Setting', |
|
col2 => 'Value',}], |
|
print => \&print_wafproxy, |
|
modify => \&modify_wafproxy, |
|
}, |
'passwords' => |
'passwords' => |
{ text => 'Passwords (Internal authentication)', |
{ text => 'Passwords (Internal authentication)', |
help => 'Domain_Configuration_Passwords', |
help => 'Domain_Configuration_Passwords', |
Line 541 sub handler {
|
Line 567 sub handler {
|
print => \&print_ltitools, |
print => \&print_ltitools, |
modify => \&modify_ltitools, |
modify => \&modify_ltitools, |
}, |
}, |
|
'proctoring' => |
|
{text => 'Remote Proctoring Integration', |
|
help => 'Domain_Configuration_Proctoring', |
|
header => [{col1 => 'Name', |
|
col2 => 'Configuration'}], |
|
print => \&print_proctoring, |
|
modify => \&modify_proctoring, |
|
}, |
'ssl' => |
'ssl' => |
{text => 'LON-CAPA Network (SSL)', |
{text => 'LON-CAPA Network (SSL)', |
help => 'Domain_Configuration_Network_SSL', |
help => 'Domain_Configuration_Network_SSL', |
Line 771 sub process_changes {
|
Line 805 sub process_changes {
|
$output = &modify_loadbalancing($dom,%domconfig); |
$output = &modify_loadbalancing($dom,%domconfig); |
} elsif ($action eq 'ltitools') { |
} elsif ($action eq 'ltitools') { |
$output = &modify_ltitools($r,$dom,$action,$lastactref,%domconfig); |
$output = &modify_ltitools($r,$dom,$action,$lastactref,%domconfig); |
|
} elsif ($action eq 'proctoring') { |
|
$output = &modify_proctoring($r,$dom,$action,$lastactref,%domconfig); |
} elsif ($action eq 'ssl') { |
} elsif ($action eq 'ssl') { |
$output = &modify_ssl($dom,$lastactref,%domconfig); |
$output = &modify_ssl($dom,$lastactref,%domconfig); |
} elsif ($action eq 'trust') { |
} elsif ($action eq 'trust') { |
Line 781 sub process_changes {
|
Line 817 sub process_changes {
|
$output = &modify_privacy($dom,%domconfig); |
$output = &modify_privacy($dom,%domconfig); |
} elsif ($action eq 'passwords') { |
} elsif ($action eq 'passwords') { |
$output = &modify_passwords($r,$dom,$confname,$lastactref,%domconfig); |
$output = &modify_passwords($r,$dom,$confname,$lastactref,%domconfig); |
|
} elsif ($action eq 'wafproxy') { |
|
$output = &modify_wafproxy($dom,$action,$lastactref,%domconfig); |
} |
} |
return $output; |
return $output; |
} |
} |
Line 815 sub print_config_box {
|
Line 853 sub print_config_box {
|
$output .= <itools_javascript($settings); |
$output .= <itools_javascript($settings); |
} elsif ($action eq 'lti') { |
} elsif ($action eq 'lti') { |
$output .= <i_javascript($settings); |
$output .= <i_javascript($settings); |
|
} elsif ($action eq 'proctoring') { |
|
$output .= &proctoring_javascript($settings); |
} |
} |
$output .= |
$output .= |
'<table class="LC_nested_outer"> |
'<table class="LC_nested_outer"> |
Line 856 sub print_config_box {
|
Line 896 sub print_config_box {
|
($action eq 'usermodification') || ($action eq 'defaults') || ($action eq 'coursedefaults') || |
($action eq 'usermodification') || ($action eq 'defaults') || ($action eq 'coursedefaults') || |
($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'ssl') || |
($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'ssl') || |
($action eq 'directorysrch') || ($action eq 'trust') || ($action eq 'helpsettings') || |
($action eq 'directorysrch') || ($action eq 'trust') || ($action eq 'helpsettings') || |
($action eq 'contacts') || ($action eq 'privacy')) { |
($action eq 'contacts') || ($action eq 'privacy') || ($action eq 'wafproxy')) { |
$output .= $item->{'print'}->('top',$dom,$settings,\$rowtotal); |
$output .= $item->{'print'}->('top',$dom,$settings,\$rowtotal); |
} elsif ($action eq 'passwords') { |
} elsif ($action eq 'passwords') { |
$output .= $item->{'print'}->('top',$dom,$confname,$settings,\$rowtotal); |
$output .= $item->{'print'}->('top',$dom,$confname,$settings,\$rowtotal); |
Line 893 sub print_config_box {
|
Line 933 sub print_config_box {
|
($action eq 'usersessions') || ($action eq 'coursecategories') || |
($action eq 'usersessions') || ($action eq 'coursecategories') || |
($action eq 'trust') || ($action eq 'contacts') || |
($action eq 'trust') || ($action eq 'contacts') || |
($action eq 'privacy') || ($action eq 'passwords')) { |
($action eq 'privacy') || ($action eq 'passwords')) { |
my $leftnobr = ' LC_nobreak'; |
|
if ($action eq 'coursecategories') { |
if ($action eq 'coursecategories') { |
$output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal); |
$output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal); |
$colspan = ' colspan="2"'; |
$colspan = ' colspan="2"'; |
Line 980 sub print_config_box {
|
Line 1019 sub print_config_box {
|
$rowtotal ++; |
$rowtotal ++; |
} elsif (($action eq 'usermodification') || ($action eq 'coursedefaults') || |
} elsif (($action eq 'usermodification') || ($action eq 'coursedefaults') || |
($action eq 'defaults') || ($action eq 'directorysrch') || |
($action eq 'defaults') || ($action eq 'directorysrch') || |
($action eq 'helpsettings')) { |
($action eq 'helpsettings') || ($action eq 'wafproxy')) { |
$output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal); |
$output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal); |
} elsif ($action eq 'scantron') { |
} elsif ($action eq 'scantron') { |
$output .= $item->{'print'}->($r,'bottom',$dom,$confname,$settings,\$rowtotal); |
$output .= $item->{'print'}->($r,'bottom',$dom,$confname,$settings,\$rowtotal); |
Line 1163 sub print_config_box {
|
Line 1202 sub print_config_box {
|
$output .= &print_quotas($dom,$settings,\$rowtotal,$action); |
$output .= &print_quotas($dom,$settings,\$rowtotal,$action); |
} elsif (($action eq 'autoenroll') || ($action eq 'autocreate') || |
} elsif (($action eq 'autoenroll') || ($action eq 'autocreate') || |
($action eq 'serverstatuses') || ($action eq 'loadbalancing') || |
($action eq 'serverstatuses') || ($action eq 'loadbalancing') || |
($action eq 'ltitools') || ($action eq 'lti')) { |
($action eq 'ltitools') || ($action eq 'lti') || |
|
($action eq 'proctoring')) { |
$output .= $item->{'print'}->($dom,$settings,\$rowtotal); |
$output .= $item->{'print'}->($dom,$settings,\$rowtotal); |
} |
} |
} |
} |
Line 2804 function toggleLTITools(form,setting,ite
|
Line 2844 function toggleLTITools(form,setting,ite
|
ENDSCRIPT |
ENDSCRIPT |
} |
} |
|
|
|
sub proctoring_javascript { |
|
my ($settings) = @_; |
|
my (%ordered,$total,%jstext); |
|
$total = 0; |
|
if (ref($settings) eq 'HASH') { |
|
foreach my $item (keys(%{$settings})) { |
|
if (ref($settings->{$item}) eq 'HASH') { |
|
my $num = $settings->{$item}{'order'}; |
|
$ordered{$num} = $item; |
|
} |
|
} |
|
$total = scalar(keys(%{$settings})); |
|
} else { |
|
%ordered = ( |
|
0 => 'proctorio', |
|
1 => 'examity', |
|
); |
|
$total = 2; |
|
} |
|
my @jsarray = (); |
|
foreach my $item (sort {$a <=> $b } (keys(%ordered))) { |
|
push(@jsarray,$ordered{$item}); |
|
} |
|
my $jstext = ' var proctors = Array('."'".join("','",@jsarray)."'".');'."\n"; |
|
return <<"ENDSCRIPT"; |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
function reorderProctoring(form,item) { |
|
var changedVal; |
|
$jstext |
|
var maxh = $total; |
|
var current = new Array; |
|
var changedVal = form.elements[item].options[form.elements[item].selectedIndex].value; |
|
for (var i=0; i<proctors.length; i++) { |
|
var elementName = 'proctoring_pos_'+proctors[i]; |
|
if (elementName != item) { |
|
if (form.elements[elementName]) { |
|
var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value; |
|
current[currVal] = elementName; |
|
} |
|
} |
|
} |
|
var oldVal; |
|
for (var j=0; j<maxh; j++) { |
|
if (current[j] == undefined) { |
|
oldVal = j; |
|
} |
|
} |
|
if (oldVal < changedVal) { |
|
for (var k=oldVal+1; k<=changedVal ; k++) { |
|
var elementName = current[k]; |
|
form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1; |
|
} |
|
} else { |
|
for (var k=changedVal; k<oldVal; k++) { |
|
var elementName = current[k]; |
|
form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1; |
|
} |
|
} |
|
return; |
|
} |
|
|
|
function toggleProctoring(form,item) { |
|
var fieldsets = document.getElementsByClassName('proctoring_'+item); |
|
if (fieldsets.length) { |
|
var radioname = 'proctoring_available_'+item; |
|
var num = form.elements[radioname].length; |
|
if (num) { |
|
var setvis = ''; |
|
for (var i=0; i<num; i++) { |
|
if (form.elements[radioname][i].checked) { |
|
if (form.elements[radioname][i].value == '1') { |
|
setvis = 1; |
|
break; |
|
} |
|
} |
|
} |
|
for (var j=0; j<fieldsets.length; j++) { |
|
if (setvis) { |
|
fieldsets[j].style.display = 'block'; |
|
} else { |
|
fieldsets[j].style.display = 'none'; |
|
} |
|
} |
|
} |
|
} |
|
return; |
|
} |
|
|
|
// ]]> |
|
</script> |
|
|
|
ENDSCRIPT |
|
} |
|
|
|
|
sub lti_javascript { |
sub lti_javascript { |
my ($settings) = @_; |
my ($settings) = @_; |
my $togglejs = <i_toggle_js(); |
my $togglejs = <i_toggle_js(); |
Line 3645 sub print_contacts {
|
Line 3781 sub print_contacts {
|
\%choices,$rownum); |
\%choices,$rownum); |
$datatable .= $reports; |
$datatable .= $reports; |
} elsif ($position eq 'lower') { |
} elsif ($position eq 'lower') { |
$css_class = $rownum%2?' class="LC_odd_row"':''; |
my (%current,%excluded,%weights); |
my ($threshold,$sysmail,%excluded,%weights); |
|
my ($defaults,$names) = &Apache::loncommon::lon_status_items(); |
my ($defaults,$names) = &Apache::loncommon::lon_status_items(); |
if ($lonstatus{'threshold'} =~ /^\d+$/) { |
if ($lonstatus{'threshold'} =~ /^\d+$/) { |
$threshold = $lonstatus{'threshold'}; |
$current{'errorthreshold'} = $lonstatus{'threshold'}; |
} else { |
} else { |
$threshold = $defaults->{'threshold'}; |
$current{'errorthreshold'} = $defaults->{'threshold'}; |
} |
} |
if ($lonstatus{'sysmail'} =~ /^\d+$/) { |
if ($lonstatus{'sysmail'} =~ /^\d+$/) { |
$sysmail = $lonstatus{'sysmail'}; |
$current{'errorsysmail'} = $lonstatus{'sysmail'}; |
} else { |
} else { |
$sysmail = $defaults->{'sysmail'}; |
$current{'errorsysmail'} = $defaults->{'sysmail'}; |
} |
} |
if (ref($lonstatus{'weights'}) eq 'HASH') { |
if (ref($lonstatus{'weights'}) eq 'HASH') { |
foreach my $type ('E','W','N','U') { |
foreach my $type ('E','W','N','U') { |
Line 3676 sub print_contacts {
|
Line 3811 sub print_contacts {
|
map {$excluded{$_} = 1; } @{$lonstatus{'excluded'}}; |
map {$excluded{$_} = 1; } @{$lonstatus{'excluded'}}; |
} |
} |
} |
} |
$datatable .= '<tr'.$css_class.'>'. |
foreach my $item ('errorthreshold','errorsysmail') { |
'<td class="LC_left_item"><span class="LC_nobreak">'. |
$css_class = $rownum%2?' class="LC_odd_row"':''; |
$titles->{'errorthreshold'}. |
$datatable .= '<tr'.$css_class.'>'. |
'</span></td><td class="LC_left_item">'. |
'<td class="LC_left_item"><span class="LC_nobreak">'. |
'<input type="text" name="errorthreshold" value="'. |
$titles->{$item}. |
$threshold.'" size="5" /></td></tr>'; |
'</span></td><td class="LC_left_item">'. |
$rownum ++; |
'<input type="text" name="'.$item.'" value="'. |
|
$current{$item}.'" size="5" /></td></tr>'; |
|
$rownum ++; |
|
} |
$css_class = $rownum%2?' class="LC_odd_row"':''; |
$css_class = $rownum%2?' class="LC_odd_row"':''; |
$datatable .= '<tr'.$css_class.'>'. |
$datatable .= '<tr'.$css_class.'>'. |
'<td class="LC_left_item">'. |
'<td class="LC_left_item">'. |
Line 3728 sub print_contacts {
|
Line 3866 sub print_contacts {
|
} |
} |
$datatable .= '</tr></table></td></tr>'; |
$datatable .= '</tr></table></td></tr>'; |
$rownum ++; |
$rownum ++; |
$css_class = $rownum%2?' class="LC_odd_row"':''; |
|
$datatable .= '<tr'.$css_class.'>'. |
|
'<td class="LC_left_item"><span class="LC_nobreak">'. |
|
$titles->{'errorsysmail'}. |
|
'</span></td><td class="LC_left_item">'. |
|
'<input type="text" name="errorsysmail" value="'. |
|
$sysmail.'" size="5" /></td></tr>'; |
|
$rownum ++; |
|
} elsif ($position eq 'bottom') { |
} elsif ($position eq 'bottom') { |
my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); |
my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); |
my (@posstypes,%usertypeshash); |
my (@posstypes,%usertypeshash); |
Line 4621 sub print_ltitools {
|
Line 4751 sub print_ltitools {
|
} |
} |
$datatable .= '<label>'. |
$datatable .= '<label>'. |
'<input type="checkbox" name="ltitools_courseconfig_'.$i.'" value="'.$item.'"'.$checked.' />'. |
'<input type="checkbox" name="ltitools_courseconfig_'.$i.'" value="'.$item.'"'.$checked.' />'. |
$lt{'crs'.$item}.'</label>'.(' ' x2)."\n"; |
$lt{'crs'.$item}.'</label> '."\n"; |
} |
} |
$datatable .= '</span></fieldset>'. |
$datatable .= '</span></fieldset>'. |
'<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'. |
'<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'. |
Line 4823 sub ltitools_names {
|
Line 4953 sub ltitools_names {
|
return %lt; |
return %lt; |
} |
} |
|
|
|
sub print_proctoring { |
|
my ($dom,$settings,$rowtotal) = @_; |
|
my $itemcount = 1; |
|
my (%ordered,%providernames,%current,%currentdef); |
|
my $confname = $dom.'-domainconfig'; |
|
my $switchserver = &check_switchserver($dom,$confname); |
|
if (ref($settings) eq 'HASH') { |
|
foreach my $item (keys(%{$settings})) { |
|
if (ref($settings->{$item}) eq 'HASH') { |
|
my $num = $settings->{$item}{'order'}; |
|
$ordered{$num} = $item; |
|
} |
|
} |
|
} else { |
|
%ordered = ( |
|
1 => 'proctorio', |
|
2 => 'examity', |
|
); |
|
} |
|
%providernames = &proctoring_providernames(); |
|
my $maxnum = scalar(keys(%ordered)); |
|
my (%requserfields,%optuserfields,%defaults,%extended,%crsconf,@courseroles,@ltiroles); |
|
my ($requref,$opturef,$defref,$extref,$crsref,$rolesref,$ltiref) = &proctoring_data(); |
|
if (ref($requref) eq 'HASH') { |
|
%requserfields = %{$requref}; |
|
} |
|
if (ref($opturef) eq 'HASH') { |
|
%optuserfields = %{$opturef}; |
|
} |
|
if (ref($defref) eq 'HASH') { |
|
%defaults = %{$defref}; |
|
} |
|
if (ref($extref) eq 'HASH') { |
|
%extended = %{$extref}; |
|
} |
|
if (ref($crsref) eq 'HASH') { |
|
%crsconf = %{$crsref}; |
|
} |
|
if (ref($rolesref) eq 'ARRAY') { |
|
@courseroles = @{$rolesref}; |
|
} |
|
if (ref($ltiref) eq 'ARRAY') { |
|
@ltiroles = @{$ltiref}; |
|
} |
|
my $datatable; |
|
my $css_class; |
|
if (keys(%ordered)) { |
|
my @items = sort { $a <=> $b } keys(%ordered); |
|
for (my $i=0; $i<@items; $i++) { |
|
$css_class = $itemcount%2?' class="LC_odd_row"':''; |
|
my $provider = $ordered{$items[$i]}; |
|
my $optionsty = 'none'; |
|
my ($available,$version,$lifetime,$imgsrc,$userincdom,$showroles, |
|
%checkedfields,%rolemaps,%inuse,%crsconfig,%current); |
|
if (ref($settings) eq 'HASH') { |
|
if (ref($settings->{$provider}) eq 'HASH') { |
|
%current = %{$settings->{$provider}}; |
|
if ($current{'available'}) { |
|
$optionsty = 'block'; |
|
$available = 1; |
|
} |
|
if ($current{'lifetime'} =~ /^\d+$/) { |
|
$lifetime = $current{'lifetime'}; |
|
} |
|
if ($current{'version'} =~ /^\d+\.\d+$/) { |
|
$version = $current{'version'}; |
|
} |
|
if ($current{'image'} ne '') { |
|
$imgsrc = '<img src="'.$current{'image'}.'" alt="'.&mt('Proctoring service icon').'" />'; |
|
} |
|
if (ref($current{'fields'}) eq 'ARRAY') { |
|
map { $checkedfields{$_} = 1; } @{$current{'fields'}}; |
|
} |
|
$userincdom = $current{'incdom'}; |
|
if (ref($current{'roles'}) eq 'HASH') { |
|
%rolemaps = %{$current{'roles'}}; |
|
$checkedfields{'roles'} = 1; |
|
} |
|
if (ref($current{'defaults'}) eq 'ARRAY') { |
|
foreach my $val (@{$current{'defaults'}}) { |
|
if (grep(/^\Q$val\E$/,@{$defaults{$provider}})) { |
|
$inuse{$val} = 1; |
|
} else { |
|
foreach my $poss (keys(%{$extended{$provider}})) { |
|
if (ref($extended{$provider}{$poss}) eq 'ARRAY') { |
|
if (grep(/^\Q$val\E$/,@{$extended{$provider}{$poss}})) { |
|
$inuse{$poss} = $val; |
|
last; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} elsif (ref($current{'defaults'}) eq 'HASH') { |
|
foreach my $key (keys(%{$current{'defaults'}})) { |
|
my $currval = $current{'defaults'}{$key}; |
|
if (grep(/^\Q$key\E$/,@{$defaults{$provider}})) { |
|
$inuse{$key} = 1; |
|
} else { |
|
my $match; |
|
foreach my $poss (keys(%{$extended{$provider}})) { |
|
if (ref($extended{$provider}{$poss}) eq 'ARRAY') { |
|
if (grep(/^\Q$key\E$/,@{$extended{$provider}{$poss}})) { |
|
$inuse{$poss} = $key; |
|
last; |
|
} |
|
} elsif (ref($extended{$provider}{$poss}) eq 'HASH') { |
|
foreach my $inner (sort(keys(%{$extended{$provider}{$poss}}))) { |
|
if (ref($extended{$provider}{$poss}{$inner}) eq 'ARRAY') { |
|
if (grep(/^\Q$currval\E$/,@{$extended{$provider}{$poss}{$inner}})) { |
|
$currentdef{$inner} = $currval; |
|
$match = 1; |
|
last; |
|
} |
|
} elsif ($inner eq $key) { |
|
$currentdef{$key} = $currval; |
|
$match = 1; |
|
last; |
|
} |
|
} |
|
} |
|
last if ($match); |
|
} |
|
} |
|
} |
|
} |
|
if (ref($current{'crsconf'}) eq 'ARRAY') { |
|
map { $crsconfig{$_} = 1; } @{$current{'crsconf'}}; |
|
} |
|
} |
|
} |
|
my %lt = &proctoring_titles($provider); |
|
my %fieldtitles = &proctoring_fieldtitles($provider); |
|
my $onclickavailable = ' onclick="toggleProctoring(this.form,'."'$provider'".');"'; |
|
my %checkedavailable = ( |
|
yes => '', |
|
no => ' checked="checked"', |
|
); |
|
if ($available) { |
|
$checkedavailable{'yes'} = $checkedavailable{'no'}; |
|
$checkedavailable{'no'} = ''; |
|
} |
|
my $chgstr = ' onchange="javascript:reorderProctoring(this.form,'."'proctoring_pos_".$provider."'".');"'; |
|
$datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">' |
|
.'<select name="proctoring_pos_'.$provider.'"'.$chgstr.'>'; |
|
for (my $k=0; $k<$maxnum; $k++) { |
|
my $vpos = $k+1; |
|
my $selstr; |
|
if ($k == $i) { |
|
$selstr = ' selected="selected" '; |
|
} |
|
$datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>'; |
|
} |
|
if ($version eq '') { |
|
if ($provider eq 'proctorio') { |
|
$version = '1.0'; |
|
} elsif ($provider eq 'examity') { |
|
$version = '1.1'; |
|
} |
|
} |
|
if ($lifetime eq '') { |
|
$lifetime = '300'; |
|
} |
|
$datatable .= |
|
'</select>'.(' 'x2).'<b>'.$providernames{$provider}.'</b></span><br />'. |
|
'<span class="LC_nobreak">'.$lt{'avai'}.' '. |
|
'<label><input type="radio" name="proctoring_available_'.$provider.'" value="1"'.$onclickavailable.$checkedavailable{yes}.' />'.&mt('Yes').'</label> '."\n". |
|
'<label><input type="radio" name="proctoring_available_'.$provider.'" value="0"'.$onclickavailable.$checkedavailable{no}.' />'.&mt('No').'</label></span>'."\n". |
|
'</td>'. |
|
'<td colspan="2">'. |
|
'<fieldset class="proctoring_'.$provider.'" style="display:'.$optionsty.'"><legend>'.$lt{'base'}.'</legend>'. |
|
'<span class="LC_nobreak">'.$lt{'version'}.':<select name="proctoring_'.$provider.'_version">'. |
|
'<option value="'.$version.'" selected="selected">'.$version.'</option></select></span> '."\n". |
|
(' 'x2). |
|
'<span class="LC_nobreak">'.$lt{'sigmethod'}.':<select name="proctoring_'.$provider.'_sigmethod">'. |
|
'<option value="HMAC-SHA1" selected="selected">HMAC-SHA1</option>'. |
|
'<option value="HMAC-SHA256">HMAC-SHA256</option></select></span>'. |
|
(' 'x2). |
|
'<span class="LC_nobreak">'.$lt{'lifetime'}.':<input type="text" size="5" name="proctoring_'.$provider.'_lifetime" value="'.$lifetime.'" /></span> '."\n". |
|
'<br />'. |
|
'<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="40" name="proctoring_'.$provider.'_url" value="'.$current{'url'}.'" /></span> '."\n". |
|
'<br />'. |
|
'<span class="LC_nobreak">'.$lt{'key'}.':<input type="text" size="25" name="proctoring_'.$provider.'_key" value="'.$current{'key'}.'" /></span> '."\n". |
|
(' 'x2). |
|
'<span class="LC_nobreak">'.$lt{'secret'}.':<input type="password" size="20" name="proctoring_'.$provider.'_secret" value="'.$current{'secret'}.'" />'. |
|
'<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.proctoring_'.$provider.'_secret.type='."'text'".' } else { this.form.proctoring_'.$provider.'_secret.type='."'password'".' }" />'.$lt{'visible'}.'</label></span><br />'."\n"; |
|
$datatable .= '<span class="LC_nobreak">'.$lt{'icon'}.': '; |
|
if ($imgsrc) { |
|
$datatable .= $imgsrc. |
|
'<label><input type="checkbox" name="proctoring_image_del"'. |
|
' value="'.$provider.'" />'.&mt('Delete?').'</label></span> '. |
|
'<span class="LC_nobreak"> '.&mt('Replace:'); |
|
} |
|
$datatable .= ' '; |
|
if ($switchserver) { |
|
$datatable .= &mt('Upload to library server: [_1]',$switchserver); |
|
} else { |
|
$datatable .= '<input type="file" name="proctoring_image_'.$provider.'" value="" />'; |
|
} |
|
unless ($imgsrc) { |
|
$datatable .= '<br />('.&mt('if larger than 21x21 pixels, image will be scaled').')'; |
|
} |
|
$datatable .= '</fieldset>'."\n"; |
|
if (ref($requserfields{$provider}) eq 'ARRAY') { |
|
if (@{$requserfields{$provider}} > 0) { |
|
$datatable .= '<fieldset class="proctoring_'.$provider.'" style="display:'.$optionsty.'"><legend>'.$lt{'requ'}.'</legend>'; |
|
foreach my $field (@{$requserfields{$provider}}) { |
|
$datatable .= '<span class="LC_nobreak">'. |
|
'<label><input type="checkbox" name="proctoring_reqd_'.$provider.'" value="'.$field.'" checked="checked" disabled="disabled" />'. |
|
$lt{$field}.'</label>'; |
|
if ($field eq 'user') { |
|
my $seluserdom = ''; |
|
my $unseluserdom = ' selected="selected"'; |
|
if ($userincdom) { |
|
$seluserdom = $unseluserdom; |
|
$unseluserdom = ''; |
|
} |
|
$datatable .= ': '. |
|
'<select name="proctoring_userincdom_'.$provider.'">'. |
|
'<option value="0"'.$unseluserdom.'>'.$lt{'username'}.'</option>'. |
|
'<option value="1"'.$seluserdom.'>'.$lt{'uname:dom'}.'</option>'. |
|
'</select> '; |
|
} else { |
|
$datatable .= ' '; |
|
if ($field eq 'roles') { |
|
$showroles = 1; |
|
} |
|
} |
|
$datatable .= '</span> '; |
|
} |
|
} |
|
$datatable .= '</fieldset>'."\n"; |
|
} |
|
if (ref($optuserfields{$provider}) eq 'ARRAY') { |
|
if (@{$optuserfields{$provider}} > 0) { |
|
$datatable .= '<fieldset class="proctoring_'.$provider.'" style="display:'.$optionsty.'"><legend>'.$lt{'optu'}.'</legend>'; |
|
foreach my $field (@{$optuserfields{$provider}}) { |
|
my $checked; |
|
if ($checkedfields{$field}) { |
|
$checked = ' checked="checked"'; |
|
} |
|
$datatable .= '<span class="LC_nobreak">'. |
|
'<label><input type="checkbox" name="proctoring_optional_'.$provider.'" value="'.$field.'"'.$checked.' />'.$lt{$field}.'</label></span> '; |
|
} |
|
$datatable .= '</fieldset>'."\n"; |
|
} |
|
} |
|
if (ref($defaults{$provider}) eq 'ARRAY') { |
|
if (@{$defaults{$provider}}) { |
|
my (%options,@selectboxes); |
|
if (ref($extended{$provider}) eq 'HASH') { |
|
%options = %{$extended{$provider}}; |
|
} |
|
$datatable .= '<fieldset class="proctoring_'.$provider.'" style="display:'.$optionsty.'"><legend>'.$lt{'defa'}.'</legend>'; |
|
my ($rem,$numinrow,$dropdowns); |
|
if ($provider eq 'proctorio') { |
|
$datatable .= '<table>'; |
|
$numinrow = 4; |
|
} |
|
my $i = 0; |
|
foreach my $field (@{$defaults{$provider}}) { |
|
my $checked; |
|
if ($inuse{$field}) { |
|
$checked = ' checked="checked"'; |
|
} |
|
if ($provider eq 'examity') { |
|
if ($field eq 'display') { |
|
$datatable .= '<span class="LC_nobreak">'.&mt('Display target:'); |
|
foreach my $option ('iframe','tab','window') { |
|
my $checkdisp; |
|
if ($currentdef{'target'} eq $option) { |
|
$checkdisp = ' checked="checked"'; |
|
} |
|
$datatable .= '<label><input type="radio" name="proctoring_target_'.$provider.'" value="'.$option.'"'.$checkdisp.' />'. |
|
$fieldtitles{$option}.'</label>'.(' 'x2); |
|
} |
|
$datatable .= (' 'x4); |
|
foreach my $dimen ('width','height') { |
|
$datatable .= '<label>'.$fieldtitles{$dimen}.' '. |
|
'<input type="text" name="proctoring_'.$dimen.'_'.$provider.'" size="5" '. |
|
'value="'.$currentdef{$dimen}.'" /></label>'. |
|
(' 'x2); |
|
} |
|
$datatable .= '</span><br />'. |
|
'<div class="LC_left_float">'.$fieldtitles{'linktext'}.'<br />'. |
|
'<input type="text" name="proctoring_linktext_'.$provider.'" '. |
|
'size="25" value="'.$currentdef{'linktext'}.'" /></div>'. |
|
'<div class="LC_left_float">'.$fieldtitles{'explanation'}.'<br />'. |
|
'<textarea name="proctoring_explanation_'.$provider.'" rows="5" cols="40">'. |
|
$currentdef{'explanation'}. |
|
'</textarea></div><div style=""></div><br />'; |
|
} |
|
} else { |
|
if ((exists($options{$field})) && (ref($options{$field}) eq 'ARRAY')) { |
|
my ($output,$selnone); |
|
unless ($checked) { |
|
$selnone = ' selected="selected"'; |
|
} |
|
$output .= '<span class="LC_nobreak">'.$fieldtitles{$field}.': '. |
|
'<select name="proctoring_defaults_'.$field.'_'.$provider.'">'. |
|
'<option value=""'.$selnone.'>'.&mt('Not in use').'</option>'; |
|
foreach my $option (@{$options{$field}}) { |
|
my $sel; |
|
if ($inuse{$field} eq $option) { |
|
$sel = ' selected="selected"'; |
|
} |
|
$output .= '<option value="'.$option.'"'.$sel.'>'.$fieldtitles{$option}.'</option>'; |
|
} |
|
$output .= '</select></span>'; |
|
push(@selectboxes,$output); |
|
} else { |
|
$rem = $i%($numinrow); |
|
if ($rem == 0) { |
|
if ($i > 0) { |
|
$datatable .= '</tr>'; |
|
} |
|
$datatable .= '<tr>'; |
|
} |
|
$datatable .= '<td class="LC_left_item">'. |
|
'<span class="LC_nobreak">'. |
|
'<label><input type="checkbox" name="proctoring_defaults_'.$provider.'" value="'.$field.'"'.$checked.' />'. |
|
$fieldtitles{$field}.'</label></span></td>'; |
|
$i++; |
|
} |
|
} |
|
} |
|
if ($provider eq 'proctorio') { |
|
if ($numinrow) { |
|
$rem = $i%$numinrow; |
|
} |
|
my $colsleft = $numinrow - $rem; |
|
if ($colsleft > 1) { |
|
$datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'; |
|
} else { |
|
$datatable .= '<td class="LC_left_item">'; |
|
} |
|
$datatable .= ' '. |
|
'</td></tr></table>'; |
|
if (@selectboxes) { |
|
$datatable .= '<hr /><table>'; |
|
$numinrow = 2; |
|
for (my $i=0; $i<@selectboxes; $i++) { |
|
$rem = $i%($numinrow); |
|
if ($rem == 0) { |
|
if ($i > 0) { |
|
$datatable .= '</tr>'; |
|
} |
|
$datatable .= '<tr>'; |
|
} |
|
$datatable .= '<td class="LC_left_item">'. |
|
$selectboxes[$i].'</td>'; |
|
} |
|
if ($numinrow) { |
|
$rem = $i%$numinrow; |
|
} |
|
$colsleft = $numinrow - $rem; |
|
if ($colsleft > 1) { |
|
$datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'; |
|
} else { |
|
$datatable .= '<td class="LC_left_item">'; |
|
} |
|
$datatable .= ' '. |
|
'</td></tr></table>'; |
|
} |
|
} |
|
$datatable .= '</fieldset>'; |
|
} |
|
if (ref($crsconf{$provider}) eq 'ARRAY') { |
|
$datatable .= '<fieldset class="proctoring_'.$provider.'" style="display:'.$optionsty.'">'. |
|
'<legend>'.&mt('Configurable in course').'</legend>'; |
|
my ($rem,$numinrow); |
|
if ($provider eq 'proctorio') { |
|
$datatable .= '<table>'; |
|
$numinrow = 4; |
|
} |
|
my $i = 0; |
|
foreach my $item (@{$crsconf{$provider}}) { |
|
my $name; |
|
if ($provider eq 'examity') { |
|
$name = $lt{'crs'.$item}; |
|
} elsif ($provider eq 'proctorio') { |
|
$name = $fieldtitles{$item}; |
|
$rem = $i%($numinrow); |
|
if ($rem == 0) { |
|
if ($i > 0) { |
|
$datatable .= '</tr>'; |
|
} |
|
$datatable .= '<tr>'; |
|
} |
|
$datatable .= '<td class="LC_left_item>'; |
|
} |
|
my $checked; |
|
if ($crsconfig{$item}) { |
|
$checked = ' checked="checked"'; |
|
} |
|
$datatable .= '<span class="LC_nobreak"><label>'. |
|
'<input type="checkbox" name="proctoring_crsconf_'.$provider.'" value="'.$item.'"'.$checked.' />'. |
|
$name.'</label></span>'; |
|
if ($provider eq 'examity') { |
|
$datatable .= ' '; |
|
} |
|
$datatable .= "\n"; |
|
$i++; |
|
} |
|
if ($provider eq 'proctorio') { |
|
if ($numinrow) { |
|
$rem = $i%$numinrow; |
|
} |
|
my $colsleft = $numinrow - $rem; |
|
if ($colsleft > 1) { |
|
$datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'; |
|
} else { |
|
$datatable .= '<td class="LC_left_item">'; |
|
} |
|
$datatable .= ' '. |
|
'</td></tr></table>'; |
|
} |
|
$datatable .= '</fieldset>'; |
|
} |
|
if ($showroles) { |
|
$datatable .= '<fieldset class="proctoring_'.$provider.'" style="display:'.$optionsty.'">'. |
|
'<legend>'.&mt('Role mapping').'</legend><table><tr>'; |
|
foreach my $role (@courseroles) { |
|
my ($selected,$selectnone); |
|
if (!$rolemaps{$role}) { |
|
$selectnone = ' selected="selected"'; |
|
} |
|
$datatable .= '<td style="text-align: center">'. |
|
&Apache::lonnet::plaintext($role,'Course').'<br />'. |
|
'<select name="proctoring_roles_'.$role.'_'.$provider.'">'. |
|
'<option value=""'.$selectnone.'>'.&mt('Select').'</option>'; |
|
foreach my $ltirole (@ltiroles) { |
|
unless ($selectnone) { |
|
if ($rolemaps{$role} eq $ltirole) { |
|
$selected = ' selected="selected"'; |
|
} else { |
|
$selected = ''; |
|
} |
|
} |
|
$datatable .= '<option value="'.$ltirole.'"'.$selected.'>'.$ltirole.'</option>'; |
|
} |
|
$datatable .= '</select></td>'; |
|
} |
|
$datatable .= '</tr></table></fieldset>'. |
|
'<fieldset class="proctoring_'.$provider.'" style="display:'.$optionsty.'">'. |
|
'<legend>'.&mt('Custom items sent on launch').'</legend>'. |
|
'<table><tr><th>'.&mt('Action').'</th><th>'.&mt('Name').'</th><th>'.&mt('Value').'</th></tr>'. |
|
'<tr><td></td><td>lms</td>'. |
|
'<td><input type="text" name="proctoring_customval_lms_'.$provider.'"'. |
|
' value="Loncapa" disabled="disabled"/></td></tr>'; |
|
if ((ref($settings) eq 'HASH') && (ref($settings->{$provider}) eq 'HASH') && |
|
(ref($settings->{$provider}->{'custom'}) eq 'HASH')) { |
|
my %custom = %{$settings->{$provider}->{'custom'}}; |
|
if (keys(%custom) > 0) { |
|
foreach my $key (sort(keys(%custom))) { |
|
next if ($key eq 'lms'); |
|
$datatable .= '<tr><td><span class="LC_nobreak">'. |
|
'<label><input type="checkbox" name="proctoring_customdel_'.$provider.'" value="'. |
|
$key.'" />'.&mt('Delete').'</label></span></td><td>'.$key.'</td>'. |
|
'<td><input type="text" name="proctoring_customval_'.$key.'_'.$provider.'"'. |
|
' value="'.$custom{$key}.'" /></td></tr>'; |
|
} |
|
} |
|
} |
|
$datatable .= '<tr><td><span class="LC_nobreak">'. |
|
'<label><input type="checkbox" name="proctoring_customadd" value="'.$provider.'" />'. |
|
&mt('Add more').'</label></span></td><td><input type="text" name="proctoring_custom_name_'.$provider.'" />'. |
|
'</td><td><input type="text" name="proctoring_custom_value_'.$provider.'" /></td></tr>'. |
|
'</table></fieldset></td></tr>'."\n"; |
|
} |
|
$datatable .= '</td></tr>'; |
|
} |
|
$itemcount ++; |
|
} |
|
} |
|
return $datatable; |
|
} |
|
|
|
sub proctoring_data { |
|
my $requserfields = { |
|
proctorio => ['user'], |
|
examity => ['roles','user'], |
|
}; |
|
my $optuserfields = { |
|
proctorio => ['fullname'], |
|
examity => ['fullname','firstname','lastname','email'], |
|
}; |
|
my $defaults = { |
|
proctorio => ['recordvideo','recordaudio','recordscreen','recordwebtraffic', |
|
'recordroomstart','verifyvideo','verifyaudio','verifydesktop', |
|
'verifyid','verifysignature','fullscreen','clipboard','tabslinks', |
|
'closetabs','onescreen','print','downloads','cache','rightclick', |
|
'reentry','calculator','whiteboard'], |
|
examity => ['display'], |
|
}; |
|
my $extended = { |
|
proctorio => { |
|
verifyid => ['verifyidauto','verifyidlive'], |
|
fullscreen => ['fullscreenlenient','fullscreenmoderate','fullscreensever'], |
|
tabslinks => ['notabs','linksonly'], |
|
reentry => ['noreentry','agentreentry'], |
|
calculator => ['calculatorbasic','calculatorsci'], |
|
}, |
|
examity => { |
|
display => { |
|
target => ['iframe','tab','window'], |
|
width => '', |
|
height => '', |
|
linktext => '', |
|
explanation => '', |
|
}, |
|
}, |
|
}; |
|
my $crsconf = { |
|
proctorio => ['recordvideo','recordaudio','recordscreen','recordwebtraffic', |
|
'recordroomstart','verifyvideo','verifyaudio','verifydesktop', |
|
'verifyid','verifysignature','fullscreen','clipboard','tabslinks', |
|
'closetabs','onescreen','print','downloads','cache','rightclick', |
|
'reentry','calculator','whiteboard'], |
|
examity => ['label','title','target','linktext','explanation','append'], |
|
}; |
|
my $courseroles = ['cc','in','ta','ep','st']; |
|
my $ltiroles = ['Instructor','ContentDeveloper','TeachingAssistant','Learner']; |
|
return ($requserfields,$optuserfields,$defaults,$extended,$crsconf,$courseroles,$ltiroles); |
|
} |
|
|
|
sub proctoring_titles { |
|
my ($item) = @_; |
|
my (%common_lt,%custom_lt); |
|
%common_lt = &Apache::lonlocal::texthash ( |
|
'avai' => 'Available?', |
|
'base' => 'Basic Settings', |
|
'requ' => 'User data required to be sent on launch', |
|
'optu' => 'User data optionally sent on launch', |
|
'udsl' => 'User data sent on launch', |
|
'defa' => 'Defaults for items configurable in course', |
|
'sigmethod' => 'Signature Method', |
|
'key' => 'Key', |
|
'lifetime' => 'Nonce lifetime (s)', |
|
'secret' => 'Secret', |
|
'icon' => 'Icon', |
|
'fullname' => 'Full Name', |
|
'visible' => 'Visible input', |
|
'username' => 'username', |
|
'user' => 'User', |
|
); |
|
if ($item eq 'proctorio') { |
|
%custom_lt = &Apache::lonlocal::texthash ( |
|
'version' => 'OAuth version', |
|
'url' => 'API URL', |
|
'uname:dom' => 'username-domain', |
|
); |
|
} elsif ($item eq 'examity') { |
|
%custom_lt = &Apache::lonlocal::texthash ( |
|
'version' => 'LTI Version', |
|
'url' => 'URL', |
|
'uname:dom' => 'username:domain', |
|
'msgtype' => 'Message Type', |
|
'firstname' => 'First Name', |
|
'lastname' => 'Last Name', |
|
'email' => 'E-mail', |
|
'roles' => 'Role', |
|
'crstarget' => 'Display target', |
|
'crslabel' => 'Course label', |
|
'crstitle' => 'Course title', |
|
'crslinktext' => 'Link Text', |
|
'crsexplanation' => 'Explanation', |
|
'crsappend' => 'Provider URL', |
|
); |
|
} |
|
my %lt = (%common_lt,%custom_lt); |
|
return %lt; |
|
} |
|
|
|
sub proctoring_fieldtitles { |
|
my ($item) = @_; |
|
if ($item eq 'proctorio') { |
|
return &Apache::lonlocal::texthash ( |
|
'recordvideo' => 'Record video', |
|
'recordaudio' => 'Record audio', |
|
'recordscreen' => 'Record screen', |
|
'recordwebtraffic' => 'Record web traffic', |
|
'recordroomstart' => 'Record room scan', |
|
'verifyvideo' => 'Verify webcam', |
|
'verifyaudio' => 'Verify microphone', |
|
'verifydesktop' => 'Verify desktop recording', |
|
'verifyid' => 'Photo ID verification', |
|
'verifysignature' => 'Require signature', |
|
'fullscreen' => 'Fullscreen', |
|
'clipboard' => 'Disable copy/paste', |
|
'tabslinks' => 'New tabs/windows', |
|
'closetabs' => 'Close other tabs', |
|
'onescreen' => 'Limit to single screen', |
|
'print' => 'Disable Printing', |
|
'downloads' => 'Disable Downloads', |
|
'cache' => 'Empty cache after exam', |
|
'rightclick' => 'Disable right click', |
|
'reentry' => 'Re-entry to exam', |
|
'calculator' => 'Onscreen calculator', |
|
'whiteboard' => 'Onscreen whiteboard', |
|
'verifyidauto' => 'Automated verification', |
|
'verifyidlive' => 'Live agent verification', |
|
'fullscreenlenient' => 'Forced, but can navigate away for up to 30s', |
|
'fullscreenmoderate' => 'Forced, but can navigate away for up to 15s', |
|
'fullscreensever' => 'Forced, navigation away ends exam', |
|
'notabs' => 'Disaallowed', |
|
'linksonly' => 'Allowed from links in exam', |
|
'noreentry' => 'Disallowed', |
|
'agentreentry' => 'Agent required for re-entry', |
|
'calculatorbasic' => 'Basic', |
|
'calculatorsci' => 'Scientific', |
|
); |
|
} elsif ($item eq 'examity') { |
|
return &Apache::lonlocal::texthash ( |
|
'target' => 'Display target', |
|
'window' => 'Window', |
|
'tab' => 'Tab', |
|
'iframe' => 'iFrame', |
|
'height' => 'Height (pixels)', |
|
'width' => 'Width (pixels)', |
|
'linktext' => 'Default Link Text', |
|
'explanation' => 'Default Explanation', |
|
'append' => 'Provider URL', |
|
); |
|
} |
|
} |
|
|
|
sub proctoring_providernames { |
|
return ( |
|
proctorio => 'Proctorio', |
|
examity => 'Examity', |
|
); |
|
} |
|
|
sub print_lti { |
sub print_lti { |
my ($dom,$settings,$rowtotal) = @_; |
my ($dom,$settings,$rowtotal) = @_; |
my $itemcount = 1; |
my $itemcount = 1; |
Line 5138 sub lti_options {
|
Line 5902 sub lti_options {
|
$output .= '</span></div>'. |
$output .= '</span></div>'. |
'<div class="LC_floatleft" style="display:'.$userfieldsty.';" id="lti_userfield_'.$num.'">'. |
'<div class="LC_floatleft" style="display:'.$userfieldsty.';" id="lti_userfield_'.$num.'">'. |
'<input type="text" name="lti_customuser_'.$num.'" '. |
'<input type="text" name="lti_customuser_'.$num.'" '. |
'value="'.$userfield.'" /></div></fieldset>'. |
'value="'.$userfield.'" /></div></fieldset>'. |
'<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Mapping course roles').'</legend><table><tr>'; |
'<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Mapping course roles').'</legend><table><tr>'; |
foreach my $ltirole (@lticourseroles) { |
foreach my $ltirole (@lticourseroles) { |
my ($selected,$selectnone); |
my ($selected,$selectnone); |
Line 6408 sub print_passwords {
|
Line 7172 sub print_passwords {
|
return $datatable; |
return $datatable; |
} |
} |
|
|
|
sub print_wafproxy { |
|
my ($position,$dom,$settings,$rowtotal) = @_; |
|
my $css_class; |
|
my $itemcount = 0; |
|
my $datatable; |
|
my %servers = &Apache::lonnet::internet_dom_servers($dom); |
|
my (%othercontrol,%otherdoms,%aliases,%values,$setdom); |
|
my %lt = &wafproxy_titles(); |
|
foreach my $server (sort(keys(%servers))) { |
|
my $serverhome = &Apache::lonnet::get_server_homeID($servers{$server}); |
|
my $serverdom; |
|
if ($serverhome ne $server) { |
|
$serverdom = &Apache::lonnet::host_domain($serverhome); |
|
$othercontrol{$server} = $serverdom; |
|
} else { |
|
$serverdom = &Apache::lonnet::host_domain($server); |
|
if ($serverdom ne $dom) { |
|
$othercontrol{$server} = $serverdom; |
|
} else { |
|
$setdom = 1; |
|
if (ref($settings) eq 'HASH') { |
|
%{$values{$dom}} = (); |
|
if (ref($settings->{'alias'}) eq 'HASH') { |
|
$aliases{$dom} = $settings->{'alias'}; |
|
} |
|
foreach my $item ('ipheader','trusted','vpnint','vpnext') { |
|
$values{$dom}{$item} = $settings->{$item}; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if (keys(%othercontrol)) { |
|
%otherdoms = reverse(%othercontrol); |
|
foreach my $domain (keys(%otherdoms)) { |
|
%{$values{$domain}} = (); |
|
my %config = &Apache::lonnet::get_dom('configuration',['wafproxy'],$domain); |
|
if (ref($config{$domain}) eq 'HASH') { |
|
if (ref($config{$domain}{'wafproxy'}) eq 'HASH') { |
|
$aliases{$domain} = $config{$domain}{'wafproxy'}{'alias'}; |
|
foreach my $item ('ipheader','trusted','vpnint','vpnext') { |
|
$values{$domain}{$item} = $config{$domain}{'wafproxy'}{$item}; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if ($position eq 'top') { |
|
my %servers = &Apache::lonnet::internet_dom_servers($dom); |
|
foreach my $server (sort(keys(%servers))) { |
|
$itemcount ++; |
|
$css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; |
|
$datatable .= '<tr'.$css_class.'>'. |
|
'<td>'.&mt('Hostname').': '. |
|
&Apache::lonnet::hostname($server).'</td>'. |
|
'<td class="LC_right_item">'; |
|
if ($othercontrol{$server}) { |
|
my $current; |
|
if (ref($aliases{$othercontrol{$server}}) eq 'HASH') { |
|
$current = $aliases{$othercontrol{$server}{$server}}; |
|
} |
|
if ($current) { |
|
$datatable .= $current; |
|
} else { |
|
$datatable .= &mt('None in effect'); |
|
} |
|
$datatable .= '<br /><span class="LC_small">('. |
|
&mt('WAF/Reverse Proxy controlled by domain: [_1]', |
|
'<b>'.$othercontrol{$server}.'</b>').'</span>'; |
|
} else { |
|
my $current; |
|
if (ref($aliases{$dom}) eq 'HASH') { |
|
if ($aliases{$dom}{$server}) { |
|
$current = $aliases{$dom}{$server}; |
|
} |
|
} |
|
$datatable .= '<input type="text" name="wafproxy_alias_'.$server.'" '. |
|
'value="'.$current.'" size="30" />'; |
|
} |
|
$datatable .= '</td></tr>'; |
|
} |
|
} else { |
|
if ($setdom) { |
|
$itemcount ++; |
|
$css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; |
|
$datatable .= '<tr'.$css_class.'>'. |
|
'<td class="LC_left_item">'.&mt('Domain: [_1]','<b>'.$dom.'</b>').'<br /><br />'. |
|
&mt('Format for comma separated IP blocks').':<br />'. |
|
&mt('A.B.C.D/N or A.B.C.D - E.F.G.H').'</td>'. |
|
'<td class="LC_left_item"><table>'; |
|
foreach my $item ('ipheader','trusted','vpnint','vpnext') { |
|
$datatable .= '<tr>'. |
|
'<td valign="top">'.$lt{$item}.': '; |
|
if ($item eq 'ipheader') { |
|
$datatable .= '<input type="text" value="'.$values{$dom}{$item}.'" '. |
|
'name="wafproxy_'.$item.'" />'; |
|
|
|
} else { |
|
$datatable .= '<textarea name="wafproxy_'.$item.'" rows="3" cols="80">'. |
|
$values{$dom}{$item}.'</textarea>'; |
|
} |
|
$datatable .= '</td></tr>'; |
|
} |
|
$datatable .= '</table></td></tr>'; |
|
} |
|
if (keys(%otherdoms)) { |
|
foreach my $domain (sort(keys(%otherdoms))) { |
|
$itemcount ++; |
|
$css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; |
|
$datatable .= '<tr'.$css_class.'>'. |
|
'<td class="LC_left_item">'.&mt('Domain: [_1]',$domain).'</td>'. |
|
'<td class="LC_left_item"><table>'; |
|
foreach my $item ('ipheader','trusted','vpnint','vpnext') { |
|
my $showval = &mt('None'); |
|
if ($values{$domain}{$item}) { |
|
$showval = $values{$domain}{$item}; |
|
} |
|
$datatable .= '<tr>'. |
|
'<td>'.$lt{$item}.': '.$showval.'</td></tr>'; |
|
} |
|
$datatable .= '</table></td></tr>'; |
|
} |
|
} |
|
} |
|
$$rowtotal += $itemcount; |
|
return $datatable; |
|
} |
|
|
|
sub wafproxy_titles { |
|
return &Apache::lonlocal::texthash( |
|
vpnint => 'Internal IP Range(s) for VPN sessions', |
|
vpnext => 'IP Range for backend WAF connections', |
|
trusted => 'Trusted IP range(s)', |
|
ipheader => 'Custom request header', |
|
); |
|
} |
|
|
sub print_usersessions { |
sub print_usersessions { |
my ($position,$dom,$settings,$rowtotal) = @_; |
my ($position,$dom,$settings,$rowtotal) = @_; |
my ($css_class,$datatable,$itemcount,%checked,%choices); |
my ($css_class,$datatable,$itemcount,%checked,%choices); |
Line 6421 sub print_usersessions {
|
Line 7322 sub print_usersessions {
|
if ($position eq 'top') { |
if ($position eq 'top') { |
if (keys(%serverhomes) > 1) { |
if (keys(%serverhomes) > 1) { |
my %spareid = ¤t_offloads_to($dom,$settings,\%servers); |
my %spareid = ¤t_offloads_to($dom,$settings,\%servers); |
my $curroffloadnow; |
my ($curroffloadnow,$curroffloadoth); |
if (ref($settings) eq 'HASH') { |
if (ref($settings) eq 'HASH') { |
if (ref($settings->{'offloadnow'}) eq 'HASH') { |
if (ref($settings->{'offloadnow'}) eq 'HASH') { |
$curroffloadnow = $settings->{'offloadnow'}; |
$curroffloadnow = $settings->{'offloadnow'}; |
} |
} |
|
if (ref($settings->{'offloadoth'}) eq 'HASH') { |
|
$curroffloadoth = $settings->{'offloadoth'}; |
|
} |
} |
} |
$datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$curroffloadnow,$rowtotal); |
my $other_insts = scalar(keys(%by_location)); |
|
$datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids, |
|
$other_insts,$curroffloadnow,$curroffloadoth,$rowtotal); |
} else { |
} else { |
$datatable .= '<tr'.$css_class.'><td colspan="2">'. |
$datatable .= '<tr'.$css_class.'><td colspan="2">'. |
&mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.'). |
&mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.'). |
Line 6871 sub current_offloads_to {
|
Line 7777 sub current_offloads_to {
|
} |
} |
|
|
sub spares_row { |
sub spares_row { |
my ($dom,$servers,$spareid,$serverhomes,$altids,$curroffloadnow,$rowtotal) = @_; |
my ($dom,$servers,$spareid,$serverhomes,$altids,$other_insts, |
|
$curroffloadnow,$curroffloadoth,$rowtotal) = @_; |
my $css_class; |
my $css_class; |
my $numinrow = 4; |
my $numinrow = 4; |
my $itemcount = 1; |
my $itemcount = 1; |
Line 6891 sub spares_row {
|
Line 7798 sub spares_row {
|
} |
} |
} |
} |
next unless (ref($spareid->{$server}) eq 'HASH'); |
next unless (ref($spareid->{$server}) eq 'HASH'); |
my $checkednow; |
my ($checkednow,$checkedoth); |
if (ref($curroffloadnow) eq 'HASH') { |
if (ref($curroffloadnow) eq 'HASH') { |
if ($curroffloadnow->{$server}) { |
if ($curroffloadnow->{$server}) { |
$checkednow = ' checked="checked"'; |
$checkednow = ' checked="checked"'; |
} |
} |
} |
} |
|
if (ref($curroffloadoth) eq 'HASH') { |
|
if ($curroffloadoth->{$server}) { |
|
$checkedoth = ' checked="checked"'; |
|
} |
|
} |
$css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; |
$css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; |
$datatable .= '<tr'.$css_class.'> |
$datatable .= '<tr'.$css_class.'> |
<td rowspan="2"> |
<td rowspan="2"> |
Line 6905 sub spares_row {
|
Line 7817 sub spares_row {
|
,'<b>'.$server.'</b>').'</span><br />'. |
,'<b>'.$server.'</b>').'</span><br />'. |
'<span class="LC_nobreak">'."\n". |
'<span class="LC_nobreak">'."\n". |
'<label><input type="checkbox" name="offloadnow" value="'.$server.'"'.$checkednow.' />'. |
'<label><input type="checkbox" name="offloadnow" value="'.$server.'"'.$checkednow.' />'. |
' '.&mt('Switch active users on next access').'</label></span>'. |
' '.&mt('Switch any active user on next access').'</label></span>'. |
|
"\n"; |
|
if ($other_insts) { |
|
$datatable .= '<br />'. |
|
'<span class="LC_nobreak">'."\n". |
|
'<label><input type="checkbox" name="offloadoth" value="'.$server.'"'.$checkedoth.' />'. |
|
' '.&mt('Switch other institutions on next access').'</label></span>'. |
"\n"; |
"\n"; |
|
} |
my (%current,%canselect); |
my (%current,%canselect); |
my @choices = |
my @choices = |
&possible_newspares($server,$spareid->{$server},$serverhomes,$altids); |
&possible_newspares($server,$spareid->{$server},$serverhomes,$altids); |
Line 7425 sub contact_titles {
|
Line 8344 sub contact_titles {
|
'updatesmail' => 'E-mail from nightly check of LON-CAPA module integrity/updates', |
'updatesmail' => 'E-mail from nightly check of LON-CAPA module integrity/updates', |
'idconflictsmail' => 'E-mail from bi-nightly check for multiple users sharing same student/employee ID', |
'idconflictsmail' => 'E-mail from bi-nightly check for multiple users sharing same student/employee ID', |
'hostipmail' => 'E-mail from nightly check of hostname/IP network changes', |
'hostipmail' => 'E-mail from nightly check of hostname/IP network changes', |
'errorthreshold' => 'Error/warning threshold for status e-mail', |
'errorthreshold' => 'Error count threshold for status e-mail to admin(s)', |
'errorsysmail' => 'Error threshold for e-mail to core group', |
'errorsysmail' => 'Error count threshold for e-mail to developer group', |
'errorweights' => 'Weights used to compute error count', |
'errorweights' => 'Weights used to compute error count', |
'errorexcluded' => 'Servers with unsent updates excluded from count', |
'errorexcluded' => 'Servers with unsent updates excluded from count', |
); |
); |
Line 12410 sub modify_ltitools {
|
Line 13329 sub modify_ltitools {
|
} |
} |
} |
} |
if (!$numconfig) { |
if (!$numconfig) { |
$resulttext .= &mt('None'); |
$resulttext .= ' '.&mt('None'); |
} |
} |
$resulttext .= '</li>'; |
$resulttext .= '</li>'; |
foreach my $item ('passback','roster') { |
foreach my $item ('passback','roster') { |
Line 12589 sub get_ltitools_id {
|
Line 13508 sub get_ltitools_id {
|
return ($id,$error); |
return ($id,$error); |
} |
} |
|
|
|
sub modify_proctoring { |
|
my ($r,$dom,$action,$lastactref,%domconfig) = @_; |
|
my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); |
|
my (@allpos,%changes,%confhash,%encconfhash,$errors,$resulttext,%imgdeletions); |
|
my $confname = $dom.'-domainconfig'; |
|
my $servadm = $r->dir_config('lonAdmEMail'); |
|
my ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm); |
|
my %providernames = &proctoring_providernames(); |
|
my $maxnum = scalar(keys(%providernames)); |
|
|
|
my (%requserfields,%optuserfields,%defaults,%extended,%crsconf,@courseroles,@ltiroles); |
|
my ($requref,$opturef,$defref,$extref,$crsref,$rolesref,$ltiref) = &proctoring_data(); |
|
if (ref($requref) eq 'HASH') { |
|
%requserfields = %{$requref}; |
|
} |
|
if (ref($opturef) eq 'HASH') { |
|
%optuserfields = %{$opturef}; |
|
} |
|
if (ref($defref) eq 'HASH') { |
|
%defaults = %{$defref}; |
|
} |
|
if (ref($extref) eq 'HASH') { |
|
%extended = %{$extref}; |
|
} |
|
if (ref($crsref) eq 'HASH') { |
|
%crsconf = %{$crsref}; |
|
} |
|
if (ref($rolesref) eq 'ARRAY') { |
|
@courseroles = @{$rolesref}; |
|
} |
|
if (ref($ltiref) eq 'ARRAY') { |
|
@ltiroles = @{$ltiref}; |
|
} |
|
|
|
if (ref($domconfig{$action}) eq 'HASH') { |
|
my @todeleteimages = &Apache::loncommon::get_env_multiple('form.proctoring_image_del'); |
|
if (@todeleteimages) { |
|
map { $imgdeletions{$_} = 1; } @todeleteimages; |
|
} |
|
} |
|
my %customadds; |
|
my @newcustom = &Apache::loncommon::get_env_multiple('form.proctoring_customadd'); |
|
if (@newcustom) { |
|
map { $customadds{$_} = 1; } @newcustom; |
|
} |
|
foreach my $provider (sort(keys(%providernames))) { |
|
$confhash{$provider} = {}; |
|
my $pos = $env{'form.proctoring_pos_'.$provider}; |
|
$pos =~ s/\D+//g; |
|
$allpos[$pos] = $provider; |
|
my (%current,%currentenc); |
|
my $showroles = 0; |
|
if (ref($domconfig{$action}) eq 'HASH') { |
|
if (ref($domconfig{$action}{$provider}) eq 'HASH') { |
|
%current = %{$domconfig{$action}{$provider}}; |
|
foreach my $item ('key','secret') { |
|
$currentenc{$item} = $current{$item}; |
|
delete($current{$item}); |
|
} |
|
} |
|
} |
|
if ($env{'form.proctoring_available_'.$provider}) { |
|
$confhash{$provider}{'available'} = 1; |
|
unless ($current{'available'}) { |
|
$changes{$provider} = 1; |
|
} |
|
} else { |
|
%{$confhash{$provider}} = %current; |
|
%{$encconfhash{$provider}} = %currentenc; |
|
$confhash{$provider}{'available'} = 0; |
|
if ($current{'available'}) { |
|
$changes{$provider} = 1; |
|
} |
|
} |
|
if ($confhash{$provider}{'available'}) { |
|
foreach my $field ('lifetime','version','sigmethod','url','key','secret') { |
|
my $possval = $env{'form.proctoring_'.$provider.'_'.$field}; |
|
if ($field eq 'lifetime') { |
|
if ($possval =~ /^\d+$/) { |
|
$confhash{$provider}{$field} = $possval; |
|
} |
|
} elsif ($field eq 'version') { |
|
if ($possval =~ /^\d+\.\d+$/) { |
|
$confhash{$provider}{$field} = $possval; |
|
} |
|
} elsif ($field eq 'sigmethod') { |
|
if ($possval =~ /^\QHMAC-SHA\E(1|256)$/) { |
|
$confhash{$provider}{$field} = $possval; |
|
} |
|
} elsif ($field eq 'url') { |
|
$confhash{$provider}{$field} = $possval; |
|
} elsif (($field eq 'key') || ($field eq 'secret')) { |
|
$encconfhash{$provider}{$field} = $possval; |
|
unless ($currentenc{$field} eq $possval) { |
|
$changes{$provider} = 1; |
|
} |
|
} |
|
unless (($field eq 'key') || ($field eq 'secret')) { |
|
unless ($current{$field} eq $confhash{$provider}{$field}) { |
|
$changes{$provider} = 1; |
|
} |
|
} |
|
} |
|
if ($imgdeletions{$provider}) { |
|
$changes{$provider} = 1; |
|
} elsif ($env{'form.proctoring_image_'.$provider.'.filename'} ne '') { |
|
my ($imageurl,$error) = |
|
&process_proctoring_image($r,$dom,$confname,'proctoring_image_'.$provider,$provider, |
|
$configuserok,$switchserver,$author_ok); |
|
if ($imageurl) { |
|
$confhash{$provider}{'image'} = $imageurl; |
|
$changes{$provider} = 1; |
|
} |
|
if ($error) { |
|
&Apache::lonnet::logthis($error); |
|
$errors .= '<li><span class="LC_error">'.$error.'</span></li>'; |
|
} |
|
} elsif (exists($current{'image'})) { |
|
$confhash{$provider}{'image'} = $current{'image'}; |
|
} |
|
if (ref($requserfields{$provider}) eq 'ARRAY') { |
|
if (@{$requserfields{$provider}} > 0) { |
|
if (grep(/^user$/,@{$requserfields{$provider}})) { |
|
if ($env{'form.proctoring_userincdom_'.$provider}) { |
|
$confhash{$provider}{'incdom'} = 1; |
|
} |
|
unless ($current{'incdom'} eq $confhash{$provider}{'incdom'}) { |
|
$changes{$provider} = 1; |
|
} |
|
} |
|
if (grep(/^roles$/,@{$requserfields{$provider}})) { |
|
$showroles = 1; |
|
} |
|
} |
|
} |
|
$confhash{$provider}{'fields'} = []; |
|
if (ref($optuserfields{$provider}) eq 'ARRAY') { |
|
if (@{$optuserfields{$provider}} > 0) { |
|
my @optfields = &Apache::loncommon::get_env_multiple('form.proctoring_optional_'.$provider); |
|
foreach my $field (@{$optuserfields{$provider}}) { |
|
if (grep(/^\Q$field\E$/,@optfields)) { |
|
push(@{$confhash{$provider}{'fields'}},$field); |
|
} |
|
} |
|
} |
|
if (ref($current{'fields'}) eq 'ARRAY') { |
|
unless ($changes{$provider}) { |
|
my @new = sort(@{$confhash{$provider}{'fields'}}); |
|
my @old = sort(@{$current{'fields'}}); |
|
my @diffs = &Apache::loncommon::compare_arrays(\@new,\@old); |
|
if (@diffs) { |
|
$changes{$provider} = 1; |
|
} |
|
} |
|
} elsif (@{$confhash{$provider}{'fields'}}) { |
|
$changes{$provider} = 1; |
|
} |
|
} |
|
if (ref($defaults{$provider}) eq 'ARRAY') { |
|
if (@{$defaults{$provider}} > 0) { |
|
my %options; |
|
if (ref($extended{$provider}) eq 'HASH') { |
|
%options = %{$extended{$provider}}; |
|
} |
|
my @checked = &Apache::loncommon::get_env_multiple('form.proctoring_defaults_'.$provider); |
|
foreach my $field (@{$defaults{$provider}}) { |
|
if ((exists($options{$field})) && (ref($options{$field}) eq 'ARRAY')) { |
|
my $poss = $env{'form.proctoring_defaults_'.$field.'_'.$provider}; |
|
if (grep(/^\Q$poss\E$/,@{$options{$field}})) { |
|
push(@{$confhash{$provider}{'defaults'}},$poss); |
|
} |
|
} elsif ((exists($options{$field})) && (ref($options{$field}) eq 'HASH')) { |
|
foreach my $inner (keys(%{$options{$field}})) { |
|
if (ref($options{$field}{$inner}) eq 'ARRAY') { |
|
my $poss = $env{'form.proctoring_'.$inner.'_'.$provider}; |
|
if (grep(/^\Q$poss\E$/,@{$options{$field}{$inner}})) { |
|
$confhash{$provider}{'defaults'}{$inner} = $poss; |
|
} |
|
} else { |
|
$confhash{$provider}{'defaults'}{$inner} = $env{'form.proctoring_'.$inner.'_'.$provider}; |
|
} |
|
} |
|
} else { |
|
if (grep(/^\Q$field\E$/,@checked)) { |
|
push(@{$confhash{$provider}{'defaults'}},$field); |
|
} |
|
} |
|
} |
|
if (ref($confhash{$provider}{'defaults'}) eq 'ARRAY') { |
|
if (ref($current{'defaults'}) eq 'ARRAY') { |
|
unless ($changes{$provider}) { |
|
my @new = sort(@{$confhash{$provider}{'defaults'}}); |
|
my @old = sort(@{$current{'defaults'}}); |
|
my @diffs = &Apache::loncommon::compare_arrays(\@new,\@old); |
|
if (@diffs) { |
|
$changes{$provider} = 1; |
|
} |
|
} |
|
} elsif (ref($current{'defaults'}) eq 'ARRAY') { |
|
if (@{$current{'defaults'}}) { |
|
$changes{$provider} = 1; |
|
} |
|
} |
|
} elsif (ref($confhash{$provider}{'defaults'}) eq 'HASH') { |
|
if (ref($current{'defaults'}) eq 'HASH') { |
|
unless ($changes{$provider}) { |
|
foreach my $key (keys(%{$confhash{$provider}{'defaults'}})) { |
|
unless ($confhash{$provider}{'defaults'}{$key} eq $current{'defaults'}{$key}) { |
|
$changes{$provider} = 1; |
|
last; |
|
} |
|
} |
|
} |
|
unless ($changes{$provider}) { |
|
foreach my $key (keys(%{$current{'defaults'}})) { |
|
unless ($current{'defaults'}{$key} eq $confhash{$provider}{'defaults'}{$key}) { |
|
$changes{$provider} = 1; |
|
last; |
|
} |
|
} |
|
} |
|
} elsif (keys(%{$confhash{$provider}{'defaults'}})) { |
|
$changes{$provider} = 1; |
|
} |
|
} |
|
} |
|
} |
|
if (ref($crsconf{$provider}) eq 'ARRAY') { |
|
if (@{$crsconf{$provider}} > 0) { |
|
$confhash{$provider}{'crsconf'} = []; |
|
my @checked = &Apache::loncommon::get_env_multiple('form.proctoring_crsconf_'.$provider); |
|
foreach my $crsfield (@{$crsconf{$provider}}) { |
|
if (grep(/^\Q$crsfield\E$/,@checked)) { |
|
push(@{$confhash{$provider}{'crsconf'}},$crsfield); |
|
} |
|
} |
|
if (ref($current{'crsconf'}) eq 'ARRAY') { |
|
unless ($changes{$provider}) { |
|
my @new = sort(@{$confhash{$provider}{'crsconf'}}); |
|
my @old = sort(@{$current{'crsconf'}}); |
|
my @diffs = &Apache::loncommon::compare_arrays(\@new,\@old); |
|
if (@diffs) { |
|
$changes{$provider} = 1; |
|
} |
|
} |
|
} elsif (@{$confhash{$provider}{'crsconf'}}) { |
|
$changes{$provider} = 1; |
|
} |
|
} |
|
} |
|
if ($showroles) { |
|
$confhash{$provider}{'roles'} = {}; |
|
foreach my $role (@courseroles) { |
|
my $poss = $env{'form.proctoring_roles_'.$role.'_'.$provider}; |
|
if (grep(/^\Q$poss\E$/,@ltiroles)) { |
|
$confhash{$provider}{'roles'}{$role} = $poss; |
|
} |
|
} |
|
unless ($changes{$provider}) { |
|
if (ref($current{'roles'}) eq 'HASH') { |
|
foreach my $role (keys(%{$current{'roles'}})) { |
|
unless ($current{'roles'}{$role} eq $confhash{$provider}{'roles'}{$role}) { |
|
$changes{$provider} = 1; |
|
last |
|
} |
|
} |
|
unless ($changes{$provider}) { |
|
foreach my $role (keys(%{$confhash{$provider}{'roles'}})) { |
|
unless ($confhash{$provider}{'roles'}{$role} eq $current{'roles'}{$role}) { |
|
$changes{$provider} = 1; |
|
last; |
|
} |
|
} |
|
} |
|
} elsif (keys(%{$confhash{$provider}{'roles'}})) { |
|
$changes{$provider} = 1; |
|
} |
|
} |
|
} |
|
if (ref($current{'custom'}) eq 'HASH') { |
|
my @customdels = &Apache::loncommon::get_env_multiple('form.proctoring_customdel_'.$provider); |
|
foreach my $key (keys(%{$current{'custom'}})) { |
|
if (grep(/^\Q$key\E$/,@customdels)) { |
|
$changes{$provider} = 1; |
|
} else { |
|
$confhash{$provider}{'custom'}{$key} = $env{'form.proctoring_customval_'.$key.'_'.$provider}; |
|
if ($confhash{$provider}{'custom'}{$key} ne $current{'custom'}{$key}) { |
|
$changes{$provider} = 1; |
|
} |
|
} |
|
} |
|
} |
|
if ($customadds{$provider}) { |
|
my $name = $env{'form.proctoring_custom_name_'.$provider}; |
|
$name =~ s/(`)/'/g; |
|
$name =~ s/^\s+//; |
|
$name =~ s/\s+$//; |
|
my $value = $env{'form.proctoring_custom_value_'.$provider}; |
|
$value =~ s/(`)/'/g; |
|
$value =~ s/^\s+//; |
|
$value =~ s/\s+$//; |
|
if ($name ne '') { |
|
$confhash{$provider}{'custom'}{$name} = $value; |
|
$changes{$provider} = 1; |
|
} |
|
} |
|
} |
|
} |
|
if (@allpos > 0) { |
|
my $idx = 0; |
|
foreach my $provider (@allpos) { |
|
if ($provider ne '') { |
|
$confhash{$provider}{'order'} = $idx; |
|
unless ($changes{$provider}) { |
|
if (ref($domconfig{$action}) eq 'HASH') { |
|
if (ref($domconfig{$action}{$provider}) eq 'HASH') { |
|
if ($domconfig{$action}{$provider}{'order'} ne $idx) { |
|
$changes{$provider} = 1; |
|
} |
|
} |
|
} |
|
} |
|
$idx ++; |
|
} |
|
} |
|
} |
|
my %proc_hash = ( |
|
$action => { %confhash } |
|
); |
|
my $putresult = &Apache::lonnet::put_dom('configuration',\%proc_hash, |
|
$dom); |
|
if ($putresult eq 'ok') { |
|
my %proc_enchash = ( |
|
$action => { %encconfhash } |
|
); |
|
&Apache::lonnet::put_dom('encconfig',\%proc_enchash,$dom); |
|
if (keys(%changes) > 0) { |
|
my $cachetime = 24*60*60; |
|
my %procall = %confhash; |
|
foreach my $provider (keys(%procall)) { |
|
if (ref($encconfhash{$provider}) eq 'HASH') { |
|
foreach my $key ('key','secret') { |
|
$procall{$provider}{$key} = $encconfhash{$provider}{$key}; |
|
} |
|
} |
|
} |
|
&Apache::lonnet::do_cache_new('proctoring',$dom,\%procall,$cachetime); |
|
if (ref($lastactref) eq 'HASH') { |
|
$lastactref->{'proctoring'} = 1; |
|
} |
|
$resulttext = &mt('Configuration for Provider(s) with changes:').'<ul>'; |
|
my %bynum; |
|
foreach my $provider (sort(keys(%changes))) { |
|
my $position = $confhash{$provider}{'order'}; |
|
$bynum{$position} = $provider; |
|
} |
|
foreach my $pos (sort { $a <=> $b } keys(%bynum)) { |
|
my $provider = $bynum{$pos}; |
|
my %lt = &proctoring_titles($provider); |
|
my %fieldtitles = &proctoring_fieldtitles($provider); |
|
if (!$confhash{$provider}{'available'}) { |
|
$resulttext .= '<li>'.&mt('Proctoring integration unavailable for: [_1]','<b>'.$providernames{$provider}.'</b>').'</li>'; |
|
} else { |
|
$resulttext .= '<li>'.&mt('Proctoring integration available for: [_1]','<b>'.$providernames{$provider}.'</b>'); |
|
if ($confhash{$provider}{'image'}) { |
|
$resulttext .= ' '. |
|
'<img src="'.$confhash{$provider}{'image'}.'"'. |
|
' alt="'.&mt('Proctoring icon').'" />'; |
|
} |
|
$resulttext .= '<ul>'; |
|
my $position = $pos + 1; |
|
$resulttext .= '<li>'.&mt('Order: [_1]',$position).'</li>'; |
|
foreach my $key ('version','sigmethod','url','lifetime') { |
|
if ($confhash{$provider}{$key} ne '') { |
|
$resulttext .= '<li>'.$lt{$key}.': '.$confhash{$provider}{$key}.'</li>'; |
|
} |
|
} |
|
if ($encconfhash{$provider}{'key'} ne '') { |
|
$resulttext .= '<li>'.$lt{'key'}.': '.$encconfhash{$provider}{'key'}.'</li>'; |
|
} |
|
if ($encconfhash{$provider}{'secret'} ne '') { |
|
$resulttext .= '<li>'.$lt{'secret'}.': '; |
|
my $num = length($encconfhash{$provider}{'secret'}); |
|
$resulttext .= ('*'x$num).'</li>'; |
|
} |
|
my (@fields,$showroles); |
|
if (ref($requserfields{$provider}) eq 'ARRAY') { |
|
push(@fields,@{$requserfields{$provider}}); |
|
} |
|
if (ref($confhash{$provider}{'fields'}) eq 'ARRAY') { |
|
push(@fields,@{$confhash{$provider}{'fields'}}); |
|
} elsif (ref($confhash{$provider}{'fields'}) eq 'HASH') { |
|
push(@fields,(keys(%{$confhash{$provider}{'fields'}}))); |
|
} |
|
if (@fields) { |
|
if (grep(/^roles$/,@fields)) { |
|
$showroles = 1; |
|
} |
|
$resulttext .= '<li>'.$lt{'udsl'}.': "'. |
|
join('", "', map { $lt{$_}; } @fields).'"</li>'; |
|
} |
|
if (ref($requserfields{$provider}) eq 'ARRAY') { |
|
if (grep(/^user$/,@{$requserfields{$provider}})) { |
|
if ($confhash{$provider}{'incdom'}) { |
|
$resulttext .= '<li>'.&mt('[_1] sent as [_2]',$lt{'user'},$lt{'uname:dom'}).'</li>'; |
|
} else { |
|
$resulttext .= '<li>'.&mt('[_1] sent as [_2]',$lt{'user'},$lt{'username'}).'</li>'; |
|
} |
|
} |
|
} |
|
if (ref($confhash{$provider}{'defaults'}) eq 'ARRAY') { |
|
if (@{$confhash{$provider}{'defaults'}} > 0) { |
|
$resulttext .= '<li>'.$lt{'defa'}; |
|
foreach my $field (@{$confhash{$provider}{'defaults'}}) { |
|
$resulttext .= ' "'.$fieldtitles{$field}.'",'; |
|
} |
|
$resulttext =~ s/,$//; |
|
$resulttext .= '</li>'; |
|
} |
|
} elsif (ref($confhash{$provider}{'defaults'}) eq 'HASH') { |
|
if (keys(%{$confhash{$provider}{'defaults'}})) { |
|
$resulttext .= '<li>'.$lt{'defa'}.': <ul>'; |
|
foreach my $key (sort(keys(%{$confhash{$provider}{'defaults'}}))) { |
|
if ($confhash{$provider}{'defaults'}{$key} ne '') { |
|
$resulttext .= '<li>'.$fieldtitles{$key}.' = '.$confhash{$provider}{'defaults'}{$key}.'</li>'; |
|
} |
|
} |
|
$resulttext .= '</ul></li>'; |
|
} |
|
} |
|
if (ref($crsconf{$provider}) eq 'ARRAY') { |
|
if (@{$crsconf{$provider}} > 0) { |
|
$resulttext .= '<li>'.&mt('Configurable in course:'); |
|
my $numconfig = 0; |
|
if (ref($confhash{$provider}{'crsconf'}) eq 'ARRAY') { |
|
if (@{$confhash{$provider}{'crsconf'}} > 0) { |
|
foreach my $field (@{$confhash{$provider}{'crsconf'}}) { |
|
$numconfig ++; |
|
if ($provider eq 'examity') { |
|
$resulttext .= ' "'.$lt{'crs'.$field}.'",'; |
|
} else { |
|
$resulttext .= ' "'.$fieldtitles{$field}.'",'; |
|
} |
|
} |
|
$resulttext =~ s/,$//; |
|
} |
|
} |
|
if (!$numconfig) { |
|
$resulttext .= ' '.&mt('None'); |
|
} |
|
$resulttext .= '</li>'; |
|
} |
|
} |
|
if ($showroles) { |
|
if (ref($confhash{$provider}{'roles'}) eq 'HASH') { |
|
my $rolemaps; |
|
foreach my $role (@courseroles) { |
|
if ($confhash{$provider}{'roles'}{$role}) { |
|
$rolemaps .= (' 'x2).&Apache::lonnet::plaintext($role,'Course').'='. |
|
$confhash{$provider}{'roles'}{$role}.','; |
|
} |
|
} |
|
if ($rolemaps) { |
|
$rolemaps =~ s/,$//; |
|
$resulttext .= '<li>'.&mt('Role mapping:').$rolemaps.'</li>'; |
|
} |
|
} |
|
} |
|
if (ref($confhash{$provider}{'custom'}) eq 'HASH') { |
|
my $customlist; |
|
if (keys(%{$confhash{$provider}{'custom'}})) { |
|
foreach my $key (sort(keys(%{$confhash{$provider}{'custom'}}))) { |
|
$customlist .= $key.'='.$confhash{$provider}{'custom'}{$key}.', '; |
|
} |
|
$customlist =~ s/,$//; |
|
} |
|
if ($customlist) { |
|
$resulttext .= '<li>'.&mt('Custom items').': '.$customlist.'</li>'; |
|
} |
|
} |
|
$resulttext .= '</ul></li>'; |
|
} |
|
} |
|
$resulttext .= '</ul>'; |
|
} else { |
|
$resulttext = &mt('No changes made.'); |
|
} |
|
} else { |
|
$errors .= '<li><span class="LC_error">'.&mt('Failed to save changes').'</span></li>'; |
|
} |
|
if ($errors) { |
|
$resulttext .= &mt('The following errors occurred: ').'<ul>'. |
|
$errors.'</ul>'; |
|
} |
|
return $resulttext; |
|
} |
|
|
|
sub process_proctoring_image { |
|
my ($r,$dom,$confname,$caller,$provider,$configuserok,$switchserver,$author_ok) = @_; |
|
my $filename = $env{'form.'.$caller.'.filename'}; |
|
my ($error,$url); |
|
my ($width,$height) = (21,21); |
|
if ($configuserok eq 'ok') { |
|
if ($switchserver) { |
|
$error = &mt('Upload of Remote Proctoring Provider icon is not permitted to this server: [_1]', |
|
$switchserver); |
|
} elsif ($author_ok eq 'ok') { |
|
my ($result,$imageurl,$madethumb) = |
|
&publishlogo($r,'upload',$caller,$dom,$confname, |
|
"proctoring/$provider/icon",$width,$height); |
|
if ($result eq 'ok') { |
|
if ($madethumb) { |
|
my ($path,$imagefile) = ($imageurl =~ m{^(.+)/([^/]+)$}); |
|
my $imagethumb = "$path/tn-".$imagefile; |
|
$url = $imagethumb; |
|
} else { |
|
$url = $imageurl; |
|
} |
|
} else { |
|
$error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$filename,$result); |
|
} |
|
} else { |
|
$error = &mt("Upload of [_1] failed because an author role could not be assigned to a Domain Configuration user ([_2]) in domain: [_3]. Error was: [_4].",$filename,$confname,$dom,$author_ok); |
|
} |
|
} else { |
|
$error = &mt("Upload of [_1] failed because a Domain Configuration user ([_2]) could not be created in domain: [_3]. Error was: [_4].",$filename,$confname,$dom,$configuserok); |
|
} |
|
return ($url,$error); |
|
} |
|
|
sub modify_lti { |
sub modify_lti { |
my ($r,$dom,$action,$lastactref,%domconfig) = @_; |
my ($r,$dom,$action,$lastactref,%domconfig) = @_; |
my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); |
my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); |
Line 13750 sub modify_contacts {
|
Line 15199 sub modify_contacts {
|
$contacts_hash{'contacts'}{'lonstatus'}{$item} = \@excluded; |
$contacts_hash{'contacts'}{'lonstatus'}{$item} = \@excluded; |
} |
} |
} elsif ($item eq 'weights') { |
} elsif ($item eq 'weights') { |
foreach my $type ('E','W','N') { |
foreach my $type ('E','W','N','U') { |
$env{'form.error'.$item.'_'.$type} =~ s/^\s+|\s+$//g; |
$env{'form.error'.$item.'_'.$type} =~ s/^\s+|\s+$//g; |
if ($env{'form.error'.$item.'_'.$type} =~ /^\d+$/) { |
if ($env{'form.error'.$item.'_'.$type} =~ /^\d+$/) { |
unless ($env{'form.error'.$item.'_'.$type} == $lonstatus_defs->{$type}) { |
unless ($env{'form.error'.$item.'_'.$type} == $lonstatus_defs->{$type}) { |
Line 18122 sub modify_selfenrollment {
|
Line 19571 sub modify_selfenrollment {
|
return $resulttext; |
return $resulttext; |
} |
} |
|
|
|
sub modify_wafproxy { |
|
my ($dom,$action,$lastactref,%domconfig) = @_; |
|
my %servers = &Apache::lonnet::internet_dom_servers($dom); |
|
my (%othercontrol,%canset,%values,%curralias,%currvalue,@warnings,%wafproxy, |
|
%changes,%expirecache); |
|
foreach my $server (sort(keys(%servers))) { |
|
my $serverhome = &Apache::lonnet::get_server_homeID($servers{$server}); |
|
if ($serverhome eq $server) { |
|
my $serverdom = &Apache::lonnet::host_domain($server); |
|
if ($serverdom eq $dom) { |
|
$canset{$server} = 1; |
|
if (ref($domconfig{'wafproxy'}) eq 'HASH') { |
|
%{$values{$dom}} = (); |
|
if (ref($domconfig{'wafproxy'}{'alias'}) eq 'HASH') { |
|
%curralias = %{$domconfig{'wafproxy'}{'alias'}}; |
|
} |
|
foreach my $item ('ipheader','trusted','exempt') { |
|
$currvalue{$item} = $domconfig{'wafproxy'}{$item}; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
my $output; |
|
if (keys(%canset)) { |
|
%{$wafproxy{'alias'}} = (); |
|
foreach my $key (sort(keys(%canset))) { |
|
$wafproxy{'alias'}{$key} = $env{'form.wafproxy_alias_'.$key}; |
|
$wafproxy{'alias'}{$key} =~ s/^\s+|\s+$//g; |
|
if ($wafproxy{'alias'}{$key} ne $curralias{$key}) { |
|
$changes{'alias'} = 1; |
|
} |
|
if ($wafproxy{'alias'}{$key} eq '') { |
|
if ($curralias{$key}) { |
|
$expirecache{$key} = 1; |
|
} |
|
delete($wafproxy{'alias'}{$key}); |
|
} |
|
} |
|
unless (keys(%{$wafproxy{'alias'}})) { |
|
delete($wafproxy{'alias'}); |
|
} |
|
# Localization for values in %warn occus in &mt() calls separately. |
|
my %warn = ( |
|
trusted => 'trusted IP range(s)', |
|
exempt => 'exempt IP range(s)', |
|
); |
|
foreach my $item ('ipheader','trusted','exempt') { |
|
my $possible = $env{'form.wafproxy_'.$item}; |
|
$possible =~ s/^\s+|\s+$//g; |
|
if ($possible ne '') { |
|
if ($item eq 'ipheader') { |
|
$wafproxy{$item} = $possible; |
|
} else { |
|
my (@ok,$count); |
|
$possible =~ s/[\r\n]+/\s/g; |
|
$possible =~ s/\s*-\s*/-/g; |
|
$possible =~ s/\s+/,/g; |
|
$count = 0; |
|
if ($possible) { |
|
foreach my $poss (split(/\,/,$possible)) { |
|
$count ++; |
|
if (&validate_ip_pattern($poss)) { |
|
push(@ok,$poss); |
|
} |
|
} |
|
if (@ok) { |
|
$wafproxy{$item} = join(',',@ok); |
|
} |
|
my $diff = $count - scalar(@ok); |
|
if ($diff) { |
|
push(@warnings,'<li>'. |
|
&mt('[quant,_1,IP] invalid and excluded from saved value for [_2]', |
|
$diff,$warn{$item}). |
|
'</li>'); |
|
} |
|
if ($wafproxy{$item} ne $currvalue{$item}) { |
|
$changes{$item} = 1; |
|
} |
|
} |
|
} |
|
} else { |
|
if ($currvalue{$item}) { |
|
$changes{$item} = 1; |
|
} |
|
} |
|
} |
|
} |
|
if (keys(%changes)) { |
|
my %defaultshash = ( |
|
wafproxy => \%wafproxy, |
|
); |
|
my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash, |
|
$dom); |
|
if ($putresult eq 'ok') { |
|
my $cachetime = 24*60*60; |
|
my (%domdefaults,$updatedomdefs); |
|
foreach my $item ('ipheader','trusted','exempt') { |
|
if ($changes{$item}) { |
|
unless ($updatedomdefs) { |
|
%domdefaults = &Apache::lonnet::get_domain_defaults($dom); |
|
$updatedomdefs = 1; |
|
} |
|
if ($wafproxy{$item}) { |
|
$domdefaults{'waf_'.$item} = $wafproxy{$item}; |
|
} elsif (exists($domdefaults{'waf_'.$item})) { |
|
delete($domdefaults{'waf_'.$item}); |
|
} |
|
} |
|
} |
|
if ($updatedomdefs) { |
|
&Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); |
|
if (ref($lastactref) eq 'HASH') { |
|
$lastactref->{'domdefaults'} = 1; |
|
} |
|
} |
|
if ((exists($wafproxy{'alias'})) || (keys(%expirecache))) { |
|
my %updates = %expirecache; |
|
foreach my $key (keys(%expirecache)) { |
|
&Apache::lonnet::devalidate_cache_new('proxyalias',$key); |
|
} |
|
if (ref($wafproxy{'alias'}) eq 'HASH') { |
|
my $cachetime = 24*60*60; |
|
foreach my $key (keys(%{$wafproxy{'alias'}})) { |
|
$updates{$key} = 1; |
|
&Apache::lonnet::do_cache_new('proxyalias',$key,$wafproxy{'alias'}{$key}, |
|
$cachetime); |
|
} |
|
} |
|
if (ref($lastactref) eq 'HASH') { |
|
$lastactref->{'proxyalias'} = \%updates; |
|
} |
|
} |
|
$output = &mt('Changes were made to Web Application Firewall/Reverse Proxy').'<ul>'; |
|
foreach my $item ('alias','ipheader','trusted','exempt') { |
|
if ($changes{$item}) { |
|
if ($item eq 'alias') { |
|
my $numaliased = 0; |
|
if (ref($wafproxy{'alias'}) eq 'HASH') { |
|
my $shown; |
|
if (keys(%{$wafproxy{'alias'}})) { |
|
foreach my $server (sort(keys(%{$wafproxy{'alias'}}))) { |
|
$shown .= '<li>'.&mt('[_1] aliased by [_2]', |
|
&Apache::lonnet::hostname($server), |
|
$wafproxy{'alias'}{$server}).'</li>'; |
|
$numaliased ++; |
|
} |
|
if ($numaliased) { |
|
$output .= '<li>'.&mt('Aliases for hostnames set to: [_1]', |
|
'<ul>'.$shown.'</ul>').'</li>'; |
|
} |
|
} |
|
} |
|
unless ($numaliased) { |
|
$output .= '<li>'.&mt('Aliases deleted for hostnames').'</li>'; |
|
} |
|
} else { |
|
if ($item eq 'ipheader') { |
|
if ($wafproxy{$item}) { |
|
$output .= '<li>'.&mt('Custom request header set to [_1]', |
|
$wafproxy{$item}).'</li>'; |
|
} else { |
|
$output .= '<li>'.&mt('Custom request header deleted').'</li>'; |
|
} |
|
} elsif ($item eq 'trusted') { |
|
if ($wafproxy{$item}) { |
|
$output .= '<li>'.&mt('Trusted IP range(s) set to [_1]', |
|
$wafproxy{$item}).'</li>'; |
|
} else { |
|
$output .= '<li>'.&mt('Trusted IP range(s) deleted').'</li>'; |
|
} |
|
} elsif ($item eq 'exempt') { |
|
if ($wafproxy{$item}) { |
|
$output .= '<li>'.&mt('Exempt IP range(s) set to [_1]', |
|
$wafproxy{$item}).'</li>'; |
|
} else { |
|
$output .= '<li>'.&mt('Exempt IP range(s) deleted').'</li>'; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} else { |
|
$output = '<span class="LC_error">'. |
|
&mt('An error occurred: [_1]',$putresult).'</span>'; |
|
} |
|
} elsif (keys(%canset)) { |
|
$output = &mt('No changes made to Web Application Firewall/Reverse Proxy settings'); |
|
} |
|
if (@warnings) { |
|
$output .= '<br />'.&mt('Warnings:').'<ul>'. |
|
join("\n",@warnings).'</ul>'; |
|
} |
|
return $output; |
|
} |
|
|
|
sub validate_ip_pattern { |
|
my ($pattern) = @_; |
|
if ($pattern =~ /^([^-]+)\-([^-]+)$/) { |
|
my ($start,$end) = ($1,$2); |
|
if ((&Net::CIDR::cidrvalidate($start)) && (&Net::CIDR::cidrvalidate($end))) { |
|
return 1; |
|
} |
|
} elsif (&Net::CIDR::cidrvalidate($pattern)) { |
|
return 1; |
|
} |
|
return |
|
} |
|
|
sub modify_usersessions { |
sub modify_usersessions { |
my ($dom,$lastactref,%domconfig) = @_; |
my ($dom,$lastactref,%domconfig) = @_; |
my @hostingtypes = ('version','excludedomain','includedomain'); |
my @hostingtypes = ('version','excludedomain','includedomain'); |
Line 18289 sub modify_usersessions {
|
Line 19947 sub modify_usersessions {
|
} |
} |
} |
} |
$defaultshash{'usersessions'}{'offloadnow'} = {}; |
$defaultshash{'usersessions'}{'offloadnow'} = {}; |
|
$defaultshash{'usersessions'}{'offloadoth'} = {}; |
my @offloadnow = &Apache::loncommon::get_env_multiple('form.offloadnow'); |
my @offloadnow = &Apache::loncommon::get_env_multiple('form.offloadnow'); |
my @okoffload; |
my @okoffload; |
if (@offloadnow) { |
if (@offloadnow) { |
Line 18305 sub modify_usersessions {
|
Line 19964 sub modify_usersessions {
|
} |
} |
} |
} |
} |
} |
|
my @offloadoth = &Apache::loncommon::get_env_multiple('form.offloadoth'); |
|
my @okoffloadoth; |
|
if (@offloadoth) { |
|
foreach my $server (@offloadoth) { |
|
if (&Apache::lonnet::hostname($server) ne '') { |
|
unless (grep(/^\Q$server\E$/,@okoffloadoth)) { |
|
push(@okoffloadoth,$server); |
|
} |
|
} |
|
} |
|
if (@okoffloadoth) { |
|
foreach my $lonhost (@okoffloadoth) { |
|
$defaultshash{'usersessions'}{'offloadoth'}{$lonhost} = 1; |
|
} |
|
} |
|
} |
if (ref($domconfig{'usersessions'}) eq 'HASH') { |
if (ref($domconfig{'usersessions'}) eq 'HASH') { |
if (ref($domconfig{'usersessions'}{'spares'}) eq 'HASH') { |
if (ref($domconfig{'usersessions'}{'spares'}) eq 'HASH') { |
if (ref($changes{'spares'}) eq 'HASH') { |
if (ref($changes{'spares'}) eq 'HASH') { |
Line 18315 sub modify_usersessions {
|
Line 19990 sub modify_usersessions {
|
} else { |
} else { |
$savespares = 1; |
$savespares = 1; |
} |
} |
if (ref($domconfig{'usersessions'}{'offloadnow'}) eq 'HASH') { |
foreach my $offload ('offloadnow','offloadoth') { |
foreach my $lonhost (keys(%{$domconfig{'usersessions'}{'offloadnow'}})) { |
if (ref($domconfig{'usersessions'}{$offload}) eq 'HASH') { |
unless ($defaultshash{'usersessions'}{'offloadnow'}{$lonhost}) { |
foreach my $lonhost (keys(%{$domconfig{'usersessions'}{$offload}})) { |
$changes{'offloadnow'} = 1; |
unless ($defaultshash{'usersessions'}{$offload}{$lonhost}) { |
last; |
$changes{$offload} = 1; |
} |
|
} |
|
unless ($changes{'offloadnow'}) { |
|
foreach my $lonhost (keys(%{$defaultshash{'usersessions'}{'offloadnow'}})) { |
|
unless ($domconfig{'usersessions'}{'offloadnow'}{$lonhost}) { |
|
$changes{'offloadnow'} = 1; |
|
last; |
last; |
} |
} |
} |
} |
} |
unless ($changes{$offload}) { |
} elsif (@okoffload) { |
foreach my $lonhost (keys(%{$defaultshash{'usersessions'}{$offload}})) { |
|
unless ($domconfig{'usersessions'}{$offload}{$lonhost}) { |
|
$changes{$offload} = 1; |
|
last; |
|
} |
|
} |
|
} |
|
} else { |
|
if (($offload eq 'offloadnow') && (@okoffload)) { |
|
$changes{'offloadnow'} = 1; |
|
} |
|
if (($offload eq 'offloadoth') && (@okoffloadoth)) { |
|
$changes{'offloadoth'} = 1; |
|
} |
|
} |
|
} |
|
} else { |
|
if (@okoffload) { |
$changes{'offloadnow'} = 1; |
$changes{'offloadnow'} = 1; |
} |
} |
} elsif (@okoffload) { |
if (@okoffloadoth) { |
$changes{'offloadnow'} = 1; |
$changes{'offloadoth'} = 1; |
|
} |
} |
} |
my $nochgmsg = &mt('No changes made to settings for user session hosting/offloading.'); |
my $nochgmsg = &mt('No changes made to settings for user session hosting/offloading.'); |
if ((keys(%changes) > 0) || ($savespares)) { |
if ((keys(%changes) > 0) || ($savespares)) { |
Line 18351 sub modify_usersessions {
|
Line 20038 sub modify_usersessions {
|
if (ref($defaultshash{'usersessions'}{'offloadnow'}) eq 'HASH') { |
if (ref($defaultshash{'usersessions'}{'offloadnow'}) eq 'HASH') { |
$domdefaults{'offloadnow'} = $defaultshash{'usersessions'}{'offloadnow'}; |
$domdefaults{'offloadnow'} = $defaultshash{'usersessions'}{'offloadnow'}; |
} |
} |
|
if (ref($defaultshash{'usersessions'}{'offloadoth'}) eq 'HASH') { |
|
$domdefaults{'offloadoth'} = $defaultshash{'usersessions'}{'offloadoth'}; |
|
} |
} |
} |
my $cachetime = 24*60*60; |
my $cachetime = 24*60*60; |
&Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); |
&Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); |
Line 18430 sub modify_usersessions {
|
Line 20120 sub modify_usersessions {
|
if ($changes{'offloadnow'}) { |
if ($changes{'offloadnow'}) { |
if (ref($defaultshash{'usersessions'}{'offloadnow'}) eq 'HASH') { |
if (ref($defaultshash{'usersessions'}{'offloadnow'}) eq 'HASH') { |
if (keys(%{$defaultshash{'usersessions'}{'offloadnow'}}) > 0) { |
if (keys(%{$defaultshash{'usersessions'}{'offloadnow'}}) > 0) { |
$resulttext .= '<li>'.&mt('Switch active users on next access, for server(s):').'<ul>'; |
$resulttext .= '<li>'.&mt('Switch any active user on next access, for server(s):').'<ul>'; |
foreach my $lonhost (sort(keys(%{$defaultshash{'usersessions'}{'offloadnow'}}))) { |
foreach my $lonhost (sort(keys(%{$defaultshash{'usersessions'}{'offloadnow'}}))) { |
$resulttext .= '<li>'.$lonhost.'</li>'; |
$resulttext .= '<li>'.$lonhost.'</li>'; |
} |
} |
$resulttext .= '</ul>'; |
$resulttext .= '</ul>'; |
} else { |
} else { |
$resulttext .= '<li>'.&mt('No servers now set to switch active users on next access.'); |
$resulttext .= '<li>'.&mt('No servers now set to switch any active user on next access.'); |
} |
} |
} else { |
} else { |
$resulttext .= '<li>'.&mt('No servers now set to switch active users on next access.').'</li>'; |
$resulttext .= '<li>'.&mt('No servers now set to switch any active user on next access.').'</li>'; |
|
} |
|
} |
|
if ($changes{'offloadoth'}) { |
|
if (ref($defaultshash{'usersessions'}{'offloadoth'}) eq 'HASH') { |
|
if (keys(%{$defaultshash{'usersessions'}{'offloadoth'}}) > 0) { |
|
$resulttext .= '<li>'.&mt('Switch other institutions on next access, for server(s):').'<ul>'; |
|
foreach my $lonhost (sort(keys(%{$defaultshash{'usersessions'}{'offloadoth'}}))) { |
|
$resulttext .= '<li>'.$lonhost.'</li>'; |
|
} |
|
$resulttext .= '</ul>'; |
|
} else { |
|
$resulttext .= '<li>'.&mt('No servers now set to switch other institutions on next access.'); |
|
} |
|
} else { |
|
$resulttext .= '<li>'.&mt('No servers now set to switch other institutions on next access.').'</li>'; |
} |
} |
} |
} |
$resulttext .= '</ul>'; |
$resulttext .= '</ul>'; |
Line 19011 sub modify_loadbalancing {
|
Line 20716 sub modify_loadbalancing {
|
$resulttext .= '<li>'.&mt('Load Balancer: [_1] -- cookie use enabled', |
$resulttext .= '<li>'.&mt('Load Balancer: [_1] -- cookie use enabled', |
$balancer).'</li>'; |
$balancer).'</li>'; |
} |
} |
if (keys(%toupdate)) { |
} |
my %thismachine; |
} |
my $updatedhere; |
if (keys(%toupdate)) { |
my $cachetime = 60*60*24; |
my %thismachine; |
map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids(); |
my $updatedhere; |
foreach my $lonhost (keys(%toupdate)) { |
my $cachetime = 60*60*24; |
if ($thismachine{$lonhost}) { |
map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids(); |
unless ($updatedhere) { |
foreach my $lonhost (keys(%toupdate)) { |
&Apache::lonnet::do_cache_new('loadbalancing',$dom, |
if ($thismachine{$lonhost}) { |
$defaultshash{'loadbalancing'}, |
unless ($updatedhere) { |
$cachetime); |
&Apache::lonnet::do_cache_new('loadbalancing',$dom, |
$updatedhere = 1; |
$defaultshash{'loadbalancing'}, |
} |
$cachetime); |
} else { |
$updatedhere = 1; |
my $cachekey = &escape('loadbalancing').':'.&escape($dom); |
|
&Apache::lonnet::remote_devalidate_cache($lonhost,[$cachekey]); |
|
} |
|
} |
} |
|
} else { |
|
my $cachekey = &escape('loadbalancing').':'.&escape($dom); |
|
&Apache::lonnet::remote_devalidate_cache($lonhost,[$cachekey]); |
} |
} |
} |
} |
} |
} |
Line 19525 function balancerChange(balnum,baltotal,
|
Line 21230 function balancerChange(balnum,baltotal,
|
END |
END |
} |
} |
|
|
|
|
sub new_spares_js { |
sub new_spares_js { |
my @sparestypes = ('primary','default'); |
my @sparestypes = ('primary','default'); |
my $types = join("','",@sparestypes); |
my $types = join("','",@sparestypes); |
Line 19598 function updateNewSpares(formname,lonhos
|
Line 21304 function updateNewSpares(formname,lonhos
|
function checkNewSpares(lonhost,type) { |
function checkNewSpares(lonhost,type) { |
var newSpare = document.getElementById('newspare_'+type+'_'+lonhost); |
var newSpare = document.getElementById('newspare_'+type+'_'+lonhost); |
var chosen = newSpare.options[newSpare.selectedIndex].value; |
var chosen = newSpare.options[newSpare.selectedIndex].value; |
if (chosen != '') { |
if (chosen != '') { |
var othertype; |
var othertype; |
var othernewSpare; |
var othernewSpare; |
if (type == 'primary') { |
if (type == 'primary') { |
Line 19732 function toggleDisplay(domForm,caller) {
|
Line 21438 function toggleDisplay(domForm,caller) {
|
var dispval = 'block'; |
var dispval = 'block'; |
var selfcreateRegExp = /^cancreate_emailverified/; |
var selfcreateRegExp = /^cancreate_emailverified/; |
if (caller == 'emailoptions') { |
if (caller == 'emailoptions') { |
optionsElement = domForm.cancreate_email; |
optionsElement = domForm.cancreate_email; |
} |
} |
if (caller == 'studentsubmission') { |
if (caller == 'studentsubmission') { |
optionsElement = domForm.postsubmit; |
optionsElement = domForm.postsubmit; |
Line 19788 sub devalidate_remote_domconfs {
|
Line 21494 sub devalidate_remote_domconfs {
|
my %thismachine; |
my %thismachine; |
map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids(); |
map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids(); |
my @posscached = ('domainconfig','domdefaults','ltitools','usersessions', |
my @posscached = ('domainconfig','domdefaults','ltitools','usersessions', |
'directorysrch','passwdconf','cats'); |
'directorysrch','passwdconf','cats','proxyalias'); |
if (keys(%servers)) { |
if (keys(%servers)) { |
foreach my $server (keys(%servers)) { |
foreach my $server (keys(%servers)) { |
next if ($thismachine{$server}); |
next if ($thismachine{$server}); |
my @cached; |
my @cached; |
foreach my $name (@posscached) { |
foreach my $name (@posscached) { |
if ($cachekeys->{$name}) { |
if ($cachekeys->{$name}) { |
push(@cached,&escape($name).':'.&escape($dom)); |
if ($name eq 'proxyalias') { |
|
if (ref($cachekeys->{$name}) eq 'HASH') { |
|
foreach my $key (keys(%{$cachekeys->{$name}})) { |
|
push(@cached,&escape($name).':'.&escape($key)); |
|
} |
|
} |
|
} else { |
|
push(@cached,&escape($name).':'.&escape($dom)); |
|
} |
} |
} |
} |
} |
if (@cached) { |
if (@cached) { |