--- loncom/lonnet/perl/lonnet.pm 2012/12/31 14:59:54 1.1172.2.15 +++ loncom/lonnet/perl/lonnet.pm 2013/12/27 23:31:21 1.1172.2.37 @@ -1,7 +1,7 @@ # The LearningOnline Network # TCP networking package # -# $Id: lonnet.pm,v 1.1172.2.15 2012/12/31 14:59:54 raeburn Exp $ +# $Id: lonnet.pm,v 1.1172.2.37 2013/12/27 23:31:21 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -97,6 +97,7 @@ use File::MMagic; use LONCAPA qw(:DEFAULT :match); use LONCAPA::Configuration; use LONCAPA::lonmetadata; +use LONCAPA::Lond; use File::Copy; @@ -351,9 +352,11 @@ sub get_remote_globals { } sub remote_devalidate_cache { - my ($lonhost,$name,$id) = @_; - my $response = &reply('devalidatecache:'.&escape($name).':'.&escape($id),$lonhost); - return $response; + my ($lonhost,$cachekeys) = @_; + my $items; + return unless (ref($cachekeys) eq 'ARRAY'); + my $cachestr = join('&',@{$cachekeys}); + return &reply('devalidatecache:'.&escape($cachestr),$lonhost); } # -------------------------------------------------- Non-critical communication @@ -598,7 +601,7 @@ sub transfer_profile_to_env { # ---------------------------------------------------- Check for valid session sub check_for_valid_session { - my ($r,$name) = @_; + my ($r,$name,$userhashref) = @_; my %cookies=CGI::Cookie->parse($r->header_in('Cookie')); if ($name eq '') { $name = 'lonID'; @@ -629,6 +632,12 @@ sub check_for_valid_session { || !defined($disk_env{'user.domain'})) { return undef; } + + if (ref($userhashref) eq 'HASH') { + $userhashref->{'name'} = $disk_env{'user.name'}; + $userhashref->{'domain'} = $disk_env{'user.domain'}; + } + return $handle; } @@ -1311,7 +1320,7 @@ sub check_loadbalancing { } } } elsif (($homeintdom) && ($udom ne $serverhomedom)) { - my ($result,$cached)=&is_cached_new('loadbalancing',$serverhomedom); + ($result,$cached)=&is_cached_new('loadbalancing',$serverhomedom); unless (defined($cached)) { my %domconfig = &Apache::lonnet::get_dom('configuration',['loadbalancing'],$serverhomedom); @@ -1566,6 +1575,36 @@ sub idput { } } +# ---------------------------------------- Delete unwanted IDs from ids.db file + +sub iddel { + my ($udom,$idshashref,$uhome)=@_; + my %result=(); + unless (ref($idshashref) eq 'HASH') { + return %result; + } + my %servers=(); + while (my ($id,$uname) = each(%{$idshashref})) { + my $uhom; + if ($uhome) { + $uhom = $uhome; + } else { + $uhom=&homeserver($uname,$udom); + } + if ($uhom ne 'no_host') { + if ($servers{$uhom}) { + $servers{$uhom}.='&'.&escape($id); + } else { + $servers{$uhom}=&escape($id); + } + } + } + foreach my $server (keys(%servers)) { + $result{$server} = &critical('iddel:'.$udom.':'.$servers{$server},$uhome); + } + return %result; +} + # ------------------------------dump from db file owned by domainconfig user sub dump_dom { my ($namespace, $udom, $regexp) = @_; @@ -1942,12 +1981,15 @@ sub inst_userrules { # ------------- Get Authentication, Language and User Tools Defaults for Domain sub get_domain_defaults { - my ($domain) = @_; + my ($domain,$ignore_cache) = @_; + return if (($domain eq '') || ($domain eq 'public')); my $cachetime = 60*60*24; - my ($result,$cached)=&is_cached_new('domdefaults',$domain); - if (defined($cached)) { - if (ref($result) eq 'HASH') { - return %{$result}; + unless ($ignore_cache) { + my ($result,$cached)=&is_cached_new('domdefaults',$domain); + if (defined($cached)) { + if (ref($result) eq 'HASH') { + return %{$result}; + } } } my %domdefaults; @@ -1973,16 +2015,19 @@ sub get_domain_defaults { $domdefaults{'defaultquota'} = $domconfig{'quotas'}{'defaultquota'}; } else { $domdefaults{'defaultquota'} = $domconfig{'quotas'}; - } + } my @usertools = ('aboutme','blog','webdav','portfolio'); foreach my $item (@usertools) { if (ref($domconfig{'quotas'}{$item}) eq 'HASH') { $domdefaults{$item} = $domconfig{'quotas'}{$item}; } } + if (ref($domconfig{'quotas'}{'authorquota'}) eq 'HASH') { + $domdefaults{'authorquota'} = $domconfig{'quotas'}{'authorquota'}; + } } if (ref($domconfig{'requestcourses'}) eq 'HASH') { - foreach my $item ('official','unofficial','community') { + foreach my $item ('official','unofficial','community','textbook') { $domdefaults{$item} = $domconfig{'requestcourses'}{$item}; } } @@ -1995,8 +2040,16 @@ sub get_domain_defaults { } } if (ref($domconfig{'coursedefaults'}) eq 'HASH') { - foreach my $item ('canuse_pdfforms') { - $domdefaults{$item} = $domconfig{'coursedefaults'}{$item}; + if (ref($domconfig{'coursedefaults'}{'coursecredits'}) eq 'HASH') { + $domdefaults{'officialcredits'} = $domconfig{'coursedefaults'}{'coursecredits'}{'official'}; + $domdefaults{'unofficialcredits'} = $domconfig{'coursedefaults'}{'coursecredits'}{'unofficial'}; + $domdefaults{'textbookcredits'} = $domconfig{'coursedefaults'}{'coursecredits'}{'textbook'}; + } + if (ref($domconfig{'coursedefaults'}{'uploadquota'}) eq 'HASH') { + $domdefaults{'officialquota'} = $domconfig{'coursedefaults'}{'uploadquota'}{'official'}; + $domdefaults{'unofficialquota'} = $domconfig{'coursedefaults'}{'uploadquota'}{'unofficial'}; + $domdefaults{'communityquota'} = $domconfig{'coursedefaults'}{'uploadquota'}{'community'}; + $domdefaults{'textbookquota'} = $domconfig{'coursedefaults'}{'uploadquota'}{'textbook'}; } } if (ref($domconfig{'usersessions'}) eq 'HASH') { @@ -2007,8 +2060,7 @@ sub get_domain_defaults { $domdefaults{'hostedsessions'} = $domconfig{'usersessions'}{'hosted'}; } } - &Apache::lonnet::do_cache_new('domdefaults',$domain,\%domdefaults, - $cachetime); + &do_cache_new('domdefaults',$domain,\%domdefaults,$cachetime); return %domdefaults; } @@ -2798,6 +2850,13 @@ sub can_edit_resource { $cfile =~ s{^http://}{}; $cfile = '/adm/wrapper/ext/'.$cfile; } + } elsif ($resurl =~ m{^/?adm/viewclasslist$}) { + if ($env{'form.forceedit'}) { + $forceview = 1; + } else { + $forceedit = 1; + } + $cfile = ($resurl =~ m{^/} ? $resurl : "/$resurl"); } } if ($uploaded || $incourse) { @@ -2839,9 +2898,13 @@ sub in_course { my ($udom,$uname,$cdom,$cnum,$type,$hideprivileged) = @_; if ($hideprivileged) { my $skipuser; - if (&privileged($uname,$udom)) { + my %coursehash = &coursedescription($cdom.'_'.$cnum); + my @possdoms = ($cdom); + if ($coursehash{'checkforpriv'}) { + push(@possdoms,split(/,/,$coursehash{'checkforpriv'})); + } + if (&privileged($uname,$udom,\@possdoms)) { $skipuser = 1; - my %coursehash = &coursedescription($cdom.'_'.$cnum); if ($coursehash{'nothideprivileged'}) { foreach my $item (split(/\s*\,\s*/,$coursehash{'nothideprivileged'})) { my $user; @@ -3174,7 +3237,9 @@ sub userfileupload { $codebase,$thumbwidth,$thumbheight, $resizewidth,$resizeheight,$context,$mimetype); } else { - $fname=$env{'form.folder'}.'/'.$fname; + if ($env{'form.folder'}) { + $fname=$env{'form.folder'}.'/'.$fname; + } return &process_coursefile('uploaddoc',$docuname,$docudom, $fname,$formname,$parser, $allfiles,$codebase,$mimetype); @@ -3189,7 +3254,7 @@ sub userfileupload { } else { my $docuname=$env{'user.name'}; my $docudom=$env{'user.domain'}; - if (exists($env{'form.group'})) { + if ((exists($env{'form.group'})) || ($context eq 'syllabus')) { $docuname=$env{'course.'.$env{'request.course.id'}.'.num'}; $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'}; } @@ -3339,7 +3404,9 @@ sub extract_embedded_items { &add_filetype($allfiles,$attr->{'src'},'src'); } if (lc($tagname) eq 'a') { - &add_filetype($allfiles,$attr->{'href'},'href'); + unless (($attr->{'href'} =~ /^#/) || ($attr->{'href'} eq '')) { + &add_filetype($allfiles,$attr->{'href'},'href'); + } } if (lc($tagname) eq 'script') { my $src; @@ -3427,8 +3494,26 @@ sub extract_embedded_items { } } } + if (lc($tagname) eq 'iframe') { + my $src = $attr->{'src'} ; + if (($src ne '') && ($src !~ m{^(/|https?://)})) { + &add_filetype($allfiles,$src,'src'); + } elsif ($src =~ m{^/}) { + if ($env{'request.course.id'}) { + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my $url = &hreflocation('',$fullpath); + if ($url =~ m{^/uploaded/$cdom/$cnum/docs/(\w+/\d+)/}) { + my $relpath = $1; + if ($src =~ m{^/uploaded/$cdom/$cnum/docs/\Q$relpath\E/(.+)$}) { + &add_filetype($allfiles,$1,'src'); + } + } + } + } + } if ($t->[4] =~ m{/>$}) { - pop(@state); + pop(@state); } } elsif ($t->[0] eq 'E') { my ($tagname) = ($t->[1]); @@ -3870,6 +3955,10 @@ sub get_course_adv_roles { $nothide{$user}=1; } } + my @possdoms = ($coursehash{'domain'}); + if ($coursehash{'checkforpriv'}) { + push(@possdoms,split(/,/,$coursehash{'checkforpriv'})); + } my %returnhash=(); my %dumphash= &dump('nohist_userroles',$coursehash{'domain'},$coursehash{'num'}); @@ -3882,20 +3971,7 @@ sub get_course_adv_roles { if (($tstart) && ($now<$tstart)) { next; } my ($role,$username,$domain,$section)=split(/\:/,$entry); if ($username eq '' || $domain eq '') { next; } - unless (ref($privileged{$domain}) eq 'HASH') { - my %dompersonnel = - &Apache::lonnet::get_domain_roles($domain,['dc'],$now,$now); - $privileged{$domain} = {}; - foreach my $server (keys(%dompersonnel)) { - if (ref($dompersonnel{$server}) eq 'HASH') { - foreach my $user (keys(%{$dompersonnel{$server}})) { - my ($trole,$uname,$udom) = split(/:/,$user); - $privileged{$udom}{$uname} = 1; - } - } - } - } - if ((exists($privileged{$domain}{$username})) && + if ((&privileged($username,$domain,\@possdoms)) && (!$nothide{$username.':'.$domain})) { next; } if ($role eq 'cr') { next; } if ($codes) { @@ -3926,8 +4002,7 @@ sub get_my_roles { if ($context eq 'userroles') { %dumphash = &dump('roles',$udom,$uname); } else { - %dumphash= - &dump('nohist_userroles',$udom,$uname); + %dumphash = &dump('nohist_userroles',$udom,$uname); if ($hidepriv) { my %coursehash=&coursedescription($udom.'_'.$uname); foreach my $user (split(/\s*\,\s*/,$coursehash{'nothideprivileged'})) { @@ -3995,28 +4070,15 @@ sub get_my_roles { } } if ($hidepriv) { + my @privroles = ('dc','su'); if ($context eq 'userroles') { - if ((&privileged($username,$domain)) && - (!$nothide{$username.':'.$domain})) { - next; - } + next if (grep(/^\Q$role\E$/,@privroles)); } else { - unless (ref($privileged{$domain}) eq 'HASH') { - my %dompersonnel = - &Apache::lonnet::get_domain_roles($domain,['dc'],$now,$now); - $privileged{$domain} = {}; - if (keys(%dompersonnel)) { - foreach my $server (keys(%dompersonnel)) { - if (ref($dompersonnel{$server}) eq 'HASH') { - foreach my $user (keys(%{$dompersonnel{$server}})) { - my ($trole,$uname,$udom) = split(/:/,$user); - $privileged{$udom}{$uname} = $trole; - } - } - } - } + my $possdoms = [$domain]; + if (ref($roledoms) eq 'ARRAY') { + push(@{$possdoms},@{$roledoms}); } - if (exists($privileged{$domain}{$username})) { + if (&privileged($username,$domain,$possdoms,\@privroles)) { if (!$nothide{$username.':'.$domain}) { next; } @@ -4120,18 +4182,32 @@ sub courseiddump { if (($domfilter eq '') || (&host_domain($tryserver) eq $domfilter)) { - my $rep = - &reply('courseiddump:'.&host_domain($tryserver).':'. - $sincefilter.':'.&escape($descfilter).':'. - &escape($instcodefilter).':'.&escape($ownerfilter). - ':'.&escape($coursefilter).':'.&escape($typefilter). - ':'.&escape($regexp_ok).':'.$as_hash.':'. - &escape($selfenrollonly).':'.&escape($catfilter).':'. - $showhidden.':'.$caller.':'.&escape($cloner).':'. - &escape($cc_clone).':'.$cloneonly.':'. - &escape($createdbefore).':'.&escape($createdafter).':'. - &escape($creationcontext).':'.$domcloner, - $tryserver); + my $rep; + if (grep { $_ eq $tryserver } ¤t_machine_ids()) { + $rep = &LONCAPA::Lond::dump_course_id_handler( + join(":", (&host_domain($tryserver), $sincefilter, + &escape($descfilter), &escape($instcodefilter), + &escape($ownerfilter), &escape($coursefilter), + &escape($typefilter), &escape($regexp_ok), + $as_hash, &escape($selfenrollonly), + &escape($catfilter), $showhidden, $caller, + &escape($cloner), &escape($cc_clone), $cloneonly, + &escape($createdbefore), &escape($createdafter), + &escape($creationcontext), $domcloner))); + } else { + $rep = &reply('courseiddump:'.&host_domain($tryserver).':'. + $sincefilter.':'.&escape($descfilter).':'. + &escape($instcodefilter).':'.&escape($ownerfilter). + ':'.&escape($coursefilter).':'.&escape($typefilter). + ':'.&escape($regexp_ok).':'.$as_hash.':'. + &escape($selfenrollonly).':'.&escape($catfilter).':'. + $showhidden.':'.$caller.':'.&escape($cloner).':'. + &escape($cc_clone).':'.$cloneonly.':'. + &escape($createdbefore).':'.&escape($createdafter).':'. + &escape($creationcontext).':'.$domcloner, + $tryserver); + } + my @pairs=split(/\&/,$rep); foreach my $item (@pairs) { my ($key,$value)=split(/\=/,$item,2); @@ -4237,7 +4313,7 @@ sub get_domain_roles { } my $rolelist; if (ref($roles) eq 'ARRAY') { - $rolelist = join(':',@{$roles}); + $rolelist = join('&',@{$roles}); } my %personnel = (); @@ -4330,6 +4406,92 @@ sub set_first_access { return 'already_set'; } } + +sub checkout { + my ($symb,$tuname,$tudom,$tcrsid)=@_; + my $now=time; + my $lonhost=$perlvar{'lonHostID'}; + my $infostr=&escape( + 'CHECKOUTTOKEN&'. + $tuname.'&'. + $tudom.'&'. + $tcrsid.'&'. + $symb.'&'. + $now.'&'.$ENV{'REMOTE_ADDR'}); + my $token=&reply('tmpput:'.$infostr,$lonhost); + if ($token=~/^error\:/) { + &logthis("WARNING: ". + "Checkout tmpput failed ".$tudom.' - '.$tuname.' - '.$symb. + ""); + return ''; + } + + $token=~s/^(\d+)\_.*\_(\d+)$/$1\*$2\*$lonhost/; + $token=~tr/a-z/A-Z/; + + my %infohash=('resource.0.outtoken' => $token, + 'resource.0.checkouttime' => $now, + 'resource.0.outremote' => $ENV{'REMOTE_ADDR'}); + + unless (&cstore(\%infohash,$symb,$tcrsid,$tudom,$tuname) eq 'ok') { + return ''; + } else { + &logthis("WARNING: ". + "Checkout cstore failed ".$tudom.' - '.$tuname.' - '.$symb. + ""); + } + + if (&log($tudom,$tuname,&homeserver($tuname,$tudom), + &escape('Checkout '.$infostr.' - '. + $token)) ne 'ok') { + return ''; + } else { + &logthis("WARNING: ". + "Checkout log failed ".$tudom.' - '.$tuname.' - '.$symb. + ""); + } + return $token; +} + +# ------------------------------------------------------------ Check in an item + +sub checkin { + my $token=shift; + my $now=time; + my ($ta,$tb,$lonhost)=split(/\*/,$token); + $lonhost=~tr/A-Z/a-z/; + my $dtoken=$ta.'_'.&hostname($lonhost).'_'.$tb; + $dtoken=~s/\W/\_/g; + my ($dummy,$tuname,$tudom,$tcrsid,$symb,$chtim,$rmaddr)= + split(/\&/,&unescape(&reply('tmpget:'.$dtoken,$lonhost))); + + unless (($tuname) && ($tudom)) { + &logthis('Check in '.$token.' ('.$dtoken.') failed'); + return ''; + } + + unless (&allowed('mgr',$tcrsid)) { + &logthis('Check in '.$token.' ('.$dtoken.') unauthorized: '. + $env{'user.name'}.' - '.$env{'user.domain'}); + return ''; + } + + my %infohash=('resource.0.intoken' => $token, + 'resource.0.checkintime' => $now, + 'resource.0.inremote' => $ENV{'REMOTE_ADDR'}); + + unless (&cstore(\%infohash,$symb,$tcrsid,$tudom,$tuname) eq 'ok') { + return ''; + } + + if (&log($tudom,$tuname,&homeserver($tuname,$tudom), + &escape('Checkin - '.$token)) ne 'ok') { + return ''; + } + + return ($symb,$tuname,$tudom,$tcrsid); +} + # --------------------------------------------- Set Expire Date for Spreadsheet sub expirespread { @@ -4779,9 +4941,12 @@ sub restore { if ($stuname) { $home=&homeserver($stuname,$domain); } if (!$symb) { - unless ($symb=escape(&symbread())) { return ''; } + return if ($namespace eq 'courserequests'); + unless ($symb=escape(&symbread())) { return ''; } } else { - $symb=&escape(&symbclean($symb)); + unless ($namespace eq 'courserequests') { + $symb=&escape(&symbclean($symb)); + } } if (!$namespace) { unless ($namespace=$env{'request.course.id'}) { @@ -4916,22 +5081,95 @@ sub update_released_required { # -------------------------------------------------See if a user is privileged sub privileged { - my ($username,$domain)=@_; - - my %rolesdump = &dump("roles", $domain, $username) or return 0; + my ($username,$domain,$possdomains,$possroles)=@_; my $now = time; + my $roles; + if (ref($possroles) eq 'ARRAY') { + $roles = $possroles; + } else { + $roles = ['dc','su']; + } + if (ref($possdomains) eq 'ARRAY') { + my %privileged = &privileged_by_domain($possdomains,$roles); + foreach my $dom (@{$possdomains}) { + if (($username =~ /^$match_username$/) && ($domain =~ /^$match_domain$/) && + (ref($privileged{$dom}) eq 'HASH')) { + foreach my $role (@{$roles}) { + if (ref($privileged{$dom}{$role}) eq 'HASH') { + if (exists($privileged{$dom}{$role}{$username.':'.$domain})) { + my ($end,$start) = split(/:/,$privileged{$dom}{$role}{$username.':'.$domain}); + return 1 unless (($end && $end < $now) || + ($start && $start > $now)); + } + } + } + } + } + } else { + my %rolesdump = &dump("roles", $domain, $username) or return 0; + my $now = time; - for my $role (@rolesdump{grep { ! /^rolesdef_/ } keys %rolesdump}) { + for my $role (@rolesdump{grep { ! /^rolesdef_/ } keys %rolesdump}) { my ($trole, $tend, $tstart) = split(/_/, $role); - if (($trole eq 'dc') || ($trole eq 'su')) { - return 1 unless ($tend && $tend < $now) - or ($tstart && $tstart > $now); + if (grep(/^\Q$trole\E$/,@{$roles})) { + return 1 unless ($tend && $tend < $now) + or ($tstart && $tstart > $now); } - } - + } + } return 0; } +sub privileged_by_domain { + my ($domains,$roles) = @_; + my %privileged = (); + my $cachetime = 60*60*24; + my $now = time; + unless ((ref($domains) eq 'ARRAY') && (ref($roles) eq 'ARRAY')) { + return %privileged; + } + foreach my $dom (@{$domains}) { + next if (ref($privileged{$dom}) eq 'HASH'); + my $needroles; + foreach my $role (@{$roles}) { + my ($result,$cached)=&is_cached_new('priv_'.$role,$dom); + if (defined($cached)) { + if (ref($result) eq 'HASH') { + $privileged{$dom}{$role} = $result; + } + } else { + $needroles = 1; + } + } + if ($needroles) { + my %dompersonnel = &get_domain_roles($dom,$roles); + $privileged{$dom} = {}; + foreach my $server (keys(%dompersonnel)) { + if (ref($dompersonnel{$server}) eq 'HASH') { + foreach my $item (keys(%{$dompersonnel{$server}})) { + my ($trole,$uname,$udom,$rest) = split(/:/,$item,4); + my ($end,$start) = split(/:/,$dompersonnel{$server}{$item}); + next if ($end && $end < $now); + $privileged{$dom}{$trole}{$uname.':'.$udom} = + $dompersonnel{$server}{$item}; + } + } + } + if (ref($privileged{$dom}) eq 'HASH') { + foreach my $role (@{$roles}) { + if (ref($privileged{$dom}{$role}) eq 'HASH') { + &do_cache_new('priv_'.$role,$dom,$privileged{$dom}{$role},$cachetime); + } else { + my %hash = (); + &do_cache_new('priv_'.$role,$dom,\%hash,$cachetime); + } + } + } + } + } + return %privileged; +} + # -------------------------------------------------------- Get user privileges sub rolesinit { @@ -5041,9 +5279,11 @@ sub rolesinit { } sub set_arearole { - my ($trole,$area,$tstart,$tend,$domain,$username) = @_; + my ($trole,$area,$tstart,$tend,$domain,$username,$nolog) = @_; + unless ($nolog) { # log the associated role with the area - &userrolelog($trole,$username,$domain,$area,$tstart,$tend); + &userrolelog($trole,$username,$domain,$area,$tstart,$tend); + } return ('user.role.'.$trole.'.'.$area => $tstart.'.'.$tend); } @@ -5312,7 +5552,7 @@ sub set_adhoc_privileges { my $area = '/'.$dcdom.'/'.$pickedcourse; my $spec = $role.'.'.$area; my %userroles = &set_arearole($role,$area,'','',$env{'user.domain'}, - $env{'user.name'}); + $env{'user.name'},1); my %ccrole = (); &standard_roleprivs(\%ccrole,$role,$dcdom,$spec,$pickedcourse,$area); my ($author,$adv)= &set_userprivs(\%userroles,\%ccrole); @@ -5375,12 +5615,36 @@ sub del { # -------------------------------------------------------------- dump interface +sub unserialize { + my ($rep, $escapedkeys) = @_; + + return {} if $rep =~ /^error/; + + my %returnhash=(); + foreach my $item (split(/\&/,$rep)) { + my ($key, $value) = split(/=/, $item, 2); + $key = unescape($key) unless $escapedkeys; + next if $key =~ /^error: 2 /; + $returnhash{$key} = &thaw_unescape($value); + } + return \%returnhash; +} + +# see Lond::dump_with_regexp +# if $escapedkeys hash keys won't get unescaped. sub dump { - my ($namespace,$udomain,$uname,$regexp,$range)=@_; + my ($namespace,$udomain,$uname,$regexp,$range,$escapedkeys)=@_; if (!$udomain) { $udomain=$env{'user.domain'}; } if (!$uname) { $uname=$env{'user.name'}; } my $uhome=&homeserver($uname,$udomain); + my $reply; + if (grep { $_ eq $uhome } ¤t_machine_ids()) { + # user is hosted on this machine + $reply = LONCAPA::Lond::dump_with_regexp(join(':', ($udomain, + $uname, $namespace, $regexp, $range)), $perlvar{'lonVersion'}); + return %{&unserialize($reply, $escapedkeys)}; + } if ($regexp) { $regexp=&escape($regexp); } else { @@ -5392,7 +5656,7 @@ sub dump { if (!($rep =~ /^error/ )) { foreach my $item (@pairs) { my ($key,$value)=split(/=/,$item,2); - $key = &unescape($key); + $key = &unescape($key) unless ($escapedkeys); next if ($key =~ /^error: 2 /); $returnhash{$key}=&thaw_unescape($value); } @@ -5405,23 +5669,9 @@ sub dump { sub dumpstore { my ($namespace,$udomain,$uname,$regexp,$range)=@_; - if (!$udomain) { $udomain=$env{'user.domain'}; } - if (!$uname) { $uname=$env{'user.name'}; } - my $uhome=&homeserver($uname,$udomain); - if ($regexp) { - $regexp=&escape($regexp); - } else { - $regexp='.'; - } - my $rep=&reply("dump:$udomain:$uname:$namespace:$regexp:$range",$uhome); - my @pairs=split(/\&/,$rep); - my %returnhash=(); - foreach my $item (@pairs) { - my ($key,$value)=split(/=/,$item,2); - next if ($key =~ /^error: 2 /); - $returnhash{$key}=&thaw_unescape($value); - } - return %returnhash; + # same as dump but keys must be escaped. They may contain colon separated + # lists of values that may themself contain colons (e.g. symbs). + return &dump($namespace, $udomain, $uname, $regexp, $range, 1); } # -------------------------------------------------------------- keys interface @@ -6026,6 +6276,7 @@ sub usertools_access { official => 1, unofficial => 1, community => 1, + textbook => 1, ); } elsif ($context eq 'requestauthor') { %tools = ( @@ -6041,7 +6292,7 @@ sub usertools_access { } return if (!defined($tools{$tool})); - if ((!defined($udom)) || (!defined($uname))) { + if (($udom eq '') || ($uname eq '')) { $udom = $env{'user.domain'}; $uname = $env{'user.name'}; } @@ -6851,7 +7102,7 @@ sub constructaccess { if (($allowed eq 'F') || ($allowed eq 'U')) { # Grant temporary access my $then=$env{'user.login.time'}; - my $update==$env{'user.update.time'}; + my $update=$env{'user.update.time'}; if (!$update) { $update = $then; } my $refresh=$env{'user.refresh.time'}; if (!$refresh) { $refresh = $update; } @@ -7132,19 +7383,23 @@ sub definerole { # ---------------- Make a metadata query against the network of library servers sub metadata_query { - my ($query,$custom,$customshow,$server_array)=@_; + my ($query,$custom,$customshow,$server_array,$domains_hash)=@_; my %rhash; my %libserv = &all_library(); my @server_list = (defined($server_array) ? @$server_array : keys(%libserv) ); for my $server (@server_list) { + my $domains = ''; + if (ref($domains_hash) eq 'HASH') { + $domains = $domains_hash->{$server}; + } unless ($custom or $customshow) { - my $reply=&reply("querysend:".&escape($query),$server); + my $reply=&reply("querysend:".&escape($query).':::'.&escape($domains),$server); $rhash{$server}=$reply; } else { my $reply=&reply("querysend:".&escape($query).':'. - &escape($custom).':'.&escape($customshow), + &escape($custom).':'.&escape($customshow).':'.&escape($domains), $server); $rhash{$server}=$reply; } @@ -7390,8 +7645,8 @@ sub auto_validate_instcode { } $response=&unescape(&reply('autovalidateinstcode:'.$cdom.':'. &escape($instcode).':'.&escape($owner),$homeserver)); - my ($outcome,$description) = map { &unescape($_); } split('&',$response,2); - return ($outcome,$description); + my ($outcome,$description,$defaultcredits) = map { &unescape($_); } split('&',$response,3); + return ($outcome,$description,$defaultcredits); } sub auto_create_password { @@ -8331,7 +8586,7 @@ sub modifyuser { sub modifystudent { my ($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene,$usec, $end,$start,$forceid,$desiredhome,$email,$type,$locktype,$cid, - $selfenroll,$context,$inststatus)=@_; + $selfenroll,$context,$inststatus,$credits)=@_; if (!$cid) { unless ($cid=$env{'request.course.id'}) { return 'not_in_class'; @@ -8343,15 +8598,17 @@ sub modifystudent { $desiredhome,$email,$inststatus); unless ($reply eq 'ok') { return $reply; } # This will cause &modify_student_enrollment to get the uid from the - # students environment + # student's environment $uid = undef if (!$forceid); $reply = &modify_student_enrollment($udom,$uname,$uid,$first,$middle,$last, - $gene,$usec,$end,$start,$type,$locktype,$cid,$selfenroll,$context); + $gene,$usec,$end,$start,$type,$locktype, + $cid,$selfenroll,$context,$credits); return $reply; } sub modify_student_enrollment { - my ($udom,$uname,$uid,$first,$middle,$last,$gene,$usec,$end,$start,$type,$locktype,$cid,$selfenroll,$context) = @_; + my ($udom,$uname,$uid,$first,$middle,$last,$gene,$usec,$end,$start,$type, + $locktype,$cid,$selfenroll,$context,$credits) = @_; my ($cdom,$cnum,$chome); if (!$cid) { unless ($cid=$env{'request.course.id'}) { @@ -8398,7 +8655,7 @@ sub modify_student_enrollment { my %old_entry = &Apache::lonnet::get('classlist',[$user],$cdom,$cnum); my $reply=cput('classlist', {$user => - join(':',$end,$start,$uid,$usec,$fullname,$type,$locktype) }, + join(':',$end,$start,$uid,$usec,$fullname,$type,$locktype,$credits) }, $cdom,$cnum); if (($reply eq 'ok') || ($reply eq 'delayed')) { &devalidate_getsection_cache($udom,$uname,$cid); @@ -8627,7 +8884,7 @@ sub is_course { my %courses = &courseiddump($cdom, '.', 1, '.', '.', $cnum, undef, undef, '.'); - return unless exists($courses{$cdom.'_'.$cnum}); + return unless(exists($courses{$cdom.'_'.$cnum})); return wantarray ? ($cdom, $cnum) : $cdom.'_'.$cnum; } @@ -8652,6 +8909,9 @@ sub store_userdata { $namevalue.=&escape($key).'='.&freeze_escape($$storehash{$key}).'&'; } $namevalue=~s/\&$//; + unless ($namespace eq 'courserequests') { + $datakey = &escape($datakey); + } $result = &reply("store:$udom:$uname:$namespace:$datakey:". $namevalue,$uhome); } @@ -9474,6 +9734,26 @@ sub resdata { return undef; } +sub get_numsuppfiles { + my ($cnum,$cdom,$ignorecache)=@_; + my $hashid=$cnum.':'.$cdom; + my ($suppcount,$cached); + unless ($ignorecache) { + ($suppcount,$cached) = &is_cached_new('suppcount',$hashid); + } + unless (defined($cached)) { + my $chome=&homeserver($cnum,$cdom); + unless ($chome eq 'no_host') { + ($suppcount,my $errors) = (0,0); + my $suppmap = 'supplemental.sequence'; + ($suppcount,$errors) = + &Apache::loncommon::recurse_supplemental($cnum,$cdom,$suppmap,$suppcount,$errors); + } + &do_cache_new('suppcount',$hashid,$suppcount,600); + } + return $suppcount; +} + # # EXT resource caching routines # @@ -9502,7 +9782,7 @@ sub EXT_cache_set { # --------------------------------------------------------- Value of a Variable sub EXT { - my ($varname,$symbparm,$udom,$uname,$usection,$recurse)=@_; + my ($varname,$symbparm,$udom,$uname,$usection,$recurse,$cid)=@_; unless ($varname) { return ''; } #get real user name/domain, courseid and symb my $courseid; @@ -9617,26 +9897,51 @@ sub EXT { if (!$symbparm) { $symbparm=&symbread(); } } - if ($space eq 'title') { - if (!$symbparm) { $symbparm = $env{'request.filename'}; } - return &gettitle($symbparm); - } + if ($qualifier eq '') { + if ($space eq 'title') { + if (!$symbparm) { $symbparm = $env{'request.filename'}; } + return &gettitle($symbparm); + } - if ($space eq 'map') { - my ($map) = &decode_symb($symbparm); - return &symbread($map); - } - if ($space eq 'filename') { - if ($symbparm) { - return &clutter((&decode_symb($symbparm))[2]); + if ($space eq 'map') { + my ($map) = &decode_symb($symbparm); + return &symbread($map); + } + if ($space eq 'maptitle') { + my ($map) = &decode_symb($symbparm); + return &gettitle($map); + } + if ($space eq 'filename') { + if ($symbparm) { + return &clutter((&decode_symb($symbparm))[2]); + } + return &hreflocation('',$env{'request.filename'}); } - return &hreflocation('',$env{'request.filename'}); - } + + if ((defined($courseid)) && ($courseid eq $env{'request.course.id'}) && $symbparm) { + if ($space eq 'visibleparts') { + my $navmap = Apache::lonnavmaps::navmap->new(); + my $item; + if (ref($navmap)) { + my $res = $navmap->getBySymb($symbparm); + my $parts = $res->parts(); + if (ref($parts) eq 'ARRAY') { + $item = join(',',@{$parts}); + } + undef($navmap); + } + return $item; + } + } + } my ($section, $group, @groups); my ($courselevelm,$courselevel); - if ($symbparm && defined($courseid) && - $courseid eq $env{'request.course.id'}) { + if (($courseid eq '') && ($cid)) { + $courseid = $cid; + } + if (($symbparm && $courseid) && + (($courseid eq $env{'request.course.id'}) || ($courseid eq $cid))) { #print '
'.$space.' - '.$qualifier.' - '.$spacequalifierrest; @@ -9883,7 +10188,7 @@ sub metadata { # if it is a non metadata possible uri return quickly if (($uri eq '') || (($uri =~ m|^/*adm/|) && - ($uri !~ m|^adm/includes|) && ($uri !~ m|/bulletinboard$|)) || + ($uri !~ m|^adm/includes|) && ($uri !~ m{/(smppg|bulletinboard)$})) || ($uri =~ m|/$|) || ($uri =~ m|/.meta$|) || ($uri =~ m{^/*uploaded/.+\.sequence$})) { return undef; } @@ -10261,78 +10566,6 @@ sub gettitle { return $title; } -sub getdocspath { - my ($symb) = @_; - my $path; - if ($symb) { - my ($mapurl,$id,$resurl) = &decode_symb($symb); - if ($resurl=~/\.(sequence|page)$/) { - $mapurl=$resurl; - } elsif ($resurl eq 'adm/navmaps') { - $mapurl=$env{'course.'.$env{'request.course.id'}.'.url'}; - } - my $mapresobj; - my $navmap = Apache::lonnavmaps::navmap->new(); - if (ref($navmap)) { - $mapresobj = $navmap->getResourceByUrl($mapurl); - } - $mapurl=~s{^.*/([^/]+)\.(\w+)$}{$1}; - my $type=$2; - if (ref($mapresobj)) { - my $pcslist = $mapresobj->map_hierarchy(); - if ($pcslist ne '') { - foreach my $pc (split(/,/,$pcslist)) { - next if ($pc <= 1); - my $res = $navmap->getByMapPc($pc); - if (ref($res)) { - my $thisurl = $res->src(); - $thisurl=~s{^.*/([^/]+)\.\w+$}{$1}; - my $thistitle = $res->title(); - $path .= '&'. - &Apache::lonhtmlcommon::entity_encode($thisurl).'&'. - &Apache::lonhtmlcommon::entity_encode($thistitle). - ':'.$res->randompick(). - ':'.$res->randomout(). - ':'.$res->encrypted(). - ':'.$res->randomorder(). - ':'.$res->is_page(); - } - } - } - $path =~ s/^\&//; - my $maptitle = $mapresobj->title(); - if ($mapurl eq 'default') { - $maptitle = 'Main Course Documents'; - } - $path .= ($path ne '')? '&' : ''. - &Apache::lonhtmlcommon::entity_encode($mapurl).'&'. - &Apache::lonhtmlcommon::entity_encode($maptitle). - ':'.$mapresobj->randompick(). - ':'.$mapresobj->randomout(). - ':'.$mapresobj->encrypted(). - ':'.$mapresobj->randomorder(). - ':'.$mapresobj->is_page(); - } else { - my $maptitle = &gettitle($mapurl); - my $ispage; - if ($mapurl =~ /\.page$/) { - $ispage = 1; - } - if ($mapurl eq 'default') { - $maptitle = 'Main Course Documents'; - } - $path = &Apache::lonhtmlcommon::entity_encode($mapurl).'&'. - &Apache::lonhtmlcommon::entity_encode($maptitle).':::::'.$ispage; - } - unless ($mapurl eq 'default') { - $path = 'default&'. - &Apache::lonhtmlcommon::entity_encode('Main Course Documents'). - ':::::&'.$path; - } - } - return $path; -} - sub get_slot { my ($which,$cnum,$cdom)=@_; if (!$cnum || !$cdom) { @@ -10386,7 +10619,7 @@ sub get_course_slots { my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum); my ($tmp) = keys(%slots); if ($tmp !~ /^(con_lost|error|no_such_host)/i) { - &Apache::lonnet::do_cache_new('allslots',$hashid,\%slots,600); + &do_cache_new('allslots',$hashid,\%slots,600); return %slots; } } @@ -11513,12 +11746,12 @@ sub goodbye { } sub get_dns { - my ($url,$func,$ignore_cache) = @_; + my ($url,$func,$ignore_cache,$nocache,$hashref) = @_; if (!$ignore_cache) { my ($content,$cached)= &Apache::lonnet::is_cached_new('dns',$url); if ($cached) { - &$func($content); + &$func($content,$hashref); return; } } @@ -11543,8 +11776,10 @@ sub get_dns { delete($alldns{$dns}); next if ($response->is_error()); my @content = split("\n",$response->content); - &Apache::lonnet::do_cache_new('dns',$url,\@content,30*24*60*60); - &$func(\@content); + unless ($nocache) { + &do_cache_new('dns',$url,\@content,30*24*60*60); + } + &$func(\@content,$hashref); return; } close($config); @@ -11552,9 +11787,47 @@ sub get_dns { &logthis("unable to contact DNS defaulting to on disk file dns_$which.tab\n"); open($config,"<$perlvar{'lonTabDir'}/dns_$which.tab"); my @content = <$config>; - &$func(\@content); + &$func(\@content,$hashref); + return; +} + +# ------------------------------------------------------Get DNS checksums file +sub parse_dns_checksums_tab { + my ($lines,$hashref) = @_; + my $machine_dom = &Apache::lonnet::host_domain($perlvar{'lonHostID'}); + my $loncaparev = &get_server_loncaparev($machine_dom); + my ($release,$timestamp) = split(/\-/,$loncaparev); + my (%chksum,%revnum); + if (ref($lines) eq 'ARRAY') { + chomp(@{$lines}); + my $version = shift(@{$lines}); + if ($version eq $release) { + foreach my $line (@{$lines}) { + my ($file,$version,$shasum) = split(/,/,$line); + $chksum{$file} = $shasum; + $revnum{$file} = $version; + } + if (ref($hashref) eq 'HASH') { + %{$hashref} = ( + sums => \%chksum, + versions => \%revnum, + ); + } + } + } return; } + +sub fetch_dns_checksums { + my %checksums; + my $machine_dom = &Apache::lonnet::host_domain($perlvar{'lonHostID'}); + my $loncaparev = &get_server_loncaparev($machine_dom); + my ($release,$timestamp) = split(/\-/,$loncaparev); + &get_dns("/adm/dns/checksums/$release",\&parse_dns_checksums_tab,1,1, + \%checksums); + return \%checksums; +} + # ------------------------------------------------------------ Read domain file { my $loaded; @@ -11864,9 +12137,9 @@ sub get_dns { } push(@{$iphost{$ip}},@{$name_to_host{$name}}); } - &Apache::lonnet::do_cache_new('iphost','iphost', - [\%iphost,\%name_to_ip,\%lonid_to_ip], - 48*60*60); + &do_cache_new('iphost','iphost', + [\%iphost,\%name_to_ip,\%lonid_to_ip], + 48*60*60); return %iphost; } @@ -11922,7 +12195,7 @@ sub get_dns { } $seen{$prim_ip} = 1; } - return &Apache::lonnet::do_cache_new('internetnames',$lonid,\@idns,12*60*60); + return &do_cache_new('internetnames',$lonid,\@idns,12*60*60); } } @@ -11931,6 +12204,39 @@ sub all_loncaparevs { return qw(1.1 1.2 1.3 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10); } +# ------------------------------------------------------- Read loncaparev table +{ + sub load_loncaparevs { + if (-e "$perlvar{'lonTabDir'}/loncaparevs.tab") { + if (open(my $config,"<$perlvar{'lonTabDir'}/loncaparevs.tab")) { + while (my $configline=<$config>) { + chomp($configline); + my ($hostid,$loncaparev)=split(/:/,$configline); + $loncaparevs{$hostid}=$loncaparev; + } + close($config); + } + } + } +} + +# ----------------------------------------------------- Read serverhostID table +{ + sub load_serverhomeIDs { + if (-e "$perlvar{'lonTabDir'}/serverhomeIDs.tab") { + if (open(my $config,"<$perlvar{'lonTabDir'}/serverhomeIDs.tab")) { + while (my $configline=<$config>) { + chomp($configline); + my ($name,$id)=split(/:/,$configline); + $serverhomeIDs{$name}=$id; + } + close($config); + } + } + } +} + + BEGIN { # ----------------------------------- Read loncapa.conf and loncapa_apache.conf @@ -12006,34 +12312,15 @@ BEGIN { close($config); } -# ---------------------------------------------------------- Read loncaparev table -{ - if (-e "$perlvar{'lonTabDir'}/loncaparevs.tab") { - if (open(my $config,"<$perlvar{'lonTabDir'}/loncaparevs.tab")) { - while (my $configline=<$config>) { - chomp($configline); - my ($hostid,$loncaparev)=split(/:/,$configline); - $loncaparevs{$hostid}=$loncaparev; - } - close($config); - } - } -} +# --------------------------------------------------------- Read loncaparev table -# ---------------------------------------------------------- Read serverhostID table -{ - if (-e "$perlvar{'lonTabDir'}/serverhomeIDs.tab") { - if (open(my $config,"<$perlvar{'lonTabDir'}/serverhomeIDs.tab")) { - while (my $configline=<$config>) { - chomp($configline); - my ($name,$id)=split(/:/,$configline); - $serverhomeIDs{$name}=$id; - } - close($config); - } - } -} +&load_loncaparevs(); + +# ------------------------------------------------------- Read serverhostID table +&load_serverhomeIDs(); + +# ---------------------------------------------------------- Read releaseslist XML { my $file = $Apache::lonnet::perlvar{'lonTabDir'}.'/releaseslist.xml'; if (-e $file) { @@ -12232,8 +12519,8 @@ were new keys. I.E. 1:foo will become 1: Calling convention: - my %record=&Apache::lonnet::restore($symb,$courseid,$domain,$uname,$home); - &Apache::lonnet::cstore(\%newrecord,$symb,$courseid,$domain,$uname,$home); + my %record=&Apache::lonnet::restore($symb,$courseid,$domain,$uname); + &Apache::lonnet::cstore(\%newrecord,$symb,$courseid,$domain,$uname); For more detailed information, see lonnet specific documentation. @@ -12410,7 +12697,7 @@ environment). If no custom name is defi =item * -get_my_roles($uname,$udom,$context,$types,$roles,$roledoms,$withsec) : +get_my_roles($uname,$udom,$context,$types,$roles,$roledoms,$withsec,$hidepriv) : All arguments are optional. Returns a hash of a roles, either for co-author/assistant author roles for a user's Construction Space (default), or if $context is 'userroles', roles for the user himself, @@ -12433,7 +12720,31 @@ Additional optional arguments are: $type to certain user status types -- previous (expired roles), active (currently available roles) or future (roles available in the future), and $hideprivileged -- if true will not report course roles for users who -have active Domain Coordinator or Super User roles. +have active Domain Coordinator role in course's domain or in additional +domains (specified in 'Domains to check for privileged users' in course +environment -- set via: Course Settings -> Classlists and staff listing). + +=item * + +privileged($username,$domain,$possdomains,$possroles) : returns 1 if user +$username:$domain is a privileged user (e.g., Domain Coordinator or Super User) +$possdomains and $possroles are optional array refs -- to domains to check and +roles to check. If $possdomains is not specified, a dump will be done of the +users' roles.db to check for a dc or su role in any domain. This can be +time consuming if &privileged is called repeatedly (e.g., when displaying a +classlist), so in such cases, supplying a $possdomains array is preferred, as +this then allows &privileged_by_domain() to be used, which caches the identity +of privileged users, eliminating the need for repeated calls to &dump(). + +=item * + +privileged_by_domain($possdomains,$roles) : returns a hash of a hash of a hash, +where the outer hash keys are domains specified in the $possdomains array ref, +next inner hash keys are privileged roles specified in the $roles array ref, +and the innermost hash contains key = value pairs for username:domain = end:start +for active or future "privileged" users with that role in that domain. To avoid +repeated dumps of domain roles -- via &get_domain_roles() -- contents of the +innerhash are cached using priv_$role and $dom as the identifiers. =back @@ -12476,8 +12787,8 @@ or when Autoupdate.pl is run by cron in modifystudent modify a student's enrollment and identification information. -The course id is resolved based on the current users environment. -This means the envoking user must be a course coordinator or otherwise +The course id is resolved based on the current user's environment. +This means the invoking user must be a course coordinator or otherwise associated with a course. This call is essentially a wrapper for lonnet::modifyuser and @@ -12527,7 +12838,9 @@ Inputs: =item B<$context> role change context (shown in User Management Logs display in a course) -=item B<$inststatus> institutional status of user - : separated string of escaped status types +=item B<$inststatus> institutional status of user - : separated string of escaped status types + +=item B<$credits> Number of credits student will earn from this class - only needs to be supplied if value needs to be different from default credits for class. =back @@ -12535,20 +12848,20 @@ Inputs: modify_student_enrollment -Change a students enrollment status in a class. The environment variable +Change a student's enrollment status in a class. The environment variable 'role.request.course' must be defined for this function to proceed. Inputs: =over 4 -=item $udom, students domain +=item $udom, student's domain -=item $uname, students name +=item $uname, student's name -=item $uid, students user id +=item $uid, student's user id -=item $first, students first name +=item $first, student's first name =item $middle @@ -12572,6 +12885,8 @@ Inputs: =item $context +=item $credits, number of credits student will earn from this class + =back @@ -12628,7 +12943,7 @@ If defined, the supplied username is use resdata($name,$domain,$type,@which) : request for current parameter setting for a specific $type, where $type is either 'course' or 'user', @what should be a list of parameters to ask about. This routine caches -answers for 5 minutes. +answers for 10 minutes. =item * @@ -12637,6 +12952,10 @@ data base, returning a hash that is keye values that are the resource value. I believe that the timestamps and versions are also returned. +get_numsuppfiles($cnum,$cdom) : retrieve number of files in a course's +supplemental content area. This routine caches the number of files for +10 minutes. + =back =head2 Course Modification @@ -12696,10 +13015,15 @@ resource. Expects the local filesystem p =item * -EXT($varname,$symb,$udom,$uname) : evaluates and returns the value of -a vairety of different possible values, $varname should be a request -string, and the other parameters can be used to specify who and what -one is asking about. +EXT($varname,$symb,$udom,$uname,$usection,$recurse,$cid) : evaluates +and returns the value of a variety of different possible values, +$varname should be a request string, and the other parameters can be +used to specify who and what one is asking about. Ordinarily, $cid +does not need to be specified, as it is retrived from +$env{'request.course.id'}, but &Apache::lonnet::EXT() is called +within lonuserstate::loadmap() when initializing a course, before +$env{'request.course.id'} has been set, so it needs to be provided +in that one case. Possible values for $varname are environment.lastname (or other item from the envirnment hash), user.name (or someother aspect about the @@ -12737,7 +13061,7 @@ returns the data handle =item * -symbverify($symb,$thisfn,$ecstate) : verifies that $symb actually exists +symbverify($symb,$thisfn,$encstate) : verifies that $symb actually exists and is a possible symb for the URL in $thisfn, and if is an encrypted resource that the user accessed using /enc/ returns a 1 on success, 0 on failure, user must be in a course, as it assumes the existence of @@ -12977,15 +13301,90 @@ server ($udom and $uhome are optional) =item * -get_domain_defaults($target_domain) : returns hash with defaults for -authentication and language in the domain. Keys are: auth_def, auth_arg_def, -lang_def; corresponsing values are authentication type (internal, krb4, krb5, -or localauth), initial password or a kerberos realm, language (e.g., en-us). -Values are retrieved from cache (if current), or from domain's configuration.db -(if available), or lastly from values in lonTabs/dns_domain,tab, -or lonTabs/domain.tab. +get_domain_defaults($target_domain,$ignore_cache) : returns hash with defaults +for: authentication, language, quotas, timezone, date locale, and portal URL in +the target domain. + +May also include additional key => value pairs for the following groups: + +=over + +=item +disk quotas (MB allocated by default to portfolios and authoring spaces). + +=over + +=item defaultquota, authorquota + +=back + +=item +tools (availability of aboutme page, blog, webDAV access for authoring spaces, +portfolio for users). + +=over + +=item +aboutme, blog, webdav, portfolio + +=back + +=item +requestcourses: ability to request courses, and how requests are processed. + +=over + +=item +official, unofficial, community, textbook + +=back + +=item +inststatus: types of institutional affiliation, and order in which they are displayed. + +=over + +=item +inststatustypes, inststatusorder + +=back + +=item +coursedefaults: can PDF forms can be created, default credits for courses, default quotas (MB) +for course's uploaded content. + +=over + +=item +canuse_pdfforms, officialcredits, unofficialcredits, textbookcredits, officialquota, unofficialquota, communityquota, textbookquota + +=back + +=item +usersessions: set options for hosting of your users in other domains, and hosting of users from other domains +on your servers. + +=over + +=item +remotesessions, hostedsessions + +=back + +=back + +In cases where a domain coordinator has never used the "Set Domain Configuration" +utility to create a configuration.db file on a domain's primary library server +only the following domain defaults: auth_def, auth_arg_def, lang_def +-- corresponding values are authentication type (internal, krb4, krb5, +or localauth), initial password or a kerberos realm, language (e.g., en-us) -- +will be available. Values are retrieved from cache (if current), unless the +optional $ignore_cache arg is true, or from domain's configuration.db (if available), +or lastly from values in lonTabs/dns_domain,tab, or lonTabs/domain.tab. + +Typical usage: -%domdefaults = &get_auth_defaults($target_domain); +%domdefaults = &get_domain_defaults($target_domain); =back