';
}
}
@@ -9628,7 +10701,7 @@ sub modify_login {
my ($r,$dom,$confname,$lastactref,%domconfig) = @_;
my ($resulttext,$errors,$colchgtext,%changes,%colchanges,%newfile,%newurl,
%curr_loginvia,%loginhash,@currlangs,@newlangs,$addedfile,%title,@offon,
- %currsaml,%saml,%samltext,%samlimg,%samlalt,%samlurl,%samltitle,%samlnotsso);
+ %currsaml,%saml,%samltext,%samlimg,%samlalt,%samlurl,%samltitle,%samlwindow,%samlnotsso);
%title = ( coursecatalog => 'Display course catalog',
adminmail => 'Display administrator E-mail address',
helpdesk => 'Display "Contact Helpdesk" link',
@@ -9652,6 +10725,7 @@ sub modify_login {
$samlalt{$lonhost} = $domconfig{login}{'saml'}{$lonhost}{'alt'};
$samlimg{$lonhost} = $domconfig{login}{'saml'}{$lonhost}{'img'};
$samltitle{$lonhost} = $domconfig{login}{'saml'}{$lonhost}{'title'};
+ $samlwindow{$lonhost} = $domconfig{login}{'saml'}{$lonhost}{'window'};
$samlnotsso{$lonhost} = $domconfig{login}{'saml'}{$lonhost}{'notsso'};
}
}
@@ -9794,13 +10868,16 @@ sub modify_login {
if ($addedfile ne '') {
push(@allnew,$addedfile);
}
+ my $modified = [];
foreach my $lang (@allnew) {
my $formelem = 'loginhelpurl_'.$lang;
if ($lang eq $env{'form.loginhelpurl_add_lang'}) {
$formelem = 'loginhelpurl_add_file';
}
- (my $result,$newurl{$lang}) = &publishlogo($r,'upload',$formelem,$dom,$confname,
- "help/$lang",'','',$newfile{$lang});
+ (my $result,$newurl{$lang}) =
+ &Apache::lonconfigsettings::publishlogo($r,'upload',$formelem,$dom,$confname,
+ "help/$lang",'','',$newfile{$lang},
+ $modified);
if ($result eq 'ok') {
$loginhash{'login'}{'helpurl'}{$lang} = $newurl{$lang};
$changes{'helpurl'}{$lang} = 1;
@@ -9813,6 +10890,7 @@ sub modify_login {
}
}
}
+ &update_modify_urls($r,$modified);
} else {
$error = &mt("Upload of custom log-in help file(s) failed because an author role could not be assigned to a Domain Configuration user ([_1]) in domain: [_2]. Error was: [_3].",$confname,$dom,$author_ok);
}
@@ -9870,11 +10948,14 @@ sub modify_login {
if ($switchserver) {
$error = &mt("Upload of custom markup is not permitted to this server: [_1]",$switchserver);
} elsif ($author_ok eq 'ok') {
+ my $modified = [];
foreach my $lonhost (@newhosts) {
my $formelem = 'loginheadtag_'.$lonhost;
- (my $result,$newheadtagurls{$lonhost}) = &publishlogo($r,'upload',$formelem,$dom,$confname,
- "login/headtag/$lonhost",'','',
- $env{'form.loginheadtag_'.$lonhost.'.filename'});
+ (my $result,$newheadtagurls{$lonhost}) =
+ &Apache::lonconfigsettings::publishlogo($r,'upload',$formelem,$dom,$confname,
+ "login/headtag/$lonhost",'','',
+ $env{'form.loginheadtag_'.$lonhost.'.filename'},
+ $modified);
if ($result eq 'ok') {
$loginhash{'login'}{'headtag'}{$lonhost}{'url'} = $newheadtagurls{$lonhost};
$changes{'headtag'}{$lonhost} = 1;
@@ -9891,6 +10972,7 @@ sub modify_login {
}
}
}
+ &update_modify_urls($r,$modified);
} else {
$error = &mt("Upload of custom markup file(s) failed because an author role could not be assigned to a Domain Configuration user ([_1]) in domain: [_2]. Error was: [_3].",$confname,$dom,$author_ok);
}
@@ -9909,10 +10991,13 @@ sub modify_login {
if ($env{'form.saml_img_'.$lonhost.'.filename'}) {
push(@newsamlimgs,$lonhost);
}
- foreach my $item ('text','alt','url','title','notsso') {
+ foreach my $item ('text','alt','url','title','window','notsso') {
$env{'form.saml_'.$item.'_'.$lonhost} =~ s/^\s+|\s+$//g;
}
if ($saml{$lonhost}) {
+ if ($env{'form.saml_window_'.$lonhost} ne '1') {
+ $env{'form.saml_window_'.$lonhost} = '';
+ }
if (grep(/^\Q$lonhost\E$/,@delsamlimg)) {
#FIXME Need to obsolete published image
delete($currsaml{$lonhost}{'img'});
@@ -9930,13 +11015,16 @@ sub modify_login {
if ($env{'form.saml_title_'.$lonhost} ne $samltitle{$lonhost}) {
$changes{'saml'}{$lonhost} = 1;
}
+ if ($env{'form.saml_window_'.$lonhost} ne $samlwindow{$lonhost}) {
+ $changes{'saml'}{$lonhost} = 1;
+ }
if ($env{'form.saml_notsso_'.$lonhost} ne $samlnotsso{$lonhost}) {
$changes{'saml'}{$lonhost} = 1;
}
} else {
$changes{'saml'}{$lonhost} = 1;
}
- foreach my $item ('text','alt','url','title','notsso') {
+ foreach my $item ('text','alt','url','title','window','notsso') {
$currsaml{$lonhost}{$item} = $env{'form.saml_'.$item.'_'.$lonhost};
}
} else {
@@ -9959,11 +11047,14 @@ sub modify_login {
if ($switchserver) {
$error = &mt("Upload of SSO Button Image is not permitted to this server: [_1].",$switchserver);
} elsif ($author_ok eq 'ok') {
+ my $modified = [];
foreach my $lonhost (@newsamlimgs) {
my $formelem = 'saml_img_'.$lonhost;
- my ($result,$imgurl) = &publishlogo($r,'upload',$formelem,$dom,$confname,
- "login/saml/$lonhost",'','',
- $env{'form.saml_img_'.$lonhost.'.filename'});
+ my ($result,$imgurl) =
+ &Apache::lonconfigsettings::publishlogo($r,'upload',$formelem,$dom,$confname,
+ "login/saml/$lonhost",'','',
+ $env{'form.saml_img_'.$lonhost.'.filename'},
+ $modified);
if ($result eq 'ok') {
$currsaml{$lonhost}{'img'} = $imgurl;
$loginhash{'login'}{'saml'}{$lonhost}{'img'} = $imgurl;
@@ -9974,6 +11065,7 @@ sub modify_login {
$errors .= '
'.$puberror.'
';
}
}
+ &update_modify_urls($r,$modified);
} else {
$error = &mt("Upload of SSO button image file(s) failed because an author role could not be assigned to a Domain Configuration user ([_1]) in domain: [_2]. Error was: [_3].",$confname,$dom,$author_ok);
}
@@ -10137,19 +11229,22 @@ sub modify_login {
alt => 'Alt text for button image',
url => 'SSO URL',
title => 'Tooltip for SSO link',
+ window => 'Pop-up window if iframe',
notsso => 'Text for non-SSO log-in',
);
foreach my $lonhost (sort(keys(%{$changes{$item}}))) {
if (ref($currsaml{$lonhost}) eq 'HASH') {
$resulttext .= '
'.&mt("$title{$item} in use for [_1]","$lonhost").
'
';
- foreach my $key ('text','img','alt','url','title','notsso') {
+ foreach my $key ('text','img','alt','url','title','window','notsso') {
if ($currsaml{$lonhost}{$key} eq '') {
$resulttext .= '
'.&mt('[_1] set to [_2]',$titles{$rule},$newsec->{rules}{$rule}).'
';
+ }
+ }
+ if (ref($newsec->{'rules'}{'chars'}) eq 'ARRAY') {
+ if (@{$newsec->{'rules'}{'chars'}} > 0) {
+ my %rulenames = &Apache::lonlocal::texthash(
+ uc => 'At least one upper case letter',
+ lc => 'At least one lower case letter',
+ num => 'At least one number',
+ spec => 'At least one non-alphanumeric',
+ );
+ my $needed = '
'.&mt('[_1] set to: [_2]',$titles{'chars'},$needed).'
';
+ } else {
+ $output .= '
'.&mt('[_1] set to none',$titles{'chars'}).'
';
}
+ } else {
+ $output .= '
'.&mt('[_1] set to none',$titles{'chars'}).'
';
+ }
+ } elsif ($item eq 'private') {
+ $needs_update = 1;
+ if ($context eq 'lti') {
+ undef($domdefaults{'ltiprivhosts'});
+ } elsif ($context eq 'ltitools') {
+ undef($domdefaults{'toolprivhosts'});
}
- if (ref($confhash{$newid}{'fields'}) eq 'HASH') {
- if ($confhash{$newid}{'fields'}{'user'}) {
- if ($env{'form.ltitools_userincdom_add'}) {
- $confhash{$newid}{'incdom'} = 1;
+ if (keys(%{$newkeyset})) {
+ my @privhosts;
+ foreach my $hostid (sort(keys(%{$newkeyset}))) {
+ if ($keystore->{$hostid} eq 'ok') {
+ $output .= '
'.&mt('Encryption key for storage of shared secrets saved for [_1]',$hostid).'
';
+ unless (grep(/^\Q$hostid\E$/,@privhosts)) {
+ push(@privhosts,$hostid);
+ }
+ }
+ }
+ if (@privhosts) {
+ if ($context eq 'lti') {
+ $domdefaults{'ltiprivhosts'} = \@privhosts;
+ } elsif ($context eq 'ltitools') {
+ $domdefaults{'toolprivhosts'} = \@privhosts;
}
}
}
- my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig');
- foreach my $item (@courseconfig) {
- $confhash{$newid}{'crsconf'}{$item} = 1;
+ } elsif ($item eq 'linkprot') {
+ next;
+ }
+ }
+ if ($needs_update) {
+ my $cachetime = 24*60*60;
+ &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
+ }
+ return $output;
+}
+
+sub modify_lti {
+ my ($r,$dom,$action,$lastactref,%domconfig) = @_;
+ my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
+ my ($newid,@allpos,%changes,%confhash,%ltienc,$errors,$resulttext);
+ my (%posslti,%posslticrs,%posscrstype);
+ my @courseroles = ('cc','in','ta','ep','st');
+ my @ltiroles = qw(Learner Instructor ContentDeveloper TeachingAssistant Mentor Member Manager Administrator);
+ my @lticourseroles = qw(Instructor TeachingAssistant Mentor Learner);
+ my @coursetypes = ('official','unofficial','community','textbook','placement','lti');
+ my %coursetypetitles = &Apache::lonlocal::texthash (
+ official => 'Official',
+ unofficial => 'Unofficial',
+ community => 'Community',
+ textbook => 'Textbook',
+ placement => 'Placement Test',
+ lti => 'LTI Provider',
+ );
+ my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
+ my %lt = <i_names();
+ map { $posslti{$_} = 1; } @ltiroles;
+ map { $posslticrs{$_} = 1; } @lticourseroles;
+ map { $posscrstype{$_} = 1; } @coursetypes;
+
+ my %menutitles = <imenu_titles();
+ my (%currltisec,%secchanges,%newltisec,%newltienc,%newkeyset);
+
+ &fetch_secrets($dom,'ltisec',\%domconfig,\%currltisec,\%secchanges,\%newltisec,\%newkeyset);
+
+ my (%linkprotchg,$linkprotoutput,$is_home);
+ my $proterror = &Apache::courseprefs::process_linkprot($dom,'',$currltisec{'linkprot'},
+ \%linkprotchg,'domain');
+ my $home = &Apache::lonnet::domain($dom,'primary');
+ unless (($home eq 'no_host') || ($home eq '')) {
+ my @ids=&Apache::lonnet::current_machine_ids();
+ foreach my $id (@ids) { if ($id eq $home) { $is_home=1; } }
+ }
+
+ if (keys(%linkprotchg)) {
+ $secchanges{'linkprot'} = 1;
+ my %oldlinkprot;
+ if (ref($currltisec{'linkprot'}) eq 'HASH') {
+ %oldlinkprot = %{$currltisec{'linkprot'}};
+ }
+ foreach my $id (keys(%linkprotchg)) {
+ if (ref($linkprotchg{$id}) eq 'HASH') {
+ foreach my $inner (keys(%{$linkprotchg{$id}})) {
+ if (($inner eq 'secret') || ($inner eq 'key')) {
+ if ($is_home) {
+ $newltienc{$id}{$inner} = $linkprotchg{$id}{$inner};
+ }
+ }
+ }
+ } else {
+ $newltisec{'linkprot'}{$id} = $linkprotchg{$id};
}
- if ($env{'form.ltitools_add_custom'}) {
- my $name = $env{'form.ltitools_add_custom_name'};
- my $value = $env{'form.ltitools_add_custom_value'};
- $value =~ s/(`)/'/g;
- $name =~ s/(`)/'/g;
- $confhash{$newid}{'custom'}{$name} = $value;
+ }
+ $linkprotoutput = &Apache::courseprefs::store_linkprot($dom,'','domain',\%linkprotchg,\%oldlinkprot);
+ if (keys(%linkprotchg)) {
+ %{$newltisec{'linkprot'}} = %linkprotchg;
+ }
+ }
+ if (ref($currltisec{'linkprot'}) eq 'HASH') {
+ foreach my $id (%{$currltisec{'linkprot'}}) {
+ next if ($id !~ /^\d+$/);
+ unless (exists($linkprotchg{$id})) {
+ if (ref($currltisec{'linkprot'}{$id}) eq 'HASH') {
+ foreach my $inner (keys(%{$currltisec{'linkprot'}{$id}})) {
+ if (($inner eq 'secret') || ($inner eq 'key')) {
+ if ($is_home) {
+ $newltienc{$id}{$inner} = $currltisec{'linkprot'}{$id}{$inner};
+ }
+ } else {
+ $newltisec{'linkprot'}{$id}{$inner} = $currltisec{'linkprot'}{$id}{$inner};
+ }
+ }
+ } else {
+ $newltisec{'linkprot'}{$id} = $currltisec{'linkprot'}{$id};
+ }
}
+ }
+ }
+ if ($proterror) {
+ $errors .= '
'.$proterror.'
';
+ }
+ my (@items,%deletions,%itemids);
+ if ($env{'form.lti_add'}) {
+ my $consumer = $env{'form.lti_consumer_add'};
+ $consumer =~ s/(`)/'/g;
+ ($newid,my $error) = &get_lti_id($dom,$consumer);
+ if ($newid) {
+ $itemids{'add'} = $newid;
+ push(@items,'add');
+ $changes{$newid} = 1;
} else {
- my $error = &mt('Failed to acquire unique ID for new external tool');
+ my $error = &mt('Failed to acquire unique ID for new LTI configuration');
$errors .= '
'.$error.'
';
}
}
if (ref($domconfig{$action}) eq 'HASH') {
- my %deletions;
- my @todelete = &Apache::loncommon::get_env_multiple('form.ltitools_del');
+ my @todelete = &Apache::loncommon::get_env_multiple('form.lti_del');
if (@todelete) {
map { $deletions{$_} = 1; } @todelete;
}
- my %customadds;
- my @newcustom = &Apache::loncommon::get_env_multiple('form.ltitools_customadd');
- if (@newcustom) {
- map { $customadds{$_} = 1; } @newcustom;
- }
- my %imgdeletions;
- my @todeleteimages = &Apache::loncommon::get_env_multiple('form.ltitools_image_del');
- if (@todeleteimages) {
- map { $imgdeletions{$_} = 1; } @todeleteimages;
- }
- my $maxnum = $env{'form.ltitools_maxnum'};
- for (my $i=0; $i<=$maxnum; $i++) {
- my $itemid = $env{'form.ltitools_id_'.$i};
+ my $maxnum = $env{'form.lti_maxnum'};
+ for (my $i=0; $i<$maxnum; $i++) {
+ my $itemid = $env{'form.lti_id_'.$i};
$itemid =~ s/\D+//g;
if (ref($domconfig{$action}{$itemid}) eq 'HASH') {
if ($deletions{$itemid}) {
- if ($domconfig{$action}{$itemid}{'image'}) {
- #FIXME need to obsolete item in RES space
- }
- $changes{$itemid} = $domconfig{$action}{$itemid}{'title'};
- next;
+ $changes{$itemid} = $domconfig{$action}{$itemid}{'consumer'};
} else {
- my $newpos = $env{'form.ltitools_'.$itemid};
- $newpos =~ s/\D+//g;
- foreach my $item ('title','url','lifetime') {
- $confhash{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i};
- if ($domconfig{$action}{$itemid}{$item} ne $confhash{$itemid}{$item}) {
- $changes{$itemid} = 1;
+ push(@items,$i);
+ $itemids{$i} = $itemid;
+ }
+ }
+ }
+ }
+ my (%keystore,$secstored);
+ if ($is_home) {
+ &store_security($dom,'lti',\%secchanges,\%newkeyset,\%keystore);
+ }
+
+ my ($cipher,$privnum);
+ if ((@items > 0) && ($is_home)) {
+ ($cipher,$privnum) = &get_priv_creds($dom,$home,$secchanges{'encrypt'},
+ $newltisec{'encrypt'},$keystore{$home});
+ }
+ foreach my $idx (@items) {
+ my $itemid = $itemids{$idx};
+ next unless ($itemid);
+ my %currlti;
+ unless ($idx eq 'add') {
+ if (ref($domconfig{$action}) eq 'HASH') {
+ if (ref($domconfig{$action}{$itemid}) eq 'HASH') {
+ %currlti = %{$domconfig{$action}{$itemid}};
+ }
+ }
+ }
+ my $position = $env{'form.lti_pos_'.$itemid};
+ $position =~ s/\D+//g;
+ if ($position ne '') {
+ $allpos[$position] = $itemid;
+ }
+ foreach my $item ('consumer','lifetime','requser','crsinc') {
+ my $formitem = 'form.lti_'.$item.'_'.$idx;
+ $env{$formitem} =~ s/(`)/'/g;
+ if ($item eq 'lifetime') {
+ $env{$formitem} =~ s/[^\d.]//g;
+ }
+ if ($env{$formitem} ne '') {
+ $confhash{$itemid}{$item} = $env{$formitem};
+ unless (($idx eq 'add') || ($changes{$itemid})) {
+ if ($currlti{$item} ne $confhash{$itemid}{$item}) {
+ $changes{$itemid} = 1;
+ }
+ }
+ }
+ }
+ if ($env{'form.lti_version_'.$idx} eq 'LTI-1p0') {
+ $confhash{$itemid}{'version'} = $env{'form.lti_version_'.$idx};
+ }
+ if ($confhash{$itemid}{'requser'}) {
+ if ($env{'form.lti_mapuser_'.$idx} eq 'sourcedid') {
+ $confhash{$itemid}{'mapuser'} = 'lis_person_sourcedid';
+ } elsif ($env{'form.lti_mapuser_'.$idx} eq 'email') {
+ $confhash{$itemid}{'mapuser'} = 'lis_person_contact_email_primary';
+ } elsif ($env{'form.lti_mapuser_'.$idx} eq 'other') {
+ my $mapuser = $env{'form.lti_customuser_'.$idx};
+ $mapuser =~ s/(`)/'/g;
+ $mapuser =~ s/^\s+|\s+$//g;
+ $confhash{$itemid}{'mapuser'} = $mapuser;
+ }
+ my @possmakeuser = &Apache::loncommon::get_env_multiple('form.lti_makeuser_'.$idx);
+ my @makeuser;
+ foreach my $ltirole (sort(@possmakeuser)) {
+ if ($posslti{$ltirole}) {
+ push(@makeuser,$ltirole);
+ }
+ }
+ $confhash{$itemid}{'makeuser'} = \@makeuser;
+ if (@makeuser) {
+ my $lcauth = $env{'form.lti_lcauth_'.$idx};
+ if ($lcauth =~ /^(internal|krb4|krb5|localauth)$/) {
+ $confhash{$itemid}{'lcauth'} = $lcauth;
+ if ($lcauth ne 'internal') {
+ my $lcauthparm = $env{'form.lti_lcauthparm_'.$idx};
+ $lcauthparm =~ s/^(\s+|\s+)$//g;
+ $lcauthparm =~ s/`//g;
+ if ($lcauthparm ne '') {
+ $confhash{$itemid}{'lcauthparm'} = $lcauthparm;
}
}
- foreach my $item ('key','secret') {
- $encconfig{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i};
- if ($domconfig{$action}{$itemid}{$item} ne $encconfig{$itemid}{$item}) {
- $changes{$itemid} = 1;
+ } else {
+ $confhash{$itemid}{'lcauth'} = 'lti';
+ }
+ }
+ my @possinstdata = &Apache::loncommon::get_env_multiple('form.lti_instdata_'.$idx);
+ if (@possinstdata) {
+ foreach my $field (@possinstdata) {
+ if (exists($fieldtitles{$field})) {
+ push(@{$confhash{$itemid}{'instdata'}});
+ }
+ }
+ }
+ if ($env{'form.lti_callback_'.$idx}) {
+ if ($env{'form.lti_callbackparam_'.$idx}) {
+ my $callback = $env{'form.lti_callbackparam_'.$idx};
+ $callback =~ s/^\s+|\s+$//g;
+ $confhash{$itemid}{'callback'} = $callback;
+ }
+ }
+ foreach my $field ('topmenu','inlinemenu') {
+ if ($env{'form.lti_'.$field.'_'.$idx}) {
+ $confhash{$itemid}{$field} = 1;
+ }
+ }
+ if ($env{'form.lti_topmenu_'.$idx} || $env{'form.lti_inlinemenu_'.$idx}) {
+ $confhash{$itemid}{lcmenu} = [];
+ my @possmenu = &Apache::loncommon::get_env_multiple('form.lti_menuitem_'.$idx);
+ foreach my $field (@possmenu) {
+ if (exists($menutitles{$field})) {
+ if ($field eq 'grades') {
+ next unless ($env{'form.lti_inlinemenu_'.$idx});
}
+ push(@{$confhash{$itemid}{lcmenu}},$field);
}
- if ($env{'form.ltitools_version_'.$i} eq 'LTI-1p0') {
- $confhash{$itemid}{'version'} = $env{'form.ltitools_version_'.$i};
+ }
+ }
+ if ($confhash{$itemid}{'crsinc'}) {
+ if (($env{'form.lti_mapcrs_'.$idx} eq 'course_offering_sourcedid') ||
+ ($env{'form.lti_mapcrs_'.$idx} eq 'context_id')) {
+ $confhash{$itemid}{'mapcrs'} = $env{'form.lti_mapcrs_'.$idx};
+ } elsif ($env{'form.lti_mapcrs_'.$idx} eq 'other') {
+ my $mapcrs = $env{'form.lti_mapcrsfield_'.$idx};
+ $mapcrs =~ s/(`)/'/g;
+ $mapcrs =~ s/^\s+|\s+$//g;
+ $confhash{$itemid}{'mapcrs'} = $mapcrs;
+ }
+ my @posstypes = &Apache::loncommon::get_env_multiple('form.lti_mapcrstype_'.$idx);
+ my @crstypes;
+ foreach my $type (sort(@posstypes)) {
+ if ($posscrstype{$type}) {
+ push(@crstypes,$type);
}
- if ($env{'form.ltitools_msgtype_'.$i} eq 'basic-lti-launch-request') {
- $confhash{$itemid}{'msgtype'} = $env{'form.ltitools_msgtype_'.$i};
+ }
+ $confhash{$itemid}{'mapcrstype'} = \@crstypes;
+ if ($env{'form.lti_storecrs_'.$idx}) {
+ $confhash{$itemid}{'storecrs'} = 1;
+ }
+ if ($env{'form.lti_makecrs_'.$idx}) {
+ $confhash{$itemid}{'makecrs'} = 1;
+ }
+ foreach my $ltirole (@lticourseroles) {
+ my $possrole = $env{'form.lti_maprole_'.$ltirole.'_'.$idx};
+ if (grep(/^\Q$possrole\E$/,@courseroles)) {
+ $confhash{$itemid}{'maproles'}{$ltirole} = $possrole;
+ }
+ }
+ my @possenroll = &Apache::loncommon::get_env_multiple('form.lti_selfenroll_'.$idx);
+ my @selfenroll;
+ foreach my $type (sort(@possenroll)) {
+ if ($posslticrs{$type}) {
+ push(@selfenroll,$type);
}
- if ($env{'form.ltitools_sigmethod_'.$i} eq 'HMAC-SHA256') {
- $confhash{$itemid}{'sigmethod'} = $env{'form.ltitools_sigmethod_'.$i};
+ }
+ $confhash{$itemid}{'selfenroll'} = \@selfenroll;
+ if ($env{'form.lti_crssec_'.$idx}) {
+ if ($env{'form.lti_crssecsrc_'.$idx} eq 'course_section_sourcedid') {
+ $confhash{$itemid}{'section'} = $env{'form.lti_crssecsrc_'.$idx};
+ } elsif ($env{'form.lti_crssecsrc_'.$idx} eq 'other') {
+ my $section = $env{'form.lti_customsection_'.$idx};
+ $section =~ s/(`)/'/g;
+ $section =~ s/^\s+|\s+$//g;
+ if ($section ne '') {
+ $confhash{$itemid}{'section'} = $section;
+ }
+ }
+ }
+ foreach my $field ('passback','roster') {
+ if ($env{'form.lti_'.$field.'_'.$idx}) {
+ $confhash{$itemid}{$field} = 1;
+ }
+ }
+ if ($env{'form.lti_passback_'.$idx}) {
+ if ($env{'form.lti_passbackformat_'.$idx} eq '1.0') {
+ $confhash{$itemid}{'passbackformat'} = '1.0';
} else {
- $confhash{$itemid}{'sigmethod'} = 'HMAC-SHA1';
+ $confhash{$itemid}{'passbackformat'} = '1.1';
}
- if ($domconfig{$action}{$itemid}{'sigmethod'} eq '') {
- if ($confhash{$itemid}{'sigmethod'} ne 'HMAC-SHA1') {
+ }
+ }
+ unless (($idx eq 'add') || ($changes{$itemid})) {
+ if ($confhash{$itemid}{'crsinc'}) {
+ foreach my $field ('mapcrs','storecrs','makecrs','section','passback','roster') {
+ if ($currlti{$field} ne $confhash{$itemid}{$field}) {
$changes{$itemid} = 1;
}
- } elsif ($domconfig{$action}{$itemid}{'sigmethod'} ne $confhash{$itemid}{'sigmethod'}) {
- $changes{$itemid} = 1;
}
- foreach my $size ('width','height') {
- $env{'form.ltitools_'.$size.'_'.$i} =~ s/^\s+//;
- $env{'form.ltitools_'.$size.'_'.$i} =~ s/\s+$//;
- if ($env{'form.ltitools_'.$size.'_'.$i} =~ /^\d+$/) {
- $confhash{$itemid}{'display'}{$size} = $env{'form.ltitools_'.$size.'_'.$i};
- if (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {
- if ($domconfig{$action}{$itemid}{'display'}{$size} ne $confhash{$itemid}{'display'}{$size}) {
- $changes{$itemid} = 1;
- }
- } else {
- $changes{$itemid} = 1;
- }
- } elsif (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {
- if ($domconfig{$action}{$itemid}{'display'}{$size} ne '') {
+ unless ($changes{$itemid}) {
+ if ($currlti{'passback'} eq $confhash{$itemid}{'passback'}) {
+ if ($currlti{'passbackformat'} ne $confhash{$itemid}{'passbackformat'}) {
$changes{$itemid} = 1;
}
}
}
- foreach my $item ('linktext','explanation') {
- $env{'form.ltitools_'.$item.'_'.$i} =~ s/^\s+//;
- $env{'form.ltitools_'.$item.'_'.$i} =~ s/\s+$//;
- if ($env{'form.ltitools_'.$item.'_'.$i} ne '') {
- $confhash{$itemid}{'display'}{$item} = $env{'form.ltitools_'.$item.'_'.$i};
- if (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {
- if ($domconfig{$action}{$itemid}{'display'}{$item} ne $confhash{$itemid}{'display'}{$item}) {
+ foreach my $field ('mapcrstype','selfenroll') {
+ unless ($changes{$itemid}) {
+ if (ref($currlti{$field}) eq 'ARRAY') {
+ if (ref($confhash{$itemid}{$field}) eq 'ARRAY') {
+ my @diffs = &Apache::loncommon::compare_arrays($currlti{$field},
+ $confhash{$itemid}{$field});
+ if (@diffs) {
+ $changes{$itemid} = 1;
+ }
+ } elsif (@{$currlti{$field}} > 0) {
$changes{$itemid} = 1;
}
- } else {
- $changes{$itemid} = 1;
- }
- } elsif (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {
- if ($domconfig{$action}{$itemid}{'display'}{$item} ne '') {
- $changes{$itemid} = 1;
- }
- }
- }
- if ($env{'form.ltitools_target_'.$i} eq 'window') {
- $confhash{$itemid}{'display'}{'target'} = $env{'form.ltitools_target_'.$i};
- } elsif ($env{'form.ltitools_target_'.$i} eq 'tab') {
- $confhash{$itemid}{'display'}{'target'} = $env{'form.ltitools_target_'.$i};
- } else {
- $confhash{$itemid}{'display'}{'target'} = 'iframe';
- }
- if (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {
- if ($domconfig{$action}{$itemid}{'display'}{'target'} ne $confhash{$itemid}{'display'}{'target'}) {
- $changes{$itemid} = 1;
- }
- } else {
- $changes{$itemid} = 1;
- }
- my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig_'.$i);
- foreach my $item ('label','title','target','linktext','explanation','append') {
- if (grep(/^\Q$item\E$/,@courseconfig)) {
- $confhash{$itemid}{'crsconf'}{$item} = 1;
- if (ref($domconfig{$action}{$itemid}{'crsconf'}) eq 'HASH') {
- if ($domconfig{$action}{$itemid}{'crsconf'}{$item} ne $confhash{$itemid}{'crsconf'}{$item}) {
+ } elsif (ref($confhash{$itemid}{$field}) eq 'ARRAY') {
+ if (@{$confhash{$itemid}{$field}} > 0) {
$changes{$itemid} = 1;
}
- } else {
- $changes{$itemid} = 1;
}
}
}
- my @fields = &Apache::loncommon::get_env_multiple('form.ltitools_fields_'.$i);
- foreach my $field (@fields) {
- if ($possfield{$field}) {
- if ($field eq 'roles') {
- foreach my $role (@courseroles) {
- my $choice = $env{'form.ltitools_roles_'.$role.'_'.$i};
- if (($choice ne '') && ($posslti{$choice})) {
- $confhash{$itemid}{'roles'}{$role} = $choice;
- if ($role eq 'cc') {
- $confhash{$itemid}{'roles'}{'co'} = $choice;
- }
+ unless ($changes{$itemid}) {
+ if (ref($currlti{'maproles'}) eq 'HASH') {
+ if (ref($confhash{$itemid}{'maproles'}) eq 'HASH') {
+ foreach my $ltirole (keys(%{$currlti{'maproles'}})) {
+ if ($currlti{'maproles'}{$ltirole} ne
+ $confhash{$itemid}{'maproles'}{$ltirole}) {
+ $changes{$itemid} = 1;
+ last;
}
- if (ref($domconfig{$action}{$itemid}{'roles'}) eq 'HASH') {
- if ($domconfig{$action}{$itemid}{'roles'}{$role} ne $confhash{$itemid}{'roles'}{$role}) {
+ }
+ unless ($changes{$itemid}) {
+ foreach my $ltirole (keys(%{$confhash{$itemid}{'maproles'}})) {
+ if ($confhash{$itemid}{'maproles'}{$ltirole} ne
+ $currlti{'maproles'}{$ltirole}) {
$changes{$itemid} = 1;
+ last;
}
- } elsif ($confhash{$itemid}{'roles'}{$role}) {
- $changes{$itemid} = 1;
}
}
- } else {
- $confhash{$itemid}{'fields'}{$field} = 1;
- if (ref($domconfig{$action}{$itemid}{'fields'}) eq 'HASH') {
- if ($domconfig{$action}{$itemid}{'fields'}{$field} ne $confhash{$itemid}{'fields'}{$field}) {
- $changes{$itemid} = 1;
- }
- } else {
+ } elsif (keys(%{$currlti{'maproles'}}) > 0) {
+ $changes{$itemid} = 1;
+ }
+ } elsif (ref($confhash{$itemid}{'maproles'}) eq 'HASH') {
+ unless ($changes{$itemid}) {
+ if (keys(%{$confhash{$itemid}{'maproles'}}) > 0) {
$changes{$itemid} = 1;
}
}
}
}
- if (ref($confhash{$itemid}{'fields'}) eq 'HASH') {
- if ($confhash{$itemid}{'fields'}{'user'}) {
- if ($env{'form.ltitools_userincdom_'.$i}) {
- $confhash{$itemid}{'incdom'} = 1;
- }
- if ($domconfig{$action}{$itemid}{'incdom'} ne $confhash{$itemid}{'incdom'}) {
- $changes{$itemid} = 1;
+ }
+ unless ($changes{$itemid}) {
+ foreach my $field ('mapuser','lcauth','lcauthparm','topmenu','inlinemenu','callback') {
+ if ($currlti{$field} ne $confhash{$itemid}{$field}) {
+ $changes{$itemid} = 1;
+ }
+ }
+ unless ($changes{$itemid}) {
+ foreach my $field ('makeuser','lcmenu') {
+ if (ref($currlti{$field}) eq 'ARRAY') {
+ if (ref($confhash{$itemid}{$field}) eq 'ARRAY') {
+ my @diffs = &Apache::loncommon::compare_arrays($currlti{$field},
+ $confhash{$itemid}{$field});
+ if (@diffs) {
+ $changes{$itemid} = 1;
+ }
+ } elsif (@{$currlti{$field}} > 0) {
+ $changes{$itemid} = 1;
+ }
+ } elsif (ref($confhash{$itemid}{$field}) eq 'ARRAY') {
+ if (@{$confhash{$itemid}{$field}} > 0) {
+ $changes{$itemid} = 1;
+ }
}
}
}
- $allpos[$newpos] = $itemid;
}
- if ($imgdeletions{$itemid}) {
- $changes{$itemid} = 1;
- #FIXME need to obsolete item in RES space
- } elsif ($env{'form.ltitools_image_'.$i.'.filename'}) {
- my ($imgurl,$error) = &process_ltitools_image($r,$dom,$confname,'ltitools_image_'.$i,
- $itemid,$configuserok,$switchserver,
- $author_ok);
- if ($imgurl) {
- $confhash{$itemid}{'image'} = $imgurl;
+ }
+ }
+ if ($is_home) {
+ my $keyitem = 'form.lti_key_'.$idx;
+ $env{$keyitem} =~ s/(`)/'/g;
+ if ($env{$keyitem} ne '') {
+ $ltienc{$itemid}{'key'} = $env{$keyitem};
+ unless ($changes{$itemid}) {
+ if ($currlti{'key'} ne $env{$keyitem}) {
$changes{$itemid} = 1;
}
- if ($error) {
- &Apache::lonnet::logthis($error);
- $errors .= '
'.$error.'
';
- }
- } elsif ($domconfig{$action}{$itemid}{'image'}) {
- $confhash{$itemid}{'image'} =
- $domconfig{$action}{$itemid}{'image'};
- }
- if ($customadds{$i}) {
- my $name = $env{'form.ltitools_custom_name_'.$i};
- $name =~ s/(`)/'/g;
- $name =~ s/^\s+//;
- $name =~ s/\s+$//;
- my $value = $env{'form.ltitools_custom_value_'.$i};
- $value =~ s/(`)/'/g;
- $value =~ s/^\s+//;
- $value =~ s/\s+$//;
- if ($name ne '') {
- $confhash{$itemid}{'custom'}{$name} = $value;
+ }
+ }
+ my $secretitem = 'form.lti_secret_'.$idx;
+ $env{$secretitem} =~ s/(`)/'/g;
+ if ($currlti{'usable'}) {
+ if ($env{'form.lti_changesecret_'.$idx}) {
+ if ($env{$secretitem} ne '') {
+ if ($privnum && $cipher) {
+ $ltienc{$itemid}{'secret'} = $cipher->encrypt_hex($env{$secretitem});
+ $confhash{$itemid}{'cipher'} = $privnum;
+ } else {
+ $ltienc{$itemid}{'secret'} = $env{$secretitem};
+ }
$changes{$itemid} = 1;
}
+ } else {
+ $ltienc{$itemid}{'secret'} = $currlti{'secret'};
+ $confhash{$itemid}{'cipher'} = $currlti{'cipher'};
}
- my %customdels;
- my @customdeletions = &Apache::loncommon::get_env_multiple('form.ltitools_customdel_'.$i);
- if (@customdeletions) {
- $changes{$itemid} = 1;
+ if (ref($ltienc{$itemid}) eq 'HASH') {
+ if (($ltienc{$itemid}{'key'} ne '') && ($ltienc{$itemid}{'secret'} ne '')) {
+ $confhash{$itemid}{'usable'} = 1;
+ }
}
- map { $customdels{$_} = 1; } @customdeletions;
- if (ref($domconfig{$action}{$itemid}{'custom'}) eq 'HASH') {
- foreach my $key (keys(%{$domconfig{$action}{$itemid}{'custom'}})) {
- unless ($customdels{$key}) {
- if ($env{'form.ltitools_customval_'.$key.'_'.$i} ne '') {
- $confhash{$itemid}{'custom'}{$key} = $env{'form.ltitools_customval_'.$key.'_'.$i};
- }
- if ($domconfig{$action}{$itemid}{'custom'}{$key} ne $env{'form.ltitools_customval_'.$key.'_'.$i}) {
- $changes{$itemid} = 1;
- }
- }
+ } elsif ($env{$secretitem} ne '') {
+ if ($privnum && $cipher) {
+ $ltienc{$itemid}{'secret'} = $cipher->encrypt_hex($env{$secretitem});
+ $confhash{$itemid}{'cipher'} = $privnum;
+ } else {
+ $ltienc{$itemid}{'secret'} = $env{$secretitem};
+ }
+ if (ref($ltienc{$itemid}) eq 'HASH') {
+ if (($ltienc{$itemid}{'key'} ne '') && ($ltienc{$itemid}{'key'} ne '')) {
+ $confhash{$itemid}{'usable'} = 1;
}
}
- unless ($changes{$itemid}) {
- foreach my $key (keys(%{$domconfig{$action}{$itemid}})) {
- if (ref($domconfig{$action}{$itemid}{$key}) eq 'HASH') {
- if (ref($confhash{$itemid}{$key}) eq 'HASH') {
- foreach my $innerkey (keys(%{$domconfig{$action}{$itemid}{$key}})) {
- unless (exists($confhash{$itemid}{$key}{$innerkey})) {
- $changes{$itemid} = 1;
- last;
- }
- }
- } elsif (keys(%{$domconfig{$action}{$itemid}{$key}}) > 0) {
+ $changes{$itemid} = 1;
+ }
+ }
+ unless ($changes{$itemid}) {
+ foreach my $key (keys(%currlti)) {
+ if (ref($currlti{$key}) eq 'HASH') {
+ if (ref($confhash{$itemid}{$key}) eq 'HASH') {
+ foreach my $innerkey (keys(%{$currlti{$key}})) {
+ unless (exists($confhash{$itemid}{$key}{$innerkey})) {
$changes{$itemid} = 1;
+ last;
}
}
- last if ($changes{$itemid});
+ } elsif (keys(%{$currlti{$key}}) > 0) {
+ $changes{$itemid} = 1;
}
}
+ last if ($changes{$itemid});
}
}
}
@@ -12397,149 +13743,232 @@ sub modify_ltitools {
}
}
}
- my %ltitoolshash = (
- $action => { %confhash }
- );
- my $putresult = &Apache::lonnet::put_dom('configuration',\%ltitoolshash,
- $dom);
+
+ if ((keys(%changes) == 0) && (keys(%secchanges) == 0)) {
+ return &mt('No changes made.');
+ }
+
+ my %ltihash = (
+ $action => { %confhash }
+ );
+ my %ltienchash;
+
+ if ($is_home) {
+ %ltienchash = (
+ $action => { %ltienc }
+ );
+ }
+ if (keys(%secchanges)) {
+ $ltihash{'ltisec'} = \%newltisec;
+ if ($secchanges{'linkprot'}) {
+ if ($is_home) {
+ $ltienchash{'linkprot'} = \%newltienc;
+ }
+ }
+ }
+ my $putresult = &Apache::lonnet::put_dom('configuration',\%ltihash,$dom);
if ($putresult eq 'ok') {
- my %ltienchash = (
- $action => { %encconfig }
- );
- &Apache::lonnet::put_dom('encconfig',\%ltienchash,$dom,undef,1);
+ if (keys(%ltienchash)) {
+ &Apache::lonnet::put_dom('encconfig',\%ltienchash,$dom,undef,1);
+ }
+ $resulttext = &mt('Changes made:').'
';
+ if (keys(%secchanges) > 0) {
+ $resulttext .= <i_security_results($dom,'lti',\%secchanges,\%newltisec,\%newkeyset,\%keystore);
+ if (exists($secchanges{'linkprot'})) {
+ $resulttext .= $linkprotoutput;
+ }
+ }
if (keys(%changes) > 0) {
my $cachetime = 24*60*60;
- my %ltiall = %confhash;
- foreach my $id (keys(%ltiall)) {
- if (ref($encconfig{$id}) eq 'HASH') {
- foreach my $item ('key','secret') {
- $ltiall{$id}{$item} = $encconfig{$id}{$item};
- }
- }
- }
- &Apache::lonnet::do_cache_new('ltitools',$dom,\%ltiall,$cachetime);
+ &Apache::lonnet::do_cache_new('lti',$dom,\%confhash,$cachetime);
if (ref($lastactref) eq 'HASH') {
- $lastactref->{'ltitools'} = 1;
+ $lastactref->{'lti'} = 1;
}
- $resulttext = &mt('Changes made:').'
';
my %bynum;
foreach my $itemid (sort(keys(%changes))) {
- my $position = $confhash{$itemid}{'order'};
- $bynum{$position} = $itemid;
+ if (ref($confhash{$itemid}) eq 'HASH') {
+ my $position = $confhash{$itemid}{'order'};
+ $bynum{$position} = $itemid;
+ }
}
foreach my $pos (sort { $a <=> $b } keys(%bynum)) {
my $itemid = $bynum{$pos};
- if (ref($confhash{$itemid}) ne 'HASH') {
- $resulttext .= '
';
+ if (ref($confhash{$itemid}{'makeuser'}) eq 'ARRAY') {
+ if (@{$confhash{$itemid}{'makeuser'}} > 0) {
+ $resulttext .= '
'.&mt('Following roles may create user accounts: [_1]',
+ join(', ',@{$confhash{$itemid}{'makeuser'}})).' ';
+ if ($confhash{$itemid}{'lcauth'} eq 'lti') {
+ $resulttext .= &mt('New users will only be able to authenticate via LTI').'
';
+ if (ref($confhash{$itemid}{'instdata'}) eq 'ARRAY') {
+ if (@{$confhash{$itemid}{'instdata'}} > 0) {
+ $resulttext .= '
'.&mt('Institutional data will be used when creating a new user for: [_1]',
+ join(', ',map { $fieldtitles{$_}; } @{$confhash{$itemid}{'instdata'}})).'
';
+ } else {
+ $resulttext .= '
'.&mt('No institutional data used when creating a new user.').'
';
}
}
- }
- if (ref($confhash{$itemid}{'fields'}) eq 'HASH') {
- my $fieldlist;
- foreach my $field (@allfields) {
- if ($confhash{$itemid}{'fields'}{$field}) {
- $fieldlist .= (' 'x2).$lt{$field}.',';
+ foreach my $item ('topmenu','inlinemenu') {
+ $resulttext .= '