--- loncom/lonnet/perl/lonnet.pm 2006/08/31 12:27:18 1.776
+++ loncom/lonnet/perl/lonnet.pm 2007/03/01 17:51:56 1.837
@@ -1,7 +1,7 @@
# The LearningOnline Network
# TCP networking package
#
-# $Id: lonnet.pm,v 1.776 2006/08/31 12:27:18 albertel Exp $
+# $Id: lonnet.pm,v 1.837 2007/03/01 17:51:56 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -52,8 +52,8 @@ use Storable qw(lock_store lock_nstore l
use Time::HiRes qw( gettimeofday tv_interval );
use Cache::Memcached;
use Digest::MD5;
-use lib '/home/httpd/lib/perl';
-use LONCAPA;
+use Math::Random;
+use LONCAPA qw(:DEFAULT :match);
use LONCAPA::Configuration;
my $readit;
@@ -201,8 +201,7 @@ sub reply {
# ----------------------------------------------------------- Send USR1 to lonc
sub reconlonc {
- my $peerfile=shift;
- &logthis("Trying to reconnect for $peerfile");
+ &logthis("Trying to reconnect lonc");
my $loncfile="$perlvar{'lonDaemons'}/logs/lonc.pid";
if (open(my $fh,"<$loncfile")) {
my $loncpid=<$fh>;
@@ -211,19 +210,13 @@ sub reconlonc {
&logthis("lonc at pid $loncpid responding, sending USR1");
kill USR1 => $loncpid;
sleep 1;
- if (-e "$peerfile") { return; }
- &logthis("$peerfile still not there, give it another try");
- sleep 5;
- if (-e "$peerfile") { return; }
- &logthis(
- "WARNING: $peerfile still not there, giving up");
- } else {
+ } else {
&logthis(
"WARNING:".
" lonc at pid $loncpid not responding, giving up");
}
} else {
- &logthis('WARNING: lonc not running, giving up');
+ &logthis('WARNING: lonc not running, giving up');
}
}
@@ -292,10 +285,40 @@ sub error {
return undef;
}
-# ------------------------------------------- Transfer profile into environment
+sub convert_and_load_session_env {
+ my ($lonidsdir,$handle)=@_;
+ my @profile;
+ {
+ open(my $idf,"$lonidsdir/$handle.id");
+ flock($idf,LOCK_SH);
+ @profile=<$idf>;
+ close($idf);
+ }
+ my %temp_env;
+ foreach my $line (@profile) {
+ if ($line !~ m/=/) {
+ return 0;
+ }
+ chomp($line);
+ my ($envname,$envvalue)=split(/=/,$line,2);
+ $temp_env{&unescape($envname)} = &unescape($envvalue);
+ }
+ unlink("$lonidsdir/$handle.id");
+ if (tie(my %disk_env,'GDBM_File',"$lonidsdir/$handle.id",&GDBM_WRCREAT(),
+ 0640)) {
+ %disk_env = %temp_env;
+ @env{keys(%temp_env)} = @disk_env{keys(%temp_env)};
+ untie(%disk_env);
+ }
+ return 1;
+}
+# ------------------------------------------- Transfer profile into environment
+my $env_loaded;
sub transfer_profile_to_env {
- my ($lonidsdir,$handle)=@_;
+ my ($lonidsdir,$handle,$force_transfer) = @_;
+ if (!$force_transfer && $env_loaded) { return; }
+
if (!defined($lonidsdir)) {
$lonidsdir = $perlvar{'lonIDsDir'};
}
@@ -303,33 +326,60 @@ sub transfer_profile_to_env {
($handle) = ($env{'user.environment'} =~m|/([^/]+)\.id$| );
}
- my @profile;
+ my $convert;
{
- open(my $idf,"$lonidsdir/$handle.id");
+ open(my $idf,"$lonidsdir/$handle.id");
flock($idf,LOCK_SH);
- @profile=<$idf>;
- close($idf);
+ if (tie(my %disk_env,'GDBM_File',"$lonidsdir/$handle.id",
+ &GDBM_READER(),0640)) {
+ @env{keys(%disk_env)} = @disk_env{keys(%disk_env)};
+ untie(%disk_env);
+ } else {
+ $convert = 1;
+ }
+ }
+ if ($convert) {
+ if (!&convert_and_load_session_env($lonidsdir,$handle)) {
+ &logthis("Failed to load session, or convert session.");
+ }
}
- my $envi;
- my %Remove;
- for ($envi=0;$envi<=$#profile;$envi++) {
- chomp($profile[$envi]);
- my ($envname,$envvalue)=split(/=/,$profile[$envi],2);
- $envname=&unescape($envname);
- $envvalue=&unescape($envvalue);
- $env{$envname} = $envvalue;
+
+ my %remove;
+ while ( my $envname = each(%env) ) {
if (my ($key,$time) = ($envname =~ /^(cgi\.(\d+)_\d+\.)/)) {
if ($time < time-300) {
- $Remove{$key}++;
+ $remove{$key}++;
}
}
}
+
$env{'user.environment'} = "$lonidsdir/$handle.id";
- foreach my $expired_key (keys(%Remove)) {
+ $env_loaded=1;
+ foreach my $expired_key (keys(%remove)) {
&delenv($expired_key);
}
}
+sub timed_flock {
+ my ($file,$lock_type) = @_;
+ my $failed=0;
+ eval {
+ local $SIG{__DIE__}='DEFAULT';
+ local $SIG{ALRM}=sub {
+ $failed=1;
+ die("failed lock");
+ };
+ alarm(13);
+ flock($file,$lock_type);
+ alarm(0);
+ };
+ if ($failed) {
+ return undef;
+ } else {
+ return 1;
+ }
+}
+
# ---------------------------------------------------------- Append Environment
sub appenv {
@@ -344,51 +394,16 @@ sub appenv {
$env{$key}=$newenv{$key};
}
}
-
- my $lockfh;
- unless (open($lockfh,"$env{'user.environment'}")) {
- return 'error: '.$!;
- }
- unless (flock($lockfh,LOCK_EX)) {
- &logthis("WARNING: ".
- 'Could not obtain exclusive lock in appenv: '.$!);
- close($lockfh);
- return 'error: '.$!;
- }
-
- my @oldenv;
- {
- my $fh;
- unless (open($fh,"$env{'user.environment'}")) {
- return 'error: '.$!;
- }
- @oldenv=<$fh>;
- close($fh);
- }
- for (my $i=0; $i<=$#oldenv; $i++) {
- chomp($oldenv[$i]);
- if ($oldenv[$i] ne '') {
- my ($name,$value)=split(/=/,$oldenv[$i],2);
- $name=&unescape($name);
- $value=&unescape($value);
- unless (defined($newenv{$name})) {
- $newenv{$name}=$value;
- }
- }
- }
- {
- my $fh;
- unless (open($fh,">$env{'user.environment'}")) {
- return 'error';
- }
- my $newname;
- foreach $newname (keys %newenv) {
- print $fh &escape($newname).'='.&escape($newenv{$newname})."\n";
+ open(my $env_file,$env{'user.environment'});
+ if (&timed_flock($env_file,LOCK_EX)
+ &&
+ tie(my %disk_env,'GDBM_File',$env{'user.environment'},
+ (&GDBM_WRITER()|&GDBM_NOLOCK()),0640)) {
+ while (my ($key,$value) = each(%newenv)) {
+ $disk_env{$key} = $value;
}
- close($fh);
+ untie(%disk_env);
}
-
- close($lockfh);
return 'ok';
}
# ----------------------------------------------------- Delete from Environment
@@ -400,47 +415,36 @@ sub delenv {
"Attempt to delete from environment ".$delthis);
return 'error';
}
- my @oldenv;
- {
- my $fh;
- unless (open($fh,"$env{'user.environment'}")) {
- return 'error';
- }
- unless (flock($fh,LOCK_SH)) {
- &logthis("WARNING: ".
- 'Could not obtain shared lock in delenv: '.$!);
- close($fh);
- return 'error: '.$!;
- }
- @oldenv=<$fh>;
- close($fh);
- }
- {
- my $fh;
- unless (open($fh,">$env{'user.environment'}")) {
- return 'error';
- }
- unless (flock($fh,LOCK_EX)) {
- &logthis("WARNING: ".
- 'Could not obtain exclusive lock in delenv: '.$!);
- close($fh);
- return 'error: '.$!;
- }
- foreach my $cur_key (@oldenv) {
- my $unescaped_cur_key = &unescape($cur_key);
- if ($unescaped_cur_key=~/^$delthis/) {
- my ($key) = split('=',$cur_key,2);
- $key = &unescape($key);
+ open(my $env_file,$env{'user.environment'});
+ if (&timed_flock($env_file,LOCK_EX)
+ &&
+ tie(my %disk_env,'GDBM_File',$env{'user.environment'},
+ (&GDBM_WRITER()|&GDBM_NOLOCK()),0640)) {
+ foreach my $key (keys(%disk_env)) {
+ if ($key=~/^$delthis/) {
delete($env{$key});
- } else {
- print $fh $cur_key;
+ delete($disk_env{$key});
}
}
- close($fh);
+ untie(%disk_env);
}
return 'ok';
}
+sub get_env_multiple {
+ my ($name) = @_;
+ my @values;
+ if (defined($env{$name})) {
+ # exists is it an array
+ if (ref($env{$name})) {
+ @values=@{ $env{$name} };
+ } else {
+ $values[0]=$env{$name};
+ }
+ }
+ return(@values);
+}
+
# ------------------------------------------ Find out current server userload
# there is a copy in lond
sub userload {
@@ -493,48 +497,67 @@ sub overloaderror {
sub spareserver {
my ($loadpercent,$userloadpercent,$want_server_name) = @_;
- my $tryserver;
- my $spareserver='';
+ my $spare_server;
if ($userloadpercent !~ /\d/) { $userloadpercent=0; }
- my $lowestserver=$loadpercent > $userloadpercent?
- $loadpercent : $userloadpercent;
- foreach $tryserver (keys(%spareid)) {
- my $loadans=&reply('load',$tryserver);
- my $userloadans=&reply('userload',$tryserver);
- if ($loadans !~ /\d/ && $userloadans !~ /\d/) {
- next; #didn't get a number from the server
- }
- my $answer;
- if ($loadans =~ /\d/) {
- if ($userloadans =~ /\d/) {
- #both are numbers, pick the bigger one
- $answer=$loadans > $userloadans?
- $loadans : $userloadans;
- } else {
- $answer = $loadans;
- }
- } else {
- $answer = $userloadans;
- }
- if (($answer =~ /\d/) && ($answer<$lowestserver)) {
- if ($want_server_name) {
- $spareserver=$tryserver;
- } else {
- $spareserver="http://$hostname{$tryserver}";
- }
- $lowestserver=$answer;
+ my $lowest_load=($loadpercent > $userloadpercent) ? $loadpercent
+ : $userloadpercent;
+
+ foreach my $try_server (@{ $spareid{'primary'} }) {
+ ($spare_server, $lowest_load) =
+ &compare_server_load($try_server, $spare_server, $lowest_load);
+ }
+
+ my $found_server = ($spare_server ne '' && $lowest_load < 100);
+
+ if (!$found_server) {
+ foreach my $try_server (@{ $spareid{'default'} }) {
+ ($spare_server, $lowest_load) =
+ &compare_server_load($try_server, $spare_server, $lowest_load);
}
}
- return $spareserver;
+
+ if (!$want_server_name) {
+ $spare_server="http://$hostname{$spare_server}";
+ }
+ return $spare_server;
}
+sub compare_server_load {
+ my ($try_server, $spare_server, $lowest_load) = @_;
+
+ my $loadans = &reply('load', $try_server);
+ my $userloadans = &reply('userload',$try_server);
+
+ if ($loadans !~ /\d/ && $userloadans !~ /\d/) {
+ next; #didn't get a number from the server
+ }
+
+ my $load;
+ if ($loadans =~ /\d/) {
+ if ($userloadans =~ /\d/) {
+ #both are numbers, pick the bigger one
+ $load = ($loadans > $userloadans) ? $loadans
+ : $userloadans;
+ } else {
+ $load = $loadans;
+ }
+ } else {
+ $load = $userloadans;
+ }
+
+ if (($load =~ /\d/) && ($load < $lowest_load)) {
+ $spare_server = $try_server;
+ $lowest_load = $load;
+ }
+ return ($spare_server,$lowest_load);
+}
# --------------------------------------------- Try to change a user's password
sub changepass {
- my ($uname,$udom,$currentpass,$newpass,$server)=@_;
+ my ($uname,$udom,$currentpass,$newpass,$server,$context)=@_;
$currentpass = &escape($currentpass);
$newpass = &escape($newpass);
- my $answer = reply("encrypt:passwd:$udom:$uname:$currentpass:$newpass",
+ my $answer = reply("encrypt:passwd:$udom:$uname:$currentpass:$newpass:$context",
$server);
if (! $answer) {
&logthis("No reply on password change request to $server ".
@@ -583,11 +606,17 @@ sub queryauthenticate {
sub authenticate {
my ($uname,$upass,$udom)=@_;
- $upass=escape($upass);
- $uname=~s/\W//g;
- my $uhome=&homeserver($uname,$udom);
- if (!$uhome) {
- &logthis("User $uname at $udom is unknown in authenticate");
+ $upass=&escape($upass);
+ $uname= &LONCAPA::clean_username($uname);
+ my $uhome=&homeserver($uname,$udom,1);
+ if ((!$uhome) || ($uhome eq 'no_host')) {
+# Maybe the machine was offline and only re-appeared again recently?
+ &reconlonc();
+# One more
+ my $uhome=&homeserver($uname,$udom,1);
+ if ((!$uhome) || ($uhome eq 'no_host')) {
+ &logthis("User $uname at $udom is unknown in authenticate");
+ }
return 'no_host';
}
my $answer=reply("encrypt:auth:$udom:$uname:$upass",$uhome);
@@ -617,7 +646,8 @@ sub homeserver {
exists($badServerCache{$tryserver}));
if ($hostdom{$tryserver} eq $udom) {
my $answer=reply("home:$udom:$uname",$tryserver);
- if ($answer eq 'found') {
+ if ($answer eq 'found') {
+ delete($badServerCache{$tryserver});
return $homecache{$index}=$tryserver;
} elsif ($answer eq 'no_host') {
$badServerCache{$tryserver}=1;
@@ -659,8 +689,8 @@ sub idget {
sub idrget {
my ($udom,@unames)=@_;
my %returnhash=();
- foreach (@unames) {
- $returnhash{$_}=(&userenvironment($udom,$_,'id'))[1];
+ foreach my $uname (@unames) {
+ $returnhash{$uname}=(&userenvironment($udom,$uname,'id'))[1];
}
return %returnhash;
}
@@ -670,25 +700,96 @@ sub idrget {
sub idput {
my ($udom,%ids)=@_;
my %servers=();
- foreach (keys %ids) {
- &cput('environment',{'id'=>$ids{$_}},$udom,$_);
- my $uhom=&homeserver($_,$udom);
+ foreach my $uname (keys(%ids)) {
+ &cput('environment',{'id'=>$ids{$uname}},$udom,$uname);
+ my $uhom=&homeserver($uname,$udom);
if ($uhom ne 'no_host') {
- my $id=&escape($ids{$_});
+ my $id=&escape($ids{$uname});
$id=~tr/A-Z/a-z/;
- my $unam=&escape($_);
+ my $esc_unam=&escape($uname);
if ($servers{$uhom}) {
- $servers{$uhom}.='&'.$id.'='.$unam;
+ $servers{$uhom}.='&'.$id.'='.$esc_unam;
} else {
- $servers{$uhom}=$id.'='.$unam;
+ $servers{$uhom}=$id.'='.$esc_unam;
}
}
}
- foreach (keys %servers) {
- &critical('idput:'.$udom.':'.$servers{$_},$_);
+ foreach my $server (keys(%servers)) {
+ &critical('idput:'.$udom.':'.$servers{$server},$server);
}
}
+# ------------------------------------------- get items from domain db files
+
+sub get_dom {
+ my ($namespace,$storearr,$udom)=@_;
+ my $items='';
+ foreach my $item (@$storearr) {
+ $items.=&escape($item).'&';
+ }
+ $items=~s/\&$//;
+ if (!$udom) { $udom=$env{'user.domain'}; }
+ if (exists($domain_primary{$udom})) {
+ my $uhome=$domain_primary{$udom};
+ my $rep=&reply("getdom:$udom:$namespace:$items",$uhome);
+ my @pairs=split(/\&/,$rep);
+ if ( $#pairs==0 && $pairs[0] =~ /^(con_lost|error|no_such_host)/i) {
+ return @pairs;
+ }
+ my %returnhash=();
+ my $i=0;
+ foreach my $item (@$storearr) {
+ $returnhash{$item}=&thaw_unescape($pairs[$i]);
+ $i++;
+ }
+ return %returnhash;
+ } else {
+ &logthis("get_dom failed - no primary domain server for $udom");
+ }
+}
+
+# -------------------------------------------- put items in domain db files
+
+sub put_dom {
+ my ($namespace,$storehash,$udom)=@_;
+ if (!$udom) { $udom=$env{'user.domain'}; }
+ if (exists($domain_primary{$udom})) {
+ my $uhome=$domain_primary{$udom};
+ my $items='';
+ foreach my $item (keys(%$storehash)) {
+ $items.=&escape($item).'='.&freeze_escape($$storehash{$item}).'&';
+ }
+ $items=~s/\&$//;
+ return &reply("putdom:$udom:$namespace:$items",$uhome);
+ } else {
+ &logthis("put_dom failed - no primary domain server for $udom");
+ }
+}
+
+sub retrieve_inst_usertypes {
+ my ($udom) = @_;
+ my (%returnhash,@order);
+ if (exists($domain_primary{$udom})) {
+ my $uhome=$domain_primary{$udom};
+ my $rep=&reply("inst_usertypes:$udom",$uhome);
+ my ($hashitems,$orderitems) = split(/:/,$rep);
+ my @pairs=split(/\&/,$hashitems);
+ foreach my $item (@pairs) {
+ my ($key,$value)=split(/=/,$item,2);
+ $key = &unescape($key);
+ next if ($key =~ /^error: 2 /);
+ $returnhash{$key}=&thaw_unescape($value);
+ }
+ my @esc_order = split(/\&/,$orderitems);
+ foreach my $item (@esc_order) {
+ push(@order,&unescape($item));
+ }
+ } else {
+ &logthis("get_dom failed - no primary domain server for $udom");
+ }
+ return (\%returnhash,\@order);
+}
+
# --------------------------------------------------- Assign a key to a student
sub assign_access_key {
@@ -822,17 +923,32 @@ sub validate_access_key {
# ------------------------------------- Find the section of student in a course
sub devalidate_getsection_cache {
my ($udom,$unam,$courseid)=@_;
- $courseid=~s/\_/\//g;
- $courseid=~s/^(\w)/\/$1/;
my $hashid="$udom:$unam:$courseid";
&devalidate_cache_new('getsection',$hashid);
}
+sub courseid_to_courseurl {
+ my ($courseid) = @_;
+ #already url style courseid
+ return $courseid if ($courseid =~ m{^/});
+
+ if (exists($env{'course.'.$courseid.'.num'})) {
+ my $cnum = $env{'course.'.$courseid.'.num'};
+ my $cdom = $env{'course.'.$courseid.'.domain'};
+ return "/$cdom/$cnum";
+ }
+
+ my %courseinfo=&Apache::lonnet::coursedescription($courseid);
+ if (exists($courseinfo{'num'})) {
+ return "/$courseinfo{'domain'}/$courseinfo{'num'}";
+ }
+
+ return undef;
+}
+
sub getsection {
my ($udom,$unam,$courseid)=@_;
my $cachetime=1800;
- $courseid=~s/\_/\//g;
- $courseid=~s/^(\w)/\/$1/;
my $hashid="$udom:$unam:$courseid";
my ($result,$cached)=&is_cached_new('getsection',$hashid);
@@ -853,14 +969,13 @@ sub getsection {
# If there is more than one expired role, choose the one which ended last.
# If there is a role which has expired, return it.
#
- foreach (split(/\&/,&reply('dump:'.$udom.':'.$unam.':roles',
- &homeserver($unam,$udom)))) {
- my ($key,$value)=split(/\=/,$_);
- $key=&unescape($key);
+ $courseid = &courseid_to_courseurl($courseid);
+ my %roleshash = &dump('roles',$udom,$unam,$courseid);
+ foreach my $key (keys(%roleshash)) {
next if ($key !~/^\Q$courseid\E(?:\/)*(\w+)*\_st$/);
my $section=$1;
if ($key eq $courseid.'_st') { $section=''; }
- my ($dummy,$end,$start)=split(/\_/,&unescape($value));
+ my ($dummy,$end,$start)=split(/\_/,&unescape($roleshash{$key}));
my $now=time;
if (defined($end) && $end && ($now > $end)) {
$Expired{$end}=$section;
@@ -891,6 +1006,7 @@ sub save_cache {
&purge_remembered();
#&Apache::loncommon::validate_page();
undef(%env);
+ undef($env_loaded);
}
my $to_remember=-1;
@@ -1110,6 +1226,7 @@ sub repcopy {
}
$filename=~s/[\n\r]//g;
my $transname="$filename.in.transfer";
+# FIXME: this should flock
if ((-e $filename) || (-e $transname)) { return 'ok'; }
my $remoteurl=subscribe($filename);
if ($remoteurl =~ /^con_lost by/) {
@@ -1176,7 +1293,7 @@ sub ssi_body {
}
my $output=($filelink=~/^http\:/?&externalssi($filelink):
&ssi($filelink,%form));
- $output=~s|//(\s*)?\s||gs;
+ $output=~s|//(\s*)?\s||gs;
$output=~s/^.*?\]*\>//si;
$output=~s/(.*)\<\/body\s*\>.*?$/$1/si;
return $output;
@@ -1184,6 +1301,15 @@ sub ssi_body {
# --------------------------------------------------------- Server Side Include
+sub absolute_url {
+ my ($host_name) = @_;
+ my $protocol = ($ENV{'SERVER_PORT'} == 443?'https://':'http://');
+ if ($host_name eq '') {
+ $host_name = $ENV{'SERVER_NAME'};
+ }
+ return $protocol.$host_name;
+}
+
sub ssi {
my ($fn,%form)=@_;
@@ -1195,10 +1321,10 @@ sub ssi {
$form{'no_update_last_known'}=1;
if (%form) {
- $request=new HTTP::Request('POST',"http://".$ENV{'HTTP_HOST'}.$fn);
+ $request=new HTTP::Request('POST',&absolute_url().$fn);
$request->content(join('&',map { &escape($_).'='.&escape($form{$_}) } keys %form));
} else {
- $request=new HTTP::Request('GET',"http://".$ENV{'HTTP_HOST'}.$fn);
+ $request=new HTTP::Request('GET',&absolute_url().$fn);
}
$request->header(Cookie => $ENV{'HTTP_COOKIE'});
@@ -1349,15 +1475,17 @@ sub store_edited_file {
}
sub clean_filename {
- my ($fname)=@_;
+ my ($fname,$args)=@_;
# Replace Windows backslashes by forward slashes
$fname=~s/\\/\//g;
-# Get rid of everything but the actual filename
- $fname=~s/^.*\/([^\/]+)$/$1/;
+ if (!$args->{'keep_path'}) {
+ # Get rid of everything but the actual filename
+ $fname=~s/^.*\/([^\/]+)$/$1/;
+ }
# Replace spaces by underscores
$fname=~s/\s+/\_/g;
# Replace all other weird characters by nothing
- $fname=~s/[^\w\.\-]//g;
+ $fname=~s{[^/\w\.\-]}{}g;
# Replace all .\d. sequences with _\d. so they no longer look like version
# numbers
$fname=~s/\.(\d+)(?=\.)/_$1/g;
@@ -1621,7 +1749,20 @@ sub removeuploadedurl {
sub removeuserfile {
my ($docuname,$docudom,$fname)=@_;
my $home=&homeserver($docuname,$docudom);
- return &reply("removeuserfile:$docudom/$docuname/$fname",$home);
+ my $result = &reply("removeuserfile:$docudom/$docuname/$fname",$home);
+ if ($result eq 'ok') {
+ if (($fname !~ /\.meta$/) && (&is_portfolio_file($fname))) {
+ my $metafile = $fname.'.meta';
+ my $metaresult = &removeuserfile($docuname,$docudom,$metafile);
+ my $url = "/uploaded/$docudom/$docuname/$fname";
+ my ($file,$group) = (&parse_portfolio_url($url))[3,4];
+ my $sqlresult =
+ &update_portfolio_table($docuname,$docudom,$file,
+ 'portfolio_metadata',$group,
+ 'delete');
+ }
+ }
+ return $result;
}
sub mkdiruserfile {
@@ -1633,8 +1774,23 @@ sub mkdiruserfile {
sub renameuserfile {
my ($docuname,$docudom,$old,$new)=@_;
my $home=&homeserver($docuname,$docudom);
- return &reply("renameuserfile:$docudom:$docuname:".&escape("$old").':'.
- &escape("$new"),$home);
+ my $result = &reply("renameuserfile:$docudom:$docuname:".
+ &escape("$old").':'.&escape("$new"),$home);
+ if ($result eq 'ok') {
+ if (($old !~ /\.meta$/) && (&is_portfolio_file($old))) {
+ my $oldmeta = $old.'.meta';
+ my $newmeta = $new.'.meta';
+ my $metaresult =
+ &renameuserfile($docuname,$docudom,$oldmeta,$newmeta);
+ my $url = "/uploaded/$docudom/$docuname/$old";
+ my ($file,$group) = (&parse_portfolio_url($url))[3,4];
+ my $sqlresult =
+ &update_portfolio_table($docuname,$docudom,$file,
+ 'portfolio_metadata',$group,
+ 'delete');
+ }
+ }
+ return $result;
}
# ------------------------------------------------------------------------- Log
@@ -1660,8 +1816,7 @@ sub flushcourselogs {
# times and course titles for all courseids
#
my %courseidbuffer=();
- foreach (keys %courselogs) {
- my $crsid=$_;
+ foreach my $crsid (keys %courselogs) {
if (&reply('log:'.$coursedombuf{$crsid}.':'.$coursenumbuf{$crsid}.':'.
&escape($courselogs{$crsid}),
$coursehombuf{$crsid}) eq 'ok') {
@@ -1688,8 +1843,8 @@ sub flushcourselogs {
# Write course id database (reverse lookup) to homeserver of courses
# Is used in pickcourse
#
- foreach (keys %courseidbuffer) {
- &courseidput($hostdom{$_},$courseidbuffer{$_},$_);
+ foreach my $crsid (keys(%courseidbuffer)) {
+ &courseidput($hostdom{$crsid},$courseidbuffer{$crsid},$crsid);
}
#
# File accesses
@@ -1698,7 +1853,8 @@ sub flushcourselogs {
foreach my $entry (keys(%accesshash)) {
if ($entry =~ /___count$/) {
my ($dom,$name);
- ($dom,$name,undef)=($entry=~m:___(\w+)/(\w+)/(.*)___count$:);
+ ($dom,$name,undef)=
+ ($entry=~m{___($match_domain)/($match_name)/(.*)___count$});
if (! defined($dom) || $dom eq '' ||
! defined($name) || $name eq '') {
my $cid = $env{'request.course.id'};
@@ -1719,7 +1875,7 @@ sub flushcourselogs {
}
}
} else {
- my ($dom,$name) = ($entry=~m:___(\w+)/(\w+)/(.*)___(\w+)$:);
+ my ($dom,$name) = ($entry=~m{___($match_domain)/($match_name)/(.*)___(\w+)$});
my %temphash=($entry => $accesshash{$entry});
if (&put('nohist_resevaldata',\%temphash,$dom,$name) eq 'ok') {
delete $accesshash{$entry};
@@ -1730,8 +1886,7 @@ sub flushcourselogs {
# Roles
# Reverse lookup of user roles for course faculty/staff and co-authorship
#
- foreach (keys %userrolehash) {
- my $entry=$_;
+ foreach my $entry (keys(%userrolehash)) {
my ($role,$uname,$udom,$runame,$rudom,$rsec)=
split(/\:/,$entry);
if (&Apache::lonnet::put('nohist_userroles',
@@ -1803,9 +1958,9 @@ sub courseacclog {
if ($fnsymb=~/(problem|exam|quiz|assess|survey|form|task|page)$/) {
$what.=':POST';
# FIXME: Probably ought to escape things....
- foreach (keys %env) {
- if ($_=~/^form\.(.*)/) {
- $what.=':'.$1.'='.$env{$_};
+ foreach my $key (keys(%env)) {
+ if ($key=~/^form\.(.*)/) {
+ $what.=':'.$1.'='.$env{$key};
}
}
} elsif ($fnsymb =~ m:^/adm/searchcat:) {
@@ -1867,19 +2022,19 @@ sub get_course_adv_roles {
$cid=$env{'request.course.id'} unless (defined($cid));
my %coursehash=&coursedescription($cid);
my %nothide=();
- foreach (split(/\s*\,\s*/,$coursehash{'nothideprivileged'})) {
- $nothide{join(':',split(/[\@\:]/,$_))}=1;
+ foreach my $user (split(/\s*\,\s*/,$coursehash{'nothideprivileged'})) {
+ $nothide{join(':',split(/[\@\:]/,$user))}=1;
}
my %returnhash=();
my %dumphash=
&dump('nohist_userroles',$coursehash{'domain'},$coursehash{'num'});
my $now=time;
- foreach (keys %dumphash) {
- my ($tend,$tstart)=split(/\:/,$dumphash{$_});
+ foreach my $entry (keys %dumphash) {
+ my ($tend,$tstart)=split(/\:/,$dumphash{$entry});
if (($tstart) && ($tstart<0)) { next; }
if (($tend) && ($tend<$now)) { next; }
if (($tstart) && ($now<$tstart)) { next; }
- my ($role,$username,$domain,$section)=split(/\:/,$_);
+ my ($role,$username,$domain,$section)=split(/\:/,$entry);
if ($username eq '' || $domain eq '') { next; }
if ((&privileged($username,$domain)) &&
(!$nothide{$username.':'.$domain})) { next; }
@@ -1896,21 +2051,45 @@ sub get_course_adv_roles {
}
sub get_my_roles {
- my ($uname,$udom)=@_;
+ my ($uname,$udom,$types,$roles,$roledoms)=@_;
unless (defined($uname)) { $uname=$env{'user.name'}; }
unless (defined($udom)) { $udom=$env{'user.domain'}; }
my %dumphash=
&dump('nohist_userroles',$udom,$uname);
my %returnhash=();
my $now=time;
- foreach (keys %dumphash) {
- my ($tend,$tstart)=split(/\:/,$dumphash{$_});
+ foreach my $entry (keys(%dumphash)) {
+ my ($tend,$tstart)=split(/\:/,$dumphash{$entry});
if (($tstart) && ($tstart<0)) { next; }
- if (($tend) && ($tend<$now)) { next; }
- if (($tstart) && ($now<$tstart)) { next; }
- my ($role,$username,$domain,$section)=split(/\:/,$_);
+ my $status = 'active';
+ if (($tend) && ($tend<$now)) {
+ $status = 'previous';
+ }
+ if (($tstart) && ($now<$tstart)) {
+ $status = 'future';
+ }
+ if (ref($types) eq 'ARRAY') {
+ if (!grep(/^\Q$status\E$/,@{$types})) {
+ next;
+ }
+ } else {
+ if ($status ne 'active') {
+ next;
+ }
+ }
+ my ($role,$username,$domain,$section)=split(/\:/,$entry);
+ if (ref($roledoms) eq 'ARRAY') {
+ if (!grep(/^\Q$domain\E$/,@{$roledoms})) {
+ next;
+ }
+ }
+ if (ref($roles) eq 'ARRAY') {
+ if (!grep(/^\Q$role\E$/,@{$roles})) {
+ next;
+ }
+ }
$returnhash{$username.':'.$domain.':'.$role}=$tstart.':'.$tend;
- }
+ }
return %returnhash;
}
@@ -1929,7 +2108,7 @@ sub getannounce {
if (open(my $fh,$perlvar{'lonDocRoot'}.'/announcement.txt')) {
my $announcement='';
- while (<$fh>) { $announcement .=$_; }
+ while (my $line = <$fh>) { $announcement .= $line; }
close($fh);
if ($announcement=~/\w/) {
return
@@ -1953,18 +2132,18 @@ sub courseidput {
}
sub courseiddump {
- my ($domfilter,$descfilter,$sincefilter,$instcodefilter,$ownerfilter,$coursefilter,$hostidflag,$hostidref,$typefilter)=@_;
+ my ($domfilter,$descfilter,$sincefilter,$instcodefilter,$ownerfilter,$coursefilter,$hostidflag,$hostidref,$typefilter,$regexp_ok)=@_;
my %returnhash=();
unless ($domfilter) { $domfilter=''; }
foreach my $tryserver (keys %libserv) {
if ( ($hostidflag == 1 && grep/^$tryserver$/,@{$hostidref}) || (!defined($hostidflag)) ) {
if ((!$domfilter) || ($hostdom{$tryserver} eq $domfilter)) {
- foreach (
+ foreach my $line (
split(/\&/,&reply('courseiddump:'.$hostdom{$tryserver}.':'.
$sincefilter.':'.&escape($descfilter).':'.
- &escape($instcodefilter).':'.&escape($ownerfilter).':'.&escape($coursefilter).':'.&escape($typefilter),
+ &escape($instcodefilter).':'.&escape($ownerfilter).':'.&escape($coursefilter).':'.&escape($typefilter).':'.&escape($regexp_ok),
$tryserver))) {
- my ($key,$value)=split(/\=/,$_);
+ my ($key,$value)=split(/\=/,$line,2);
if (($key) && ($value)) {
$returnhash{&unescape($key)}=$value;
}
@@ -1993,8 +2172,8 @@ sub dcmaildump {
&escape($enddate).':';
my @esc_senders=map { &escape($_)} @$senders;
$cmd.=&escape(join('&',@esc_senders));
- foreach (split(/\&/,&reply($cmd,$domain_primary{$dom}))) {
- my ($key,$value) = split(/\=/,$_);
+ foreach my $line (split(/\&/,&reply($cmd,$domain_primary{$dom}))) {
+ my ($key,$value) = split(/\=/,$line,2);
if (($key) && ($value)) {
$returnhash{&unescape($key)} = &unescape($value);
}
@@ -2017,11 +2196,11 @@ sub get_domain_roles {
foreach my $tryserver (keys(%libserv)) {
if ($hostdom{$tryserver} eq $dom) {
%{$personnel{$tryserver}}=();
- foreach (
+ foreach my $line (
split(/\&/,&reply('domrolesdump:'.$dom.':'.
&escape($startdate).':'.&escape($enddate).':'.
&escape($rolelist), $tryserver))) {
- my($key,$value) = split(/\=/,$_);
+ my ($key,$value) = split(/\=/,$line,2);
if (($key) && ($value)) {
$personnel{$tryserver}{&unescape($key)} = &unescape($value);
}
@@ -2035,7 +2214,7 @@ sub get_domain_roles {
sub get_first_access {
my ($type,$argsymb)=@_;
- my ($symb,$courseid,$udom,$uname)=&Apache::lonxml::whichuser();
+ my ($symb,$courseid,$udom,$uname)=&whichuser();
if ($argsymb) { $symb=$argsymb; }
my ($map,$id,$res)=&decode_symb($symb);
if ($type eq 'map') {
@@ -2049,7 +2228,7 @@ sub get_first_access {
sub set_first_access {
my ($type)=@_;
- my ($symb,$courseid,$udom,$uname)=&Apache::lonxml::whichuser();
+ my ($symb,$courseid,$udom,$uname)=&whichuser();
my ($map,$id,$res)=&decode_symb($symb);
if ($type eq 'map') {
$res=&symbread($map);
@@ -2243,27 +2422,27 @@ sub hash2str {
sub hashref2str {
my ($hashref)=@_;
my $result='__HASH_REF__';
- foreach (sort(keys(%$hashref))) {
- if (ref($_) eq 'ARRAY') {
- $result.=&arrayref2str($_).'=';
- } elsif (ref($_) eq 'HASH') {
- $result.=&hashref2str($_).'=';
- } elsif (ref($_)) {
+ foreach my $key (sort(keys(%$hashref))) {
+ if (ref($key) eq 'ARRAY') {
+ $result.=&arrayref2str($key).'=';
+ } elsif (ref($key) eq 'HASH') {
+ $result.=&hashref2str($key).'=';
+ } elsif (ref($key)) {
$result.='=';
- #print("Got a ref of ".(ref($_))." skipping.");
+ #print("Got a ref of ".(ref($key))." skipping.");
} else {
- if ($_) {$result.=&escape($_).'=';} else { last; }
+ if ($key) {$result.=&escape($key).'=';} else { last; }
}
- if(ref($hashref->{$_}) eq 'ARRAY') {
- $result.=&arrayref2str($hashref->{$_}).'&';
- } elsif(ref($hashref->{$_}) eq 'HASH') {
- $result.=&hashref2str($hashref->{$_}).'&';
- } elsif(ref($hashref->{$_})) {
+ if(ref($hashref->{$key}) eq 'ARRAY') {
+ $result.=&arrayref2str($hashref->{$key}).'&';
+ } elsif(ref($hashref->{$key}) eq 'HASH') {
+ $result.=&hashref2str($hashref->{$key}).'&';
+ } elsif(ref($hashref->{$key})) {
$result.='&';
- #print("Got a ref of ".(ref($hashref->{$_}))." skipping.");
+ #print("Got a ref of ".(ref($hashref->{$key}))." skipping.");
} else {
- $result.=&escape($hashref->{$_}).'&';
+ $result.=&escape($hashref->{$key}).'&';
}
}
$result=~s/\&$//;
@@ -2543,8 +2722,8 @@ sub store {
$$storehash{'host'}=$perlvar{'lonHostID'};
my $namevalue='';
- foreach (keys %$storehash) {
- $namevalue.=&escape($_).'='.&freeze_escape($$storehash{$_}).'&';
+ foreach my $key (keys(%$storehash)) {
+ $namevalue.=&escape($key).'='.&freeze_escape($$storehash{$key}).'&';
}
$namevalue=~s/\&$//;
&courselog($symb.':'.$stuname.':'.$domain.':STORE:'.$namevalue);
@@ -2579,8 +2758,8 @@ sub cstore {
$$storehash{'host'}=$perlvar{'lonHostID'};
my $namevalue='';
- foreach (keys %$storehash) {
- $namevalue.=&escape($_).'='.&freeze_escape($$storehash{$_}).'&';
+ foreach my $key (keys(%$storehash)) {
+ $namevalue.=&escape($key).'='.&freeze_escape($$storehash{$key}).'&';
}
$namevalue=~s/\&$//;
&courselog($symb.':'.$stuname.':'.$domain.':CSTORE:'.$namevalue);
@@ -2612,14 +2791,14 @@ sub restore {
my $answer=&reply("restore:$domain:$stuname:$namespace:$symb","$home");
my %returnhash=();
- foreach (split(/\&/,$answer)) {
- my ($name,$value)=split(/\=/,$_);
+ foreach my $line (split(/\&/,$answer)) {
+ my ($name,$value)=split(/\=/,$line);
$returnhash{&unescape($name)}=&thaw_unescape($value);
}
my $version;
for ($version=1;$version<=$returnhash{'version'};$version++) {
- foreach (split(/\:/,$returnhash{$version.':keys'})) {
- $returnhash{$_}=$returnhash{$version.':'.$_};
+ foreach my $item (split(/\:/,$returnhash{$version.':keys'})) {
+ $returnhash{$item}=$returnhash{$version.':'.$item};
}
}
return %returnhash;
@@ -2659,6 +2838,7 @@ sub coursedescription {
if (!$args->{'one_time'}) {
$envhash{'course.'.$normalid.'.last_cache'}=time;
}
+
if ($chome ne 'no_host') {
%returnhash=&dump('environment',$cdomain,$cnum);
if (!exists($returnhash{'con_lost'})) {
@@ -2694,9 +2874,9 @@ sub privileged {
if (($rolesdump eq 'con_lost') || ($rolesdump eq '')) { return 0; }
my $now=time;
if ($rolesdump ne '') {
- foreach (split(/&/,$rolesdump)) {
- if ($_!~/^rolesdef_/) {
- my ($area,$role)=split(/=/,$_);
+ foreach my $entry (split(/&/,$rolesdump)) {
+ if ($entry!~/^rolesdef_/) {
+ my ($area,$role)=split(/=/,$entry);
$area=~s/\_\w\w$//;
my ($trole,$tend,$tstart)=split(/_/,$role);
if (($trole eq 'dc') || ($trole eq 'su')) {
@@ -2728,14 +2908,14 @@ sub rolesinit {
my $group_privs;
if ($rolesdump ne '') {
- foreach (split(/&/,$rolesdump)) {
- if ($_!~/^rolesdef_/) {
- my ($area,$role)=split(/=/,$_);
+ foreach my $entry (split(/&/,$rolesdump)) {
+ if ($entry!~/^rolesdef_/) {
+ my ($area,$role)=split(/=/,$entry);
$area=~s/\_\w\w$//;
my ($trole,$tend,$tstart,$group_privs);
if ($role=~/^cr/) {
- if ($role=~m|^(cr/\w+/\w+/[a-zA-Z0-9]+)_(.*)$|) {
- ($trole,my $trest)=($role=~m|^(cr/\w+/\w+/[a-zA-Z0-9]+)_(.*)$|);
+ if ($role=~m|^(cr/$match_domain/$match_username/[a-zA-Z0-9]+)_(.*)$|) {
+ ($trole,my $trest)=($role=~m|^(cr/$match_domain/$match_username/[a-zA-Z0-9]+)_(.*)$|);
($tend,$tstart)=split('_',$trest);
} else {
$trole=$role;
@@ -2814,7 +2994,7 @@ sub group_roleprivs {
if (($tend!=0) && ($tend<$now)) { $access = 0; }
if (($tstart!=0) && ($tstart>$now)) { $access=0; }
if ($access) {
- my ($course,$group) = ($area =~ m|(/\w+/\w+)/([^/]+)$|);
+ my ($course,$group) = ($area =~ m|(/$match_domain/$match_courseid)/([^/]+)$|);
$$allgroups{$course}{$group} .=':'.$group_privs;
}
}
@@ -2845,7 +3025,7 @@ sub set_userprivs {
if (keys(%{$allgroups}) > 0) {
foreach my $role (keys %{$allroles}) {
my ($trole,$area,$sec,$extendedarea);
- if ($role =~ m-^(\w+|cr/\w+/\w+/\w+)\.(/\w+/\w+)(/?\w*)-) {
+ if ($role =~ m-^(\w+|cr/$match_domain/$match_username/\w+)\.(/$match_domain/$match_courseid)(/?\w*)-) {
$trole = $1;
$area = $2;
$sec = $3;
@@ -2860,15 +3040,15 @@ sub set_userprivs {
}
}
}
- foreach (keys(%grouproles)) {
- $$allroles{$_} = $grouproles{$_};
+ foreach my $group (keys(%grouproles)) {
+ $$allroles{$group} = $grouproles{$group};
}
- foreach (keys %{$allroles}) {
- my %thesepriv=();
- if (($_=~/^au/) || ($_=~/^ca/)) { $author=1; }
- foreach (split(/:/,$$allroles{$_})) {
- if ($_ ne '') {
- my ($privilege,$restrictions)=split(/&/,$_);
+ foreach my $role (keys(%{$allroles})) {
+ my %thesepriv;
+ if (($role=~/^au/) || ($role=~/^ca/)) { $author=1; }
+ foreach my $item (split(/:/,$$allroles{$role})) {
+ if ($item ne '') {
+ my ($privilege,$restrictions)=split(/&/,$item);
if ($restrictions eq '') {
$thesepriv{$privilege}='F';
} elsif ($thesepriv{$privilege} ne 'F') {
@@ -2878,8 +3058,10 @@ sub set_userprivs {
}
}
my $thesestr='';
- foreach (keys %thesepriv) { $thesestr.=':'.$_.'&'.$thesepriv{$_}; }
- $userroles->{'user.priv.'.$_} = $thesestr;
+ foreach my $priv (keys(%thesepriv)) {
+ $thesestr.=':'.$priv.'&'.$thesepriv{$priv};
+ }
+ $userroles->{'user.priv.'.$role} = $thesestr;
}
return ($author,$adv);
}
@@ -2889,8 +3071,8 @@ sub set_userprivs {
sub get {
my ($namespace,$storearr,$udomain,$uname)=@_;
my $items='';
- foreach (@$storearr) {
- $items.=escape($_).'&';
+ foreach my $item (@$storearr) {
+ $items.=&escape($item).'&';
}
$items=~s/\&$//;
if (!$udomain) { $udomain=$env{'user.domain'}; }
@@ -2904,8 +3086,8 @@ sub get {
}
my %returnhash=();
my $i=0;
- foreach (@$storearr) {
- $returnhash{$_}=&thaw_unescape($pairs[$i]);
+ foreach my $item (@$storearr) {
+ $returnhash{$item}=&thaw_unescape($pairs[$i]);
$i++;
}
return %returnhash;
@@ -2916,8 +3098,8 @@ sub get {
sub del {
my ($namespace,$storearr,$udomain,$uname)=@_;
my $items='';
- foreach (@$storearr) {
- $items.=escape($_).'&';
+ foreach my $item (@$storearr) {
+ $items.=&escape($item).'&';
}
$items=~s/\&$//;
if (!$udomain) { $udomain=$env{'user.domain'}; }
@@ -2955,7 +3137,23 @@ sub dump {
sub dumpstore {
my ($namespace,$udomain,$uname,$regexp,$range)=@_;
- return &dump($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;
}
# -------------------------------------------------------------- keys interface
@@ -2967,8 +3165,9 @@ sub getkeys {
my $uhome=&homeserver($uname,$udomain);
my $rep=reply("keys:$udomain:$uname:$namespace",$uhome);
my @keyarray=();
- foreach (split(/\&/,$rep)) {
- push (@keyarray,&unescape($_));
+ foreach my $key (split(/\&/,$rep)) {
+ next if ($key =~ /^error: 2 /);
+ push(@keyarray,&unescape($key));
}
return @keyarray;
}
@@ -2988,15 +3187,15 @@ sub currentdump {
if ($rep eq "unknown_cmd") {
# an old lond will not know currentdump
# Do a dump and make it look like a currentdump
- my @tmp = &dump($courseid,$sdom,$sname,'.');
+ my @tmp = &dumpstore($courseid,$sdom,$sname,'.');
return if ($tmp[0] =~ /^(error:|no_such_host)/);
my %hash = @tmp;
@tmp=();
%returnhash = %{&convert_dump_to_currentdump(\%hash)};
} else {
my @pairs=split(/\&/,$rep);
- foreach (@pairs) {
- my ($key,$value)=split(/=/,$_);
+ foreach my $pair (@pairs) {
+ my ($key,$value)=split(/=/,$pair,2);
my ($symb,$param) = split(/:/,$key);
$returnhash{&unescape($symb)}->{&unescape($param)} =
&thaw_unescape($value);
@@ -3013,6 +3212,8 @@ sub convert_dump_to_currentdump{
# we might run in to problems with parameter names =~ /^v\./
while (my ($key,$value) = each(%hash)) {
my ($v,$symb,$param) = split(/:/,$key);
+ $symb = &unescape($symb);
+ $param = &unescape($param);
next if ($v eq 'version' || $symb eq 'keys');
next if (exists($returnhash{$symb}) &&
exists($returnhash{$symb}->{$param}) &&
@@ -3074,8 +3275,8 @@ sub put {
if (!$uname) { $uname=$env{'user.name'}; }
my $uhome=&homeserver($uname,$udomain);
my $items='';
- foreach (keys %$storehash) {
- $items.=&escape($_).'='.&freeze_escape($$storehash{$_}).'&';
+ foreach my $item (keys(%$storehash)) {
+ $items.=&escape($item).'='.&freeze_escape($$storehash{$item}).'&';
}
$items=~s/\&$//;
return &reply("put:$udomain:$uname:$namespace:$items",$uhome);
@@ -3127,22 +3328,22 @@ sub old_putstore {
if (!$uname) { $uname=$env{'user.name'}; }
my $uhome=&homeserver($uname,$udomain);
my %newstorehash;
- foreach (keys %$storehash) {
- my $key = $version.':'.&escape($symb).':'.$_;
- $newstorehash{$key} = $storehash->{$_};
+ foreach my $item (keys(%$storehash)) {
+ my $key = $version.':'.&escape($symb).':'.$item;
+ $newstorehash{$key} = $storehash->{$item};
}
my $items='';
my %allitems = ();
- foreach (keys %newstorehash) {
- if ($_ =~ m/^([^\:]+):([^\:]+):([^\:]+)$/) {
+ foreach my $item (keys(%newstorehash)) {
+ if ($item =~ m/^([^\:]+):([^\:]+):([^\:]+)$/) {
my $key = $1.':keys:'.$2;
$allitems{$key} .= $3.':';
}
- $items.=$_.'='.&freeze_escape($newstorehash{$_}).'&';
+ $items.=$item.'='.&freeze_escape($newstorehash{$item}).'&';
}
- foreach (keys %allitems) {
- $allitems{$_} =~ s/\:$//;
- $items.= $_.'='.$allitems{$_}.'&';
+ foreach my $item (keys(%allitems)) {
+ $allitems{$item} =~ s/\:$//;
+ $items.= $item.'='.$allitems{$item}.'&';
}
$items=~s/\&$//;
return &reply("put:$udomain:$uname:$namespace:$items",$uhome);
@@ -3156,8 +3357,8 @@ sub cput {
if (!$uname) { $uname=$env{'user.name'}; }
my $uhome=&homeserver($uname,$udomain);
my $items='';
- foreach (keys %$storehash) {
- $items.=&escape($_).'='.&freeze_escape($$storehash{$_}).'&';
+ foreach my $item (keys(%$storehash)) {
+ $items.=&escape($item).'='.&freeze_escape($$storehash{$item}).'&';
}
$items=~s/\&$//;
return &critical("put:$udomain:$uname:$namespace:$items",$uhome);
@@ -3168,8 +3369,8 @@ sub cput {
sub eget {
my ($namespace,$storearr,$udomain,$uname)=@_;
my $items='';
- foreach (@$storearr) {
- $items.=escape($_).'&';
+ foreach my $item (@$storearr) {
+ $items.=&escape($item).'&';
}
$items=~s/\&$//;
if (!$udomain) { $udomain=$env{'user.domain'}; }
@@ -3179,8 +3380,8 @@ sub eget {
my @pairs=split(/\&/,$rep);
my %returnhash=();
my $i=0;
- foreach (@$storearr) {
- $returnhash{$_}=&thaw_unescape($pairs[$i]);
+ foreach my $item (@$storearr) {
+ $returnhash{$item}=&thaw_unescape($pairs[$i]);
$i++;
}
return %returnhash;
@@ -3188,12 +3389,15 @@ sub eget {
# ------------------------------------------------------------ tmpput interface
sub tmpput {
- my ($storehash,$server)=@_;
+ my ($storehash,$server,$context)=@_;
my $items='';
- foreach (keys(%$storehash)) {
- $items.=&escape($_).'='.&freeze_escape($$storehash{$_}).'&';
+ foreach my $item (keys(%$storehash)) {
+ $items.=&escape($item).'='.&freeze_escape($$storehash{$item}).'&';
}
$items=~s/\&$//;
+ if (defined($context)) {
+ $items .= ':'.&escape($context);
+ }
return &reply("tmpput:$items",$server);
}
@@ -3223,6 +3427,22 @@ sub portfolio_access {
my ($requrl) = @_;
my (undef,$udom,$unum,$file_name,$group) = &parse_portfolio_url($requrl);
my $result = &get_portfolio_access($udom,$unum,$file_name,$group);
+ if ($result) {
+ my %setters;
+ if ($env{'user.name'} eq 'public' && $env{'user.domain'} eq 'public') {
+ my ($startblock,$endblock) =
+ &Apache::loncommon::blockcheck(\%setters,'port',$unum,$udom);
+ if ($startblock && $endblock) {
+ return 'B';
+ }
+ } else {
+ my ($startblock,$endblock) =
+ &Apache::loncommon::blockcheck(\%setters,'port');
+ if ($startblock && $endblock) {
+ return 'B';
+ }
+ }
+ }
if ($result eq 'ok') {
return 'F';
} elsif ($result =~ /^[^:]+:guest_/) {
@@ -3298,7 +3518,7 @@ sub get_portfolio_access {
my (%allgroups,%allroles);
my ($start,$end,$role,$sec,$group);
foreach my $envkey (%env) {
- if ($envkey =~ m-^user\.role\.(gr|cc|in|ta|ep|st)\./([^/]+)/([^/]+)/?([^/]*)$-) {
+ if ($envkey =~ m-^user\.role\.(gr|cc|in|ta|ep|st)\./($match_domain)/($match_courseid)/?([^/]*)$-) {
my $cid = $2.'_'.$3;
if ($1 eq 'gr') {
$group = $4;
@@ -3311,7 +3531,7 @@ sub get_portfolio_access {
}
$allroles{$cid}{$1}{$sec} = $env{$envkey};
}
- } elsif ($envkey =~ m-^user\.role\./cr/(\w+/\w+/\w*)./([^/]+)/([^/]+)/?([^/]*)$-) {
+ } elsif ($envkey =~ m-^user\.role\./cr/($match_domain/$match_username/\w*)./($match_domain)/($match_courseid)/?([^/]*)$-) {
my $cid = $2.'_'.$3;
if ($4 eq '') {
$sec = 'none';
@@ -3406,12 +3626,12 @@ sub parse_portfolio_url {
my ($type,$udom,$unum,$group,$file_name);
- if ($url =~ m-^/*uploaded/([^/]+)/([^/]+)/portfolio(/.+)$-) {
+ if ($url =~ m-^/*(?:uploaded|editupload)/($match_domain)/($match_username)/portfolio(/.+)$-) {
$type = 1;
$udom = $1;
$unum = $2;
$file_name = $3;
- } elsif ($url =~ m-^/*uploaded/([^/]+)/([^/]+)/groups/([^/]+)/portfolio/(.+)$-) {
+ } elsif ($url =~ m-^/*(?:uploaded|editupload)/($match_domain)/($match_courseid)/groups/([^/]+)/portfolio/(.+)$-) {
$type = 2;
$udom = $1;
$unum = $2;
@@ -3429,21 +3649,31 @@ sub is_portfolio_url {
return scalar(&parse_portfolio_url($url));
}
+sub is_portfolio_file {
+ my ($file) = @_;
+ if (($file =~ /^portfolio/) || ($file =~ /^groups\/\w+\/portfolio/)) {
+ return 1;
+ }
+ return;
+}
+
+
# ---------------------------------------------- Custom access rule evaluation
sub customaccess {
my ($priv,$uri)=@_;
- my ($urole,$urealm)=split(/\./,$env{'request.role'});
- $urealm=~s/^\W//;
- my ($udom,$ucrs,$usec)=split(/\//,$urealm);
+ my ($urole,$urealm)=split(/\./,$env{'request.role'},2);
+ my (undef,$udom,$ucrs,$usec)=split(/\//,$urealm);
+ $udom = &LONCAPA::clean_domain($udom);
+ $ucrs = &LONCAPA::clean_username($ucrs);
my $access=0;
- foreach (split(/\s*\,\s*/,&metadata($uri,'rule_rights'))) {
- my ($effect,$realm,$role)=split(/\:/,$_);
+ foreach my $right (split(/\s*\,\s*/,&metadata($uri,'rule_rights'))) {
+ my ($effect,$realm,$role)=split(/\:/,$right);
if ($role) {
if ($role ne $urole) { next; }
}
- foreach (split(/\s*\,\s*/,$realm)) {
- my ($tdom,$tcrs,$tsec)=split(/\_/,$_);
+ foreach my $scope (split(/\s*\,\s*/,$realm)) {
+ my ($tdom,$tcrs,$tsec)=split(/\_/,$scope);
if ($tdom) {
if ($tdom ne $udom) { next; }
}
@@ -3466,12 +3696,21 @@ sub customaccess {
# ------------------------------------------------- Check for a user privilege
sub allowed {
- my ($priv,$uri,$symb)=@_;
+ my ($priv,$uri,$symb,$role)=@_;
my $ver_orguri=$uri;
$uri=&deversion($uri);
my $orguri=$uri;
$uri=&declutter($uri);
-
+
+ if ($priv eq 'evb') {
+# Evade communication block restrictions for specified role in a course
+ if ($env{'user.priv.'.$role} =~/evb\&([^\:]*)/) {
+ return $1;
+ } else {
+ return;
+ }
+ }
+
if (defined($env{'allowed.'.$priv})) { return $env{'allowed.'.$priv}; }
# Free bre access to adm and meta resources
if (((($uri=~/^adm\//) && ($uri !~ m{/(?:smppg|bulletinboard)$}))
@@ -3484,7 +3723,14 @@ sub allowed {
my ($space,$domain,$name,@dir)=split('/',$uri);
if (($space=~/^(uploaded|editupload)$/) && ($env{'user.name'} eq $name) &&
($env{'user.domain'} eq $domain) && ('portfolio' eq $dir[0])) {
- return 'F';
+ my %setters;
+ my ($startblock,$endblock) =
+ &Apache::loncommon::blockcheck(\%setters,'port');
+ if ($startblock && $endblock) {
+ return 'B';
+ } else {
+ return 'F';
+ }
}
# bre access to group portfolio for rgf priv in group, or mdg or vcg in course.
@@ -3655,14 +3901,14 @@ sub allowed {
if ($checkreferer) {
my $refuri=$env{'httpref.'.$orguri};
unless ($refuri) {
- foreach (keys %env) {
- if ($_=~/^httpref\..*\*/) {
- my $pattern=$_;
+ foreach my $key (keys(%env)) {
+ if ($key=~/^httpref\..*\*/) {
+ my $pattern=$key;
$pattern=~s/^httpref\.\/res\///;
$pattern=~s/\*/\[\^\/\]\+/g;
$pattern=~s/\//\\\//g;
if ($orguri=~/$pattern/) {
- $refuri=$env{$_};
+ $refuri=$env{$key};
}
}
}
@@ -3760,6 +4006,8 @@ sub allowed {
unless ($env{'request.course.id'}) {
if ($thisallowed eq 'A') {
return 'A';
+ } elsif ($thisallowed eq 'B') {
+ return 'B';
} else {
return '1';
}
@@ -3827,6 +4075,8 @@ sub allowed {
if ($thisallowed eq 'A') {
return 'A';
+ } elsif ($thisallowed eq 'B') {
+ return 'B';
}
return 'F';
}
@@ -3880,8 +4130,8 @@ sub get_symb_from_alias {
sub definerole {
if (allowed('mcr','/')) {
my ($rolename,$sysrole,$domrole,$courole)=@_;
- foreach (split(':',$sysrole)) {
- my ($crole,$cqual)=split(/\&/,$_);
+ foreach my $role (split(':',$sysrole)) {
+ my ($crole,$cqual)=split(/\&/,$role);
if ($pr{'cr:s'}!~/\Q$crole\E/) { return "refused:s:$crole"; }
if ($pr{'cr:s'}=~/\Q$crole\E\&/) {
if ($pr{'cr:s'}!~/\Q$crole\E\&\w*\Q$cqual\E/) {
@@ -3889,8 +4139,8 @@ sub definerole {
}
}
}
- foreach (split(':',$domrole)) {
- my ($crole,$cqual)=split(/\&/,$_);
+ foreach my $role (split(':',$domrole)) {
+ my ($crole,$cqual)=split(/\&/,$role);
if ($pr{'cr:d'}!~/\Q$crole\E/) { return "refused:d:$crole"; }
if ($pr{'cr:d'}=~/\Q$crole\E\&/) {
if ($pr{'cr:d'}!~/\Q$crole\W\&\w*\Q$cqual\E/) {
@@ -3898,8 +4148,8 @@ sub definerole {
}
}
}
- foreach (split(':',$courole)) {
- my ($crole,$cqual)=split(/\&/,$_);
+ foreach my $role (split(':',$courole)) {
+ my ($crole,$cqual)=split(/\&/,$role);
if ($pr{'cr:c'}!~/\Q$crole\E/) { return "refused:c:$crole"; }
if ($pr{'cr:c'}=~/\Q$crole\E\&/) {
if ($pr{'cr:c'}!~/\Q$crole\E\&\w*\Q$cqual\E/) {
@@ -3946,13 +4196,25 @@ sub log_query {
my $uhome=&homeserver($uname,$udom);
if ($uhome eq 'no_host') { return 'error: no_host'; }
my $uhost=$hostname{$uhome};
- my $command=&escape(join(':',map{$_.'='.$filters{$_}} keys %filters));
+ my $command=&escape(join(':',map{$_.'='.$filters{$_}} keys(%filters)));
my $queryid=&reply("querysend:".$query.':'.$udom.':'.$uname.':'.$command,
$uhome);
unless ($queryid=~/^\Q$uhost\E\_/) { return 'error: '.$queryid; }
return get_query_reply($queryid);
}
+# -------------------------- Update MySQL table for portfolio file
+
+sub update_portfolio_table {
+ my ($uname,$udom,$file_name,$query,$group,$action) = @_;
+ my $homeserver = &homeserver($uname,$udom);
+ my $queryid=
+ &reply("querysend:".$query.':'.&escape($uname.':'.$udom.':'.$group).
+ ':'.&escape($file_name).':'.$action,$homeserver);
+ my $reply = &get_query_reply($queryid);
+ return $reply;
+}
+
# ------- Request retrieval of institutional classlists for course(s)
sub fetch_enrollment_query {
@@ -3967,8 +4229,8 @@ sub fetch_enrollment_query {
}
my $host=$hostname{$homeserver};
my $cmd = '';
- foreach (keys %{$affiliatesref}) {
- $cmd .= $_.'='.join(",",@{$$affiliatesref{$_}}).'%%';
+ foreach my $affiliate (keys %{$affiliatesref}) {
+ $cmd .= $affiliate.'='.join(",",@{$$affiliatesref{$affiliate}}).'%%';
}
$cmd =~ s/%%$//;
$cmd = &escape($cmd);
@@ -3989,18 +4251,18 @@ sub fetch_enrollment_query {
} else {
my @responses = split/:/,$reply;
if ($homeserver eq $perlvar{'lonHostID'}) {
- foreach (@responses) {
- my ($key,$value) = split/=/,$_;
+ foreach my $line (@responses) {
+ my ($key,$value) = split(/=/,$line,2);
$$replyref{$key} = $value;
}
} else {
my $pathname = $perlvar{'lonDaemons'}.'/tmp';
- foreach (@responses) {
- my ($key,$value) = split/=/,$_;
+ foreach my $line (@responses) {
+ my ($key,$value) = split(/=/,$line);
$$replyref{$key} = $value;
if ($value > 0) {
- foreach (@{$$affiliatesref{$key}}) {
- my $filename = $dom.'_'.$key.'_'.$_.'_classlist.xml';
+ foreach my $item (@{$$affiliatesref{$key}}) {
+ my $filename = $dom.'_'.$key.'_'.$item.'_classlist.xml';
my $destname = $pathname.'/'.$filename;
my $xml_classlist = &reply("autoretrieve:".$filename,$homeserver);
if ($xml_classlist =~ /^error/) {
@@ -4159,8 +4421,8 @@ sub auto_photoupdate {
my $host=$hostname{$homeserver};
my $cmd = '';
my $maxtries = 1;
- foreach (keys %{$affiliatesref}) {
- $cmd .= $_.'='.join(",",@{$$affiliatesref{$_}}).'%%';
+ foreach my $affiliate (keys(%{$affiliatesref})) {
+ $cmd .= $affiliate.'='.join(",",@{$$affiliatesref{$affiliate}}).'%%';
}
$cmd =~ s/%%$//;
$cmd = &escape($cmd);
@@ -4191,13 +4453,14 @@ sub auto_photoupdate {
}
sub auto_instcode_format {
- my ($caller,$codedom,$instcodes,$codes,$codetitles,$cat_titles,$cat_order) = @_;
+ my ($caller,$codedom,$instcodes,$codes,$codetitles,$cat_titles,
+ $cat_order) = @_;
my $courses = '';
my @homeservers;
if ($caller eq 'global') {
- foreach my $tryserver (keys %libserv) {
+ foreach my $tryserver (keys(%libserv)) {
if ($hostdom{$tryserver} eq $codedom) {
- if (!grep/^\Q$tryserver\E$/,@homeservers) {
+ if (!grep(/^\Q$tryserver\E$/,@homeservers)) {
push(@homeservers,$tryserver);
}
}
@@ -4205,8 +4468,8 @@ sub auto_instcode_format {
} else {
push(@homeservers,&homeserver($caller,$codedom));
}
- foreach (keys %{$instcodes}) {
- $courses .= &escape($_).'='.&escape($$instcodes{$_}).'&';
+ foreach my $code (keys(%{$instcodes})) {
+ $courses .= &escape($code).'='.&escape($$instcodes{$code}).'&';
}
chop($courses);
my $ok_response = 0;
@@ -4216,7 +4479,7 @@ sub auto_instcode_format {
$response=&reply('autoinstcodeformat:'.$codedom.':'.$courses,$server);
if ($response !~ /(con_lost|error|no_such_host|refused)/) {
my ($codes_str,$codetitles_str,$cat_titles_str,$cat_order_str) =
- split/:/,$response;
+ split/:/,$response;
%{$codes} = (%{$codes},&str2hash($codes_str));
push(@{$codetitles},&str2array($codetitles_str));
%{$cat_titles} = (%{$cat_titles},&str2hash($cat_titles_str));
@@ -4231,7 +4494,41 @@ sub auto_instcode_format {
}
}
-sub autovalidateclass_sec {
+sub auto_instcode_defaults {
+ my ($domain,$returnhash,$code_order) = @_;
+ my @homeservers;
+ foreach my $tryserver (keys(%libserv)) {
+ if ($hostdom{$tryserver} eq $domain) {
+ if (!grep(/^\Q$tryserver\E$/,@homeservers)) {
+ push(@homeservers,$tryserver);
+ }
+ }
+ }
+ my $ok_response = 0;
+ my $response;
+ while (@homeservers > 0 && $ok_response == 0) {
+ my $server = shift(@homeservers);
+ $response=&reply('autoinstcodedefaults:'.$domain,$server);
+ if ($response !~ /(con_lost|error|no_such_host|refused)/) {
+ foreach my $pair (split(/\&/,$response)) {
+ my ($name,$value)=split(/\=/,$pair);
+ if ($name eq 'code_order') {
+ @{$code_order} = split(/\&/,&unescape($value));
+ } else {
+ $returnhash->{&unescape($name)}=&unescape($value);
+ }
+ }
+ $ok_response = 1;
+ }
+ }
+ if ($ok_response) {
+ return 'ok';
+ } else {
+ return $response;
+ }
+}
+
+sub auto_validate_class_sec {
my ($cdom,$cnum,$owner,$inst_class) = @_;
my $homeserver = &homeserver($cnum,$cdom);
my $response=&reply('autovalidateclass_sec:'.$inst_class.':'.
@@ -4242,8 +4539,8 @@ sub autovalidateclass_sec {
# ------------------------------------------------------- Course Group routines
sub get_coursegroups {
- my ($cdom,$cnum,$group) = @_;
- return(&dump('coursegroups',$cdom,$cnum,$group));
+ my ($cdom,$cnum,$group,$namespace) = @_;
+ return(&dump($namespace,$cdom,$cnum,$group));
}
sub modify_coursegroup {
@@ -4251,6 +4548,37 @@ sub modify_coursegroup {
return(&put('coursegroups',$groupsettings,$cdom,$cnum));
}
+sub toggle_coursegroup_status {
+ my ($cdom,$cnum,$group,$action) = @_;
+ my ($from_namespace,$to_namespace);
+ if ($action eq 'delete') {
+ $from_namespace = 'coursegroups';
+ $to_namespace = 'deleted_groups';
+ } else {
+ $from_namespace = 'deleted_groups';
+ $to_namespace = 'coursegroups';
+ }
+ my %curr_group = &get_coursegroups($cdom,$cnum,$group,$from_namespace);
+ if (my $tmp = &error(%curr_group)) {
+ &Apache::lonnet::logthis('Error retrieving group: '.$tmp.' in '.$cnum.':'.$cdom);
+ return ('read error',$tmp);
+ } else {
+ my %savedsettings = %curr_group;
+ my $result = &put($to_namespace,\%savedsettings,$cdom,$cnum);
+ my $deloutcome;
+ if ($result eq 'ok') {
+ $deloutcome = &del($from_namespace,[$group],$cdom,$cnum);
+ } else {
+ return ('write error',$result);
+ }
+ if ($deloutcome eq 'ok') {
+ return 'ok';
+ } else {
+ return ('delete error',$deloutcome);
+ }
+ }
+}
+
sub modify_group_roles {
my ($cdom,$cnum,$group_id,$user,$end,$start,$userprivs) = @_;
my $url = '/'.$cdom.'/'.$cnum.'/'.$group_id;
@@ -4274,7 +4602,7 @@ sub get_active_groups {
my $now = time;
my %groups = ();
foreach my $key (keys(%env)) {
- if ($key =~ m-user\.role\.gr\./([^/]+)/([^/]+)/(\w+)$-) {
+ if ($key =~ m-user\.role\.gr\./($match_domain)/($match_courseid)/(\w+)$-) {
my ($start,$end) = split(/\./,$env{$key});
if (($end!=0) && ($end<$now)) { next; }
if (($start!=0) && ($start>$now)) { next; }
@@ -4295,8 +4623,6 @@ sub get_users_groups {
my ($udom,$uname,$courseid) = @_;
my @usersgroups;
my $cachetime=1800;
- $courseid=~s/\_/\//g;
- $courseid=~s/^(\w)/\/$1/;
my $hashid="$udom:$uname:$courseid";
my ($grouplist,$cached)=&is_cached_new('getgroups',$hashid);
@@ -4304,38 +4630,34 @@ sub get_users_groups {
@usersgroups = split(/:/,$grouplist);
} else {
$grouplist = '';
- my %roleshash = &dump('roles',$udom,$uname,$courseid);
- my ($tmp) = keys(%roleshash);
- if ($tmp=~/^error:/) {
- &logthis('Error retrieving roles: '.$tmp.' for '.$uname.':'.$udom);
- } else {
- my $access_end = $env{'course.'.$courseid.
- '.default_enrollment_end_date'};
- my $now = time;
- foreach my $key (keys(%roleshash)) {
- if ($key =~ /^\Q$courseid\E\/(\w+)\_gr$/) {
- my $group = $1;
- if ($roleshash{$key} =~ /_(\d+)_(\d+)$/) {
- my $start = $2;
- my $end = $1;
- if ($start == -1) { next; } # deleted from group
- if (($start!=0) && ($start>$now)) { next; }
- if (($end!=0) && ($end<$now)) {
- if ($access_end && $access_end < $now) {
- if ($access_end - $end < 86400) {
- push(@usersgroups,$group);
- }
+ my $courseurl = &courseid_to_courseurl($courseid);
+ my %roleshash = &dump('roles',$udom,$uname,$courseurl);
+ my $access_end = $env{'course.'.$courseid.
+ '.default_enrollment_end_date'};
+ my $now = time;
+ foreach my $key (keys(%roleshash)) {
+ if ($key =~ /^\Q$courseurl\E\/(\w+)\_gr$/) {
+ my $group = $1;
+ if ($roleshash{$key} =~ /_(\d+)_(\d+)$/) {
+ my $start = $2;
+ my $end = $1;
+ if ($start == -1) { next; } # deleted from group
+ if (($start!=0) && ($start>$now)) { next; }
+ if (($end!=0) && ($end<$now)) {
+ if ($access_end && $access_end < $now) {
+ if ($access_end - $end < 86400) {
+ push(@usersgroups,$group);
}
- next;
}
- push(@usersgroups,$group);
+ next;
}
+ push(@usersgroups,$group);
}
}
- @usersgroups = &sort_course_groups($courseid,@usersgroups);
- $grouplist = join(':',@usersgroups);
- &do_cache_new('getgroups',$hashid,$grouplist,$cachetime);
}
+ @usersgroups = &sort_course_groups($courseid,@usersgroups);
+ $grouplist = join(':',@usersgroups);
+ &do_cache_new('getgroups',$hashid,$grouplist,$cachetime);
}
return @usersgroups;
}
@@ -4343,8 +4665,7 @@ sub get_users_groups {
sub devalidate_getgroups_cache {
my ($udom,$uname,$cdom,$cnum)=@_;
my $courseid = $cdom.'_'.$cnum;
- $courseid=~s/\_/\//g;
- $courseid=~s/^(\w)/\/$1/;
+
my $hashid="$udom:$uname:$courseid";
&devalidate_cache_new('getgroups',$hashid);
}
@@ -4383,7 +4704,7 @@ sub assignrole {
my $mrole;
if ($role =~ /^cr\//) {
my $cwosec=$url;
- $cwosec=~s/^\/(\w+)\/(\w+)\/.*/$1\/$2/;
+ $cwosec=~s/^\/($match_domain)\/($match_courseid)\/.*/$1\/$2/;
unless (&allowed('ccr',$cwosec)) {
&logthis('Refused custom assignrole: '.
$udom.' '.$uname.' '.$url.' '.$role.' '.$end.' '.$start.' by '.
@@ -4393,7 +4714,7 @@ sub assignrole {
$mrole='cr';
} elsif ($role =~ /^gr\//) {
my $cwogrp=$url;
- $cwogrp=~s/^\/(\w+)\/(\w+)\/.*/$1\/$2/;
+ $cwogrp=~s{^/($match_domain)/($match_courseid)/.*}{$1/$2};
unless (&allowed('mdg',$cwogrp)) {
&logthis('Refused group assignrole: '.
$udom.' '.$uname.' '.$url.' '.$role.' '.$end.' '.$start.' by '.
@@ -4403,7 +4724,7 @@ sub assignrole {
$mrole='gr';
} else {
my $cwosec=$url;
- $cwosec=~s/^\/(\w+)\/(\w+)\/.*/$1\/$2/;
+ $cwosec=~s/^\/($match_domain)\/($match_courseid)\/.*/$1\/$2/;
unless ((&allowed('c'.$role,$cwosec)) || &allowed('c'.$role,$udom)) {
&logthis('Refused assignrole: '.
$udom.' '.$uname.' '.$url.' '.$role.' '.$end.' '.$start.' by '.
@@ -4483,8 +4804,8 @@ sub modifyuser {
$umode, $upass, $first,
$middle, $last, $gene,
$forceid, $desiredhome, $email)=@_;
- $udom=~s/\W//g;
- $uname=~s/\W//g;
+ $udom= &LONCAPA::clean_domain($udom);
+ $uname=&LONCAPA::clean_username($uname);
&logthis('Call to modify user '.$udom.', '.$uname.', '.$uid.', '.
$umode.', '.$first.', '.$middle.', '.
$last.', '.$gene.'(forceid: '.$forceid.')'.
@@ -4633,8 +4954,8 @@ sub modify_student_enrollment {
['firstname','middlename','lastname', 'generation','id']
,$udom,$uname);
- #foreach (keys(%tmp)) {
- # &logthis("key $_ = ".$tmp{$_});
+ #foreach my $key (keys(%tmp)) {
+ # &logthis("key $key = ".$tmp{$key});
#}
$first = $tmp{'firstname'} if (!defined($first) || $first eq '');
$middle = $tmp{'middlename'} if (!defined($middle) || $middle eq '');
@@ -4692,8 +5013,8 @@ sub writecoursepref {
return 'error: no such course';
}
my $cstring='';
- foreach (keys %prefs) {
- $cstring.=escape($_).'='.escape($prefs{$_}).'&';
+ foreach my $pref (keys(%prefs)) {
+ $cstring.=&escape($pref).'='.&escape($prefs{$pref}).'&';
}
$cstring=~s/\&$//;
return reply('put:'.$cdomain.':'.$cnum.':environment:'.$cstring,$chome);
@@ -4769,6 +5090,16 @@ ENDINITMAP
return '/'.$udom.'/'.$uname;
}
+sub is_course {
+ my ($cdom,$cnum) = @_;
+ my %courses = &courseiddump($cdom,'.',1,'.','.',$cnum,undef,
+ undef,'.');
+ if (exists($courses{$cdom.'_'.$cnum})) {
+ return 1;
+ }
+ return 0;
+}
+
# ---------------------------------------------------------- Assign Custom Role
sub assigncustomrole {
@@ -4827,9 +5158,7 @@ sub is_locked {
sub declutter_portfile {
my ($file) = @_;
- &logthis("got $file");
- $file =~ s-^(/portfolio/|portfolio/)-/-;
- &logthis("ret $file");
+ $file =~ s{^(/portfolio/|portfolio/)}{/};
return $file;
}
@@ -4900,20 +5229,20 @@ sub files_not_in_path {
my $filename = $user."savedfiles";
my @return_files;
my $path_part;
- open (IN, '<'.$Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/'.$filename);
- while () {
+ open(IN, '<'.$Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/'.$filename);
+ while (my $line = ) {
#ok, I know it's clunky, but I want it to work
- my @paths_and_file = split m!/!, $_;
- my $file_part = pop (@paths_and_file);
- chomp ($file_part);
- my $path_part = join ('/', @paths_and_file);
+ my @paths_and_file = split(m|/|, $line);
+ my $file_part = pop(@paths_and_file);
+ chomp($file_part);
+ my $path_part = join('/', @paths_and_file);
$path_part .= '/';
my $path_and_file = $path_part.$file_part;
if ($path_part ne $path) {
- push (@return_files, ($path_and_file));
+ push(@return_files, ($path_and_file));
}
}
- close (OUT);
+ close(OUT);
return (@return_files);
}
@@ -4976,8 +5305,13 @@ sub modify_access_controls {
for (my $i=0; $i<$numnew; $i++) {
my $newkey = $newitems[$i];
my $newid = &Apache::loncommon::get_cgi_id();
- $newkey =~ s/^(\d+)/$newid/;
- $translation{$1} = $newid;
+ if ($newkey =~ /^\d+:/) {
+ $newkey =~ s/^(\d+)/$newid/;
+ $translation{$1} = $newid;
+ } elsif ($newkey =~ /^\d+_\d+_\d+:/) {
+ $newkey =~ s/^(\d+_\d+_\d+)/$newid/;
+ $translation{$1} = $newid;
+ }
$new_values{$file_name."\0".$newkey} =
$$changes{'activate'}{$newitems[$i]};
$new_control{$newkey} = $now;
@@ -5042,12 +5376,68 @@ sub modify_access_controls {
# remove lock
my @del_lock = ($file_name."\0".'locked_access_records');
my $dellockoutcome = &del('file_permissions',\@del_lock,$domain,$user);
+ my ($file,$group);
+ if (&is_course($domain,$user)) {
+ ($group,$file) = split(/\//,$file_name,2);
+ } else {
+ $file = $file_name;
+ }
+ my $sqlresult =
+ &update_portfolio_table($user,$domain,$file,'portfolio_access',
+ $group);
} else {
$outcome = "error: could not obtain lockfile\n";
}
return ($outcome,$deloutcome,\%new_values,\%translation);
}
+sub make_public_indefinitely {
+ my ($requrl) = @_;
+ my $now = time;
+ my $action = 'activate';
+ my $aclnum = 0;
+ if (&is_portfolio_url($requrl)) {
+ my (undef,$udom,$unum,$file_name,$group) =
+ &parse_portfolio_url($requrl);
+ my $current_perms = &get_portfile_permissions($udom,$unum);
+ my %access_controls = &get_access_controls($current_perms,
+ $group,$file_name);
+ foreach my $key (keys(%{$access_controls{$file_name}})) {
+ my ($num,$scope,$end,$start) =
+ ($key =~ /^([^:]+):([a-z]+)_(\d*)_?(\d*)$/);
+ if ($scope eq 'public') {
+ if ($start <= $now && $end == 0) {
+ $action = 'none';
+ } else {
+ $action = 'update';
+ $aclnum = $num;
+ }
+ last;
+ }
+ }
+ if ($action eq 'none') {
+ return 'ok';
+ } else {
+ my %changes;
+ my $newend = 0;
+ my $newstart = $now;
+ my $newkey = $aclnum.':public_'.$newend.'_'.$newstart;
+ $changes{$action}{$newkey} = {
+ type => 'public',
+ time => {
+ start => $newstart,
+ end => $newend,
+ },
+ };
+ my ($outcome,$deloutcome,$new_values,$translation) =
+ &modify_access_controls($file_name,\%changes,$udom,$unum);
+ return $outcome;
+ }
+ } else {
+ return 'invalid';
+ }
+}
+
#------------------------------------------------------Get Marked as Read Only
sub get_marked_as_readonly {
@@ -5177,28 +5567,27 @@ sub dirlist {
if($udom) {
if($uname) {
- my $listing=reply('ls2:'.$dirRoot.'/'.$uri,
- homeserver($uname,$udom));
+ my $listing = &reply('ls2:'.$dirRoot.'/'.$uri,
+ &homeserver($uname,$udom));
my @listing_results;
if ($listing eq 'unknown_cmd') {
- $listing=reply('ls:'.$dirRoot.'/'.$uri,
- homeserver($uname,$udom));
+ $listing = &reply('ls:'.$dirRoot.'/'.$uri,
+ &homeserver($uname,$udom));
@listing_results = split(/:/,$listing);
} else {
@listing_results = map { &unescape($_); } split(/:/,$listing);
}
return @listing_results;
} elsif(!defined($alternateDirectoryRoot)) {
- my $tryserver;
- my %allusers=();
- foreach $tryserver (keys %libserv) {
+ my %allusers;
+ foreach my $tryserver (keys(%libserv)) {
if($hostdom{$tryserver} eq $udom) {
- my $listing=reply('ls2:'.$perlvar{'lonDocRoot'}.'/res/'.
- $udom, $tryserver);
+ my $listing = &reply('ls2:'.$perlvar{'lonDocRoot'}.'/res/'.
+ $udom, $tryserver);
my @listing_results;
if ($listing eq 'unknown_cmd') {
- $listing=reply('ls:'.$perlvar{'lonDocRoot'}.'/res/'.
- $udom, $tryserver);
+ $listing = &reply('ls:'.$perlvar{'lonDocRoot'}.'/res/'.
+ $udom, $tryserver);
@listing_results = split(/:/,$listing);
} else {
@listing_results =
@@ -5207,40 +5596,36 @@ sub dirlist {
if ($listing_results[0] ne 'no_such_dir' &&
$listing_results[0] ne 'empty' &&
$listing_results[0] ne 'con_lost') {
- foreach (@listing_results) {
- my ($entry,@stat)=split(/&/,$_);
- $allusers{$entry}=1;
+ foreach my $line (@listing_results) {
+ my ($entry) = split(/&/,$line,2);
+ $allusers{$entry} = 1;
}
}
}
}
my $alluserstr='';
- foreach (sort keys %allusers) {
- $alluserstr.=$_.'&user:';
+ foreach my $user (sort(keys(%allusers))) {
+ $alluserstr.=$user.'&user:';
}
$alluserstr=~s/:$//;
return split(/:/,$alluserstr);
} else {
- my @emptyResults = ();
- push(@emptyResults, 'missing user name');
- return split(':',@emptyResults);
+ return ('missing user name');
}
} elsif(!defined($alternateDirectoryRoot)) {
my $tryserver;
my %alldom=();
- foreach $tryserver (keys %libserv) {
+ foreach $tryserver (keys(%libserv)) {
$alldom{$hostdom{$tryserver}}=1;
}
my $alldomstr='';
- foreach (sort keys %alldom) {
- $alldomstr.=$perlvar{'lonDocRoot'}.'/res/'.$_.'/&domain:';
+ foreach my $domain (sort(keys(%alldom))) {
+ $alldomstr.=$perlvar{'lonDocRoot'}.'/res/'.$domain.'/&domain:';
}
$alldomstr=~s/:$//;
return split(/:/,$alldomstr);
} else {
- my @emptyResults = ();
- push(@emptyResults, 'missing domain');
- return split(':',@emptyResults);
+ return ('missing domain');
}
}
@@ -5258,8 +5643,8 @@ sub dirlist {
##
sub GetFileTimestamp {
my ($studentDomain,$studentName,$filename,$root)=@_;
- $studentDomain=~s/\W//g;
- $studentName=~s/\W//g;
+ $studentDomain = &LONCAPA::clean_domain($studentDomain);
+ $studentName = &LONCAPA::clean_username($studentName);
my $subdir=$studentName.'__';
$subdir =~ s/(.)(.)(.).*/$1\/$2\/$3/;
my $proname="$studentDomain/$subdir/$studentName";
@@ -5277,23 +5662,18 @@ sub GetFileTimestamp {
sub stat_file {
my ($uri) = @_;
- $uri = &clutter($uri);
+ $uri = &clutter_with_no_wrapper($uri);
- # we want just the url part without the unneeded accessor url bits
- if ($uri =~ m-^/adm/-) {
- $uri=~s-^/adm/wrapper/-/-;
- $uri=~s-^/adm/coursedocs/showdoc/-/-;
- }
my ($udom,$uname,$file,$dir);
if ($uri =~ m-^/(uploaded|editupload)/-) {
($udom,$uname,$file) =
- ($uri =~ m-/(?:uploaded|editupload)/?([^/]*)/?([^/]*)/?(.*)-);
+ ($uri =~ m-/(?:uploaded|editupload)/?($match_domain)/?($match_name)/?(.*)-);
$file = 'userfiles/'.$file;
$dir = &propath($udom,$uname);
}
if ($uri =~ m-^/res/-) {
($udom,$uname) =
- ($uri =~ m-/(?:res)/?([^/]*)/?([^/]*)/-);
+ ($uri =~ m-/(?:res)/?($match_domain)/?($match_username)/-);
$file = $uri;
}
@@ -5515,8 +5895,7 @@ sub EXT {
$symbparm=&get_symb_from_alias($symbparm);
}
if (!($uname && $udom)) {
- (my $cursymb,$courseid,$udom,$uname,$publicuser)=
- &Apache::lonxml::whichuser($symbparm);
+ (my $cursymb,$courseid,$udom,$uname,$publicuser)= &whichuser($symbparm);
if (!$symbparm) { $symbparm=$cursymb; }
} else {
$courseid=$env{'request.course.id'};
@@ -5875,7 +6254,7 @@ sub metadata {
(($uri =~ m|^/*adm/|) &&
($uri !~ m|^adm/includes|) && ($uri !~ m|/bulletinboard$|)) ||
($uri =~ m|/$|) || ($uri =~ m|/.meta$|) || ($uri =~ /^~/) ||
- ($uri =~ m|home/[^/]+/public_html/|)) {
+ ($uri =~ m|home/$match_username/public_html/|)) {
return undef;
}
my $filename=$uri;
@@ -6170,7 +6549,7 @@ sub gettitle {
sub get_slot {
my ($which,$cnum,$cdom)=@_;
if (!$cnum || !$cdom) {
- (undef,my $courseid)=&Apache::lonxml::whichuser();
+ (undef,my $courseid)=&whichuser();
$cdom=$env{'course.'.$courseid.'.domain'};
$cnum=$env{'course.'.$courseid.'.num'};
}
@@ -6219,9 +6598,6 @@ sub symblist {
sub symbverify {
my ($symb,$thisurl)=@_;
my $thisfn=$thisurl;
-# wrapper not part of symbs
- $thisfn=~s/^\/adm\/wrapper//;
- $thisfn=~s/^\/adm\/coursedocs\/showdoc\///;
$thisfn=&declutter($thisfn);
# direct jump to resource in page or to a sequence - will construct own symbs
if ($thisfn=~/\.(page|sequence)$/) { return 1; }
@@ -6245,13 +6621,13 @@ sub symbverify {
}
if ($ids) {
# ------------------------------------------------------------------- Has ID(s)
- foreach (split(/\,/,$ids)) {
- my ($mapid,$resid)=split(/\./,$_);
+ foreach my $id (split(/\,/,$ids)) {
+ my ($mapid,$resid)=split(/\./,$id);
if (
&symbclean(&declutter($bighash{'map_id_'.$mapid}).'___'.$resid.'___'.$thisfn)
eq $symb) {
if (($env{'request.role.adv'}) ||
- $bighash{'encrypted_'.$_} eq $env{'request.enc'}) {
+ $bighash{'encrypted_'.$id} eq $env{'request.enc'}) {
$okay=1;
}
}
@@ -6394,10 +6770,10 @@ sub symbread {
} elsif (!$donotrecurse) {
# ------------------------------------------ There is more than one possibility
my $realpossible=0;
- foreach (@possibilities) {
- my $file=$bighash{'src_'.$_};
+ foreach my $id (@possibilities) {
+ my $file=$bighash{'src_'.$id};
if (&allowed('bre',$file)) {
- my ($mapid,$resid)=split(/\./,$_);
+ my ($mapid,$resid)=split(/\./,$id);
if ($bighash{'map_type_'.$mapid} ne 'page') {
$realpossible++;
$syval=&encode_symb($bighash{'map_id_'.$mapid},
@@ -6504,7 +6880,7 @@ sub latest_rnd_algorithm_id {
sub get_rand_alg {
my ($courseid)=@_;
- if (!$courseid) { $courseid=(&Apache::lonxml::whichuser())[1]; }
+ if (!$courseid) { $courseid=(&whichuser())[1]; }
if ($courseid) {
return $env{"course.$courseid.rndseed"};
}
@@ -6530,7 +6906,7 @@ sub getCODE {
sub rndseed {
my ($symb,$courseid,$domain,$username)=@_;
- my ($wsymb,$wcourseid,$wdomain,$wusername)=&Apache::lonxml::whichuser();
+ my ($wsymb,$wcourseid,$wdomain,$wusername)=&whichuser();
if (!$symb) {
unless ($symb=$wsymb) { return time; }
}
@@ -6538,6 +6914,7 @@ sub rndseed {
if (!$domain) { $domain=$wdomain; }
if (!$username) { $username=$wusername }
my $which=&get_rand_alg();
+
if (defined(&getCODE())) {
if ($which eq '64bit5') {
return &rndseed_CODE_64bit5($symb,$courseid,$domain,$username);
@@ -6571,8 +6948,8 @@ sub rndseed_32bit {
my $domainseed=unpack("%32C*",$domain) << 7;
my $courseseed=unpack("%32C*",$courseid);
my $num=$symbseed+$nameseed+$domainseed+$courseseed+$namechck+$symbchck;
- #&Apache::lonxml::debug("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck");
- #&Apache::lonxml::debug("rndseed :$num:$symb");
+ #&logthis("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck");
+ #&logthis("rndseed :$num:$symb");
if ($_64bit) { $num=(($num<<32)>>32); }
return $num;
}
@@ -6592,9 +6969,8 @@ sub rndseed_64bit {
my $num1=$symbchck+$symbseed+$namechck;
my $num2=$nameseed+$domainseed+$courseseed;
- #&Apache::lonxml::debug("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck");
- #&Apache::lonxml::debug("rndseed :$num:$symb");
- if ($_64bit) { $num1=(($num1<<32)>>32); $num2=(($num2<<32)>>32); }
+ #&logthis("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck");
+ #&logthis("rndseed :$num:$symb");
if ($_64bit) { $num1=(($num1<<32)>>32); $num2=(($num2<<32)>>32); }
return "$num1,$num2";
}
@@ -6616,8 +6992,9 @@ sub rndseed_64bit2 {
my $num1=$symbchck+$symbseed+$namechck;
my $num2=$nameseed+$domainseed+$courseseed;
- #&Apache::lonxml::debug("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck");
- #&Apache::lonxml::debug("rndseed :$num:$symb");
+ #&logthis("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck");
+ #&logthis("rndseed :$num:$symb");
+ if ($_64bit) { $num1=(($num1<<32)>>32); $num2=(($num2<<32)>>32); }
return "$num1,$num2";
}
}
@@ -6638,8 +7015,8 @@ sub rndseed_64bit3 {
my $num1=$symbchck+$symbseed+$namechck;
my $num2=$nameseed+$domainseed+$courseseed;
- #&Apache::lonxml::debug("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck");
- #&Apache::lonxml::debug("rndseed :$num1:$num2:$_64bit");
+ #&logthis("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck");
+ #&logthis("rndseed :$num1:$num2:$_64bit");
if ($_64bit) { $num1=(($num1<<32)>>32); $num2=(($num2<<32)>>32); }
return "$num1:$num2";
@@ -6662,8 +7039,8 @@ sub rndseed_64bit4 {
my $num1=$symbchck+$symbseed+$namechck;
my $num2=$nameseed+$domainseed+$courseseed;
- #&Apache::lonxml::debug("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck");
- #&Apache::lonxml::debug("rndseed :$num1:$num2:$_64bit");
+ #&logthis("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck");
+ #&logthis("rndseed :$num1:$num2:$_64bit");
if ($_64bit) { $num1=(($num1<<32)>>32); $num2=(($num2<<32)>>32); }
return "$num1:$num2";
@@ -6687,8 +7064,8 @@ sub rndseed_CODE_64bit {
my $courseseed=unpack("%32S*",$courseid.' ');
my $num1=$symbseed+$CODEchck;
my $num2=$CODEseed+$courseseed+$symbchck;
- #&Apache::lonxml::debug("$symbseed:$CODEchck|$CODEseed:$courseseed:$symbchck");
- #&Apache::lonxml::debug("rndseed :$num1:$num2:$symb");
+ #&logthis("$symbseed:$CODEchck|$CODEseed:$courseseed:$symbchck");
+ #&logthis("rndseed :$num1:$num2:$symb");
if ($_64bit) { $num1=(($num1<<32)>>32); }
if ($_64bit) { $num2=(($num2<<32)>>32); }
return "$num1:$num2";
@@ -6706,8 +7083,8 @@ sub rndseed_CODE_64bit4 {
my $courseseed=unpack("%32S*",$courseid.' ');
my $num1=$symbseed+$CODEchck;
my $num2=$CODEseed+$courseseed+$symbchck;
- #&Apache::lonxml::debug("$symbseed:$CODEchck|$CODEseed:$courseseed:$symbchck");
- #&Apache::lonxml::debug("rndseed :$num1:$num2:$symb");
+ #&logthis("$symbseed:$CODEchck|$CODEseed:$courseseed:$symbchck");
+ #&logthis("rndseed :$num1:$num2:$symb");
if ($_64bit) { $num1=(($num1<<32)>>32); }
if ($_64bit) { $num2=(($num2<<32)>>32); }
return "$num1:$num2";
@@ -6732,13 +7109,14 @@ sub setup_random_from_rndseed {
}
sub latest_receipt_algorithm_id {
- return 'receipt2';
+ return 'receipt3';
}
sub recunique {
my $fucourseid=shift;
my $unique;
- if ($env{"course.$fucourseid.receiptalg"} eq 'receipt2') {
+ if ($env{"course.$fucourseid.receiptalg"} eq 'receipt2' ||
+ $env{"course.$fucourseid.receiptalg"} eq 'receipt3' ) {
$unique=$env{"course.$fucourseid.internal.encseed"};
} else {
$unique=$perlvar{'lonReceipt'};
@@ -6749,7 +7127,8 @@ sub recunique {
sub recprefix {
my $fucourseid=shift;
my $prefix;
- if ($env{"course.$fucourseid.receiptalg"} eq 'receipt2') {
+ if ($env{"course.$fucourseid.receiptalg"} eq 'receipt2'||
+ $env{"course.$fucourseid.receiptalg"} eq 'receipt3' ) {
$prefix=$env{"course.$fucourseid.internal.encpref"};
} else {
$prefix=$perlvar{'lonHostID'};
@@ -6759,17 +7138,24 @@ sub recprefix {
sub ireceipt {
my ($funame,$fudom,$fucourseid,$fusymb,$part)=@_;
+
+ my $return =&recprefix($fucourseid).'-';
+
+ if ($env{"course.$fucourseid.receiptalg"} eq 'receipt3' ||
+ $env{'request.state'} eq 'construct') {
+ $return .= (&digest("$funame,$fudom,$fucourseid,$fusymb,$part")%10000);
+ return $return;
+ }
+
my $cuname=unpack("%32C*",$funame);
my $cudom=unpack("%32C*",$fudom);
my $cucourseid=unpack("%32C*",$fucourseid);
my $cusymb=unpack("%32C*",$fusymb);
my $cunique=&recunique($fucourseid);
my $cpart=unpack("%32S*",$part);
- my $return =&recprefix($fucourseid).'-';
- if ($env{"course.$fucourseid.receiptalg"} eq 'receipt2' ||
- $env{'request.state'} eq 'construct') {
- &Apache::lonxml::debug("doing receipt2 using parts $cpart, uname $cuname and udom $cudom gets ".($cpart%$cuname).
- " and ".($cpart%$cudom));
+ if ($env{"course.$fucourseid.receiptalg"} eq 'receipt2') {
+
+ #&logthis("doing receipt2 using parts $cpart, uname $cuname and udom $cudom gets ".($cpart%$cuname)." and ".($cpart%$cudom));
$return.= ($cunique%$cuname+
$cunique%$cudom+
@@ -6792,10 +7178,48 @@ sub ireceipt {
sub receipt {
my ($part)=@_;
- my ($symb,$courseid,$domain,$name) = &Apache::lonxml::whichuser();
+ my ($symb,$courseid,$domain,$name) = &whichuser();
return &ireceipt($name,$domain,$courseid,$symb,$part);
}
+sub whichuser {
+ my ($passedsymb)=@_;
+ my ($symb,$courseid,$domain,$name,$publicuser);
+ if (defined($env{'form.grade_symb'})) {
+ my ($tmp_courseid)=&get_env_multiple('form.grade_courseid');
+ my $allowed=&allowed('vgr',$tmp_courseid);
+ if (!$allowed &&
+ exists($env{'request.course.sec'}) &&
+ $env{'request.course.sec'} !~ /^\s*$/) {
+ $allowed=&allowed('vgr',$tmp_courseid.
+ '/'.$env{'request.course.sec'});
+ }
+ if ($allowed) {
+ ($symb)=&get_env_multiple('form.grade_symb');
+ $courseid=$tmp_courseid;
+ ($domain)=&get_env_multiple('form.grade_domain');
+ ($name)=&get_env_multiple('form.grade_username');
+ return ($symb,$courseid,$domain,$name,$publicuser);
+ }
+ }
+ if (!$passedsymb) {
+ $symb=&symbread();
+ } else {
+ $symb=$passedsymb;
+ }
+ $courseid=$env{'request.course.id'};
+ $domain=$env{'user.domain'};
+ $name=$env{'user.name'};
+ if ($name eq 'public' && $domain eq 'public') {
+ if (!defined($env{'form.username'})) {
+ $env{'form.username'}.=time.rand(10000000);
+ }
+ $name.=$env{'form.username'};
+ }
+ return ($symb,$courseid,$domain,$name,$publicuser);
+
+}
+
# ------------------------------------------------------------ Serves up a file
# returns either the contents of the file or
# -1 if the file doesn't exist
@@ -6818,61 +7242,60 @@ sub repcopy_userfile {
if ($file =~ m -^/*(uploaded|editupload)/-) { $file=&filelocation("",$file); }
if ($file =~ m|^/home/httpd/html/lonUsers/|) { return 'ok'; }
my ($cdom,$cnum,$filename) =
- ($file=~m|^\Q$perlvar{'lonDocRoot'}\E/+userfiles/+([^/]+)/+([^/]+)/+(.*)|);
- my ($info,$rtncode);
+ ($file=~m|^\Q$perlvar{'lonDocRoot'}\E/+userfiles/+($match_domain)/+($match_name)/+(.*)|);
my $uri="/uploaded/$cdom/$cnum/$filename";
if (-e "$file") {
+# we already have a local copy, check it out
my @fileinfo = stat($file);
+ my $rtncode;
+ my $info;
my $lwpresp = &getuploaded('HEAD',$uri,$cdom,$cnum,\$info,\$rtncode);
if ($lwpresp ne 'ok') {
+# there is no such file anymore, even though we had a local copy
if ($rtncode eq '404') {
unlink($file);
}
- #my $ua=new LWP::UserAgent;
- #my $request=new HTTP::Request('GET',&tokenwrapper($uri));
- #my $response=$ua->request($request);
- #if ($response->is_success()) {
- # return $response->content;
- # } else {
- # return -1;
- # }
return -1;
}
if ($info < $fileinfo[9]) {
+# nice, the file we have is up-to-date, just say okay
return 'ok';
+ } else {
+# the file is outdated, get rid of it
+ unlink($file);
}
- $info = '';
- $lwpresp = &getuploaded('GET',$uri,$cdom,$cnum,\$info,\$rtncode);
- if ($lwpresp ne 'ok') {
- return -1;
- }
- } else {
- my $lwpresp = &getuploaded('GET',$uri,$cdom,$cnum,\$info,\$rtncode);
- if ($lwpresp ne 'ok') {
- my $ua=new LWP::UserAgent;
- my $request=new HTTP::Request('GET',&tokenwrapper($uri));
- my $response=$ua->request($request);
- if ($response->is_success()) {
- $info=$response->content;
- } else {
- return -1;
- }
- }
- my @parts = ($cdom,$cnum);
- if ($filename =~ m|^(.+)/[^/]+$|) {
- push @parts, split(/\//,$1);
- }
- my $path = $perlvar{'lonDocRoot'}.'/userfiles';
- foreach my $part (@parts) {
- $path .= '/'.$part;
- if (!-e $path) {
- mkdir($path,0770);
- }
+ }
+# one way or the other, at this point, we don't have the file
+# construct the correct path for the file
+ my @parts = ($cdom,$cnum);
+ if ($filename =~ m|^(.+)/[^/]+$|) {
+ push @parts, split(/\//,$1);
+ }
+ my $path = $perlvar{'lonDocRoot'}.'/userfiles';
+ foreach my $part (@parts) {
+ $path .= '/'.$part;
+ if (!-e $path) {
+ mkdir($path,0770);
}
}
- open(FILE,">$file");
- print FILE $info;
- close(FILE);
+# now the path exists for sure
+# get a user agent
+ my $ua=new LWP::UserAgent;
+ my $transferfile=$file.'.in.transfer';
+# FIXME: this should flock
+ if (-e $transferfile) { return 'ok'; }
+ my $request;
+ $uri=~s/^\///;
+ $request=new HTTP::Request('GET','http://'.$hostname{&homeserver($cnum,$cdom)}.'/raw/'.$uri);
+ my $response=$ua->request($request,$transferfile);
+# did it work?
+ if ($response->is_error()) {
+ unlink($transferfile);
+ &logthis("Userfile repcopy failed for $uri");
+ return -1;
+ }
+# worked, rename the transfer file
+ rename($transferfile,$file);
return 'ok';
}
@@ -6894,6 +7317,10 @@ sub tokenwrapper {
}
}
+# call with reqtype HEAD: get last modification time
+# call with reqtype GET: get the file contents
+# Do not call this with reqtype GET for large files! It loads everything into memory
+#
sub getuploaded {
my ($reqtype,$uri,$cdom,$cnum,$info,$rtncode) = @_;
$uri=~s/^\///;
@@ -6919,7 +7346,7 @@ sub readfile {
my $fh;
open($fh,"<$file");
my $a='';
- while (<$fh>) { $a .=$_; }
+ while (my $line = <$fh>) { $a .= $line; }
return $a;
}
@@ -6935,12 +7362,12 @@ sub filelocation {
if ($file=~m:^/~:) { # is a contruction space reference
$location = $file;
$location =~ s:/~(.*?)/(.*):/home/$1/public_html/$2:;
- } elsif ($file=~m:^/home/[^/]*/public_html/:) {
+ } elsif ($file=~m{^/home/$match_username/public_html/}) {
# is a correct contruction space reference
$location = $file;
} elsif ($file=~/^\/*(uploaded|editupload)/) { # is an uploaded file
my ($udom,$uname,$filename)=
- ($file=~m -^/+(?:uploaded|editupload)/+([^/]+)/+([^/]+)/+(.*)$-);
+ ($file=~m -^/+(?:uploaded|editupload)/+($match_domain)/+($match_name)/+(.*)$-);
my $home=&homeserver($uname,$udom);
my $is_me=0;
my @ids=¤t_machine_ids();
@@ -6977,10 +7404,10 @@ sub hreflocation {
}
if ($file=~m-^\Q$perlvar{'lonDocRoot'}\E-) {
$file=~s-^\Q$perlvar{'lonDocRoot'}\E--;
- } elsif ($file=~m-/home/(\w+)/public_html/-) {
- $file=~s-^/home/(\w+)/public_html/-/~$1/-;
+ } elsif ($file=~m-/home/($match_username)/public_html/-) {
+ $file=~s-^/home/($match_username)/public_html/-/~$1/-;
} elsif ($file=~m-^\Q$perlvar{'lonUsersDir'}\E-) {
- $file=~s-^/home/httpd/lonUsers/([^/]*)/./././([^/]*)/userfiles/
+ $file=~s-^/home/httpd/lonUsers/($match_domain)/./././($match_name)/userfiles/
-/uploaded/$1/$2/-x;
}
return $file;
@@ -7010,6 +7437,29 @@ sub current_machine_ids {
return @ids;
}
+sub additional_machine_domains {
+ my @domains;
+ open(my $fh,"<$perlvar{'lonTabDir'}/expected_domains.tab");
+ while( my $line = <$fh>) {
+ $line =~ s/\s//g;
+ push(@domains,$line);
+ }
+ return @domains;
+}
+
+sub default_login_domain {
+ my $domain = $perlvar{'lonDefDomain'};
+ my $testdomain=(split(/\./,$ENV{'HTTP_HOST'}))[0];
+ foreach my $posdom (¤t_machine_domains(),
+ &additional_machine_domains()) {
+ if (lc($posdom) eq lc($testdomain)) {
+ $domain=$posdom;
+ last;
+ }
+ }
+ return $domain;
+}
+
# ------------------------------------------------------------- Declutters URLs
sub declutter {
@@ -7058,6 +7508,15 @@ sub clutter {
return $thisfn;
}
+sub clutter_with_no_wrapper {
+ my $uri = &clutter(shift);
+ if ($uri =~ m-^/adm/-) {
+ $uri =~ s-^/adm/wrapper/-/-;
+ $uri =~ s-^/adm/coursedocs/showdoc/-/-;
+ }
+ return $uri;
+}
+
sub freeze_escape {
my ($value)=@_;
if (ref($value)) {
@@ -7110,29 +7569,8 @@ BEGIN {
# ----------------------------------- Read loncapa.conf and loncapa_apache.conf
unless ($readit) {
{
- # FIXME: Use LONCAPA::Configuration::read_conf here and omit next block
- open(my $config,") {
- if ($configline=~/\S/ && $configline =~ /^[^\#]*PerlSetVar/) {
- my ($dummy,$varname,$varvalue)=split(/\s+/,$configline);
- chomp($varvalue);
- $perlvar{$varname}=$varvalue;
- }
- }
- close($config);
-}
-{
- open(my $config,") {
- if ($configline =~ /^[^\#]*PerlSetVar/) {
- my ($dummy,$varname,$varvalue)=split(/\s+/,$configline);
- chomp($varvalue);
- $perlvar{$varname}=$varvalue;
- }
- }
- close($config);
+ my $configvars = LONCAPA::Configuration::read_conf('loncapa.conf');
+ %perlvar = (%perlvar,%{$configvars});
}
# ------------------------------------------------------------ Read domain file
@@ -7142,12 +7580,12 @@ BEGIN {
%domain_auth_arg_def = ();
my $fh;
if (open($fh,"<".$Apache::lonnet::perlvar{'lonTabDir'}.'/domain.tab')) {
- while (<$fh>) {
- next if (/^(\#|\s*$)/);
+ while (my $line = <$fh>) {
+ next if ($line =~ /^(\#|\s*$)/);
# next if /^\#/;
- chomp;
+ chomp $line;
my ($domain, $domain_description, $def_auth, $def_auth_arg,
- $def_lang, $city, $longi, $lati, $primary) = split(/:/,$_);
+ $def_lang, $city, $longi, $lati, $primary) = split(/:/,$line,9);
$domain_auth_def{$domain}=$def_auth;
$domain_auth_arg_def{$domain}=$def_auth_arg;
$domaindescription{$domain}=$domain_description;
@@ -7194,7 +7632,7 @@ sub get_iphost {
if (!exists($name_to_ip{$name})) {
$ip = gethostbyname($name);
if (!$ip || length($ip) ne 4) {
- &logthis("Skipping host $id name $name no IP found\n");
+ &logthis("Skipping host $id name $name no IP found");
next;
}
$ip=inet_ntoa($ip);
@@ -7214,7 +7652,9 @@ sub get_iphost {
while (my $configline=<$config>) {
chomp($configline);
if ($configline) {
- $spareid{$configline}=1;
+ my ($host,$type) = split(':',$configline,2);
+ if (!defined($type) || $type eq '') { $type = 'default' };
+ push(@{ $spareid{$type} }, $host);
}
}
close($config);
@@ -7276,7 +7716,9 @@ sub get_iphost {
}
-$memcache=new Cache::Memcached({'servers'=>['127.0.0.1:11211']});
+$memcache=new Cache::Memcached({'servers' => ['127.0.0.1:11211'],
+ 'compress_threshold'=> 20_000,
+ });
$processmarker='_'.time.'_'.$perlvar{'lonHostID'};
$dumpcount=0;
@@ -7473,6 +7915,13 @@ B: removes all items fr
environment file that matches the regular expression in $regexp. The
values are also delted from the current processes %env.
+=item * get_env_multiple($name)
+
+gets $name from the %env hash, it seemlessly handles the cases where multiple
+values may be defined and end up as an array ref.
+
+returns an array of values
+
=back
=head2 User Information
@@ -7535,8 +7984,7 @@ passed in @what from the requested user'
=item *
-allowed($priv,$uri) : check for a user privilege; returns codes for allowed
-actions
+allowed($priv,$uri,$symb,$role) : check for a user privilege; returns codes for allowed actions
F: full access
U,I,K: authentication modes (cxx only)
'': forbidden
@@ -7555,6 +8003,19 @@ and course level
plaintext($short) : return value in %prp hash (rolesplain.tab); plain text
explanation of a user role term
+=item *
+
+get_my_roles($uname,$udom,$types,$roles,$roledoms) : All arguments are
+optional. Returns a hash of a user's roles, with keys set to
+colon-sparated $uname,$udom,and $role, and value set to
+colon-separated start and end times for the role. If no username and
+domain are specified, will default to current user/domain. Types,
+roles, and roledoms are references to arrays, of role statuses
+(active, future or previous), roles (e.g., cc,in, st etc.) and domains
+of the roles which can be used to restrict the list if roles
+reported. If no array ref is provided for types, will default to
+return only active roles.
+
=back
=head2 User Modification
@@ -7976,6 +8437,15 @@ reference filled in from namesp (encrypt
log($udom,$name,$home,$message) : write to permanent log for user; use
critical subroutine
+=item *
+
+get_dom($namespace,$storearr,$udomain) : returns hash with keys from array
+reference filled in from namespace found in domain level on primary domain server ($udomain is optional)
+
+=item *
+
+put_dom($namespace,$storehash,$udomain) : stores hash in namespace at domain level on primary domain server ($udomain is optional)
+
=back
=head2 Network Status Functions