--- loncom/interface/domainprefs.pm 2008/02/15 17:02:31 1.42 +++ loncom/interface/domainprefs.pm 2008/02/24 23:18:40 1.43 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set domain-wide configuration settings # -# $Id: domainprefs.pm,v 1.42 2008/02/15 17:02:31 raeburn Exp $ +# $Id: domainprefs.pm,v 1.43 2008/02/24 23:18:40 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -36,9 +36,11 @@ use Apache::lonnet; use Apache::loncommon(); use Apache::lonhtmlcommon(); use Apache::lonlocal; +use Apache::lonmsg(); use LONCAPA(); use LONCAPA::Enrollment; use File::Copy; +use Locale::Language; sub handler { my $r=shift; @@ -68,8 +70,8 @@ sub handler { my %domconfig = &Apache::lonnet::get_dom('configuration',['login','rolecolors', 'quotas','autoenroll','autoupdate','directorysrch', - 'usercreation','usermodification','contacts'],$dom); - my @prefs_order = ('rolecolors','login','quotas','autoenroll', + 'usercreation','usermodification','contacts','defaults'],$dom); + my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll', 'autoupdate','directorysrch','contacts', 'usercreation','usermodification'); my %prefs = ( @@ -91,6 +93,12 @@ sub handler { header => [{col1 => 'Item', col2 => '',}], }, + 'defaults' => + { text => 'Default authentication/language', + help => '', + header => [{col1 => 'Setting', + col2 => 'Value'}], + }, 'quotas' => { text => 'Default quotas for user portfolios', help => 'Default_User_Quota', @@ -108,7 +116,7 @@ sub handler { help => 'Domain_Auto_Update', header => [{col1 => 'Setting', col2 => 'Value',}, - {col1 => 'User Population', + {col1 => 'User population', col2 => 'Updataeable user data'}], }, 'directorysrch' => @@ -127,12 +135,12 @@ sub handler { 'usercreation' => { text => 'User creation', help => 'Domain_User_Creation', - header => [{col1 => 'Format Rule Type', - col2 => 'Format Rules in force'}, + header => [{col1 => 'Format rule type', + col2 => 'Format rules in force'}, {col1 => 'User account creation', col2 => 'Usernames which may be created',}, {col1 => 'Context', - col2 => 'Assignable Authentication Types'}], + col2 => 'Assignable authentication types'}], }, 'usermodification' => { text => 'User modification', @@ -333,6 +341,8 @@ sub process_changes { $output = &modify_usermodification($dom,%domconfig); } elsif ($action eq 'contacts') { $output = &modify_contacts($dom,%domconfig); + } elsif ($action eq 'defaults') { + $output = &modify_defaults($dom,$r); } return $output; } @@ -454,6 +464,8 @@ sub print_config_box { $output .= &print_directorysrch($dom,$settings,\$rowtotal); } elsif ($action eq 'contacts') { $output .= &print_contacts($dom,$settings,\$rowtotal); + } elsif ($action eq 'defaults') { + $output .= &print_defaults($dom,\$rowtotal); } } $output .= ' @@ -569,10 +581,11 @@ sub print_login { my ($dom,$confname,$phase,$settings,$rowtotal) = @_; my %choices = &login_choices(); my %defaultchecked = ( - 'coursecatalog' => 'on', - 'adminmail' => 'off', - ); - my @toggles = ('coursecatalog','adminmail'); + 'coursecatalog' => 'on', + 'adminmail' => 'off', + 'newuser' => 'off', + ); + my @toggles = ('coursecatalog','adminmail','newuser'); my (%checkedon,%checkedoff); foreach my $item (@toggles) { if ($defaultchecked{$item} eq 'on') { @@ -699,6 +712,7 @@ sub login_choices { &Apache::lonlocal::texthash ( coursecatalog => 'Display Course Catalog link?', adminmail => "Display Administrator's E-mail Address?", + newuser => "Link to create a user account", img => "Header", logo => "Main Logo", domlogo => "Domain Logo", @@ -1479,13 +1493,23 @@ sub print_usercreation { $rowcount ++; } } + my ($emailrules,$emailruleorder) = + &Apache::lonnet::inst_userrules($dom,'email'); + if (ref($emailrules) eq 'HASH') { + if (keys(%{$emailrules}) > 0) { + $datatable .= &user_formats_row('email',$settings,$emailrules, + $emailruleorder,$numinrow,$rowcount); + $$rowtotal ++; + $rowcount ++; + } + } if ($rowcount == 0) { $datatable .= ''.&mt('No format rules have been defined for usernames or IDs in this domain.').''; $$rowtotal ++; $rowcount ++; } } elsif ($position eq 'middle') { - my @creators = ('author','course'); + my @creators = ('author','course','selfenroll'); my ($rules,$ruleorder) = &Apache::lonnet::inst_userrules($dom,'username'); my %lt = &usercreation_types(); @@ -1507,7 +1531,11 @@ sub print_usercreation { foreach my $item (@creators) { $rownum ++; if ($checked{$item} eq '') { - $checked{$item} = 'any'; + if ($item eq 'selfenroll') { + $checked{$item} = 'none'; + } else { + $checked{$item} = 'any'; + } } my $css_class; if ($rownum%2) { @@ -1519,9 +1547,13 @@ sub print_usercreation { ''.$lt{$item}. ''; my @options = ('any'); - if (ref($rules) eq 'HASH') { - if (keys(%{$rules}) > 0) { - push(@options,('official','unofficial')); + if ($item eq 'selfenroll') { + push(@options,('email','login','sso')); + } else { + if (ref($rules) eq 'HASH') { + if (keys(%{$rules}) > 0) { + push(@options,('official','unofficial')); + } } } push(@options,'none'); @@ -1594,6 +1626,7 @@ sub user_formats_row { my %text = ( 'username' => 'new usernames', 'id' => 'IDs', + 'email' => 'e-mail addresses of self-enrollers', ); my $css_class = $rowcount%2?' class="LC_odd_row"':''; $output = ''. @@ -1644,9 +1677,13 @@ sub usercreation_types { my %lt = &Apache::lonlocal::texthash ( author => 'When adding a co-author', course => 'When adding a user to a course', + selfenroll => 'When a user is self-enrolling', any => 'Any', official => 'Institutional only ', unofficial => 'Non-institutional only', + email => 'Email address', + login => 'Institutional Login', + sso => 'SSO', none => 'None', ); return %lt; @@ -1697,6 +1734,61 @@ sub print_usermodification { return $datatable; } +sub print_defaults { + my ($dom,$rowtotal) = @_; + my @items = ('auth_def','auth_arg_def','lang_def'); + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); + my $titles = &defaults_titles(); + my $rownum = 0; + my ($datatable,$css_class); + foreach my $item (@items) { + if ($rownum%2) { + $css_class = ''; + } else { + $css_class = ' class="LC_odd_row" '; + } + $datatable .= ''. + ''.$titles->{$item}. + ''; + if ($item eq 'auth_def') { + my @authtypes = ('internal','krb4','krb5','localauth'); + my %shortauth = ( + internal => 'int', + krb4 => 'krb4', + krb5 => 'krb5', + localauth => 'loc' + ); + my %authnames = &authtype_names(); + foreach my $auth (@authtypes) { + my $checked = ' '; + if ($domdefaults{$item} eq $auth) { + $checked = ' checked="checked" '; + } + $datatable .= '  '; + } + } else { + $datatable .= ''; + } + $datatable .= ''; + $rownum ++; + } + $$rowtotal += $rownum; + return $datatable; +} + +sub defaults_titles { + my %titles = &Apache::lonlocal::texthash ( + 'auth_def' => 'Default authentication type', + 'auth_arg_def' => 'Default authentication argument', + 'lang_def' => 'Default language', + ); + return (\%titles); +} + + sub modifiable_userdata_row { my ($context,$role,$settings,$numinrow,$rowcount) = @_; my $rolename; @@ -1908,12 +2000,13 @@ sub modify_login { my ($resulttext,$errors,$colchgtext,%changes,%colchanges); my %title = ( coursecatalog => 'Display course catalog', adminmail => 'Display administrator E-mail address', + newuser => 'Link for visitors to create a user account', loginheader => 'Log-in box header'); my @offon = ('off','on'); my %loginhash; ($errors,%colchanges) = &modify_colors($r,$dom,$confname,['login'], \%domconfig,\%loginhash); - my @toggles = ('coursecatalog','adminmail'); + my @toggles = ('coursecatalog','adminmail','newuser'); foreach my $item (@toggles) { $loginhash{login}{$item} = $env{'form.'.$item}; } @@ -1925,10 +2018,11 @@ sub modify_login { my $putresult = &Apache::lonnet::put_dom('configuration',\%loginhash, $dom); if ($putresult eq 'ok') { - my @toggles = ('coursecatalog','adminmail'); + my @toggles = ('coursecatalog','adminmail','newuser'); my %defaultchecked = ( 'coursecatalog' => 'on', 'adminmail' => 'off', + 'newuser' => 'off', ); foreach my $item (@toggles) { if ($defaultchecked{$item} eq 'on') { @@ -3097,20 +3191,26 @@ sub modify_contacts { sub modify_usercreation { my ($dom,%domconfig) = @_; my ($resulttext,%curr_usercreation,%changes,%authallowed,%cancreate); + my $warningmsg; if (ref($domconfig{'usercreation'}) eq 'HASH') { foreach my $key (keys(%{$domconfig{'usercreation'}})) { $curr_usercreation{$key} = $domconfig{'usercreation'}{$key}; } } - my %title = &Apache::lonlocal::texthash ( - author => 'adding co-authors/assistant authors', - course => 'adding users to a course', - ); my @username_rule = &Apache::loncommon::get_env_multiple('form.username_rule'); my @id_rule = &Apache::loncommon::get_env_multiple('form.id_rule'); - my @contexts = ('author','course'); + my @email_rule = &Apache::loncommon::get_env_multiple('form.email_rule'); + my @contexts = ('author','course','selfenroll'); foreach my $item(@contexts) { $cancreate{$item} = $env{'form.can_createuser_'.$item}; + if ($item eq 'selfenroll') { + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); + if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) || ($domdefaults{'auth_def'} eq 'localauth'))) { + if (($cancreate{$item} eq 'any') || ($cancreate{$item} eq 'login')) { + $warningmsg = &mt('Although account creation has been set to be available for institutional logins, currently default authentication in this domain has not been set to support this.').' '.&mt('You need to set the default authentication type to Kerberos 4 or 5 (with a Kerberos domain specified), or to Local authentication, if the localauth module has been customized in your domain to authenticate institutional logins.'); + } + } + } } if (ref($curr_usercreation{'cancreate'}) eq 'HASH') { foreach my $item (@contexts) { @@ -3120,7 +3220,7 @@ sub modify_usercreation { } } elsif (ref($curr_usercreation{'cancreate'}) eq 'ARRAY') { foreach my $item (@contexts) { - if (grep(/^\Q$item\E$/,@{$curr_usercreation{'cancreate'}})) { + if (!grep(/^\Q$item\E$/,@{$curr_usercreation{'cancreate'}})) { if ($cancreate{$item} ne 'any') { push(@{$changes{'cancreate'}},$item); } @@ -3131,7 +3231,7 @@ sub modify_usercreation { } } } else { - foreach my $item ('author','course') { + foreach my $item (@contexts) { push(@{$changes{'cancreate'}},$item); } } @@ -3166,10 +3266,25 @@ sub modify_usercreation { push(@{$changes{'id_rule'}},@id_rule); } - my @contexts = ('author','course','domain'); + if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') { + foreach my $type (@{$curr_usercreation{'email_rule'}}) { + if (!grep(/^\Q$type\E$/,@email_rule)) { + push(@{$changes{'email_rule'}},$type); + } + } + foreach my $type (@email_rule) { + if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'email_rule'}})) { + push(@{$changes{'email_rule'}},$type); + } + } + } else { + push(@{$changes{'email_rule'}},@email_rule); + } + + my @authen_contexts = ('author','course','domain'); my @authtypes = ('int','krb4','krb5','loc'); my %authhash; - foreach my $item (@contexts) { + foreach my $item (@authen_contexts) { my @authallowed = &Apache::loncommon::get_env_multiple('form.'.$item.'_auth'); foreach my $auth (@authtypes) { if (grep(/^\Q$auth\E$/,@authallowed)) { @@ -3180,7 +3295,7 @@ sub modify_usercreation { } } if (ref($curr_usercreation{'authtypes'}) eq 'HASH') { - foreach my $item (@contexts) { + foreach my $item (@authen_contexts) { if (ref($curr_usercreation{'authtypes'}{$item}) eq 'HASH') { foreach my $auth (@authtypes) { if ($authhash{$item}{$auth} ne $curr_usercreation{'authtypes'}{$item}{$auth}) { @@ -3191,7 +3306,7 @@ sub modify_usercreation { } } } else { - foreach my $item (@contexts) { + foreach my $item (@authen_contexts) { push(@{$changes{'authtypes'}},$item); } } @@ -3201,6 +3316,7 @@ sub modify_usercreation { cancreate => \%cancreate, username_rule => \@username_rule, id_rule => \@id_rule, + email_rule => \@email_rule, authtypes => \%authhash, } ); @@ -3213,15 +3329,29 @@ sub modify_usercreation { if (ref($changes{'cancreate'}) eq 'ARRAY') { my %lt = &usercreation_types(); foreach my $type (@{$changes{'cancreate'}}) { - my $chgtext; - if ($cancreate{$type} eq 'none') { - $chgtext = $lt{$type}.' '.&mt('creation of new users is not permitted, except by a Domain Coordinator.'); - } elsif ($cancreate{$type} eq 'any') { - $chgtext = $lt{$type}.' '.&mt('creation of new users is permitted for both institutional and non-institutional usernames.'); - } elsif ($cancreate{$type} eq 'official') { - $chgtext = $lt{$type}.' '.&mt('creation of new users is only permitted for institutional usernames.',$lt{$type}); - } elsif ($cancreate{$type} eq 'unofficial') { - $chgtext = $lt{$type}.' '.&mt('creation of new users is only permitted for non-institutional usernames.',$lt{$type}); + my $chgtext = $lt{$type}.', '; + if ($type eq 'selfenroll') { + if ($cancreate{$type} eq 'none') { + $chgtext .= &mt('creation of a new user account is not permitted.'); + } elsif ($cancreate{$type} eq 'any') { + $chgtext .= &mt('creation of a new account is permitted for users authenticated by institutional log-in and SSO, and also for e-mail addresses used as usernames.'); + } elsif ($cancreate{$type} eq 'login') { + $chgtext .= &mt('creation of a new account is only permitted for users authenticated by institutional log-in.'); + } elsif ($cancreate{$type} eq 'sso') { + $chgtext .= &mt('creation of a new account is only permitted for users authenticated by institutional single sign on.'); + } elsif ($cancreate{$type} eq 'email') { + $chgtext .= &mt('creation of a new account is only permitted for users who provide a valid e-mail address for use as the username.'); + } + } else { + if ($cancreate{$type} eq 'none') { + $chgtext .= &mt('creation of new users is not permitted, except by a Domain Coordinator.'); + } elsif ($cancreate{$type} eq 'any') { + $chgtext .= &mt('creation of new users is permitted for both institutional and non-institutional usernames.'); + } elsif ($cancreate{$type} eq 'official') { + $chgtext .= &mt('creation of new users is only permitted for institutional usernames.'); + } elsif ($cancreate{$type} eq 'unofficial') { + $chgtext .= &mt('creation of new users is only permitted for non-institutional usernames.'); + } } $resulttext .= '
  • '.$chgtext.'
  • '; } @@ -3258,6 +3388,23 @@ sub modify_usercreation { $resulttext .= '
  • '.&mt('There are now no ID formats restricted to verified users in the institutional directory.').'
  • '; } } + if (ref($changes{'email_rule'}) eq 'ARRAY') { + my ($emailrules,$emailruleorder) = + &Apache::lonnet::inst_userrules($dom,'email'); + my $chgtext = ''; + if (@email_rule > 0) { + $resulttext .= '
  • '.&mt('Accounts may not be created by users self-enrolling with e-mail addresses of the following types: ').$chgtext.'
  • '; + } else { + $resulttext .= '
  • '.&mt('There are now no restrictions on e-mail addresses which may be used as a username when self-enrolling.').'
  • '; + } + } + my %authname = &authtype_names(); my %context_title = &context_names(); if (ref($changes{'authtypes'}) eq 'ARRAY') { @@ -3270,7 +3417,11 @@ sub modify_usercreation { push(@allowed,$authname{$auth}); } } - $chgtext .= join(', ',@allowed).''; + if (@allowed > 0) { + $chgtext .= join(', ',@allowed).''; + } else { + $chgtext .= &mt('none').''; + } } $chgtext .= ''; $resulttext .= '
  • '.&mt('Authentication types available for assignment to new users').'
    '.$chgtext; @@ -3284,6 +3435,9 @@ sub modify_usercreation { $resulttext = ''. &mt('An error occurred: [_1]',$putresult).''; } + if ($warningmsg ne '') { + $resulttext .= '
    '.$warningmsg.'
    '; + } return $resulttext; } @@ -3386,5 +3540,92 @@ sub modify_usermodification { } return $resulttext; } + +sub modify_defaults { + my ($dom,$r) = @_; + my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors); + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); + my @items = ('auth_def','auth_arg_def','lang_def'); + my @authtypes = ('internal','krb4','krb5','localauth'); + foreach my $item (@items) { + $newvalues{$item} = $env{'form.'.$item}; + if ($item eq 'auth_def') { + if ($newvalues{$item} ne '') { + if (!grep(/^\Q$newvalues{$item}\E$/,@authtypes)) { + push(@errors,$item); + } + } + } elsif ($item eq 'lang_def') { + if ($newvalues{$item} ne '') { + if ($newvalues{$item} =~ /^(\w+)/) { + my $langcode = $1; + if (code2language($langcode) eq '') { + push(@errors,$item); + } + } else { + push(@errors,$item); + } + } + } + if (grep(/^\Q$item\E$/,@errors)) { + $newvalues{$item} = $domdefaults{$item}; + } elsif ($domdefaults{$item} ne $newvalues{$item}) { + $changes{$item} = 1; + } + } + my %defaults_hash = ( + defaults => { auth_def => $newvalues{'auth_def'}, + auth_arg_def => $newvalues{'auth_arg_def'}, + lang_def => $newvalues{'lang_def'}, + } + ); + my $title = &defaults_titles(); + my $putresult = &Apache::lonnet::put_dom('configuration',\%defaults_hash, + $dom); + if ($putresult eq 'ok') { + if (keys(%changes) > 0) { + $resulttext = &mt('Changes made:').''; + $mailmsgtext .= "\n"; + my $cachetime = 24*60*60; + &Apache::lonnet::do_cache_new('domdefaults',$dom, + $defaults_hash{'defaults'},$cachetime); + my $sysmail = $r->dir_config('lonSysEMail'); + &Apache::lonmsg::sendemail($sysmail,"LON-CAPA Domain Settings Change - $dom",$mailmsgtext); + } else { + $resulttext = &mt('No changes made to default authentication/language settings'); + } + } else { + $resulttext = ''. + &mt('An error occurred: [_1]',$putresult).''; + } + if (@errors > 0) { + $resulttext .= '
    '.&mt('The following were left unchanged because the values entered were invalid:'); + foreach my $item (@errors) { + $resulttext .= ' "'.$title->{$item}.'",'; + } + $resulttext =~ s/,$//; + } + return $resulttext; +} 1;