';
if ($othercontrol{$server}) {
$dom_in_effect = $othercontrol{$server};
my ($current,$forsaml);
@@ -6675,12 +7685,14 @@ sub print_usersessions {
$other_insts,$curroffloadnow,$curroffloadoth,$rowtotal);
} else {
$datatable .= '
'.
- &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.').
+ '
'.
- &mt('Nothing to set here, as the cluster to which this domain belongs only contains one institution.');
+ &mt('Nothing to set here, as the cluster to which this domain belongs only contains one institution.').
+ '
';
} else {
my %lt = &usersession_titles();
my $numinrow = 5;
@@ -7396,7 +8408,7 @@ sub loadbalance_rule_row {
}
my $space;
if ($islast && $num == 1) {
- $space = '
';
+ $space = '
';
}
my $output =
'
'.$space.
@@ -7533,8 +8545,9 @@ sub tool_titles {
my %titles = &Apache::lonlocal::texthash (
aboutme => 'Personal web page',
blog => 'Blog',
- webdav => 'WebDAV',
portfolio => 'Portfolio',
+ portaccess => 'Share portfolio files',
+ timezone => 'Can set time zone',
official => 'Official courses (with institutional codes)',
unofficial => 'Unofficial courses',
community => 'Communities',
@@ -7549,6 +8562,7 @@ sub courserequest_titles {
unofficial => 'Unofficial',
community => 'Communities',
textbook => 'Textbook',
+ lti => 'LTI Provider',
norequest => 'Not allowed',
approval => 'Approval by Dom. Coord.',
validate => 'With validation',
@@ -7662,7 +8676,7 @@ sub print_usercreation {
}
} else {
my @contexts = ('author','course','domain');
- my @authtypes = ('int','krb4','krb5','loc');
+ my @authtypes = ('int','krb4','krb5','loc','lti');
my %checked;
if (ref($settings) eq 'HASH') {
if (ref($settings->{'authtypes'}) eq 'HASH') {
@@ -8224,7 +9238,7 @@ sub noninst_users {
sub captcha_choice {
my ($context,$settings,$itemcount,$customcss,$rowstyle) = @_;
my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext,
- $vertext,$currver);
+ $vertext,$currver);
my %lt = &captcha_phrases();
$keyentry = 'hidden';
my $colspan=2;
@@ -8313,7 +9327,7 @@ sub user_formats_row {
'username' => 'new usernames',
'id' => 'IDs',
);
- unless ($type eq 'email') {
+ unless (($type eq 'email') || ($type eq 'unamemap')) {
my $css_class = $rowcount%2?' class="LC_odd_row"':'';
$output = '
';
return $output;
@@ -9985,7 +11116,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',
@@ -10009,6 +11140,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'};
}
}
@@ -10151,13 +11283,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;
@@ -10170,6 +11305,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);
}
@@ -10227,11 +11363,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;
@@ -10248,6 +11387,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);
}
@@ -10266,10 +11406,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'});
@@ -10287,13 +11430,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 {
@@ -10316,11 +11462,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;
@@ -10331,6 +11480,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);
}
@@ -10494,19 +11644,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 .= '
';
+ }
+ return $resulttext;
+}
+
+sub fetch_secrets {
+ my ($dom,$context,$domconfig,$currsec,$secchanges,$newsec,$newkeyset) = @_;
+ my %keyset;
+ %{$currsec} = ();
+ $newsec->{'private'}{'keys'} = [];
+ $newsec->{'encrypt'} = {};
+ $newsec->{'rules'} = {};
+ if ($context eq 'ltisec') {
+ $newsec->{'linkprot'} = {};
+ }
+ if (ref($domconfig->{$context}) eq 'HASH') {
+ %{$currsec} = %{$domconfig->{$context}};
+ if ($context eq 'ltisec') {
+ if (ref($currsec->{'linkprot'}) eq 'HASH') {
+ foreach my $id (keys(%{$currsec->{'linkprot'}})) {
+ unless ($id =~ /^\d+$/) {
+ delete($currsec->{'linkprot'}{$id});
+ }
+ }
}
- if ($env{'form.ltitools_add_msgtype'} eq 'basic-lti-launch-request') {
- $confhash{$newid}{'msgtype'} = $env{'form.ltitools_add_msgtype'};
+ }
+ if (ref($currsec->{'private'}) eq 'HASH') {
+ if (ref($currsec->{'private'}{'keys'}) eq 'ARRAY') {
+ $newsec->{'private'}{'keys'} = $currsec->{'private'}{'keys'};
+ map { $keyset{$_} = 1; } @{$currsec->{'private'}{'keys'}};
}
- if ($env{'form.ltitools_add_sigmethod'} eq 'HMAC-SHA256') {
- $confhash{$newid}{'sigmethod'} = $env{'form.ltitools_add_sigmethod'};
+ }
+ }
+ my @items= ('crs','dom');
+ if ($context eq 'ltisec') {
+ push(@items,'consumers');
+ }
+ foreach my $item (@items) {
+ my $formelement;
+ if (($context eq 'toolsec') || ($item eq 'consumers')) {
+ $formelement = 'form.'.$context.'_'.$item;
+ } else {
+ $formelement = 'form.'.$context.'_'.$item.'linkprot';
+ }
+ if ($env{$formelement}) {
+ $newsec->{'encrypt'}{$item} = 1;
+ if (ref($currsec->{'encrypt'}) eq 'HASH') {
+ unless ($currsec->{'encrypt'}{$item}) {
+ $secchanges->{'encrypt'} = 1;
+ }
} else {
- $confhash{$newid}{'sigmethod'} = 'HMAC-SHA1';
+ $secchanges->{'encrypt'} = 1;
+ }
+ } elsif (ref($currsec->{'encrypt'}) eq 'HASH') {
+ if ($currsec->{'encrypt'}{$item}) {
+ $secchanges->{'encrypt'} = 1;
}
- foreach my $item ('width','height','linktext','explanation') {
- $env{'form.ltitools_add_'.$item} =~ s/^\s+//;
- $env{'form.ltitools_add_'.$item} =~ s/\s+$//;
- if (($item eq 'width') || ($item eq 'height')) {
- if ($env{'form.ltitools_add_'.$item} =~ /^\d+$/) {
- $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item};
+ }
+ }
+ my $secrets;
+ if ($context eq 'ltisec') {
+ $secrets = 'ltisecrets';
+ } else {
+ $secrets = 'toolsecrets';
+ }
+ unless (exists($currsec->{'rules'})) {
+ $currsec->{'rules'} = {};
+ }
+ &password_rule_changes($secrets,$newsec->{'rules'},$currsec->{'rules'},$secchanges);
+
+ my @ids=&Apache::lonnet::current_machine_ids();
+ my %servers = &Apache::lonnet::get_servers($dom,'library');
+
+ foreach my $hostid (keys(%servers)) {
+ if (($hostid ne '') && (grep(/^\Q$hostid\E$/,@ids))) {
+ my $keyitem = 'form.'.$context.'_privkey_'.$hostid;
+ if (exists($env{$keyitem})) {
+ $env{$keyitem} =~ s/(`)/'/g;
+ if ($keyset{$hostid}) {
+ if ($env{'form.'.$context.'_changeprivkey_'.$hostid}) {
+ if ($env{$keyitem} ne '') {
+ $secchanges->{'private'} = 1;
+ $newkeyset->{$hostid} = $env{$keyitem};
+ }
}
- } else {
- if ($env{'form.ltitools_add_'.$item} ne '') {
- $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item};
+ } elsif ($env{$keyitem} ne '') {
+ unless (grep(/^\Q$hostid\E$/,@{$newsec->{'private'}{'keys'}})) {
+ push(@{$newsec->{'private'}{'keys'}},$hostid);
}
+ $secchanges->{'private'} = 1;
+ $newkeyset->{$hostid} = $env{$keyitem};
}
}
- if ($env{'form.ltitools_add_target'} eq 'window') {
- $confhash{$newid}{'display'}{'target'} = $env{'form.ltitools_add_target'};
- } elsif ($env{'form.ltitools_add_target'} eq 'tab') {
- $confhash{$newid}{'display'}{'target'} = $env{'form.ltitools_add_target'};
+ }
+ }
+}
+
+sub store_security {
+ my ($dom,$context,$secchanges,$newkeyset,$keystore) = @_;
+ return unless ((ref($secchanges) eq 'HASH') && (ref($newkeyset) eq 'HASH') &&
+ (ref($keystore) eq 'HASH'));
+ if (keys(%{$secchanges})) {
+ if ($secchanges->{'private'}) {
+ my $who = &escape($env{'user.name'}.':'.$env{'user.domain'});
+ foreach my $hostid (keys(%{$newkeyset})) {
+ my $storehash = {
+ key => $newkeyset->{$hostid},
+ who => $env{'user.name'}.':'.$env{'user.domain'},
+ };
+ $keystore->{$hostid} = &Apache::lonnet::store_dom($storehash,$context,'private',
+ $dom,$hostid);
+ }
+ }
+ }
+}
+
+sub lti_security_results {
+ my ($dom,$context,$secchanges,$newsec,$newkeyset,$keystore) = @_;
+ my $output;
+ my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
+ my $needs_update;
+ foreach my $item (keys(%{$secchanges})) {
+ if ($item eq 'encrypt') {
+ $needs_update = 1;
+ my %encrypted;
+ if ($context eq 'lti') {
+ %encrypted = (
+ crs => {
+ on => &mt('Encryption of stored link protection secrets defined in courses enabled'),
+ off => &mt('Encryption of stored link protection secrets defined in courses disabled'),
+ },
+ dom => {
+ on => &mt('Encryption of stored link protection secrets defined in domain enabled'),
+ off => &mt('Encryption of stored link protection secrets defined in domain disabled'),
+ },
+ consumers => {
+ on => &mt('Encryption of stored consumer secrets defined in domain enabled'),
+ off => &mt('Encryption of stored consumer secrets defined in domain disabled'),
+ },
+ );
} else {
- $confhash{$newid}{'display'}{'target'} = 'iframe';
+ %encrypted = (
+ crs => {
+ on => &mt('Encryption of stored external tool secrets defined in courses enabled'),
+ off => &mt('Encryption of stored external tool secrets defined in courses disabled'),
+ },
+ dom => {
+ on => &mt('Encryption of stored external tool secrets defined in domain enabled'),
+ off => &mt('Encryption of stored external tool secrets defined in domain disabled'),
+ },
+ );
}
- if ($env{'form.ltitools_add_image.filename'} ne '') {
- my ($imageurl,$error) =
- &process_ltitools_image($r,$dom,$confname,'ltitools_add_image',$newid,
- $configuserok,$switchserver,$author_ok);
- if ($imageurl) {
- $confhash{$newid}{'image'} = $imageurl;
+ my @types= ('crs','dom');
+ if ($context eq 'lti') {
+ foreach my $type (@types) {
+ undef($domdefaults{'linkprotenc_'.$type});
}
- if ($error) {
- &Apache::lonnet::logthis($error);
- $errors .= '
'.$error.'
';
+ push(@types,'consumers');
+ undef($domdefaults{'ltienc_consumers'});
+ } elsif ($context eq 'ltitools') {
+ foreach my $type (@types) {
+ undef($domdefaults{'toolenc_'.$type});
}
}
- my @fields = &Apache::loncommon::get_env_multiple('form.ltitools_add_fields');
- foreach my $field (@fields) {
- if ($possfield{$field}) {
- if ($field eq 'roles') {
- foreach my $role (@courseroles) {
- my $choice = $env{'form.ltitools_add_roles_'.$role};
- if (($choice ne '') && ($posslti{$choice})) {
- $confhash{$newid}{'roles'}{$role} = $choice;
- if ($role eq 'cc') {
- $confhash{$newid}{'roles'}{'co'} = $choice;
- }
+ foreach my $type (@types) {
+ my $shown = $encrypted{$type}{'off'};
+ if (ref($newsec->{$item}) eq 'HASH') {
+ if ($newsec->{$item}{$type}) {
+ if ($context eq 'lti') {
+ if ($type eq 'consumers') {
+ $domdefaults{'ltienc_consumers'} = 1;
+ } else {
+ $domdefaults{'linkprotenc_'.$type} = 1;
}
+ } elsif ($context eq 'ltitools') {
+ $domdefaults{'toolenc_'.$type} = 1;
+ }
+ $shown = $encrypted{$type}{'on'};
+ }
+ }
+ $output .= '
'.$shown.'
';
+ }
+ } elsif ($item eq 'rules') {
+ my %titles = &Apache::lonlocal::texthash(
+ min => 'Minimum password length',
+ max => 'Maximum password length',
+ chars => 'Required characters',
+ );
+ foreach my $rule ('min','max') {
+ if ($newsec->{rules}{$rule} eq '') {
+ if ($rule eq 'min') {
+ $output .= '
'.&mt('[_1] not set.',$titles{$rule});
+ ' '.&mt('Default of [_1] will be used',
+ $Apache::lonnet::passwdmin).'
';
+ } else {
+ $output .= '
'.&mt('[_1] set to none',$titles{$rule}).'
';
+ }
+ } else {
+ $output .= '
'.&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 = '
';
+ 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 .= '
';
@@ -12908,57 +14685,51 @@ sub modify_ltitools {
return $resulttext;
}
-sub process_ltitools_image {
- my ($r,$dom,$confname,$caller,$itemid,$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 Tool Provider (LTI) icon is not permitted to this server: [_1]',
- $switchserver);
- } elsif ($author_ok eq 'ok') {
- my ($result,$imageurl,$madethumb) =
- &publishlogo($r,'upload',$caller,$dom,$confname,
- "ltitools/$itemid/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);
+sub get_priv_creds {
+ my ($dom,$home,$encchg,$encrypt,$storedsec) = @_;
+ my ($needenc,$cipher,$privnum);
+ my %domdefs = &Apache::lonnet::get_domain_defaults($dom);
+ if (($encchg) && (ref($encrypt) eq 'HASH')) {
+ $needenc = $encrypt->{'consumers'}
+ } else {
+ $needenc = $domdefs{'ltienc_consumers'};
+ }
+ if ($needenc) {
+ if (($storedsec eq 'ok') || ((ref($domdefs{'ltiprivhosts'}) eq 'ARRAY') &&
+ (grep(/^\Q$home\E$/,@{$domdefs{'ltiprivhosts'}})))) {
+ my %privhash = &Apache::lonnet::restore_dom('lti','private',$dom,$home,1);
+ my $privkey = $privhash{'key'};
+ $privnum = $privhash{'version'};
+ if (($privnum) && ($privkey ne '')) {
+ $cipher = Crypt::CBC->new({'key' => $privkey,
+ 'cipher' => 'DES'});
}
- } 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);
+ return ($cipher,$privnum);
}
-sub get_ltitools_id {
- my ($cdom,$title) = @_;
- # get lock on ltitools db
+sub get_lti_id {
+ my ($domain,$consumer,$dbname) = @_;
+ unless (($dbname eq 'lti') || ($dbname eq 'suggested')) {
+ return ('','invalid db');
+ }
+ # get lock on db
my $lockhash = {
lock => $env{'user.name'}.
':'.$env{'user.domain'},
};
my $tries = 0;
- my $gotlock = &Apache::lonnet::newput_dom('ltitools',$lockhash,$cdom);
+ my $gotlock = &Apache::lonnet::newput_dom($dbname,$lockhash,$domain);
my ($id,$error);
while (($gotlock ne 'ok') && ($tries<10)) {
$tries ++;
sleep (0.1);
- $gotlock = &Apache::lonnet::newput_dom('ltitools',$lockhash,$cdom);
+ $gotlock = &Apache::lonnet::newput_dom($dbname,$lockhash,$domain);
}
if ($gotlock eq 'ok') {
- my %currids = &Apache::lonnet::dump_dom('ltitools',$cdom);
+ my %currids = &Apache::lonnet::dump_dom($dbname,$domain);
if ($currids{'lock'}) {
delete($currids{'lock'});
if (keys(%currids)) {
@@ -12970,269 +14741,20 @@ sub get_ltitools_id {
$id = 1;
}
if ($id) {
- unless (&Apache::lonnet::newput_dom('ltitools',{ $id => $title },$cdom) eq 'ok') {
+ unless (&Apache::lonnet::newput_dom($dbname,{ $id => $consumer },$domain) eq 'ok') {
$error = 'nostore';
}
} else {
$error = 'nonumber';
}
}
- my $dellockoutcome = &Apache::lonnet::del_dom('ltitools',['lock'],$cdom);
+ my $dellockoutcome = &Apache::lonnet::del_dom($dbname,['lock'],$domain);
} else {
$error = 'nolock';
}
return ($id,$error);
}
-sub modify_lti {
- my ($r,$dom,$action,$lastactref,%domconfig) = @_;
- my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
- my (%encconfig,$errors,$resulttext);
-
- my (%currltisec,%secchanges,%newltisec,%newltienc,%keyset,%newkeyset);
- $newltisec{'private'}{'keys'} = [];
- $newltisec{'encrypt'} = {};
- $newltisec{'rules'} = {};
- $newltisec{'linkprot'} = {};
- if (ref($domconfig{'ltisec'}) eq 'HASH') {
- %currltisec = %{$domconfig{'ltisec'}};
- if (ref($currltisec{'linkprot'}) eq 'HASH') {
- foreach my $id (keys(%{$currltisec{'linkprot'}})) {
- unless ($id =~ /^\d+$/) {
- delete($currltisec{'linkprot'}{$id});
- }
- }
- }
- if (ref($currltisec{'private'}) eq 'HASH') {
- if (ref($currltisec{'private'}{'keys'}) eq 'ARRAY') {
- $newltisec{'private'}{'keys'} = $currltisec{'private'}{'keys'};
- map { $keyset{$_} = 1; } @{$currltisec{'private'}{'keys'}};
- }
- }
- }
- foreach my $item ('crs','dom') {
- my $formelement = 'form.ltisec_'.$item.'linkprot';
- if ($env{$formelement}) {
- $newltisec{'encrypt'}{$item} = 1;
- if (ref($currltisec{'encrypt'}) eq 'HASH') {
- unless ($currltisec{'encrypt'}{$item}) {
- $secchanges{'encrypt'} = 1;
- }
- } else {
- $secchanges{'encrypt'} = 1;
- }
- } elsif (ref($currltisec{'encrypt'}) eq 'HASH') {
- if ($currltisec{'encrypt'}{$item}) {
- $secchanges{'encrypt'} = 1;
- }
- }
- }
- unless (exists($currltisec{'rules'})) {
- $currltisec{'rules'} = {};
- }
- &password_rule_changes('secrets',$newltisec{'rules'},$currltisec{'rules'},\%secchanges);
-
- my @ids=&Apache::lonnet::current_machine_ids();
- my %servers = &Apache::lonnet::get_servers($dom,'library');
-
- foreach my $hostid (keys(%servers)) {
- if (($hostid ne '') && (grep(/^\Q$hostid\E$/,@ids))) {
- my $newkey;
- my $keyitem = 'form.ltisec_privkey_'.$hostid;
- if (exists($env{$keyitem})) {
- $env{$keyitem} =~ s/(`)/'/g;
- if ($keyset{$hostid}) {
- if ($env{'form.ltisec_changeprivkey_'.$hostid}) {
- if ($env{$keyitem} ne '') {
- $secchanges{'private'} = 1;
- $newkeyset{$hostid} = $env{$keyitem};
- }
- }
- } elsif ($env{$keyitem} ne '') {
- unless (grep(/^\Q$hostid\E$/,@{$newltisec{'private'}{'keys'}})) {
- push(@{$newltisec{'private'}{'keys'}},$hostid);
- }
- $secchanges{'private'} = 1;
- $newkeyset{$hostid} = $env{$keyitem};
- }
- }
- }
- }
-
- 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};
- }
- }
- $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 ($putresult,%keystore);
- if (keys(%secchanges)) {
- my %ltienchash;
- my %ltihash = (
- 'ltisec' => { %newltisec }
- );
- $putresult = &Apache::lonnet::put_dom('configuration',\%ltihash,$dom);
- if ($putresult eq 'ok') {
- if ($secchanges{'private'}) {
- my $who = &escape($env{'user.name'}.':'.$env{'user.domain'});
- foreach my $hostid (keys(%newkeyset)) {
- my $storehash = {
- key => $newkeyset{$hostid},
- who => $env{'user.name'}.':'.$env{'user.domain'},
- };
- $keystore{$hostid} = &Apache::lonnet::store_dom($storehash,'lti','private',
- $dom,$hostid);
- }
- }
- if (ref($lastactref) eq 'HASH') {
- if (($secchanges{'encrypt'}) || ($secchanges{'private'})) {
- $lastactref->{'domdefaults'} = 1;
- }
- }
- if (($secchanges{'linkprot'}) && ($is_home)) {
- my %ltienchash = (
- 'linkprot' => { %newltienc }
- );
- &Apache::lonnet::put_dom('encconfig',\%ltienchash,$dom,undef,1);
- }
- }
- } else {
- return &mt('No changes made.');
- }
- if ($putresult eq 'ok') {
- $resulttext = &mt('Changes made:').'
';
- foreach my $item (keys(%secchanges)) {
- if ($item eq 'encrypt') {
- my %encrypted = (
- crs => {
- on => &mt('Encryption of stored link protection secrets defined in courses enabled'),
- off => &mt('Encryption of stored link protection secrets defined in courses disabled'),
- },
- dom => {
- on => &mt('Encryption of stored link protection secrets defined in domain enabled'),
- off => &mt('Encryption of stored link protection secrets defined in domain disabled'),
- },
- );
- foreach my $type ('crs','dom') {
- my $shown = $encrypted{$type}{'off'};
- if (ref($newltisec{$item}) eq 'HASH') {
- if ($newltisec{$item}{$type}) {
- $shown = $encrypted{$type}{'on'};
- }
- }
- $resulttext .= '
'.$shown.'
';
- }
- } elsif ($item eq 'rules') {
- my %titles = &Apache::lonlocal::texthash(
- min => 'Minimum password length',
- max => 'Maximum password length',
- chars => 'Required characters',
- );
- foreach my $rule ('min','max') {
- if ($newltisec{rules}{$rule} eq '') {
- if ($rule eq 'min') {
- $resulttext .= '
'.&mt('[_1] not set.',$titles{$rule});
- ' '.&mt('Default of [_1] will be used',
- $Apache::lonnet::passwdmin).'
';
- } else {
- $resulttext .= '
'.&mt('[_1] set to none',$titles{$rule}).'
';
- }
- } else {
- $resulttext .= '
'.&mt('[_1] set to [_2]',$titles{$rule},$newltisec{rules}{$rule}).'
';
- }
- }
- if (ref($newltisec{'rules'}{'chars'}) eq 'ARRAY') {
- if (@{$newltisec{'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]"',$title->{$item},$value).'
';
- $mailmsgtext .= "$title->{$item} set to $value\n";
+ $mailmsgtext .= "$title->{$item} set to $value\n";
+ if ($item eq 'portal_def') {
+ if ($env{'form.'.$item} ne '') {
+ foreach my $field ('email','web') {
+ $value = $env{'form.'.$item.'_'.$field};
+ if ($value) {
+ $value = &mt('Yes');
+ } else {
+ $value = &mt('No');
+ }
+ $resulttext .= '
'.&mt('[_1] set to "[_2]"',$title->{$field},$value).'
';
+ }
+ }
+ }
}
}
$resulttext .= '
';
@@ -16530,12 +18164,15 @@ sub modify_scantron {
$error = &mt("Upload of bubblesheet format file is not permitted to this server: [_1]",$switchserver);
} else {
if ($author_ok eq 'ok') {
+ my $modified = [];
my ($result,$scantronurl) =
- &publishlogo($r,'upload','scantronformat',$dom,
- $confname,'scantron','','',$custom);
+ &Apache::lonconfigsettings::publishlogo($r,'upload','scantronformat',$dom,
+ $confname,'scantron','','',$custom,
+ $modified);
if ($result eq 'ok') {
$confhash{'scantron'}{'scantronformat'} = $scantronurl;
$changes{'scantronformat'} = 1;
+ &update_modify_urls($r,$modified);
} else {
$error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$custom,$result);
}
@@ -16687,8 +18324,8 @@ sub modify_scantron {
$resulttext = &mt('No changes made to bubblesheet format settings');
}
if ($errors) {
- $resulttext .= &mt('The following errors occurred: ').'