--- loncom/interface/lonuserutils.pm 2017/01/28 03:48:44 1.182
+++ loncom/interface/lonuserutils.pm 2022/02/14 01:15:24 1.210
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Utility functions for managing LON-CAPA user accounts
#
-# $Id: lonuserutils.pm,v 1.182 2017/01/28 03:48:44 raeburn Exp $
+# $Id: lonuserutils.pm,v 1.210 2022/02/14 01:15:24 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -438,7 +438,7 @@ sub javascript_validations {
} elsif ($context eq 'domain') {
$setsection_call = 'setCourse()';
$setsections_js = &dc_setcourse_js($param{'formname'},$mode,
- $context,$showcredits);
+ $context,$showcredits,$domain);
}
$finish = " var checkSec = $setsection_call\n".
" if (checkSec == 'ok') {\n".
@@ -531,21 +531,28 @@ END
/* regexp here to check for non \d \. in credits */
END
} else {
+ my ($numrules,$intargjs) =
+ &Apache::loncommon::passwd_validation_js('vf.elements[current.argfield].value',$domain);
$auth_checks .= (< 0) {
+$intargjs
+ }
}
END
}
@@ -641,6 +652,7 @@ END
$section_checks.$authheader;
return $result;
}
+
###############################################################
###############################################################
sub upload_manager_javascript_forward_associate {
@@ -898,6 +910,7 @@ sub print_upload_manager_footer {
my $krbform = &Apache::loncommon::authform_kerberos(%param);
my $intform = &Apache::loncommon::authform_internal(%param);
my $locform = &Apache::loncommon::authform_local(%param);
+ my $ltiform = &Apache::loncommon::authform_lti(%param);
my $date_table = &date_setting_table(undef,undef,$context,undef,
$formname,$permission,$crstype);
@@ -926,7 +939,7 @@ sub print_upload_manager_footer {
&Apache::loncommon::help_open_topic('Auth_Options').
"
\n";
}
- $Str .= &set_login($defdom,$krbform,$intform,$locform);
+ $Str .= &set_login($defdom,$krbform,$intform,$locform,$ltiform);
my ($home_server_pick,$numlib) =
&Apache::loncommon::home_server_form_item($defdom,'lcserver',
@@ -943,8 +956,14 @@ sub print_upload_manager_footer {
&Apache::lonhtmlcommon::row_closure();
}
+ my ($trusted,$untrusted);
+ if ($context eq 'course') {
+ ($trusted,$untrusted) = &Apache::lonnet::trusted_domains('enroll',$defdom);
+ } elsif ($context eq 'author') {
+ ($trusted,$untrusted) = &Apache::lonnet::trusted_domains('othcoau',$defdom);
+ }
$Str .= &Apache::lonhtmlcommon::row_title(&mt('Default domain'))
- .&Apache::loncommon::select_dom_form($defdom,'defaultdomain',undef,1)
+ .&Apache::loncommon::select_dom_form($defdom,'defaultdomain',undef,1,undef,$trusted,$untrusted)
.&Apache::lonhtmlcommon::row_closure();
$Str .= &Apache::lonhtmlcommon::row_title(&mt('Starting and Ending Dates'))
@@ -1121,8 +1140,15 @@ sub print_upload_manager_form {
if (!$env{'form.datatoken'}) {
$datatoken=&Apache::loncommon::upfile_store($r);
} else {
- $datatoken=$env{'form.datatoken'};
- &Apache::loncommon::load_tmp_file($r);
+ $datatoken=&Apache::loncommon::valid_datatoken($env{'form.datatoken'});
+ if ($datatoken ne '') {
+ &Apache::loncommon::load_tmp_file($r,$datatoken);
+ }
+ }
+ if ($datatoken eq '') {
+ $r->print(''.&mt('Error').': '.
+ &mt('Invalid datatoken').'
');
+ return 'missingdata';
}
my @records=&Apache::loncommon::upfile_record_sep();
if($env{'form.noFirstLine'}){
@@ -1206,6 +1232,7 @@ sub print_upload_manager_form {
}
&print_upload_manager_footer($r,$i,$keyfields,$defdom,$today,$halfyear,
$context,$permission,$crstype,$showcredits);
+ return 'ok';
}
sub setup_date_selectors {
@@ -1553,10 +1580,11 @@ sub my_custom_roles {
my %rolehash=&Apache::lonnet::dump('roles',$udom,$uname);
foreach my $key (keys(%rolehash)) {
if ($key=~/^rolesdef\_(\w+)$/) {
+ my $role = $1;
if ($crstype eq 'Community') {
next if ($rolehash{$key} =~ /bre\&S/);
}
- $returnhash{$1}=$1;
+ $returnhash{$role}=$role;
}
}
return %returnhash;
@@ -2279,7 +2307,6 @@ sub build_user_record {
sub courses_selector {
my ($cdom,$formname) = @_;
- my %coursecodes = ();
my %codes = ();
my @codetitles = ();
my %cat_titles = ();
@@ -2292,14 +2319,15 @@ sub courses_selector {
my $jscript = '';
my $totcodes = 0;
- $totcodes =
- &Apache::courseclassifier::retrieve_instcodes(\%coursecodes,
- $cdom,$totcodes);
- if ($totcodes > 0) {
- $format_reply =
- &Apache::lonnet::auto_instcode_format($caller,$cdom,\%coursecodes,
- \%codes,\@codetitles,\%cat_titles,\%cat_order);
- if ($format_reply eq 'ok') {
+ my $instcats = &Apache::lonnet::get_dom_instcats($cdom);
+ if (ref($instcats) eq 'HASH') {
+ if ((ref($instcats->{'codetitles'}) eq 'ARRAY') && (ref($instcats->{'codes'}) eq 'HASH') &&
+ (ref($instcats->{'cat_titles'}) eq 'HASH') && (ref($instcats->{'cat_order'}) eq 'HASH')) {
+ %codes = %{$instcats->{'codes'}};
+ @codetitles = @{$instcats->{'codetitles'}};
+ %cat_titles = %{$instcats->{'cat_titles'}};
+ %cat_order = %{$instcats->{'cat_order'}};
+ $totcodes = scalar(keys(%codes));
my $numtypes = @codetitles;
&Apache::courseclassifier::build_code_selections(\%codes,\@codetitles,\%cat_titles,\%cat_order,\%idlist,\%idnums,\%idlist_titles);
my ($scripttext,$longtitles) = &Apache::courseclassifier::javascript_definitions(\@codetitles,\%idlist,\%idlist_titles,\%idnums,\%cat_titles);
@@ -2336,7 +2364,8 @@ function setCourseCat(formname) {
}
courseSet('$codetitles[1]');
for (var j=0; j '.$lt{'owin'}
.'';
}
- $output .= "\n".' '."\n".
+ $output .= "\n".'
'."\n".
&Apache::loncommon::start_data_table().
&Apache::loncommon::start_data_table_header_row();
if ($mode eq 'autoenroll') {
@@ -3101,7 +3130,14 @@ END
}
if ($showcheckbox) {
$r->print(' ');
+ 'actionlist" value="'.
+ &HTML::Entities::encode($checkval,'&<>"').'" />');
+ foreach my $item ('start','end') {
+ $r->print(' ');
+ }
+ $r->print('');
} else {
$r->print(' ');
}
@@ -3115,8 +3151,6 @@ END
foreach my $item (@cols) {
if ($item eq 'username') {
$r->print(''.&print_username_link($mode,\%in).' ');
- } elsif (($item eq 'start' || $item eq 'end') && ($actionselect)) {
- $r->print(''.$in{$item}.' '."\n");
} elsif ($item eq 'status') {
my $showitem = $in{$item};
if (defined($ltstatus{$in{$item}})) {
@@ -3507,6 +3541,8 @@ END
setSections(formname,'$crstype');
if (seccheck == 'ok') {
opener.document.$callingform.newsecs.value = formname.sections.value;
+ } else {
+ return;
}
END
} else {
@@ -4091,7 +4127,7 @@ sub print_first_users_upload_form {
.&Apache::lonhtmlcommon::end_pick_box();
$str .= ''
- .' '
.'
';
@@ -4102,7 +4138,10 @@ sub print_first_users_upload_form {
# ================================================= Drop/Add from uploaded file
sub upfile_drop_add {
my ($r,$context,$permission,$showcredits) = @_;
- &Apache::loncommon::load_tmp_file($r);
+ my $datatoken = &Apache::loncommon::valid_datatoken($env{'form.datatoken'});
+ if ($datatoken ne '') {
+ &Apache::loncommon::load_tmp_file($r,$datatoken);
+ }
my @userdata=&Apache::loncommon::upfile_record_sep();
if($env{'form.noFirstLine'}){shift(@userdata);}
my @keyfields = split(/\,/,$env{'form.keyfields'});
@@ -4116,10 +4155,6 @@ sub upfile_drop_add {
$fields{$env{'form.f'.$i}}=$keyfields[$i];
}
}
- if ($env{'form.fullup'} ne 'yes') {
- $r->print(''."\n");
+ $r->print(''.
+ &mt('There are no students with current/future access to the course.').
+ '
'."\n");
} elsif (ref($classlist) eq 'HASH') {
# Remove the students we just added from the list of students.
foreach my $line (@userdata) {
@@ -4856,9 +5009,7 @@ sub upfile_drop_add {
}
}
} # end of unless
- if ($env{'form.fullup'} ne 'yes') {
- $r->print('');
- }
+ return 'ok';
}
sub print_namespacing_alerts {
@@ -4901,6 +5052,42 @@ sub print_namespacing_alerts {
}
}
+sub passwdrule_alerts {
+ my ($domain,$passwdrules) = @_;
+ my $warning;
+ if (ref($passwdrules) eq 'HASH') {
+ my %showrules = %{$passwdrules};
+ if (keys(%showrules)) {
+ my %passwdconf = &Apache::lonnet::get_passwdconf($domain);
+ $warning = ''.&mt('Password requirement(s) unmet for one or more users:').' ';
+ if ($showrules{'min'}) {
+ my $min = $passwdconf{'min'};
+ if ($min eq '') {
+ $min = $Apache::lonnet::passwdmin;
+ }
+ $warning .= ''.&mt('minimum [quant,_1,character]',$min).' ';
+ }
+ if ($showrules{'max'}) {
+ $warning .= ''.&mt('maximum [quant,_1,character]',$passwdconf{'max'}).' ';
+ }
+ if ($showrules{'uc'}) {
+ $warning .= ''.&mt('contain at least one upper case letter').' ';
+ }
+ if ($showrules{'lc'}) {
+ $warning .= ''.&mt('contain at least one lower case letter').' ';
+ }
+ if ($showrules{'num'}) {
+ $warning .= ''.&mt('contain at least one number').' ';
+ }
+ if ($showrules{'spec'}) {
+ $warning .= ''.&mt('contain at least one non-alphanumeric').' ';
+ }
+ $warning .= ' ';
+ }
+ }
+ return $warning;
+}
+
sub user_change_result {
my ($r,$userresult,$authresult,$roleresult,$idresult,$counts,$flushc,
$username,$userdomain,$userchg) = @_;
@@ -5404,7 +5591,7 @@ END
}
sub set_login {
- my ($dom,$authformkrb,$authformint,$authformloc) = @_;
+ my ($dom,$authformkrb,$authformint,$authformloc,$authformlti) = @_;
my %domconfig = &Apache::lonnet::get_dom('configuration',['usercreation'],$dom);
my $response;
my ($authnum,%can_assign) =
@@ -5426,6 +5613,11 @@ sub set_login {
''.$authformloc.' '.
&Apache::loncommon::end_data_table_row()."\n";
}
+ if ($can_assign{'lti'}) {
+ $response .= &Apache::loncommon::start_data_table_row().
+ ''.$authformlti.' '.
+ &Apache::loncommon::end_data_table_row()."\n";
+ }
$response .= &Apache::loncommon::end_data_table();
}
return $response;
@@ -5770,6 +5962,70 @@ sub can_modify_userinfo {
return %canmodify;
}
+sub can_change_internalpass {
+ my ($uname,$udom,$crstype,$permission) = @_;
+ my $canchange;
+ if (&Apache::lonnet::allowed('mau',$udom)) {
+ $canchange = 1;
+ } elsif ((ref($permission) eq 'HASH') && ($permission->{'mip'}) &&
+ ($udom eq $env{'request.role.domain'})) {
+ unless ($env{'course.'.$env{'request.course.id'}.'.internal.nopasswdchg'}) {
+ my ($cnum,$cdom) = &get_course_identity();
+ if ((&Apache::lonnet::is_course_owner($cdom,$cnum)) && ($udom eq $env{'user.domain'})) {
+ my @userstatuses = ('default');
+ my %userenv = &Apache::lonnet::userenvironment($udom,$uname,'inststatus');
+ if ($userenv{'inststatus'} ne '') {
+ @userstatuses = split(/:/,$userenv{'inststatus'});
+ }
+ my $noupdate = 1;
+ my %passwdconf = &Apache::lonnet::get_passwdconf($cdom);
+ if (ref($passwdconf{'crsownerchg'}) eq 'HASH') {
+ if (ref($passwdconf{'crsownerchg'}{'for'}) eq 'ARRAY') {
+ foreach my $status (@userstatuses) {
+ if (grep(/^\Q$status\E$/,@{$passwdconf{'crsownerchg'}{'for'}})) {
+ undef($noupdate);
+ last;
+ }
+ }
+ }
+ }
+ if ($noupdate) {
+ return;
+ }
+ my %owned = &Apache::lonnet::courseiddump($cdom,'.',1,'.',
+ $env{'user.name'}.':'.$env{'user.domain'},
+ undef,undef,undef,'.');
+ my %roleshash = &Apache::lonnet::get_my_roles($uname,$udom,'userroles',
+ ['active','future']);
+ foreach my $key (keys(%roleshash)) {
+ my ($name,$domain,$role) = split(/:/,$key);
+ if ($role eq 'st') {
+ next if (($name eq $cnum) && ($domain eq $cdom));
+ if ($owned{$domain.'_'.$name}) {
+ if (ref($owned{$domain.'_'.$name}) eq 'HASH') {
+ if ($owned{$domain.'_'.$name}{'nopasswdchg'}) {
+ $noupdate = 1;
+ last;
+ }
+ }
+ } else {
+ $noupdate = 1;
+ last;
+ }
+ } else {
+ $noupdate = 1;
+ last;
+ }
+ }
+ unless ($noupdate) {
+ $canchange = 1;
+ }
+ }
+ }
+ }
+ return $canchange;
+}
+
sub check_usertype {
my ($dom,$uname,$rules,$curr_rules,$got_rules) = @_;
my $usertype;
@@ -5892,10 +6148,16 @@ sub get_permission {
}
}
if ($env{'request.course.id'}) {
- my $user = $env{'user.name'}.':'.$env{'user.domain'};
+ my $user;
+ if (($env{'user.name'} ne '') && ($env{'user.domain'} ne '')) {
+ $user = $env{'user.name'}.':'.$env{'user.domain'};
+ }
if (($user ne '') && ($env{'course.'.$env{'request.course.id'}.'.internal.courseowner'} eq
$user)) {
$permission{'owner'} = 1;
+ if (&Apache::lonnet::allowed('mip',$env{'request.course.id'})) {
+ $permission{'mip'} = 1;
+ }
} elsif (($user ne '') && ($env{'course.'.$env{'request.course.id'}.'.internal.co-owners'} ne '')) {
if (grep(/^\Q$user\E$/,split(/,/,$env{'course.'.$env{'request.course.id'}.'.internal.co-owners'}))) {
$permission{'co-owner'} = 1;
@@ -5982,7 +6244,7 @@ sub get_course_identity {
}
sub dc_setcourse_js {
- my ($formname,$mode,$context,$showcredits) = @_;
+ my ($formname,$mode,$context,$showcredits,$domain) = @_;
my ($dc_setcourse_code,$authen_check);
my $cctext = &Apache::lonnet::plaintext('cc');
my $cotext = &Apache::lonnet::plaintext('co');
@@ -5991,7 +6253,7 @@ sub dc_setcourse_js {
if ($mode eq 'upload') {
$role = 'courserole';
} else {
- $authen_check = &verify_authen($formname,$context);
+ $authen_check = &verify_authen($formname,$context,$domain);
}
$dc_setcourse_code = (<<"SCRIPTTOP");
$authen_check
@@ -6135,12 +6397,14 @@ ENDSCRIPT
}
sub verify_authen {
- my ($formname,$context) = @_;
+ my ($formname,$context,$domain) = @_;
my %alerts = &authcheck_alerts();
my $finish = "return 'ok';";
if ($context eq 'author') {
$finish = "document.$formname.submit();";
}
+ my ($numrules,$intargjs) =
+ &Apache::loncommon::passwd_validation_js('argpicked',$domain);
my $outcome = <<"ENDSCRIPT";
function auth_check() {
@@ -6174,6 +6438,7 @@ function auth_check() {
break;
case 'int':
alertmsg = '$alerts{'ipass'}';
+ break;
case 'fsys':
alertmsg = '$alerts{'ipass'}';
break;
@@ -6187,6 +6452,11 @@ function auth_check() {
alert(alertmsg);
return;
}
+ } else if (logintype == 'int') {
+ var numrules = $numrules;
+ if (numrules > 0) {
+$intargjs
+ }
}
$finish
}