version 1.602, 2005/03/02 22:26:36
|
version 1.833, 2007/02/18 01:51:20
|
Line 37 use HTTP::Date;
|
Line 37 use HTTP::Date;
|
use vars |
use vars |
qw(%perlvar %hostname %badServerCache %iphost %spareid %hostdom |
qw(%perlvar %hostname %badServerCache %iphost %spareid %hostdom |
%libserv %pr %prp $memcache %packagetab |
%libserv %pr %prp $memcache %packagetab |
%courselogs %accesshash %userrolehash $processmarker $dumpcount |
%courselogs %accesshash %userrolehash %domainrolehash $processmarker $dumpcount |
%coursedombuf %coursenumbuf %coursehombuf %coursedescrbuf %courseinstcodebuf %courseownerbuf |
%coursedombuf %coursenumbuf %coursehombuf %coursedescrbuf %courseinstcodebuf %courseownerbuf %coursetypebuf |
%domaindescription %domain_auth_def %domain_auth_arg_def |
%domaindescription %domain_auth_def %domain_auth_arg_def |
%domain_lang_def %domain_city %domain_longi %domain_lati $tmpdir $_64bit); |
%domain_lang_def %domain_city %domain_longi %domain_lati %domain_primary |
|
$tmpdir $_64bit %env); |
|
|
use IO::Socket; |
use IO::Socket; |
use GDBM_File; |
use GDBM_File; |
use Apache::Constants qw(:common :http); |
|
use HTML::LCParser; |
use HTML::LCParser; |
|
use HTML::Parser; |
use Fcntl qw(:flock); |
use Fcntl qw(:flock); |
use Apache::lonlocal; |
|
use Storable qw(lock_store lock_nstore lock_retrieve freeze thaw nfreeze); |
use Storable qw(lock_store lock_nstore lock_retrieve freeze thaw nfreeze); |
use Time::HiRes qw( gettimeofday tv_interval ); |
use Time::HiRes qw( gettimeofday tv_interval ); |
use Cache::Memcached; |
use Cache::Memcached; |
|
use Digest::MD5; |
|
use Math::Random; |
|
use LONCAPA qw(:DEFAULT :match); |
|
use LONCAPA::Configuration; |
|
|
my $readit; |
my $readit; |
my $max_connection_retries = 10; # Or some such value. |
my $max_connection_retries = 10; # Or some such value. |
|
|
|
require Exporter; |
|
|
|
our @ISA = qw (Exporter); |
|
our @EXPORT = qw(%env); |
|
|
=pod |
=pod |
|
|
=head1 Package Variables |
=head1 Package Variables |
Line 78 delayed.
|
Line 88 delayed.
|
|
|
|
|
# --------------------------------------------------------------------- Logging |
# --------------------------------------------------------------------- Logging |
|
{ |
|
my $logid; |
|
sub instructor_log { |
|
my ($hash_name,$storehash,$delflag,$uname,$udom)=@_; |
|
$logid++; |
|
my $id=time().'00000'.$$.'00000'.$logid; |
|
return &Apache::lonnet::put('nohist_'.$hash_name, |
|
{ $id => { |
|
'exe_uname' => $env{'user.name'}, |
|
'exe_udom' => $env{'user.domain'}, |
|
'exe_time' => time(), |
|
'exe_ip' => $ENV{'REMOTE_ADDR'}, |
|
'delflag' => $delflag, |
|
'logentry' => $storehash, |
|
'uname' => $uname, |
|
'udom' => $udom, |
|
} |
|
}, |
|
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
|
$env{'course.'.$env{'request.course.id'}.'.num'} |
|
); |
|
} |
|
} |
|
|
sub logtouch { |
sub logtouch { |
my $execdir=$perlvar{'lonDaemons'}; |
my $execdir=$perlvar{'lonDaemons'}; |
Line 116 sub logperm {
|
Line 149 sub logperm {
|
# -------------------------------------------------- Non-critical communication |
# -------------------------------------------------- Non-critical communication |
sub subreply { |
sub subreply { |
my ($cmd,$server)=@_; |
my ($cmd,$server)=@_; |
my $peerfile="$perlvar{'lonSockDir'}/$server"; |
my $peerfile="$perlvar{'lonSockDir'}/".$hostname{$server}; |
# |
# |
# With loncnew process trimming, there's a timing hole between lonc server |
# With loncnew process trimming, there's a timing hole between lonc server |
# process exit and the master server picking up the listen on the AF_UNIX |
# process exit and the master server picking up the listen on the AF_UNIX |
Line 144 sub subreply {
|
Line 177 sub subreply {
|
} |
} |
my $answer; |
my $answer; |
if ($client) { |
if ($client) { |
print $client "$cmd\n"; |
print $client "sethost:$server:$cmd\n"; |
$answer=<$client>; |
$answer=<$client>; |
if (!$answer) { $answer="con_lost"; } |
if (!$answer) { $answer="con_lost"; } |
chomp($answer); |
chomp($answer); |
Line 159 sub reply {
|
Line 192 sub reply {
|
unless (defined($hostname{$server})) { return 'no_such_host'; } |
unless (defined($hostname{$server})) { return 'no_such_host'; } |
my $answer=subreply($cmd,$server); |
my $answer=subreply($cmd,$server); |
if (($answer=~/^refused/) || ($answer=~/^rejected/)) { |
if (($answer=~/^refused/) || ($answer=~/^rejected/)) { |
&logthis("<font color=blue>WARNING:". |
&logthis("<font color=\"blue\">WARNING:". |
" $cmd to $server returned $answer</font>"); |
" $cmd to $server returned $answer</font>"); |
} |
} |
return $answer; |
return $answer; |
Line 183 sub reconlonc {
|
Line 216 sub reconlonc {
|
sleep 5; |
sleep 5; |
if (-e "$peerfile") { return; } |
if (-e "$peerfile") { return; } |
&logthis( |
&logthis( |
"<font color=blue>WARNING: $peerfile still not there, giving up</font>"); |
"<font color=\"blue\">WARNING: $peerfile still not there, giving up</font>"); |
} else { |
} else { |
&logthis( |
&logthis( |
"<font color=blue>WARNING:". |
"<font color=\"blue\">WARNING:". |
" lonc at pid $loncpid not responding, giving up</font>"); |
" lonc at pid $loncpid not responding, giving up</font>"); |
} |
} |
} else { |
} else { |
&logthis('<font color=blue>WARNING: lonc not running, giving up</font>'); |
&logthis('<font color="blue">WARNING: lonc not running, giving up</font>'); |
} |
} |
} |
} |
|
|
Line 199 sub reconlonc {
|
Line 232 sub reconlonc {
|
sub critical { |
sub critical { |
my ($cmd,$server)=@_; |
my ($cmd,$server)=@_; |
unless ($hostname{$server}) { |
unless ($hostname{$server}) { |
&logthis("<font color=blue>WARNING:". |
&logthis("<font color=\"blue\">WARNING:". |
" Critical message to unknown server ($server)</font>"); |
" Critical message to unknown server ($server)</font>"); |
return 'no_such_host'; |
return 'no_such_host'; |
} |
} |
Line 233 sub critical {
|
Line 266 sub critical {
|
} |
} |
chomp($wcmd); |
chomp($wcmd); |
if ($wcmd eq $cmd) { |
if ($wcmd eq $cmd) { |
&logthis("<font color=blue>WARNING: ". |
&logthis("<font color=\"blue\">WARNING: ". |
"Connection buffer $dfilename: $cmd</font>"); |
"Connection buffer $dfilename: $cmd</font>"); |
&logperm("D:$server:$cmd"); |
&logperm("D:$server:$cmd"); |
return 'con_delayed'; |
return 'con_delayed'; |
} else { |
} else { |
&logthis("<font color=red>CRITICAL:" |
&logthis("<font color=\"red\">CRITICAL:" |
." Critical connection failed: $server $cmd</font>"); |
." Critical connection failed: $server $cmd</font>"); |
&logperm("F:$server:$cmd"); |
&logperm("F:$server:$cmd"); |
return 'con_failed'; |
return 'con_failed'; |
Line 248 sub critical {
|
Line 281 sub critical {
|
return $answer; |
return $answer; |
} |
} |
|
|
# |
# ------------------------------------------- check if return value is an error |
# -------------- Remove all key from the env that start witha lowercase letter |
|
# (Which is always a lon-capa value) |
|
|
|
sub cleanenv { |
sub error { |
# unless (defined(&Apache::exists_config_define("MODPERL2"))) { return; } |
my ($result) = @_; |
# unless (&Apache::exists_config_define("MODPERL2")) { return; } |
if ($result =~ /^(con_lost|no_such_host|error: (\d+) (.*))/) { |
foreach my $key (keys(%ENV)) { |
if ($2 == 2) { return undef; } |
if ($key =~ /^[a-z]/) { |
return $1; |
delete($ENV{$key}); |
|
} |
|
} |
} |
|
return undef; |
} |
} |
|
|
# ------------------------------------------- Transfer profile into environment |
|
|
|
sub transfer_profile_to_env { |
sub convert_and_load_session_env { |
my ($lonidsdir,$handle)=@_; |
my ($lonidsdir,$handle)=@_; |
my @profile; |
my @profile; |
{ |
{ |
Line 273 sub transfer_profile_to_env {
|
Line 301 sub transfer_profile_to_env {
|
@profile=<$idf>; |
@profile=<$idf>; |
close($idf); |
close($idf); |
} |
} |
my $envi; |
my %temp_env; |
my %Remove; |
foreach my $line (@profile) { |
for ($envi=0;$envi<=$#profile;$envi++) { |
if ($line !~ m/=/) { |
chomp($profile[$envi]); |
return 0; |
my ($envname,$envvalue)=split(/=/,$profile[$envi]); |
} |
$ENV{$envname} = $envvalue; |
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,$force_transfer) = @_; |
|
if (!$force_transfer && $env_loaded) { return; } |
|
|
|
if (!defined($lonidsdir)) { |
|
$lonidsdir = $perlvar{'lonIDsDir'}; |
|
} |
|
if (!defined($handle)) { |
|
($handle) = ($env{'user.environment'} =~m|/([^/]+)\.id$| ); |
|
} |
|
|
|
my $convert; |
|
{ |
|
open(my $idf,"$lonidsdir/$handle.id"); |
|
flock($idf,LOCK_SH); |
|
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 %remove; |
|
while ( my $envname = each(%env) ) { |
if (my ($key,$time) = ($envname =~ /^(cgi\.(\d+)_\d+\.)/)) { |
if (my ($key,$time) = ($envname =~ /^(cgi\.(\d+)_\d+\.)/)) { |
if ($time < time-300) { |
if ($time < time-300) { |
$Remove{$key}++; |
$remove{$key}++; |
} |
} |
} |
} |
} |
} |
$ENV{'user.environment'} = "$lonidsdir/$handle.id"; |
|
foreach my $expired_key (keys(%Remove)) { |
$env{'user.environment'} = "$lonidsdir/$handle.id"; |
|
$env_loaded=1; |
|
foreach my $expired_key (keys(%remove)) { |
&delenv($expired_key); |
&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 |
# ---------------------------------------------------------- Append Environment |
|
|
sub appenv { |
sub appenv { |
my %newenv=@_; |
my %newenv=@_; |
foreach (keys %newenv) { |
foreach my $key (keys(%newenv)) { |
if (($newenv{$_}=~/^user\.role/) || ($newenv{$_}=~/^user\.priv/)) { |
if (($newenv{$key}=~/^user\.role/) || ($newenv{$key}=~/^user\.priv/)) { |
&logthis("<font color=blue>WARNING: ". |
&logthis("<font color=\"blue\">WARNING: ". |
"Attempt to modify environment ".$_." to ".$newenv{$_} |
"Attempt to modify environment ".$key." to ".$newenv{$key} |
.'</font>'); |
.'</font>'); |
delete($newenv{$_}); |
delete($newenv{$key}); |
} else { |
} else { |
$ENV{$_}=$newenv{$_}; |
$env{$key}=$newenv{$key}; |
} |
} |
} |
} |
|
open(my $env_file,$env{'user.environment'}); |
my $lockfh; |
if (&timed_flock($env_file,LOCK_EX) |
unless (open($lockfh,"$ENV{'user.environment'}")) { |
&& |
return 'error: '.$!; |
tie(my %disk_env,'GDBM_File',$env{'user.environment'}, |
} |
(&GDBM_WRITER()|&GDBM_NOLOCK()),0640)) { |
unless (flock($lockfh,LOCK_EX)) { |
while (my ($key,$value) = each(%newenv)) { |
&logthis("<font color=blue>WARNING: ". |
$disk_env{$key} = $value; |
'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>; |
untie(%disk_env); |
close($fh); |
|
} |
|
for (my $i=0; $i<=$#oldenv; $i++) { |
|
chomp($oldenv[$i]); |
|
if ($oldenv[$i] ne '') { |
|
my ($name,$value)=split(/=/,$oldenv[$i]); |
|
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 "$newname=$newenv{$newname}\n"; |
|
} |
|
close($fh); |
|
} |
|
|
|
close($lockfh); |
|
return 'ok'; |
return 'ok'; |
} |
} |
# ----------------------------------------------------- Delete from Environment |
# ----------------------------------------------------- Delete from Environment |
|
|
sub delenv { |
sub delenv { |
my $delthis=shift; |
my $delthis=shift; |
my %newenv=(); |
|
if (($delthis=~/user\.role/) || ($delthis=~/user\.priv/)) { |
if (($delthis=~/user\.role/) || ($delthis=~/user\.priv/)) { |
&logthis("<font color=blue>WARNING: ". |
&logthis("<font color=\"blue\">WARNING: ". |
"Attempt to delete from environment ".$delthis); |
"Attempt to delete from environment ".$delthis); |
return 'error'; |
return 'error'; |
} |
} |
my @oldenv; |
open(my $env_file,$env{'user.environment'}); |
{ |
if (&timed_flock($env_file,LOCK_EX) |
my $fh; |
&& |
unless (open($fh,"$ENV{'user.environment'}")) { |
tie(my %disk_env,'GDBM_File',$env{'user.environment'}, |
return 'error'; |
(&GDBM_WRITER()|&GDBM_NOLOCK()),0640)) { |
} |
foreach my $key (keys(%disk_env)) { |
unless (flock($fh,LOCK_SH)) { |
if ($key=~/^$delthis/) { |
&logthis("<font color=blue>WARNING: ". |
delete($env{$key}); |
'Could not obtain shared lock in delenv: '.$!); |
delete($disk_env{$key}); |
close($fh); |
|
return 'error: '.$!; |
|
} |
|
@oldenv=<$fh>; |
|
close($fh); |
|
} |
|
{ |
|
my $fh; |
|
unless (open($fh,">$ENV{'user.environment'}")) { |
|
return 'error'; |
|
} |
|
unless (flock($fh,LOCK_EX)) { |
|
&logthis("<font color=blue>WARNING: ". |
|
'Could not obtain exclusive lock in delenv: '.$!); |
|
close($fh); |
|
return 'error: '.$!; |
|
} |
|
foreach (@oldenv) { |
|
if ($_=~/^$delthis/) { |
|
my ($key,undef) = split('=',$_); |
|
delete($ENV{$key}); |
|
} else { |
|
print $fh $_; |
|
} |
} |
} |
} |
close($fh); |
untie(%disk_env); |
} |
} |
return 'ok'; |
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 |
# ------------------------------------------ Find out current server userload |
# there is a copy in lond |
# there is a copy in lond |
sub userload { |
sub userload { |
Line 450 sub overloaderror {
|
Line 503 sub overloaderror {
|
# ------------------------------ Find server with least workload from spare.tab |
# ------------------------------ Find server with least workload from spare.tab |
|
|
sub spareserver { |
sub spareserver { |
my ($loadpercent,$userloadpercent) = @_; |
my ($loadpercent,$userloadpercent,$want_server_name) = @_; |
my $tryserver; |
my $spare_server; |
my $spareserver=''; |
|
if ($userloadpercent !~ /\d/) { $userloadpercent=0; } |
if ($userloadpercent !~ /\d/) { $userloadpercent=0; } |
my $lowestserver=$loadpercent > $userloadpercent? |
my $lowest_load=($loadpercent > $userloadpercent) ? $loadpercent |
$loadpercent : $userloadpercent; |
: $userloadpercent; |
foreach $tryserver (keys %spareid) { |
|
my $loadans=reply('load',$tryserver); |
foreach my $try_server (@{ $spareid{'primary'} }) { |
my $userloadans=reply('userload',$tryserver); |
($spare_server, $lowest_load) = |
if ($loadans !~ /\d/ && $userloadans !~ /\d/) { |
&compare_server_load($try_server, $spare_server, $lowest_load); |
next; #didn't get a number from the server |
} |
} |
|
my $answer; |
my $found_server = ($spare_server ne '' && $lowest_load < 100); |
if ($loadans =~ /\d/) { |
|
if ($userloadans =~ /\d/) { |
if (!$found_server) { |
#both are numbers, pick the bigger one |
foreach my $try_server (@{ $spareid{'default'} }) { |
$answer=$loadans > $userloadans? |
($spare_server, $lowest_load) = |
$loadans : $userloadans; |
&compare_server_load($try_server, $spare_server, $lowest_load); |
} else { |
|
$answer = $loadans; |
|
} |
|
} else { |
|
$answer = $userloadans; |
|
} |
|
if (($answer =~ /\d/) && ($answer<$lowestserver)) { |
|
$spareserver="http://$hostname{$tryserver}"; |
|
$lowestserver=$answer; |
|
} |
} |
} |
} |
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 |
# --------------------------------------------- Try to change a user's password |
|
|
sub changepass { |
sub changepass { |
my ($uname,$udom,$currentpass,$newpass,$server)=@_; |
my ($uname,$udom,$currentpass,$newpass,$server,$context)=@_; |
$currentpass = &escape($currentpass); |
$currentpass = &escape($currentpass); |
$newpass = &escape($newpass); |
$newpass = &escape($newpass); |
my $answer = reply("encrypt:passwd:$udom:$uname:$currentpass:$newpass", |
my $answer = reply("encrypt:passwd:$udom:$uname:$currentpass:$newpass:$context", |
$server); |
$server); |
if (! $answer) { |
if (! $answer) { |
&logthis("No reply on password change request to $server ". |
&logthis("No reply on password change request to $server ". |
Line 537 sub queryauthenticate {
|
Line 613 sub queryauthenticate {
|
|
|
sub authenticate { |
sub authenticate { |
my ($uname,$upass,$udom)=@_; |
my ($uname,$upass,$udom)=@_; |
$upass=escape($upass); |
$upass=&escape($upass); |
$uname=~s/\W//g; |
$uname= &LONCAPA::clean_username($uname); |
my $uhome=&homeserver($uname,$udom); |
my $uhome=&homeserver($uname,$udom); |
if (!$uhome) { |
if (!$uhome) { |
&logthis("User $uname at $udom is unknown in authenticate"); |
&logthis("User $uname at $udom is unknown in authenticate"); |
Line 613 sub idget {
|
Line 689 sub idget {
|
sub idrget { |
sub idrget { |
my ($udom,@unames)=@_; |
my ($udom,@unames)=@_; |
my %returnhash=(); |
my %returnhash=(); |
foreach (@unames) { |
foreach my $uname (@unames) { |
$returnhash{$_}=(&userenvironment($udom,$_,'id'))[1]; |
$returnhash{$uname}=(&userenvironment($udom,$uname,'id'))[1]; |
} |
} |
return %returnhash; |
return %returnhash; |
} |
} |
Line 624 sub idrget {
|
Line 700 sub idrget {
|
sub idput { |
sub idput { |
my ($udom,%ids)=@_; |
my ($udom,%ids)=@_; |
my %servers=(); |
my %servers=(); |
foreach (keys %ids) { |
foreach my $uname (keys(%ids)) { |
&cput('environment',{'id'=>$ids{$_}},$udom,$_); |
&cput('environment',{'id'=>$ids{$uname}},$udom,$uname); |
my $uhom=&homeserver($_,$udom); |
my $uhom=&homeserver($uname,$udom); |
if ($uhom ne 'no_host') { |
if ($uhom ne 'no_host') { |
my $id=&escape($ids{$_}); |
my $id=&escape($ids{$uname}); |
$id=~tr/A-Z/a-z/; |
$id=~tr/A-Z/a-z/; |
my $unam=&escape($_); |
my $esc_unam=&escape($uname); |
if ($servers{$uhom}) { |
if ($servers{$uhom}) { |
$servers{$uhom}.='&'.$id.'='.$unam; |
$servers{$uhom}.='&'.$id.'='.$esc_unam; |
} else { |
} else { |
$servers{$uhom}=$id.'='.$unam; |
$servers{$uhom}=$id.'='.$esc_unam; |
} |
} |
} |
} |
} |
} |
foreach (keys %servers) { |
foreach my $server (keys(%servers)) { |
&critical('idput:'.$udom.':'.$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"); |
} |
} |
} |
} |
|
|
Line 652 sub assign_access_key {
|
Line 775 sub assign_access_key {
|
# |
# |
my ($ckey,$kdom,$knum,$cdom,$cnum,$udom,$uname,$logentry)=@_; |
my ($ckey,$kdom,$knum,$cdom,$cnum,$udom,$uname,$logentry)=@_; |
$kdom= |
$kdom= |
$ENV{'course.'.$ENV{'request.course.id'}.'.domain'} unless (defined($kdom)); |
$env{'course.'.$env{'request.course.id'}.'.domain'} unless (defined($kdom)); |
$knum= |
$knum= |
$ENV{'course.'.$ENV{'request.course.id'}.'.num'} unless (defined($knum)); |
$env{'course.'.$env{'request.course.id'}.'.num'} unless (defined($knum)); |
$cdom= |
$cdom= |
$ENV{'course.'.$ENV{'request.course.id'}.'.domain'} unless (defined($cdom)); |
$env{'course.'.$env{'request.course.id'}.'.domain'} unless (defined($cdom)); |
$cnum= |
$cnum= |
$ENV{'course.'.$ENV{'request.course.id'}.'.num'} unless (defined($cnum)); |
$env{'course.'.$env{'request.course.id'}.'.num'} unless (defined($cnum)); |
$udom=$ENV{'user.name'} unless (defined($udom)); |
$udom=$env{'user.name'} unless (defined($udom)); |
$uname=$ENV{'user.domain'} unless (defined($uname)); |
$uname=$env{'user.domain'} unless (defined($uname)); |
my %existing=&get('accesskeys',[$ckey],$kdom,$knum); |
my %existing=&get('accesskeys',[$ckey],$kdom,$knum); |
if (($existing{$ckey}=~/^\#(.*)$/) || # - new key |
if (($existing{$ckey}=~/^\#(.*)$/) || # - new key |
($existing{$ckey}=~/^\Q$uname\E\:\Q$udom\E\#(.*)$/)) { |
($existing{$ckey}=~/^\Q$uname\E\:\Q$udom\E\#(.*)$/)) { |
Line 702 sub comment_access_key {
|
Line 825 sub comment_access_key {
|
# |
# |
my ($ckey,$cdom,$cnum,$logentry)=@_; |
my ($ckey,$cdom,$cnum,$logentry)=@_; |
$cdom= |
$cdom= |
$ENV{'course.'.$ENV{'request.course.id'}.'.domain'} unless (defined($cdom)); |
$env{'course.'.$env{'request.course.id'}.'.domain'} unless (defined($cdom)); |
$cnum= |
$cnum= |
$ENV{'course.'.$ENV{'request.course.id'}.'.num'} unless (defined($cnum)); |
$env{'course.'.$env{'request.course.id'}.'.num'} unless (defined($cnum)); |
my %existing=&get('accesskeys',[$ckey],$cdom,$cnum); |
my %existing=&get('accesskeys',[$ckey],$cdom,$cnum); |
if ($existing{$ckey}) { |
if ($existing{$ckey}) { |
$existing{$ckey}.='; '.$logentry; |
$existing{$ckey}.='; '.$logentry; |
Line 726 sub comment_access_key {
|
Line 849 sub comment_access_key {
|
sub generate_access_keys { |
sub generate_access_keys { |
my ($number,$cdom,$cnum,$logentry)=@_; |
my ($number,$cdom,$cnum,$logentry)=@_; |
$cdom= |
$cdom= |
$ENV{'course.'.$ENV{'request.course.id'}.'.domain'} unless (defined($cdom)); |
$env{'course.'.$env{'request.course.id'}.'.domain'} unless (defined($cdom)); |
$cnum= |
$cnum= |
$ENV{'course.'.$ENV{'request.course.id'}.'.num'} unless (defined($cnum)); |
$env{'course.'.$env{'request.course.id'}.'.num'} unless (defined($cnum)); |
unless (&allowed('mky',$cdom)) { return 0; } |
unless (&allowed('mky',$cdom)) { return 0; } |
unless (($cdom) && ($cnum)) { return 0; } |
unless (($cdom) && ($cnum)) { return 0; } |
if ($number>10000) { return 0; } |
if ($number>10000) { return 0; } |
Line 747 sub generate_access_keys {
|
Line 870 sub generate_access_keys {
|
} else { |
} else { |
if (&put('accesskeys', |
if (&put('accesskeys', |
{ $newkey => '# generated '.localtime(). |
{ $newkey => '# generated '.localtime(). |
' by '.$ENV{'user.name'}.'@'.$ENV{'user.domain'}. |
' by '.$env{'user.name'}.'@'.$env{'user.domain'}. |
'; '.$logentry }, |
'; '.$logentry }, |
$cdom,$cnum) eq 'ok') { |
$cdom,$cnum) eq 'ok') { |
$total++; |
$total++; |
} |
} |
} |
} |
} |
} |
&log($ENV{'user.domain'},$ENV{'user.name'},$ENV{'user.home'}, |
&log($env{'user.domain'},$env{'user.name'},$env{'user.home'}, |
'Generated '.$total.' keys for '.$cnum.' at '.$cdom); |
'Generated '.$total.' keys for '.$cnum.' at '.$cdom); |
return $total; |
return $total; |
} |
} |
Line 764 sub generate_access_keys {
|
Line 887 sub generate_access_keys {
|
sub validate_access_key { |
sub validate_access_key { |
my ($ckey,$cdom,$cnum,$udom,$uname)=@_; |
my ($ckey,$cdom,$cnum,$udom,$uname)=@_; |
$cdom= |
$cdom= |
$ENV{'course.'.$ENV{'request.course.id'}.'.domain'} unless (defined($cdom)); |
$env{'course.'.$env{'request.course.id'}.'.domain'} unless (defined($cdom)); |
$cnum= |
$cnum= |
$ENV{'course.'.$ENV{'request.course.id'}.'.num'} unless (defined($cnum)); |
$env{'course.'.$env{'request.course.id'}.'.num'} unless (defined($cnum)); |
$udom=$ENV{'user.domain'} unless (defined($udom)); |
$udom=$env{'user.domain'} unless (defined($udom)); |
$uname=$ENV{'user.name'} unless (defined($uname)); |
$uname=$env{'user.name'} unless (defined($uname)); |
my %existing=&get('accesskeys',[$ckey],$cdom,$cnum); |
my %existing=&get('accesskeys',[$ckey],$cdom,$cnum); |
return ($existing{$ckey}=~/^\Q$uname\E\:\Q$udom\E\#/); |
return ($existing{$ckey}=~/^\Q$uname\E\:\Q$udom\E\#/); |
} |
} |
|
|
# ------------------------------------- Find the section of student in a course |
# ------------------------------------- Find the section of student in a course |
|
sub devalidate_getsection_cache { |
|
my ($udom,$unam,$courseid)=@_; |
|
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 { |
sub getsection { |
my ($udom,$unam,$courseid)=@_; |
my ($udom,$unam,$courseid)=@_; |
my $cachetime=1800; |
my $cachetime=1800; |
$courseid=~s/\_/\//g; |
|
$courseid=~s/^(\w)/\/$1/; |
|
|
|
my $hashid="$udom:$unam:$courseid"; |
my $hashid="$udom:$unam:$courseid"; |
my ($result,$cached)=&is_cached_new('getsection',$hashid); |
my ($result,$cached)=&is_cached_new('getsection',$hashid); |
Line 800 sub getsection {
|
Line 945 sub getsection {
|
# If there is more than one expired role, choose the one which ended last. |
# If there is more than one expired role, choose the one which ended last. |
# If there is a role which has expired, return it. |
# If there is a role which has expired, return it. |
# |
# |
foreach (split(/\&/,&reply('dump:'.$udom.':'.$unam.':roles', |
$courseid = &courseid_to_courseurl($courseid); |
&homeserver($unam,$udom)))) { |
my %roleshash = &dump('roles',$udom,$unam,$courseid); |
my ($key,$value)=split(/\=/,$_); |
foreach my $key (keys(%roleshash)) { |
$key=&unescape($key); |
|
next if ($key !~/^\Q$courseid\E(?:\/)*(\w+)*\_st$/); |
next if ($key !~/^\Q$courseid\E(?:\/)*(\w+)*\_st$/); |
my $section=$1; |
my $section=$1; |
if ($key eq $courseid.'_st') { $section=''; } |
if ($key eq $courseid.'_st') { $section=''; } |
my ($dummy,$end,$start)=split(/\_/,&unescape($value)); |
my ($dummy,$end,$start)=split(/\_/,&unescape($roleshash{$key})); |
my $now=time; |
my $now=time; |
if (defined($end) && $end && ($now > $end)) { |
if (defined($end) && $end && ($now > $end)) { |
$Expired{$end}=$section; |
$Expired{$end}=$section; |
Line 836 sub getsection {
|
Line 980 sub getsection {
|
|
|
sub save_cache { |
sub save_cache { |
&purge_remembered(); |
&purge_remembered(); |
|
#&Apache::loncommon::validate_page(); |
|
undef(%env); |
|
undef($env_loaded); |
} |
} |
|
|
my $to_remember=-1; |
my $to_remember=-1; |
Line 882 sub do_cache_new {
|
Line 1029 sub do_cache_new {
|
if (!defined($setvalue)) { |
if (!defined($setvalue)) { |
$setvalue='__undef__'; |
$setvalue='__undef__'; |
} |
} |
|
if (!defined($time) ) { |
|
$time=600; |
|
} |
if ($debug) { &Apache::lonnet::logthis("Setting $id to $value"); } |
if ($debug) { &Apache::lonnet::logthis("Setting $id to $value"); } |
$memcache->set($id,$setvalue,$time); |
$memcache->set($id,$setvalue,$time); |
# need to make a copy of $value |
# need to make a copy of $value |
Line 911 sub make_room {
|
Line 1061 sub make_room {
|
} |
} |
|
|
sub purge_remembered { |
sub purge_remembered { |
&logthis("Tossing ".scalar(keys(%remembered))); |
#&logthis("Tossing ".scalar(keys(%remembered))); |
&logthis(sprintf("%-20s is %s",'%remembered',length(&freeze(\%remembered)))); |
#&logthis(sprintf("%-20s is %s",'%remembered',length(&freeze(\%remembered)))); |
undef(%remembered); |
undef(%remembered); |
undef(%accessed); |
undef(%accessed); |
} |
} |
Line 931 sub userenvironment {
|
Line 1081 sub userenvironment {
|
return %returnhash; |
return %returnhash; |
} |
} |
|
|
|
# ---------------------------------------------------------- Get a studentphoto |
|
sub studentphoto { |
|
my ($udom,$unam,$ext) = @_; |
|
my $home=&Apache::lonnet::homeserver($unam,$udom); |
|
if (defined($env{'request.course.id'})) { |
|
if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) { |
|
if ($udom eq $env{'course.'.$env{'request.course.id'}.'.domain'}) { |
|
return(&retrievestudentphoto($udom,$unam,$ext)); |
|
} else { |
|
my ($result,$perm_reqd)= |
|
&Apache::lonnet::auto_photo_permission($unam,$udom); |
|
if ($result eq 'ok') { |
|
if (!($perm_reqd eq 'yes')) { |
|
return(&retrievestudentphoto($udom,$unam,$ext)); |
|
} |
|
} |
|
} |
|
} |
|
} else { |
|
my ($result,$perm_reqd) = |
|
&Apache::lonnet::auto_photo_permission($unam,$udom); |
|
if ($result eq 'ok') { |
|
if (!($perm_reqd eq 'yes')) { |
|
return(&retrievestudentphoto($udom,$unam,$ext)); |
|
} |
|
} |
|
} |
|
return '/adm/lonKaputt/lonlogo_broken.gif'; |
|
} |
|
|
|
sub retrievestudentphoto { |
|
my ($udom,$unam,$ext,$type) = @_; |
|
my $home=&Apache::lonnet::homeserver($unam,$udom); |
|
my $ret=&Apache::lonnet::reply("studentphoto:$udom:$unam:$ext:$type",$home); |
|
if ($ret eq 'ok') { |
|
my $url="/uploaded/$udom/$unam/internal/studentphoto.$ext"; |
|
if ($type eq 'thumbnail') { |
|
$url="/uploaded/$udom/$unam/internal/studentphoto_tn.$ext"; |
|
} |
|
my $tokenurl=&Apache::lonnet::tokenwrapper($url); |
|
return $tokenurl; |
|
} else { |
|
if ($type eq 'thumbnail') { |
|
return '/adm/lonKaputt/genericstudent_tn.gif'; |
|
} else { |
|
return '/adm/lonKaputt/lonlogo_broken.gif'; |
|
} |
|
} |
|
} |
|
|
# -------------------------------------------------------------------- New chat |
# -------------------------------------------------------------------- New chat |
|
|
sub chatsend { |
sub chatsend { |
my ($newentry,$anon)=@_; |
my ($newentry,$anon,$group)=@_; |
my $cnum=$ENV{'course.'.$ENV{'request.course.id'}.'.num'}; |
my $cnum=$env{'course.'.$env{'request.course.id'}.'.num'}; |
my $cdom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; |
my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'}; |
my $chome=$ENV{'course.'.$ENV{'request.course.id'}.'.home'}; |
my $chome=$env{'course.'.$env{'request.course.id'}.'.home'}; |
&reply('chatsend:'.$cdom.':'.$cnum.':'. |
&reply('chatsend:'.$cdom.':'.$cnum.':'. |
&escape($ENV{'user.domain'}.':'.$ENV{'user.name'}.':'.$anon.':'. |
&escape($env{'user.domain'}.':'.$env{'user.name'}.':'.$anon.':'. |
&escape($newentry)),$chome); |
&escape($newentry)).':'.$group,$chome); |
} |
} |
|
|
# ------------------------------------------ Find current version of a resource |
# ------------------------------------------ Find current version of a resource |
Line 994 sub subscribe {
|
Line 1194 sub subscribe {
|
sub repcopy { |
sub repcopy { |
my $filename=shift; |
my $filename=shift; |
$filename=~s/\/+/\//g; |
$filename=~s/\/+/\//g; |
if ($filename=~m|^/home/httpd/html/adm/|) { return 'OK'; } |
if ($filename=~m|^/home/httpd/html/adm/|) { return 'ok'; } |
if ($filename=~m|^/home/httpd/html/lonUsers/|) { return 'OK'; } |
if ($filename=~m|^/home/httpd/html/lonUsers/|) { return 'ok'; } |
if ($filename=~m|^/home/httpd/html/userfiles/| or |
if ($filename=~m|^/home/httpd/html/userfiles/| or |
$filename=~m|^/*uploaded/|) { |
$filename=~m -^/*(uploaded|editupload)/-) { |
return &repcopy_userfile($filename); |
return &repcopy_userfile($filename); |
} |
} |
$filename=~s/[\n\r]//g; |
$filename=~s/[\n\r]//g; |
my $transname="$filename.in.transfer"; |
my $transname="$filename.in.transfer"; |
if ((-e $filename) || (-e $transname)) { return 'OK'; } |
# FIXME: this should flock |
|
if ((-e $filename) || (-e $transname)) { return 'ok'; } |
my $remoteurl=subscribe($filename); |
my $remoteurl=subscribe($filename); |
if ($remoteurl =~ /^con_lost by/) { |
if ($remoteurl =~ /^con_lost by/) { |
&logthis("Subscribe returned $remoteurl: $filename"); |
&logthis("Subscribe returned $remoteurl: $filename"); |
return 'HTTP_SERVICE_UNAVAILABLE'; |
return 'unavailable'; |
} elsif ($remoteurl eq 'not_found') { |
} elsif ($remoteurl eq 'not_found') { |
#&logthis("Subscribe returned not_found: $filename"); |
#&logthis("Subscribe returned not_found: $filename"); |
return 'HTTP_NOT_FOUND'; |
return 'not_found'; |
} elsif ($remoteurl =~ /^rejected by/) { |
} elsif ($remoteurl =~ /^rejected by/) { |
&logthis("Subscribe returned $remoteurl: $filename"); |
&logthis("Subscribe returned $remoteurl: $filename"); |
return 'FORBIDDEN'; |
return 'forbidden'; |
} elsif ($remoteurl eq 'directory') { |
} elsif ($remoteurl eq 'directory') { |
return 'OK'; |
return 'ok'; |
} else { |
} else { |
my $author=$filename; |
my $author=$filename; |
$author=~s/\/home\/httpd\/html\/res\/([^\/]*)\/([^\/]*).*/$1\/$2/; |
$author=~s/\/home\/httpd\/html\/res\/([^\/]*)\/([^\/]*).*/$1\/$2/; |
Line 1025 sub repcopy {
|
Line 1226 sub repcopy {
|
my $path="/$parts[1]/$parts[2]/$parts[3]/$parts[4]"; |
my $path="/$parts[1]/$parts[2]/$parts[3]/$parts[4]"; |
if ($path ne "$perlvar{'lonDocRoot'}/res") { |
if ($path ne "$perlvar{'lonDocRoot'}/res") { |
&logthis("Malconfiguration for replication: $filename"); |
&logthis("Malconfiguration for replication: $filename"); |
return 'HTTP_BAD_REQUEST'; |
return 'bad_request'; |
} |
} |
my $count; |
my $count; |
for ($count=5;$count<$#parts;$count++) { |
for ($count=5;$count<$#parts;$count++) { |
Line 1040 sub repcopy {
|
Line 1241 sub repcopy {
|
if ($response->is_error()) { |
if ($response->is_error()) { |
unlink($transname); |
unlink($transname); |
my $message=$response->status_line; |
my $message=$response->status_line; |
&logthis("<font color=blue>WARNING:" |
&logthis("<font color=\"blue\">WARNING:" |
." LWP get: $message: $filename</font>"); |
." LWP get: $message: $filename</font>"); |
return 'HTTP_SERVICE_UNAVAILABLE'; |
return 'unavailable'; |
} else { |
} else { |
if ($remoteurl!~/\.meta$/) { |
if ($remoteurl!~/\.meta$/) { |
my $mrequest=new HTTP::Request('GET',$remoteurl.'.meta'); |
my $mrequest=new HTTP::Request('GET',$remoteurl.'.meta'); |
Line 1050 sub repcopy {
|
Line 1251 sub repcopy {
|
if ($mresponse->is_error()) { |
if ($mresponse->is_error()) { |
unlink($filename.'.meta'); |
unlink($filename.'.meta'); |
&logthis( |
&logthis( |
"<font color=yellow>INFO: No metadata: $filename</font>"); |
"<font color=\"yellow\">INFO: No metadata: $filename</font>"); |
} |
} |
} |
} |
rename($transname,$filename); |
rename($transname,$filename); |
return 'OK'; |
return 'ok'; |
} |
} |
} |
} |
} |
} |
Line 1063 sub repcopy {
|
Line 1264 sub repcopy {
|
# ------------------------------------------------ Get server side include body |
# ------------------------------------------------ Get server side include body |
sub ssi_body { |
sub ssi_body { |
my ($filelink,%form)=@_; |
my ($filelink,%form)=@_; |
|
if (! exists($form{'LONCAPA_INTERNAL_no_discussion'})) { |
|
$form{'LONCAPA_INTERNAL_no_discussion'}='true'; |
|
} |
my $output=($filelink=~/^http\:/?&externalssi($filelink): |
my $output=($filelink=~/^http\:/?&externalssi($filelink): |
&ssi($filelink,%form)); |
&ssi($filelink,%form)); |
$output=~s|//(\s*<!--)? BEGIN LON-CAPA Internal.+// END LON-CAPA Internal\s*(-->)?\s||gs; |
$output=~s|//(\s*<!--)? BEGIN LON-CAPA Internal.+?// END LON-CAPA Internal\s*(-->)?\s||gs; |
$output=~s/^.*?\<body[^\>]*\>//si; |
$output=~s/^.*?\<body[^\>]*\>//si; |
$output=~s/(.*)\<\/body\s*\>.*?$/$1/si; |
$output=~s/(.*)\<\/body\s*\>.*?$/$1/si; |
return $output; |
return $output; |
Line 1073 sub ssi_body {
|
Line 1277 sub ssi_body {
|
|
|
# --------------------------------------------------------- Server Side Include |
# --------------------------------------------------------- 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 { |
sub ssi { |
|
|
my ($fn,%form)=@_; |
my ($fn,%form)=@_; |
Line 1080 sub ssi {
|
Line 1293 sub ssi {
|
my $ua=new LWP::UserAgent; |
my $ua=new LWP::UserAgent; |
|
|
my $request; |
my $request; |
|
|
|
$form{'no_update_last_known'}=1; |
|
|
if (%form) { |
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)); |
$request->content(join('&',map { &escape($_).'='.&escape($form{$_}) } keys %form)); |
} else { |
} 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'}); |
$request->header(Cookie => $ENV{'HTTP_COOKIE'}); |
Line 1116 sub allowuploaded {
|
Line 1331 sub allowuploaded {
|
} |
} |
|
|
# --------- File operations in /home/httpd/html/userfiles/$domain/1/2/3/$course |
# --------- File operations in /home/httpd/html/userfiles/$domain/1/2/3/$course |
# input: action, courseID, current domain, home server for course, intended |
# input: action, courseID, current domain, intended |
# path to file, source of file. |
# path to file, source of file, instruction to parse file for objects, |
|
# ref to hash for embedded objects, |
|
# ref to hash for codebase of java objects. |
|
# |
# output: url to file (if action was uploaddoc), |
# output: url to file (if action was uploaddoc), |
# ok if successful, or diagnostic message otherwise (if action was propagate or copy) |
# ok if successful, or diagnostic message otherwise (if action was propagate or copy) |
# |
# |
Line 1136 sub allowuploaded {
|
Line 1354 sub allowuploaded {
|
# course's home server. |
# course's home server. |
# |
# |
# action = uploaddoc - /home/httpd/html/userfiles/$domain/1/2/3/$course/$file |
# action = uploaddoc - /home/httpd/html/userfiles/$domain/1/2/3/$course/$file |
# will be retrived from $ENV{form.uploaddoc} (from DOCS interface) to |
# will be retrived from $env{form.uploaddoc} (from DOCS interface) to |
# /home/httpd/html/userfiles/$domain/1/2/3/$course/$file |
# /home/httpd/html/userfiles/$domain/1/2/3/$course/$file |
# and will then be copied to /home/httpd/lonUsers/1/2/3/$course/userfiles/$file |
# and will then be copied to /home/httpd/lonUsers/1/2/3/$course/userfiles/$file |
# in course's home server. |
# in course's home server. |
|
# |
|
|
sub process_coursefile { |
sub process_coursefile { |
my ($action,$docuname,$docudom,$docuhome,$file,$source)=@_; |
my ($action,$docuname,$docudom,$file,$source,$parser,$allfiles,$codebase)=@_; |
my $fetchresult; |
my $fetchresult; |
|
my $home=&homeserver($docuname,$docudom); |
if ($action eq 'propagate') { |
if ($action eq 'propagate') { |
$fetchresult= &reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$file |
$fetchresult= &reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$file, |
,$docuhome); |
$home); |
} else { |
} else { |
my $fetchresult = ''; |
|
my $fpath = ''; |
my $fpath = ''; |
my $fname = $file; |
my $fname = $file; |
($fpath,$fname) = ($file =~ m|^(.*)/([^/]+)$|); |
($fpath,$fname) = ($file =~ m|^(.*)/([^/]+)$|); |
$fpath=$docudom.'/'.$docuname.'/'.$fpath; |
$fpath=$docudom.'/'.$docuname.'/'.$fpath; |
my $filepath=$perlvar{'lonDocRoot'}.'/userfiles'; |
my $filepath = &build_filepath($fpath); |
unless ($fpath eq '') { |
|
my @parts=split('/',$fpath); |
|
foreach my $part (@parts) { |
|
$filepath.= '/'.$part; |
|
if ((-e $filepath)!=1) { |
|
mkdir($filepath,0777); |
|
} |
|
} |
|
} |
|
if ($action eq 'copy') { |
if ($action eq 'copy') { |
if ($source eq '') { |
if ($source eq '') { |
$fetchresult = 'no source file'; |
$fetchresult = 'no source file'; |
Line 1172 sub process_coursefile {
|
Line 1381 sub process_coursefile {
|
my $destination = $filepath.'/'.$fname; |
my $destination = $filepath.'/'.$fname; |
rename($source,$destination); |
rename($source,$destination); |
$fetchresult= &reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$file, |
$fetchresult= &reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$file, |
$docuhome); |
$home); |
} |
} |
} elsif ($action eq 'uploaddoc') { |
} elsif ($action eq 'uploaddoc') { |
open(my $fh,'>'.$filepath.'/'.$fname); |
open(my $fh,'>'.$filepath.'/'.$fname); |
print $fh $ENV{'form.'.$source}; |
print $fh $env{'form.'.$source}; |
close($fh); |
close($fh); |
|
if ($parser eq 'parse') { |
|
my $parse_result = &extract_embedded_items($filepath,$fname,$allfiles,$codebase); |
|
unless ($parse_result eq 'ok') { |
|
&logthis('Failed to parse '.$filepath.'/'.$fname.' for embedded media: '.$parse_result); |
|
} |
|
} |
$fetchresult= &reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$file, |
$fetchresult= &reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$file, |
$docuhome); |
$home); |
if ($fetchresult eq 'ok') { |
if ($fetchresult eq 'ok') { |
return '/uploaded/'.$fpath.'/'.$fname; |
return '/uploaded/'.$fpath.'/'.$fname; |
} else { |
} else { |
&logthis('Failed to transfer '.$docudom.'/'.$docuname.'/'.$file. |
&logthis('Failed to transfer '.$docudom.'/'.$docuname.'/'.$file. |
' to host '.$docuhome.': '.$fetchresult); |
' to host '.$home.': '.$fetchresult); |
return '/adm/notfound.html'; |
return '/adm/notfound.html'; |
} |
} |
} |
} |
} |
} |
unless ( $fetchresult eq 'ok') { |
unless ( $fetchresult eq 'ok') { |
&logthis('Failed to transfer '.$docudom.'/'.$docuname.'/'.$file. |
&logthis('Failed to transfer '.$docudom.'/'.$docuname.'/'.$file. |
' to host '.$docuhome.': '.$fetchresult); |
' to host '.$home.': '.$fetchresult); |
} |
} |
return $fetchresult; |
return $fetchresult; |
} |
} |
|
|
# --------------- Take an uploaded file and put it into the userfiles directory |
sub build_filepath { |
# input: name of form element, coursedoc=1 means this is for the course |
my ($fpath) = @_; |
# output: url of file in userspace |
my $filepath=$perlvar{'lonDocRoot'}.'/userfiles'; |
|
unless ($fpath eq '') { |
|
my @parts=split('/',$fpath); |
|
foreach my $part (@parts) { |
|
$filepath.= '/'.$part; |
|
if ((-e $filepath)!=1) { |
|
mkdir($filepath,0777); |
|
} |
|
} |
|
} |
|
return $filepath; |
|
} |
|
|
|
sub store_edited_file { |
|
my ($primary_url,$content,$docudom,$docuname,$fetchresult) = @_; |
|
my $file = $primary_url; |
|
$file =~ s#^/uploaded/$docudom/$docuname/##; |
|
my $fpath = ''; |
|
my $fname = $file; |
|
($fpath,$fname) = ($file =~ m|^(.*)/([^/]+)$|); |
|
$fpath=$docudom.'/'.$docuname.'/'.$fpath; |
|
my $filepath = &build_filepath($fpath); |
|
open(my $fh,'>'.$filepath.'/'.$fname); |
|
print $fh $content; |
|
close($fh); |
|
my $home=&homeserver($docuname,$docudom); |
|
$$fetchresult= &reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$file, |
|
$home); |
|
if ($$fetchresult eq 'ok') { |
|
return '/uploaded/'.$fpath.'/'.$fname; |
|
} else { |
|
&logthis('Failed to transfer '.$docudom.'/'.$docuname.'/'.$file. |
|
' to host '.$home.': '.$$fetchresult); |
|
return '/adm/notfound.html'; |
|
} |
|
} |
|
|
sub clean_filename { |
sub clean_filename { |
my ($fname)=@_; |
my ($fname,$args)=@_; |
# Replace Windows backslashes by forward slashes |
# Replace Windows backslashes by forward slashes |
$fname=~s/\\/\//g; |
$fname=~s/\\/\//g; |
# Get rid of everything but the actual filename |
if (!$args->{'keep_path'}) { |
$fname=~s/^.*\/([^\/]+)$/$1/; |
# Get rid of everything but the actual filename |
|
$fname=~s/^.*\/([^\/]+)$/$1/; |
|
} |
# Replace spaces by underscores |
# Replace spaces by underscores |
$fname=~s/\s+/\_/g; |
$fname=~s/\s+/\_/g; |
# Replace all other weird characters by nothing |
# 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 |
# Replace all .\d. sequences with _\d. so they no longer look like version |
# numbers |
# numbers |
$fname=~s/\.(\d+)(?=\.)/_$1/g; |
$fname=~s/\.(\d+)(?=\.)/_$1/g; |
return $fname; |
return $fname; |
} |
} |
|
|
|
# --------------- Take an uploaded file and put it into the userfiles directory |
|
# input: $formname - the contents of the file are in $env{"form.$formname"} |
|
# the desired filenam is in $env{"form.$formname.filename"} |
|
# $coursedoc - if true up to the current course |
|
# if false |
|
# $subdir - directory in userfile to store the file into |
|
# $parser, $allfiles, $codebase - unknown |
|
# |
|
# output: url of file in userspace, or error: <message> |
|
# or /adm/notfound.html if failure to upload occurse |
|
|
|
|
sub userfileupload { |
sub userfileupload { |
my ($formname,$coursedoc,$subdir)=@_; |
my ($formname,$coursedoc,$subdir,$parser,$allfiles,$codebase,$destuname,$destudom)=@_; |
if (!defined($subdir)) { $subdir='unknown'; } |
if (!defined($subdir)) { $subdir='unknown'; } |
my $fname=$ENV{'form.'.$formname.'.filename'}; |
my $fname=$env{'form.'.$formname.'.filename'}; |
$fname=&clean_filename($fname); |
$fname=&clean_filename($fname); |
# See if there is anything left |
# See if there is anything left |
unless ($fname) { return 'error: no uploaded file'; } |
unless ($fname) { return 'error: no uploaded file'; } |
chop($ENV{'form.'.$formname}); |
chop($env{'form.'.$formname}); |
if (($formname eq 'screenshot') && ($subdir eq 'helprequests')) { #files uploaded to help request form are handled differently |
if (($formname eq 'screenshot') && ($subdir eq 'helprequests')) { #files uploaded to help request form are handled differently |
my $now = time; |
my $now = time; |
my $filepath = 'tmp/helprequests/'.$now; |
my $filepath = 'tmp/helprequests/'.$now; |
Line 1236 sub userfileupload {
|
Line 1500 sub userfileupload {
|
} |
} |
} |
} |
open(my $fh,'>'.$fullpath.'/'.$fname); |
open(my $fh,'>'.$fullpath.'/'.$fname); |
print $fh $ENV{'form.'.$formname}; |
print $fh $env{'form.'.$formname}; |
close($fh); |
close($fh); |
return $fullpath.'/'.$fname; |
return $fullpath.'/'.$fname; |
|
} elsif (($formname eq 'coursecreatorxml') && ($subdir eq 'batchupload')) { #files uploaded to create course page are handled differently |
|
my $filepath = 'tmp/addcourse/'.$destudom.'/web/'.$env{'user.name'}. |
|
'_'.$env{'user.domain'}.'/pending'; |
|
my @parts=split(/\//,$filepath); |
|
my $fullpath = $perlvar{'lonDaemons'}; |
|
for (my $i=0;$i<@parts;$i++) { |
|
$fullpath .= '/'.$parts[$i]; |
|
if ((-e $fullpath)!=1) { |
|
mkdir($fullpath,0777); |
|
} |
|
} |
|
open(my $fh,'>'.$fullpath.'/'.$fname); |
|
print $fh $env{'form.'.$formname}; |
|
close($fh); |
|
return $fullpath.'/'.$fname; |
} |
} |
|
|
# Create the directory if not present |
# Create the directory if not present |
my $docuname=''; |
|
my $docudom=''; |
|
my $docuhome=''; |
|
$fname="$subdir/$fname"; |
$fname="$subdir/$fname"; |
if ($coursedoc) { |
if ($coursedoc) { |
$docuname=$ENV{'course.'.$ENV{'request.course.id'}.'.num'}; |
my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'}; |
$docudom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; |
my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'}; |
$docuhome=$ENV{'course.'.$ENV{'request.course.id'}.'.home'}; |
if ($env{'form.folder'} =~ m/^(default|supplemental)/) { |
if ($ENV{'form.folder'} =~ m/^default/) { |
return &finishuserfileupload($docuname,$docudom, |
return &finishuserfileupload($docuname,$docudom,$docuhome,$formname,$fname); |
$formname,$fname,$parser,$allfiles, |
|
$codebase); |
} else { |
} else { |
$fname=$ENV{'form.folder'}.'/'.$fname; |
$fname=$env{'form.folder'}.'/'.$fname; |
return &process_coursefile('uploaddoc',$docuname,$docudom,$docuhome,$fname,$formname); |
return &process_coursefile('uploaddoc',$docuname,$docudom, |
|
$fname,$formname,$parser, |
|
$allfiles,$codebase); |
|
} |
|
} elsif (defined($destuname)) { |
|
my $docuname=$destuname; |
|
my $docudom=$destudom; |
|
return &finishuserfileupload($docuname,$docudom,$formname, |
|
$fname,$parser,$allfiles,$codebase); |
|
|
|
} else { |
|
my $docuname=$env{'user.name'}; |
|
my $docudom=$env{'user.domain'}; |
|
if (exists($env{'form.group'})) { |
|
$docuname=$env{'course.'.$env{'request.course.id'}.'.num'}; |
|
$docudom=$env{'course.'.$env{'request.course.id'}.'.domain'}; |
} |
} |
} else { |
return &finishuserfileupload($docuname,$docudom,$formname, |
$docuname=$ENV{'user.name'}; |
$fname,$parser,$allfiles,$codebase); |
$docudom=$ENV{'user.domain'}; |
|
$docuhome=$ENV{'user.home'}; |
|
return &finishuserfileupload($docuname,$docudom,$docuhome,$formname,$fname); |
|
} |
} |
} |
} |
|
|
sub finishuserfileupload { |
sub finishuserfileupload { |
my ($docuname,$docudom,$docuhome,$formname,$fname)=@_; |
my ($docuname,$docudom,$formname,$fname,$parser,$allfiles,$codebase) = @_; |
my $path=$docudom.'/'.$docuname.'/'; |
my $path=$docudom.'/'.$docuname.'/'; |
my $filepath=$perlvar{'lonDocRoot'}; |
my $filepath=$perlvar{'lonDocRoot'}; |
my ($fnamepath,$file); |
my ($fnamepath,$file); |
Line 1283 sub finishuserfileupload {
|
Line 1573 sub finishuserfileupload {
|
} |
} |
# Save the file |
# Save the file |
{ |
{ |
open(FH,'>'.$filepath.'/'.$file); |
if (!open(FH,'>'.$filepath.'/'.$file)) { |
print FH $ENV{'form.'.$formname}; |
&logthis('Failed to create '.$filepath.'/'.$file); |
|
print STDERR ('Failed to create '.$filepath.'/'.$file."\n"); |
|
return '/adm/notfound.html'; |
|
} |
|
if (!print FH ($env{'form.'.$formname})) { |
|
&logthis('Failed to write to '.$filepath.'/'.$file); |
|
print STDERR ('Failed to write to '.$filepath.'/'.$file."\n"); |
|
return '/adm/notfound.html'; |
|
} |
close(FH); |
close(FH); |
} |
} |
|
if ($parser eq 'parse') { |
|
my $parse_result = &extract_embedded_items($filepath,$file,$allfiles, |
|
$codebase); |
|
unless ($parse_result eq 'ok') { |
|
&logthis('Failed to parse '.$filepath.$file. |
|
' for embedded media: '.$parse_result); |
|
} |
|
} |
# Notify homeserver to grep it |
# Notify homeserver to grep it |
# |
# |
&Apache::lonnet::logthis("fetching ".$path.$file); |
my $docuhome=&homeserver($docuname,$docudom); |
my $fetchresult= &reply('fetchuserfile:'.$path.$file,$docuhome); |
my $fetchresult= &reply('fetchuserfile:'.$path.$file,$docuhome); |
if ($fetchresult eq 'ok') { |
if ($fetchresult eq 'ok') { |
# |
# |
Line 1302 sub finishuserfileupload {
|
Line 1608 sub finishuserfileupload {
|
} |
} |
} |
} |
|
|
|
sub extract_embedded_items { |
|
my ($filepath,$file,$allfiles,$codebase,$content) = @_; |
|
my @state = (); |
|
my %javafiles = ( |
|
codebase => '', |
|
code => '', |
|
archive => '' |
|
); |
|
my %mediafiles = ( |
|
src => '', |
|
movie => '', |
|
); |
|
my $p; |
|
if ($content) { |
|
$p = HTML::LCParser->new($content); |
|
} else { |
|
$p = HTML::LCParser->new($filepath.'/'.$file); |
|
} |
|
while (my $t=$p->get_token()) { |
|
if ($t->[0] eq 'S') { |
|
my ($tagname, $attr) = ($t->[1],$t->[2]); |
|
push (@state, $tagname); |
|
if (lc($tagname) eq 'allow') { |
|
&add_filetype($allfiles,$attr->{'src'},'src'); |
|
} |
|
if (lc($tagname) eq 'img') { |
|
&add_filetype($allfiles,$attr->{'src'},'src'); |
|
} |
|
if (lc($tagname) eq 'script') { |
|
if ($attr->{'archive'} =~ /\.jar$/i) { |
|
&add_filetype($allfiles,$attr->{'archive'},'archive'); |
|
} else { |
|
&add_filetype($allfiles,$attr->{'src'},'src'); |
|
} |
|
} |
|
if (lc($tagname) eq 'link') { |
|
if (lc($attr->{'rel'}) eq 'stylesheet') { |
|
&add_filetype($allfiles,$attr->{'href'},'href'); |
|
} |
|
} |
|
if (lc($tagname) eq 'object' || |
|
(lc($tagname) eq 'embed' && lc($state[-2]) ne 'object')) { |
|
foreach my $item (keys(%javafiles)) { |
|
$javafiles{$item} = ''; |
|
} |
|
} |
|
if (lc($state[-2]) eq 'object' && lc($tagname) eq 'param') { |
|
my $name = lc($attr->{'name'}); |
|
foreach my $item (keys(%javafiles)) { |
|
if ($name eq $item) { |
|
$javafiles{$item} = $attr->{'value'}; |
|
last; |
|
} |
|
} |
|
foreach my $item (keys(%mediafiles)) { |
|
if ($name eq $item) { |
|
&add_filetype($allfiles, $attr->{'value'}, 'value'); |
|
last; |
|
} |
|
} |
|
} |
|
if (lc($tagname) eq 'embed' || lc($tagname) eq 'applet') { |
|
foreach my $item (keys(%javafiles)) { |
|
if ($attr->{$item}) { |
|
$javafiles{$item} = $attr->{$item}; |
|
last; |
|
} |
|
} |
|
foreach my $item (keys(%mediafiles)) { |
|
if ($attr->{$item}) { |
|
&add_filetype($allfiles,$attr->{$item},$item); |
|
last; |
|
} |
|
} |
|
} |
|
} elsif ($t->[0] eq 'E') { |
|
my ($tagname) = ($t->[1]); |
|
if ($javafiles{'codebase'} ne '') { |
|
$javafiles{'codebase'} .= '/'; |
|
} |
|
if (lc($tagname) eq 'applet' || |
|
lc($tagname) eq 'object' || |
|
(lc($tagname) eq 'embed' && lc($state[-2]) ne 'object') |
|
) { |
|
foreach my $item (keys(%javafiles)) { |
|
if ($item ne 'codebase' && $javafiles{$item} ne '') { |
|
my $file=$javafiles{'codebase'}.$javafiles{$item}; |
|
&add_filetype($allfiles,$file,$item); |
|
} |
|
} |
|
} |
|
pop @state; |
|
} |
|
} |
|
return 'ok'; |
|
} |
|
|
|
sub add_filetype { |
|
my ($allfiles,$file,$type)=@_; |
|
if (exists($allfiles->{$file})) { |
|
unless (grep/^\Q$type\E$/, @{$allfiles->{$file}}) { |
|
push(@{$allfiles->{$file}}, &escape($type)); |
|
} |
|
} else { |
|
@{$allfiles->{$file}} = (&escape($type)); |
|
} |
|
} |
|
|
sub removeuploadedurl { |
sub removeuploadedurl { |
my ($url)=@_; |
my ($url)=@_; |
my (undef,undef,$udom,$uname,$fname)=split('/',$url,5); |
my (undef,undef,$udom,$uname,$fname)=split('/',$url,5); |
return &Apache::lonnet::removeuserfile($uname,$udom,$fname); |
return &removeuserfile($uname,$udom,$fname); |
} |
} |
|
|
sub removeuserfile { |
sub removeuserfile { |
my ($docuname,$docudom,$fname)=@_; |
my ($docuname,$docudom,$fname)=@_; |
my $home=&homeserver($docuname,$docudom); |
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 { |
sub mkdiruserfile { |
Line 1323 sub mkdiruserfile {
|
Line 1750 sub mkdiruserfile {
|
sub renameuserfile { |
sub renameuserfile { |
my ($docuname,$docudom,$old,$new)=@_; |
my ($docuname,$docudom,$old,$new)=@_; |
my $home=&homeserver($docuname,$docudom); |
my $home=&homeserver($docuname,$docudom); |
return &reply("renameuserfile:$docudom:$docuname:".&escape("$old").':'. |
my $result = &reply("renameuserfile:$docudom:$docuname:". |
&escape("$new"),$home); |
&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 |
# ------------------------------------------------------------------------- Log |
Line 1350 sub flushcourselogs {
|
Line 1792 sub flushcourselogs {
|
# times and course titles for all courseids |
# times and course titles for all courseids |
# |
# |
my %courseidbuffer=(); |
my %courseidbuffer=(); |
foreach (keys %courselogs) { |
foreach my $crsid (keys %courselogs) { |
my $crsid=$_; |
|
if (&reply('log:'.$coursedombuf{$crsid}.':'.$coursenumbuf{$crsid}.':'. |
if (&reply('log:'.$coursedombuf{$crsid}.':'.$coursenumbuf{$crsid}.':'. |
&escape($courselogs{$crsid}), |
&escape($courselogs{$crsid}), |
$coursehombuf{$crsid}) eq 'ok') { |
$coursehombuf{$crsid}) eq 'ok') { |
Line 1359 sub flushcourselogs {
|
Line 1800 sub flushcourselogs {
|
} else { |
} else { |
&logthis('Failed to flush log buffer for '.$crsid); |
&logthis('Failed to flush log buffer for '.$crsid); |
if (length($courselogs{$crsid})>40000) { |
if (length($courselogs{$crsid})>40000) { |
&logthis("<font color=blue>WARNING: Buffer for ".$crsid. |
&logthis("<font color=\"blue\">WARNING: Buffer for ".$crsid. |
" exceeded maximum size, deleting.</font>"); |
" exceeded maximum size, deleting.</font>"); |
delete $courselogs{$crsid}; |
delete $courselogs{$crsid}; |
} |
} |
Line 1367 sub flushcourselogs {
|
Line 1808 sub flushcourselogs {
|
if ($courseidbuffer{$coursehombuf{$crsid}}) { |
if ($courseidbuffer{$coursehombuf{$crsid}}) { |
$courseidbuffer{$coursehombuf{$crsid}}.='&'. |
$courseidbuffer{$coursehombuf{$crsid}}.='&'. |
&escape($crsid).'='.&escape($coursedescrbuf{$crsid}). |
&escape($crsid).'='.&escape($coursedescrbuf{$crsid}). |
':'.&escape($courseinstcodebuf{$crsid}).':'.&escape($courseownerbuf{$crsid}); |
':'.&escape($courseinstcodebuf{$crsid}).':'.&escape($courseownerbuf{$crsid}).':'.&escape($coursetypebuf{$crsid}); |
} else { |
} else { |
$courseidbuffer{$coursehombuf{$crsid}}= |
$courseidbuffer{$coursehombuf{$crsid}}= |
&escape($crsid).'='.&escape($coursedescrbuf{$crsid}). |
&escape($crsid).'='.&escape($coursedescrbuf{$crsid}). |
':'.&escape($courseinstcodebuf{$crsid}).':'.&escape($courseownerbuf{$crsid}); |
':'.&escape($courseinstcodebuf{$crsid}).':'.&escape($courseownerbuf{$crsid}).':'.&escape($coursetypebuf{$crsid}); |
} |
} |
} |
} |
# |
# |
# Write course id database (reverse lookup) to homeserver of courses |
# Write course id database (reverse lookup) to homeserver of courses |
# Is used in pickcourse |
# Is used in pickcourse |
# |
# |
foreach (keys %courseidbuffer) { |
foreach my $crsid (keys(%courseidbuffer)) { |
&courseidput($hostdom{$_},$courseidbuffer{$_},$_); |
&courseidput($hostdom{$crsid},$courseidbuffer{$crsid},$crsid); |
} |
} |
# |
# |
# File accesses |
# File accesses |
Line 1388 sub flushcourselogs {
|
Line 1829 sub flushcourselogs {
|
foreach my $entry (keys(%accesshash)) { |
foreach my $entry (keys(%accesshash)) { |
if ($entry =~ /___count$/) { |
if ($entry =~ /___count$/) { |
my ($dom,$name); |
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 '' || |
if (! defined($dom) || $dom eq '' || |
! defined($name) || $name eq '') { |
! defined($name) || $name eq '') { |
my $cid = $ENV{'request.course.id'}; |
my $cid = $env{'request.course.id'}; |
$dom = $ENV{'request.'.$cid.'.domain'}; |
$dom = $env{'request.'.$cid.'.domain'}; |
$name = $ENV{'request.'.$cid.'.num'}; |
$name = $env{'request.'.$cid.'.num'}; |
} |
} |
my $value = $accesshash{$entry}; |
my $value = $accesshash{$entry}; |
my (undef,$url,undef) = ($entry =~ /^(.*)___(.*)___count$/); |
my (undef,$url,undef) = ($entry =~ /^(.*)___(.*)___count$/); |
Line 1409 sub flushcourselogs {
|
Line 1851 sub flushcourselogs {
|
} |
} |
} |
} |
} else { |
} else { |
my ($dom,$name) = ($entry=~m:___(\w+)/(\w+)/(.*)___(\w+)$:); |
my ($dom,$name) = ($entry=~m{___($match_domain)/($match_name)/(.*)___(\w+)$}); |
my %temphash=($entry => $accesshash{$entry}); |
my %temphash=($entry => $accesshash{$entry}); |
if (&put('nohist_resevaldata',\%temphash,$dom,$name) eq 'ok') { |
if (&put('nohist_resevaldata',\%temphash,$dom,$name) eq 'ok') { |
delete $accesshash{$entry}; |
delete $accesshash{$entry}; |
Line 1420 sub flushcourselogs {
|
Line 1862 sub flushcourselogs {
|
# Roles |
# Roles |
# Reverse lookup of user roles for course faculty/staff and co-authorship |
# Reverse lookup of user roles for course faculty/staff and co-authorship |
# |
# |
foreach (keys %userrolehash) { |
foreach my $entry (keys(%userrolehash)) { |
my $entry=$_; |
|
my ($role,$uname,$udom,$runame,$rudom,$rsec)= |
my ($role,$uname,$udom,$runame,$rudom,$rsec)= |
split(/\:/,$entry); |
split(/\:/,$entry); |
if (&Apache::lonnet::put('nohist_userroles', |
if (&Apache::lonnet::put('nohist_userroles', |
Line 1430 sub flushcourselogs {
|
Line 1871 sub flushcourselogs {
|
delete $userrolehash{$entry}; |
delete $userrolehash{$entry}; |
} |
} |
} |
} |
|
# |
|
# Reverse lookup of domain roles (dc, ad, li, sc, au) |
|
# |
|
my %domrolebuffer = (); |
|
foreach my $entry (keys %domainrolehash) { |
|
my ($role,$uname,$udom,$runame,$rudom,$rsec)=split/:/,$entry; |
|
if ($domrolebuffer{$rudom}) { |
|
$domrolebuffer{$rudom}.='&'.&escape($entry). |
|
'='.&escape($domainrolehash{$entry}); |
|
} else { |
|
$domrolebuffer{$rudom}.=&escape($entry). |
|
'='.&escape($domainrolehash{$entry}); |
|
} |
|
delete $domainrolehash{$entry}; |
|
} |
|
foreach my $dom (keys(%domrolebuffer)) { |
|
foreach my $tryserver (keys %libserv) { |
|
if ($hostdom{$tryserver} eq $dom) { |
|
unless (&reply('domroleput:'.$dom.':'. |
|
$domrolebuffer{$dom},$tryserver) eq 'ok') { |
|
&logthis('Put of domain roles failed for '.$dom.' and '.$tryserver); |
|
} |
|
} |
|
} |
|
} |
$dumpcount++; |
$dumpcount++; |
} |
} |
|
|
sub courselog { |
sub courselog { |
my $what=shift; |
my $what=shift; |
$what=time.':'.$what; |
$what=time.':'.$what; |
unless ($ENV{'request.course.id'}) { return ''; } |
unless ($env{'request.course.id'}) { return ''; } |
$coursedombuf{$ENV{'request.course.id'}}= |
$coursedombuf{$env{'request.course.id'}}= |
$ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; |
$env{'course.'.$env{'request.course.id'}.'.domain'}; |
$coursenumbuf{$ENV{'request.course.id'}}= |
$coursenumbuf{$env{'request.course.id'}}= |
$ENV{'course.'.$ENV{'request.course.id'}.'.num'}; |
$env{'course.'.$env{'request.course.id'}.'.num'}; |
$coursehombuf{$ENV{'request.course.id'}}= |
$coursehombuf{$env{'request.course.id'}}= |
$ENV{'course.'.$ENV{'request.course.id'}.'.home'}; |
$env{'course.'.$env{'request.course.id'}.'.home'}; |
$coursedescrbuf{$ENV{'request.course.id'}}= |
$coursedescrbuf{$env{'request.course.id'}}= |
$ENV{'course.'.$ENV{'request.course.id'}.'.description'}; |
$env{'course.'.$env{'request.course.id'}.'.description'}; |
$courseinstcodebuf{$ENV{'request.course.id'}}= |
$courseinstcodebuf{$env{'request.course.id'}}= |
$ENV{'course.'.$ENV{'request.course.id'}.'.internal.coursecode'}; |
$env{'course.'.$env{'request.course.id'}.'.internal.coursecode'}; |
$courseownerbuf{$ENV{'request.course.id'}}= |
$courseownerbuf{$env{'request.course.id'}}= |
$ENV{'course.'.$ENV{'request.course.id'}.'.internal.courseowner'}; |
$env{'course.'.$env{'request.course.id'}.'.internal.courseowner'}; |
if (defined $courselogs{$ENV{'request.course.id'}}) { |
$coursetypebuf{$env{'request.course.id'}}= |
$courselogs{$ENV{'request.course.id'}}.='&'.$what; |
$env{'course.'.$env{'request.course.id'}.'.type'}; |
|
if (defined $courselogs{$env{'request.course.id'}}) { |
|
$courselogs{$env{'request.course.id'}}.='&'.$what; |
} else { |
} else { |
$courselogs{$ENV{'request.course.id'}}.=$what; |
$courselogs{$env{'request.course.id'}}.=$what; |
} |
} |
if (length($courselogs{$ENV{'request.course.id'}})>4048) { |
if (length($courselogs{$env{'request.course.id'}})>4048) { |
&flushcourselogs(); |
&flushcourselogs(); |
} |
} |
} |
} |
|
|
sub courseacclog { |
sub courseacclog { |
my $fnsymb=shift; |
my $fnsymb=shift; |
unless ($ENV{'request.course.id'}) { return ''; } |
unless ($env{'request.course.id'}) { return ''; } |
my $what=$fnsymb.':'.$ENV{'user.name'}.':'.$ENV{'user.domain'}; |
my $what=$fnsymb.':'.$env{'user.name'}.':'.$env{'user.domain'}; |
if ($fnsymb=~/(problem|exam|quiz|assess|survey|form|page)$/) { |
if ($fnsymb=~/(problem|exam|quiz|assess|survey|form|task|page)$/) { |
$what.=':POST'; |
$what.=':POST'; |
# FIXME: Probably ought to escape things.... |
# FIXME: Probably ought to escape things.... |
foreach (keys %ENV) { |
foreach my $key (keys(%env)) { |
if ($_=~/^form\.(.*)/) { |
if ($key=~/^form\.(.*)/) { |
$what.=':'.$1.'='.$ENV{$_}; |
$what.=':'.$1.'='.$env{$key}; |
} |
} |
} |
} |
} elsif ($fnsymb =~ m:^/adm/searchcat:) { |
} elsif ($fnsymb =~ m:^/adm/searchcat:) { |
# FIXME: We should not be depending on a form parameter that someone |
# FIXME: We should not be depending on a form parameter that someone |
# editing lonsearchcat.pm might change in the future. |
# editing lonsearchcat.pm might change in the future. |
if ($ENV{'form.phase'} eq 'course_search') { |
if ($env{'form.phase'} eq 'course_search') { |
$what.= ':POST'; |
$what.= ':POST'; |
# FIXME: Probably ought to escape things.... |
# FIXME: Probably ought to escape things.... |
foreach my $element ('courseexp','crsfulltext','crsrelated', |
foreach my $element ('courseexp','crsfulltext','crsrelated', |
'crsdiscuss') { |
'crsdiscuss') { |
$what.=':'.$element.'='.$ENV{'form.'.$element}; |
$what.=':'.$element.'='.$env{'form.'.$element}; |
} |
} |
} |
} |
} |
} |
Line 1489 sub courseacclog {
|
Line 1957 sub courseacclog {
|
sub countacc { |
sub countacc { |
my $url=&declutter(shift); |
my $url=&declutter(shift); |
return if (! defined($url) || $url eq ''); |
return if (! defined($url) || $url eq ''); |
unless ($ENV{'request.course.id'}) { return ''; } |
unless ($env{'request.course.id'}) { return ''; } |
$accesshash{$ENV{'request.course.id'}.'___'.$url.'___course'}=1; |
$accesshash{$env{'request.course.id'}.'___'.$url.'___course'}=1; |
my $key=$$.$processmarker.'_'.$dumpcount.'___'.$url.'___count'; |
my $key=$$.$processmarker.'_'.$dumpcount.'___'.$url.'___count'; |
$accesshash{$key}++; |
$accesshash{$key}++; |
} |
} |
Line 1505 sub linklog {
|
Line 1973 sub linklog {
|
|
|
sub userrolelog { |
sub userrolelog { |
my ($trole,$username,$domain,$area,$tstart,$tend)=@_; |
my ($trole,$username,$domain,$area,$tstart,$tend)=@_; |
if (($trole=~/^ca/) || ($trole=~/^in/) || |
if (($trole=~/^ca/) || ($trole=~/^aa/) || |
($trole=~/^cc/) || ($trole=~/^ep/) || |
($trole=~/^in/) || ($trole=~/^cc/) || |
($trole=~/^cr/) || ($trole=~/^ta/)) { |
($trole=~/^ep/) || ($trole=~/^cr/) || |
|
($trole=~/^ta/)) { |
my (undef,$rudom,$runame,$rsec)=split(/\//,$area); |
my (undef,$rudom,$runame,$rsec)=split(/\//,$area); |
$userrolehash |
$userrolehash |
{$trole.':'.$username.':'.$domain.':'.$runame.':'.$rudom.':'.$rsec} |
{$trole.':'.$username.':'.$domain.':'.$runame.':'.$rudom.':'.$rsec} |
=$tend.':'.$tstart; |
=$tend.':'.$tstart; |
} |
} |
|
if (($trole=~/^dc/) || ($trole=~/^ad/) || |
|
($trole=~/^li/) || ($trole=~/^li/) || |
|
($trole=~/^au/) || ($trole=~/^dg/) || |
|
($trole=~/^sc/)) { |
|
my (undef,$rudom,$runame,$rsec)=split(/\//,$area); |
|
$domainrolehash |
|
{$trole.':'.$username.':'.$domain.':'.$runame.':'.$rudom.':'.$rsec} |
|
= $tend.':'.$tstart; |
|
} |
} |
} |
|
|
sub get_course_adv_roles { |
sub get_course_adv_roles { |
my $cid=shift; |
my $cid=shift; |
$cid=$ENV{'request.course.id'} unless (defined($cid)); |
$cid=$env{'request.course.id'} unless (defined($cid)); |
my %coursehash=&coursedescription($cid); |
my %coursehash=&coursedescription($cid); |
my %nothide=(); |
my %nothide=(); |
foreach (split(/\s*\,\s*/,$coursehash{'nothideprivileged'})) { |
foreach my $user (split(/\s*\,\s*/,$coursehash{'nothideprivileged'})) { |
$nothide{join(':',split(/[\@\:]/,$_))}=1; |
$nothide{join(':',split(/[\@\:]/,$user))}=1; |
} |
} |
my %returnhash=(); |
my %returnhash=(); |
my %dumphash= |
my %dumphash= |
&dump('nohist_userroles',$coursehash{'domain'},$coursehash{'num'}); |
&dump('nohist_userroles',$coursehash{'domain'},$coursehash{'num'}); |
my $now=time; |
my $now=time; |
foreach (keys %dumphash) { |
foreach my $entry (keys %dumphash) { |
my ($tend,$tstart)=split(/\:/,$dumphash{$_}); |
my ($tend,$tstart)=split(/\:/,$dumphash{$entry}); |
if (($tstart) && ($tstart<0)) { next; } |
if (($tstart) && ($tstart<0)) { next; } |
if (($tend) && ($tend<$now)) { next; } |
if (($tend) && ($tend<$now)) { next; } |
if (($tstart) && ($now<$tstart)) { 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 ($username eq '' || $domain eq '') { next; } |
if ((&privileged($username,$domain)) && |
if ((&privileged($username,$domain)) && |
(!$nothide{$username.':'.$domain})) { next; } |
(!$nothide{$username.':'.$domain})) { next; } |
|
if ($role eq 'cr') { next; } |
my $key=&plaintext($role); |
my $key=&plaintext($role); |
if ($section) { $key.=' (Sec/Grp '.$section.')'; } |
if ($section) { $key.=' (Sec/Grp '.$section.')'; } |
if ($returnhash{$key}) { |
if ($returnhash{$key}) { |
Line 1548 sub get_course_adv_roles {
|
Line 2027 sub get_course_adv_roles {
|
} |
} |
|
|
sub get_my_roles { |
sub get_my_roles { |
my ($uname,$udom)=@_; |
my ($uname,$udom,$types,$roles,$roledoms)=@_; |
unless (defined($uname)) { $uname=$ENV{'user.name'}; } |
unless (defined($uname)) { $uname=$env{'user.name'}; } |
unless (defined($udom)) { $udom=$ENV{'user.domain'}; } |
unless (defined($udom)) { $udom=$env{'user.domain'}; } |
my %dumphash= |
my %dumphash= |
&dump('nohist_userroles',$udom,$uname); |
&dump('nohist_userroles',$udom,$uname); |
my %returnhash=(); |
my %returnhash=(); |
my $now=time; |
my $now=time; |
foreach (keys %dumphash) { |
foreach my $entry (keys(%dumphash)) { |
my ($tend,$tstart)=split(/\:/,$dumphash{$_}); |
my ($tend,$tstart)=split(/\:/,$dumphash{$entry}); |
if (($tstart) && ($tstart<0)) { next; } |
if (($tstart) && ($tstart<0)) { next; } |
if (($tend) && ($tend<$now)) { next; } |
my $status = 'active'; |
if (($tstart) && ($now<$tstart)) { next; } |
if (($tend) && ($tend<$now)) { |
my ($role,$username,$domain,$section)=split(/\:/,$_); |
$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; |
$returnhash{$username.':'.$domain.':'.$role}=$tstart.':'.$tend; |
} |
} |
return %returnhash; |
return %returnhash; |
} |
} |
|
|
Line 1581 sub getannounce {
|
Line 2084 sub getannounce {
|
|
|
if (open(my $fh,$perlvar{'lonDocRoot'}.'/announcement.txt')) { |
if (open(my $fh,$perlvar{'lonDocRoot'}.'/announcement.txt')) { |
my $announcement=''; |
my $announcement=''; |
while (<$fh>) { $announcement .=$_; } |
while (my $line = <$fh>) { $announcement .= $line; } |
close($fh); |
close($fh); |
if ($announcement=~/\w/) { |
if ($announcement=~/\w/) { |
return |
return |
Line 1605 sub courseidput {
|
Line 2108 sub courseidput {
|
} |
} |
|
|
sub courseiddump { |
sub courseiddump { |
my ($domfilter,$descfilter,$sincefilter,$instcodefilter,$ownerfilter,$hostidflag,$hostidref)=@_; |
my ($domfilter,$descfilter,$sincefilter,$instcodefilter,$ownerfilter,$coursefilter,$hostidflag,$hostidref,$typefilter,$regexp_ok)=@_; |
my %returnhash=(); |
my %returnhash=(); |
unless ($domfilter) { $domfilter=''; } |
unless ($domfilter) { $domfilter=''; } |
foreach my $tryserver (keys %libserv) { |
foreach my $tryserver (keys %libserv) { |
if ( ($hostidflag == 1 && grep/^$tryserver$/,@{$hostidref}) || (!defined($hostidflag)) ) { |
if ( ($hostidflag == 1 && grep/^$tryserver$/,@{$hostidref}) || (!defined($hostidflag)) ) { |
if ((!$domfilter) || ($hostdom{$tryserver} eq $domfilter)) { |
if ((!$domfilter) || ($hostdom{$tryserver} eq $domfilter)) { |
foreach ( |
foreach my $line ( |
split(/\&/,&reply('courseiddump:'.$hostdom{$tryserver}.':'. |
split(/\&/,&reply('courseiddump:'.$hostdom{$tryserver}.':'. |
$sincefilter.':'.&escape($descfilter).':'. |
$sincefilter.':'.&escape($descfilter).':'. |
&escape($instcodefilter).':'.&escape($ownerfilter), |
&escape($instcodefilter).':'.&escape($ownerfilter).':'.&escape($coursefilter).':'.&escape($typefilter).':'.&escape($regexp_ok), |
$tryserver))) { |
$tryserver))) { |
my ($key,$value)=split(/\=/,$_); |
my ($key,$value)=split(/\=/,$line,2); |
if (($key) && ($value)) { |
if (($key) && ($value)) { |
$returnhash{&unescape($key)}=$value; |
$returnhash{&unescape($key)}=$value; |
} |
} |
Line 1627 sub courseiddump {
|
Line 2130 sub courseiddump {
|
return %returnhash; |
return %returnhash; |
} |
} |
|
|
# |
# ---------------------------------------------------------- DC e-mail |
|
|
|
sub dcmailput { |
|
my ($domain,$msgid,$message,$server)=@_; |
|
my $status = &Apache::lonnet::critical( |
|
'dcmailput:'.$domain.':'.&escape($msgid).'='. |
|
&escape($message),$server); |
|
return $status; |
|
} |
|
|
|
sub dcmaildump { |
|
my ($dom,$startdate,$enddate,$senders) = @_; |
|
my %returnhash=(); |
|
if (exists($domain_primary{$dom})) { |
|
my $cmd='dcmaildump:'.$dom.':'.&escape($startdate).':'. |
|
&escape($enddate).':'; |
|
my @esc_senders=map { &escape($_)} @$senders; |
|
$cmd.=&escape(join('&',@esc_senders)); |
|
foreach my $line (split(/\&/,&reply($cmd,$domain_primary{$dom}))) { |
|
my ($key,$value) = split(/\=/,$line,2); |
|
if (($key) && ($value)) { |
|
$returnhash{&unescape($key)} = &unescape($value); |
|
} |
|
} |
|
} |
|
return %returnhash; |
|
} |
|
# ---------------------------------------------------------- Domain roles |
|
|
|
sub get_domain_roles { |
|
my ($dom,$roles,$startdate,$enddate)=@_; |
|
if (undef($startdate) || $startdate eq '') { |
|
$startdate = '.'; |
|
} |
|
if (undef($enddate) || $enddate eq '') { |
|
$enddate = '.'; |
|
} |
|
my $rolelist = join(':',@{$roles}); |
|
my %personnel = (); |
|
foreach my $tryserver (keys(%libserv)) { |
|
if ($hostdom{$tryserver} eq $dom) { |
|
%{$personnel{$tryserver}}=(); |
|
foreach my $line ( |
|
split(/\&/,&reply('domrolesdump:'.$dom.':'. |
|
&escape($startdate).':'.&escape($enddate).':'. |
|
&escape($rolelist), $tryserver))) { |
|
my ($key,$value) = split(/\=/,$line,2); |
|
if (($key) && ($value)) { |
|
$personnel{$tryserver}{&unescape($key)} = &unescape($value); |
|
} |
|
} |
|
} |
|
} |
|
return %personnel; |
|
} |
|
|
# ----------------------------------------------------------- Check out an item |
# ----------------------------------------------------------- Check out an item |
|
|
sub get_first_access { |
sub get_first_access { |
my ($type,$argsymb)=@_; |
my ($type,$argsymb)=@_; |
my ($symb,$courseid,$udom,$uname)=&Apache::lonxml::whichuser(); |
my ($symb,$courseid,$udom,$uname)=&whichuser(); |
if ($argsymb) { $symb=$argsymb; } |
if ($argsymb) { $symb=$argsymb; } |
my ($map,$id,$res)=&decode_symb($symb); |
my ($map,$id,$res)=&decode_symb($symb); |
if ($type eq 'map') { |
if ($type eq 'map') { |
Line 1646 sub get_first_access {
|
Line 2204 sub get_first_access {
|
|
|
sub set_first_access { |
sub set_first_access { |
my ($type)=@_; |
my ($type)=@_; |
my ($symb,$courseid,$udom,$uname)=&Apache::lonxml::whichuser(); |
my ($symb,$courseid,$udom,$uname)=&whichuser(); |
my ($map,$id,$res)=&decode_symb($symb); |
my ($map,$id,$res)=&decode_symb($symb); |
if ($type eq 'map') { |
if ($type eq 'map') { |
$res=&symbread($map); |
$res=&symbread($map); |
Line 1673 sub checkout {
|
Line 2231 sub checkout {
|
$now.'&'.$ENV{'REMOTE_ADDR'}); |
$now.'&'.$ENV{'REMOTE_ADDR'}); |
my $token=&reply('tmpput:'.$infostr,$lonhost); |
my $token=&reply('tmpput:'.$infostr,$lonhost); |
if ($token=~/^error\:/) { |
if ($token=~/^error\:/) { |
&logthis("<font color=blue>WARNING: ". |
&logthis("<font color=\"blue\">WARNING: ". |
"Checkout tmpput failed ".$tudom.' - '.$tuname.' - '.$symb. |
"Checkout tmpput failed ".$tudom.' - '.$tuname.' - '.$symb. |
"</font>"); |
"</font>"); |
return ''; |
return ''; |
Line 1689 sub checkout {
|
Line 2247 sub checkout {
|
unless (&cstore(\%infohash,$symb,$tcrsid,$tudom,$tuname) eq 'ok') { |
unless (&cstore(\%infohash,$symb,$tcrsid,$tudom,$tuname) eq 'ok') { |
return ''; |
return ''; |
} else { |
} else { |
&logthis("<font color=blue>WARNING: ". |
&logthis("<font color=\"blue\">WARNING: ". |
"Checkout cstore failed ".$tudom.' - '.$tuname.' - '.$symb. |
"Checkout cstore failed ".$tudom.' - '.$tuname.' - '.$symb. |
"</font>"); |
"</font>"); |
} |
} |
Line 1699 sub checkout {
|
Line 2257 sub checkout {
|
$token)) ne 'ok') { |
$token)) ne 'ok') { |
return ''; |
return ''; |
} else { |
} else { |
&logthis("<font color=blue>WARNING: ". |
&logthis("<font color=\"blue\">WARNING: ". |
"Checkout log failed ".$tudom.' - '.$tuname.' - '.$symb. |
"Checkout log failed ".$tudom.' - '.$tuname.' - '.$symb. |
"</font>"); |
"</font>"); |
} |
} |
Line 1725 sub checkin {
|
Line 2283 sub checkin {
|
|
|
unless (&allowed('mgr',$tcrsid)) { |
unless (&allowed('mgr',$tcrsid)) { |
&logthis('Check in '.$token.' ('.$dtoken.') unauthorized: '. |
&logthis('Check in '.$token.' ('.$dtoken.') unauthorized: '. |
$ENV{'user.name'}.' - '.$ENV{'user.domain'}); |
$env{'user.name'}.' - '.$env{'user.domain'}); |
return ''; |
return ''; |
} |
} |
|
|
Line 1749 sub checkin {
|
Line 2307 sub checkin {
|
|
|
sub expirespread { |
sub expirespread { |
my ($uname,$udom,$stype,$usymb)=@_; |
my ($uname,$udom,$stype,$usymb)=@_; |
my $cid=$ENV{'request.course.id'}; |
my $cid=$env{'request.course.id'}; |
if ($cid) { |
if ($cid) { |
my $now=time; |
my $now=time; |
my $key=$uname.':'.$udom.':'.$stype.':'.$usymb; |
my $key=$uname.':'.$udom.':'.$stype.':'.$usymb; |
return &reply('put:'.$ENV{'course.'.$cid.'.domain'}.':'. |
return &reply('put:'.$env{'course.'.$cid.'.domain'}.':'. |
$ENV{'course.'.$cid.'.num'}. |
$env{'course.'.$cid.'.num'}. |
':nohist_expirationdates:'. |
':nohist_expirationdates:'. |
&escape($key).'='.$now, |
&escape($key).'='.$now, |
$ENV{'course.'.$cid.'.home'}) |
$env{'course.'.$cid.'.home'}) |
} |
} |
return 'ok'; |
return 'ok'; |
} |
} |
Line 1766 sub expirespread {
|
Line 2324 sub expirespread {
|
|
|
sub devalidate { |
sub devalidate { |
my ($symb,$uname,$udom)=@_; |
my ($symb,$uname,$udom)=@_; |
my $cid=$ENV{'request.course.id'}; |
my $cid=$env{'request.course.id'}; |
if ($cid) { |
if ($cid) { |
# delete the stored spreadsheets for |
# delete the stored spreadsheets for |
# - the student level sheet of this user in course's homespace |
# - the student level sheet of this user in course's homespace |
Line 1777 sub devalidate {
|
Line 2335 sub devalidate {
|
my $status= |
my $status= |
&del('nohist_calculatedsheets', |
&del('nohist_calculatedsheets', |
[$key.'studentcalc:'], |
[$key.'studentcalc:'], |
$ENV{'course.'.$cid.'.domain'}, |
$env{'course.'.$cid.'.domain'}, |
$ENV{'course.'.$cid.'.num'}) |
$env{'course.'.$cid.'.num'}) |
.' '. |
.' '. |
&del('nohist_calculatedsheets_'.$cid, |
&del('nohist_calculatedsheets_'.$cid, |
[$key.'assesscalc:'.$symb],$udom,$uname); |
[$key.'assesscalc:'.$symb],$udom,$uname); |
Line 1840 sub hash2str {
|
Line 2398 sub hash2str {
|
sub hashref2str { |
sub hashref2str { |
my ($hashref)=@_; |
my ($hashref)=@_; |
my $result='__HASH_REF__'; |
my $result='__HASH_REF__'; |
foreach (sort(keys(%$hashref))) { |
foreach my $key (sort(keys(%$hashref))) { |
if (ref($_) eq 'ARRAY') { |
if (ref($key) eq 'ARRAY') { |
$result.=&arrayref2str($_).'='; |
$result.=&arrayref2str($key).'='; |
} elsif (ref($_) eq 'HASH') { |
} elsif (ref($key) eq 'HASH') { |
$result.=&hashref2str($_).'='; |
$result.=&hashref2str($key).'='; |
} elsif (ref($_)) { |
} elsif (ref($key)) { |
$result.='='; |
$result.='='; |
#print("Got a ref of ".(ref($_))." skipping."); |
#print("Got a ref of ".(ref($key))." skipping."); |
} else { |
} else { |
if ($_) {$result.=&escape($_).'=';} else { last; } |
if ($key) {$result.=&escape($key).'=';} else { last; } |
} |
} |
|
|
if(ref($hashref->{$_}) eq 'ARRAY') { |
if(ref($hashref->{$key}) eq 'ARRAY') { |
$result.=&arrayref2str($hashref->{$_}).'&'; |
$result.=&arrayref2str($hashref->{$key}).'&'; |
} elsif(ref($hashref->{$_}) eq 'HASH') { |
} elsif(ref($hashref->{$key}) eq 'HASH') { |
$result.=&hashref2str($hashref->{$_}).'&'; |
$result.=&hashref2str($hashref->{$key}).'&'; |
} elsif(ref($hashref->{$_})) { |
} elsif(ref($hashref->{$key})) { |
$result.='&'; |
$result.='&'; |
#print("Got a ref of ".(ref($hashref->{$_}))." skipping."); |
#print("Got a ref of ".(ref($hashref->{$key}))." skipping."); |
} else { |
} else { |
$result.=&escape($hashref->{$_}).'&'; |
$result.=&escape($hashref->{$key}).'&'; |
} |
} |
} |
} |
$result=~s/\&$//; |
$result=~s/\&$//; |
Line 1988 sub tmpreset {
|
Line 2546 sub tmpreset {
|
my ($symb,$namespace,$domain,$stuname) = @_; |
my ($symb,$namespace,$domain,$stuname) = @_; |
if (!$symb) { |
if (!$symb) { |
$symb=&symbread(); |
$symb=&symbread(); |
if (!$symb) { $symb= $ENV{'request.url'}; } |
if (!$symb) { $symb= $env{'request.url'}; } |
} |
} |
$symb=escape($symb); |
$symb=escape($symb); |
|
|
if (!$namespace) { $namespace=$ENV{'request.state'}; } |
if (!$namespace) { $namespace=$env{'request.state'}; } |
$namespace=~s/\//\_/g; |
$namespace=~s/\//\_/g; |
$namespace=~s/\W//g; |
$namespace=~s/\W//g; |
|
|
if (!$domain) { $domain=$ENV{'user.domain'}; } |
if (!$domain) { $domain=$env{'user.domain'}; } |
if (!$stuname) { $stuname=$ENV{'user.name'}; } |
if (!$stuname) { $stuname=$env{'user.name'}; } |
if ($domain eq 'public' && $stuname eq 'public') { |
if ($domain eq 'public' && $stuname eq 'public') { |
$stuname=$ENV{'REMOTE_ADDR'}; |
$stuname=$ENV{'REMOTE_ADDR'}; |
} |
} |
Line 2019 sub tmpstore {
|
Line 2577 sub tmpstore {
|
|
|
if (!$symb) { |
if (!$symb) { |
$symb=&symbread(); |
$symb=&symbread(); |
if (!$symb) { $symb= $ENV{'request.url'}; } |
if (!$symb) { $symb= $env{'request.url'}; } |
} |
} |
$symb=escape($symb); |
$symb=escape($symb); |
|
|
if (!$namespace) { |
if (!$namespace) { |
# I don't think we would ever want to store this for a course. |
# I don't think we would ever want to store this for a course. |
# it seems this will only be used if we don't have a course. |
# it seems this will only be used if we don't have a course. |
#$namespace=$ENV{'request.course.id'}; |
#$namespace=$env{'request.course.id'}; |
#if (!$namespace) { |
#if (!$namespace) { |
$namespace=$ENV{'request.state'}; |
$namespace=$env{'request.state'}; |
#} |
#} |
} |
} |
$namespace=~s/\//\_/g; |
$namespace=~s/\//\_/g; |
$namespace=~s/\W//g; |
$namespace=~s/\W//g; |
if (!$domain) { $domain=$ENV{'user.domain'}; } |
if (!$domain) { $domain=$env{'user.domain'}; } |
if (!$stuname) { $stuname=$ENV{'user.name'}; } |
if (!$stuname) { $stuname=$env{'user.name'}; } |
if ($domain eq 'public' && $stuname eq 'public') { |
if ($domain eq 'public' && $stuname eq 'public') { |
$stuname=$ENV{'REMOTE_ADDR'}; |
$stuname=$ENV{'REMOTE_ADDR'}; |
} |
} |
Line 2071 sub tmprestore {
|
Line 2629 sub tmprestore {
|
|
|
if (!$symb) { |
if (!$symb) { |
$symb=&symbread(); |
$symb=&symbread(); |
if (!$symb) { $symb= $ENV{'request.url'}; } |
if (!$symb) { $symb= $env{'request.url'}; } |
} |
} |
$symb=escape($symb); |
$symb=escape($symb); |
|
|
if (!$namespace) { $namespace=$ENV{'request.state'}; } |
if (!$namespace) { $namespace=$env{'request.state'}; } |
|
|
if (!$domain) { $domain=$ENV{'user.domain'}; } |
if (!$domain) { $domain=$env{'user.domain'}; } |
if (!$stuname) { $stuname=$ENV{'user.name'}; } |
if (!$stuname) { $stuname=$env{'user.name'}; } |
if ($domain eq 'public' && $stuname eq 'public') { |
if ($domain eq 'public' && $stuname eq 'public') { |
$stuname=$ENV{'REMOTE_ADDR'}; |
$stuname=$ENV{'REMOTE_ADDR'}; |
} |
} |
Line 2123 sub store {
|
Line 2681 sub store {
|
$symb=&symbclean($symb); |
$symb=&symbclean($symb); |
if (!$symb) { unless ($symb=&symbread()) { return ''; } } |
if (!$symb) { unless ($symb=&symbread()) { return ''; } } |
|
|
if (!$domain) { $domain=$ENV{'user.domain'}; } |
if (!$domain) { $domain=$env{'user.domain'}; } |
if (!$stuname) { $stuname=$ENV{'user.name'}; } |
if (!$stuname) { $stuname=$env{'user.name'}; } |
|
|
&devalidate($symb,$stuname,$domain); |
&devalidate($symb,$stuname,$domain); |
|
|
$symb=escape($symb); |
$symb=escape($symb); |
if (!$namespace) { |
if (!$namespace) { |
unless ($namespace=$ENV{'request.course.id'}) { |
unless ($namespace=$env{'request.course.id'}) { |
return ''; |
return ''; |
} |
} |
} |
} |
if (!$home) { $home=$ENV{'user.home'}; } |
if (!$home) { $home=$env{'user.home'}; } |
|
|
$$storehash{'ip'}=$ENV{'REMOTE_ADDR'}; |
$$storehash{'ip'}=$ENV{'REMOTE_ADDR'}; |
$$storehash{'host'}=$perlvar{'lonHostID'}; |
$$storehash{'host'}=$perlvar{'lonHostID'}; |
|
|
my $namevalue=''; |
my $namevalue=''; |
foreach (keys %$storehash) { |
foreach my $key (keys(%$storehash)) { |
$namevalue.=&escape($_).'='.&freeze_escape($$storehash{$_}).'&'; |
$namevalue.=&escape($key).'='.&freeze_escape($$storehash{$key}).'&'; |
} |
} |
$namevalue=~s/\&$//; |
$namevalue=~s/\&$//; |
&courselog($symb.':'.$stuname.':'.$domain.':STORE:'.$namevalue); |
&courselog($symb.':'.$stuname.':'.$domain.':STORE:'.$namevalue); |
Line 2159 sub cstore {
|
Line 2717 sub cstore {
|
$symb=&symbclean($symb); |
$symb=&symbclean($symb); |
if (!$symb) { unless ($symb=&symbread()) { return ''; } } |
if (!$symb) { unless ($symb=&symbread()) { return ''; } } |
|
|
if (!$domain) { $domain=$ENV{'user.domain'}; } |
if (!$domain) { $domain=$env{'user.domain'}; } |
if (!$stuname) { $stuname=$ENV{'user.name'}; } |
if (!$stuname) { $stuname=$env{'user.name'}; } |
|
|
&devalidate($symb,$stuname,$domain); |
&devalidate($symb,$stuname,$domain); |
|
|
$symb=escape($symb); |
$symb=escape($symb); |
if (!$namespace) { |
if (!$namespace) { |
unless ($namespace=$ENV{'request.course.id'}) { |
unless ($namespace=$env{'request.course.id'}) { |
return ''; |
return ''; |
} |
} |
} |
} |
if (!$home) { $home=$ENV{'user.home'}; } |
if (!$home) { $home=$env{'user.home'}; } |
|
|
$$storehash{'ip'}=$ENV{'REMOTE_ADDR'}; |
$$storehash{'ip'}=$ENV{'REMOTE_ADDR'}; |
$$storehash{'host'}=$perlvar{'lonHostID'}; |
$$storehash{'host'}=$perlvar{'lonHostID'}; |
|
|
my $namevalue=''; |
my $namevalue=''; |
foreach (keys %$storehash) { |
foreach my $key (keys(%$storehash)) { |
$namevalue.=&escape($_).'='.&freeze_escape($$storehash{$_}).'&'; |
$namevalue.=&escape($key).'='.&freeze_escape($$storehash{$key}).'&'; |
} |
} |
$namevalue=~s/\&$//; |
$namevalue=~s/\&$//; |
&courselog($symb.':'.$stuname.':'.$domain.':CSTORE:'.$namevalue); |
&courselog($symb.':'.$stuname.':'.$domain.':CSTORE:'.$namevalue); |
Line 2199 sub restore {
|
Line 2757 sub restore {
|
$symb=&escape(&symbclean($symb)); |
$symb=&escape(&symbclean($symb)); |
} |
} |
if (!$namespace) { |
if (!$namespace) { |
unless ($namespace=$ENV{'request.course.id'}) { |
unless ($namespace=$env{'request.course.id'}) { |
return ''; |
return ''; |
} |
} |
} |
} |
if (!$domain) { $domain=$ENV{'user.domain'}; } |
if (!$domain) { $domain=$env{'user.domain'}; } |
if (!$stuname) { $stuname=$ENV{'user.name'}; } |
if (!$stuname) { $stuname=$env{'user.name'}; } |
if (!$home) { $home=$ENV{'user.home'}; } |
if (!$home) { $home=$env{'user.home'}; } |
my $answer=&reply("restore:$domain:$stuname:$namespace:$symb","$home"); |
my $answer=&reply("restore:$domain:$stuname:$namespace:$symb","$home"); |
|
|
my %returnhash=(); |
my %returnhash=(); |
foreach (split(/\&/,$answer)) { |
foreach my $line (split(/\&/,$answer)) { |
my ($name,$value)=split(/\=/,$_); |
my ($name,$value)=split(/\=/,$line); |
$returnhash{&unescape($name)}=&thaw_unescape($value); |
$returnhash{&unescape($name)}=&thaw_unescape($value); |
} |
} |
my $version; |
my $version; |
for ($version=1;$version<=$returnhash{'version'};$version++) { |
for ($version=1;$version<=$returnhash{'version'};$version++) { |
foreach (split(/\:/,$returnhash{$version.':keys'})) { |
foreach my $item (split(/\:/,$returnhash{$version.':keys'})) { |
$returnhash{$_}=$returnhash{$version.':'.$_}; |
$returnhash{$item}=$returnhash{$version.':'.$item}; |
} |
} |
} |
} |
return %returnhash; |
return %returnhash; |
Line 2225 sub restore {
|
Line 2783 sub restore {
|
# ---------------------------------------------------------- Course Description |
# ---------------------------------------------------------- Course Description |
|
|
sub coursedescription { |
sub coursedescription { |
my $courseid=shift; |
my ($courseid,$args)=@_; |
$courseid=~s/^\///; |
$courseid=~s/^\///; |
$courseid=~s/\_/\//g; |
$courseid=~s/\_/\//g; |
my ($cdomain,$cnum)=split(/\//,$courseid); |
my ($cdomain,$cnum)=split(/\//,$courseid); |
Line 2235 sub coursedescription {
|
Line 2793 sub coursedescription {
|
# trying and trying and trying to get the course description. |
# trying and trying and trying to get the course description. |
my %envhash=(); |
my %envhash=(); |
my %returnhash=(); |
my %returnhash=(); |
$envhash{'course.'.$normalid.'.last_cache'}=time; |
|
|
my $expiretime=600; |
|
if ($env{'request.course.id'} eq $normalid) { |
|
$expiretime=120; |
|
} |
|
|
|
my $prefix='course.'.$cdomain.'_'.$cnum.'.'; |
|
if (!$args->{'freshen_cache'} |
|
&& ((time-$env{$prefix.'last_cache'}) < $expiretime) ) { |
|
foreach my $key (keys(%env)) { |
|
next if ($key !~ /^\Q$prefix\E(.*)/); |
|
my ($setting) = $1; |
|
$returnhash{$setting} = $env{$key}; |
|
} |
|
return %returnhash; |
|
} |
|
|
|
# get the data agin |
|
if (!$args->{'one_time'}) { |
|
$envhash{'course.'.$normalid.'.last_cache'}=time; |
|
} |
|
|
if ($chome ne 'no_host') { |
if ($chome ne 'no_host') { |
%returnhash=&dump('environment',$cdomain,$cnum); |
%returnhash=&dump('environment',$cdomain,$cnum); |
if (!exists($returnhash{'con_lost'})) { |
if (!exists($returnhash{'con_lost'})) { |
$returnhash{'home'}= $chome; |
$returnhash{'home'}= $chome; |
$returnhash{'domain'} = $cdomain; |
$returnhash{'domain'} = $cdomain; |
$returnhash{'num'} = $cnum; |
$returnhash{'num'} = $cnum; |
|
if (!defined($returnhash{'type'})) { |
|
$returnhash{'type'} = 'Course'; |
|
} |
while (my ($name,$value) = each %returnhash) { |
while (my ($name,$value) = each %returnhash) { |
$envhash{'course.'.$normalid.'.'.$name}=$value; |
$envhash{'course.'.$normalid.'.'.$name}=$value; |
} |
} |
$returnhash{'url'}=&clutter($returnhash{'url'}); |
$returnhash{'url'}=&clutter($returnhash{'url'}); |
$returnhash{'fn'}=$perlvar{'lonDaemons'}.'/tmp/'. |
$returnhash{'fn'}=$perlvar{'lonDaemons'}.'/tmp/'. |
$ENV{'user.name'}.'_'.$cdomain.'_'.$cnum; |
$env{'user.name'}.'_'.$cdomain.'_'.$cnum; |
$envhash{'course.'.$normalid.'.home'}=$chome; |
$envhash{'course.'.$normalid.'.home'}=$chome; |
$envhash{'course.'.$normalid.'.domain'}=$cdomain; |
$envhash{'course.'.$normalid.'.domain'}=$cdomain; |
$envhash{'course.'.$normalid.'.num'}=$cnum; |
$envhash{'course.'.$normalid.'.num'}=$cnum; |
} |
} |
} |
} |
&appenv(%envhash); |
if (!$args->{'one_time'}) { |
|
&appenv(%envhash); |
|
} |
return %returnhash; |
return %returnhash; |
} |
} |
|
|
Line 2266 sub privileged {
|
Line 2850 sub privileged {
|
if (($rolesdump eq 'con_lost') || ($rolesdump eq '')) { return 0; } |
if (($rolesdump eq 'con_lost') || ($rolesdump eq '')) { return 0; } |
my $now=time; |
my $now=time; |
if ($rolesdump ne '') { |
if ($rolesdump ne '') { |
foreach (split(/&/,$rolesdump)) { |
foreach my $entry (split(/&/,$rolesdump)) { |
if ($_!~/^rolesdef_/) { |
if ($entry!~/^rolesdef_/) { |
my ($area,$role)=split(/=/,$_); |
my ($area,$role)=split(/=/,$entry); |
$area=~s/\_\w\w$//; |
$area=~s/\_\w\w$//; |
my ($trole,$tend,$tstart)=split(/_/,$role); |
my ($trole,$tend,$tstart)=split(/_/,$role); |
if (($trole eq 'dc') || ($trole eq 'su')) { |
if (($trole eq 'dc') || ($trole eq 'su')) { |
Line 2294 sub rolesinit {
|
Line 2878 sub rolesinit {
|
my $rolesdump=reply("dump:$domain:$username:roles",$authhost); |
my $rolesdump=reply("dump:$domain:$username:roles",$authhost); |
if (($rolesdump eq 'con_lost') || ($rolesdump eq '')) { return ''; } |
if (($rolesdump eq 'con_lost') || ($rolesdump eq '')) { return ''; } |
my %allroles=(); |
my %allroles=(); |
|
my %allgroups=(); |
my $now=time; |
my $now=time; |
my $userroles="user.login.time=$now\n"; |
my %userroles = ('user.login.time' => $now); |
|
my $group_privs; |
|
|
if ($rolesdump ne '') { |
if ($rolesdump ne '') { |
foreach (split(/&/,$rolesdump)) { |
foreach my $entry (split(/&/,$rolesdump)) { |
if ($_!~/^rolesdef_/) { |
if ($entry!~/^rolesdef_/) { |
my ($area,$role)=split(/=/,$_); |
my ($area,$role)=split(/=/,$entry); |
$area=~s/\_\w\w$//; |
$area=~s/\_\w\w$//; |
|
my ($trole,$tend,$tstart,$group_privs); |
my ($trole,$tend,$tstart); |
|
if ($role=~/^cr/) { |
if ($role=~/^cr/) { |
($trole,my $trest)=($role=~m|^(cr/\w+/\w+/[a-zA-Z0-9]+)_(.*)$|); |
if ($role=~m|^(cr/$match_domain/$match_username/[a-zA-Z0-9]+)_(.*)$|) { |
($tend,$tstart)=split('_',$trest); |
($trole,my $trest)=($role=~m|^(cr/$match_domain/$match_username/[a-zA-Z0-9]+)_(.*)$|); |
|
($tend,$tstart)=split('_',$trest); |
|
} else { |
|
$trole=$role; |
|
} |
|
} elsif ($role =~ m|^gr/|) { |
|
($trole,$tend,$tstart) = split(/_/,$role); |
|
($trole,$group_privs) = split(/\//,$trole); |
|
$group_privs = &unescape($group_privs); |
} else { |
} else { |
($trole,$tend,$tstart)=split(/_/,$role); |
($trole,$tend,$tstart)=split(/_/,$role); |
} |
} |
$userroles.=&set_arearole($trole,$area,$tstart,$tend,$domain,$username); |
my %new_role = &set_arearole($trole,$area,$tstart,$tend,$domain, |
|
$username); |
|
@userroles{keys(%new_role)} = @new_role{keys(%new_role)}; |
if (($tend!=0) && ($tend<$now)) { $trole=''; } |
if (($tend!=0) && ($tend<$now)) { $trole=''; } |
if (($tstart!=0) && ($tstart>$now)) { $trole=''; } |
if (($tstart!=0) && ($tstart>$now)) { $trole=''; } |
if (($area ne '') && ($trole ne '')) { |
if (($area ne '') && ($trole ne '')) { |
Line 2318 sub rolesinit {
|
Line 2913 sub rolesinit {
|
my ($tdummy,$tdomain,$trest)=split(/\//,$area); |
my ($tdummy,$tdomain,$trest)=split(/\//,$area); |
if ($trole =~ /^cr\//) { |
if ($trole =~ /^cr\//) { |
&custom_roleprivs(\%allroles,$trole,$tdomain,$trest,$spec,$area); |
&custom_roleprivs(\%allroles,$trole,$tdomain,$trest,$spec,$area); |
|
} elsif ($trole eq 'gr') { |
|
&group_roleprivs(\%allgroups,$area,$group_privs,$tend,$tstart); |
} else { |
} else { |
&standard_roleprivs(\%allroles,$trole,$tdomain,$spec,$trest,$area); |
&standard_roleprivs(\%allroles,$trole,$tdomain,$spec,$trest,$area); |
} |
} |
} |
} |
} |
} |
} |
} |
my ($author,$adv) = &set_userprivs(\$userroles,\%allroles); |
my ($author,$adv) = &set_userprivs(\%userroles,\%allroles,\%allgroups); |
$userroles.='user.adv='.$adv."\n". |
$userroles{'user.adv'} = $adv; |
'user.author='.$author."\n"; |
$userroles{'user.author'} = $author; |
$ENV{'user.adv'}=$adv; |
$env{'user.adv'}=$adv; |
} |
} |
return $userroles; |
return \%userroles; |
} |
} |
|
|
sub set_arearole { |
sub set_arearole { |
my ($trole,$area,$tstart,$tend,$domain,$username) = @_; |
my ($trole,$area,$tstart,$tend,$domain,$username) = @_; |
# log the associated role with the area |
# 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."\n"; |
return ('user.role.'.$trole.'.'.$area => $tstart.'.'.$tend); |
} |
} |
|
|
sub custom_roleprivs { |
sub custom_roleprivs { |
Line 2366 sub custom_roleprivs {
|
Line 2963 sub custom_roleprivs {
|
} |
} |
} |
} |
|
|
|
sub group_roleprivs { |
|
my ($allgroups,$area,$group_privs,$tend,$tstart) = @_; |
|
my $access = 1; |
|
my $now = time; |
|
if (($tend!=0) && ($tend<$now)) { $access = 0; } |
|
if (($tstart!=0) && ($tstart>$now)) { $access=0; } |
|
if ($access) { |
|
my ($course,$group) = ($area =~ m|(/$match_domain/$match_courseid)/([^/]+)$|); |
|
$$allgroups{$course}{$group} .=':'.$group_privs; |
|
} |
|
} |
|
|
sub standard_roleprivs { |
sub standard_roleprivs { |
my ($allroles,$trole,$tdomain,$spec,$trest,$area) = @_; |
my ($allroles,$trole,$tdomain,$spec,$trest,$area) = @_; |
Line 2386 sub standard_roleprivs {
|
Line 2994 sub standard_roleprivs {
|
} |
} |
|
|
sub set_userprivs { |
sub set_userprivs { |
my ($userroles,$allroles) = @_; |
my ($userroles,$allroles,$allgroups) = @_; |
my $author=0; |
my $author=0; |
my $adv=0; |
my $adv=0; |
foreach (keys %{$allroles}) { |
my %grouproles = (); |
my %thesepriv=(); |
if (keys(%{$allgroups}) > 0) { |
if (($_=~/^au/) || ($_=~/^ca/)) { $author=1; } |
foreach my $role (keys %{$allroles}) { |
foreach (split(/:/,$$allroles{$_})) { |
my ($trole,$area,$sec,$extendedarea); |
if ($_ ne '') { |
if ($role =~ m-^(\w+|cr/$match_domain/$match_username/\w+)\.(/$match_domain/$match_courseid)(/?\w*)-) { |
my ($privilege,$restrictions)=split(/&/,$_); |
$trole = $1; |
|
$area = $2; |
|
$sec = $3; |
|
$extendedarea = $area.$sec; |
|
if (exists($$allgroups{$area})) { |
|
foreach my $group (keys(%{$$allgroups{$area}})) { |
|
my $spec = $trole.'.'.$extendedarea; |
|
$grouproles{$spec.'.'.$area.'/'.$group} = |
|
$$allgroups{$area}{$group}; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
foreach my $group (keys(%grouproles)) { |
|
$$allroles{$group} = $grouproles{$group}; |
|
} |
|
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 '') { |
if ($restrictions eq '') { |
$thesepriv{$privilege}='F'; |
$thesepriv{$privilege}='F'; |
} elsif ($thesepriv{$privilege} ne 'F') { |
} elsif ($thesepriv{$privilege} ne 'F') { |
Line 2404 sub set_userprivs {
|
Line 3034 sub set_userprivs {
|
} |
} |
} |
} |
my $thesestr=''; |
my $thesestr=''; |
foreach (keys %thesepriv) { $thesestr.=':'.$_.'&'.$thesepriv{$_}; } |
foreach my $priv (keys(%thesepriv)) { |
$$userroles.='user.priv.'.$_.'='.$thesestr."\n"; |
$thesestr.=':'.$priv.'&'.$thesepriv{$priv}; |
|
} |
|
$userroles->{'user.priv.'.$role} = $thesestr; |
} |
} |
return ($author,$adv); |
return ($author,$adv); |
} |
} |
Line 2415 sub set_userprivs {
|
Line 3047 sub set_userprivs {
|
sub get { |
sub get { |
my ($namespace,$storearr,$udomain,$uname)=@_; |
my ($namespace,$storearr,$udomain,$uname)=@_; |
my $items=''; |
my $items=''; |
foreach (@$storearr) { |
foreach my $item (@$storearr) { |
$items.=escape($_).'&'; |
$items.=&escape($item).'&'; |
} |
} |
$items=~s/\&$//; |
$items=~s/\&$//; |
if (!$udomain) { $udomain=$ENV{'user.domain'}; } |
if (!$udomain) { $udomain=$env{'user.domain'}; } |
if (!$uname) { $uname=$ENV{'user.name'}; } |
if (!$uname) { $uname=$env{'user.name'}; } |
my $uhome=&homeserver($uname,$udomain); |
my $uhome=&homeserver($uname,$udomain); |
|
|
my $rep=&reply("get:$udomain:$uname:$namespace:$items",$uhome); |
my $rep=&reply("get:$udomain:$uname:$namespace:$items",$uhome); |
Line 2430 sub get {
|
Line 3062 sub get {
|
} |
} |
my %returnhash=(); |
my %returnhash=(); |
my $i=0; |
my $i=0; |
foreach (@$storearr) { |
foreach my $item (@$storearr) { |
$returnhash{$_}=&thaw_unescape($pairs[$i]); |
$returnhash{$item}=&thaw_unescape($pairs[$i]); |
$i++; |
$i++; |
} |
} |
return %returnhash; |
return %returnhash; |
Line 2442 sub get {
|
Line 3074 sub get {
|
sub del { |
sub del { |
my ($namespace,$storearr,$udomain,$uname)=@_; |
my ($namespace,$storearr,$udomain,$uname)=@_; |
my $items=''; |
my $items=''; |
foreach (@$storearr) { |
foreach my $item (@$storearr) { |
$items.=escape($_).'&'; |
$items.=&escape($item).'&'; |
} |
} |
$items=~s/\&$//; |
$items=~s/\&$//; |
if (!$udomain) { $udomain=$ENV{'user.domain'}; } |
if (!$udomain) { $udomain=$env{'user.domain'}; } |
if (!$uname) { $uname=$ENV{'user.name'}; } |
if (!$uname) { $uname=$env{'user.name'}; } |
my $uhome=&homeserver($uname,$udomain); |
my $uhome=&homeserver($uname,$udomain); |
|
|
return &reply("del:$udomain:$uname:$namespace:$items",$uhome); |
return &reply("del:$udomain:$uname:$namespace:$items",$uhome); |
Line 2456 sub del {
|
Line 3088 sub del {
|
# -------------------------------------------------------------- dump interface |
# -------------------------------------------------------------- dump interface |
|
|
sub dump { |
sub dump { |
my ($namespace,$udomain,$uname,$regexp)=@_; |
my ($namespace,$udomain,$uname,$regexp,$range)=@_; |
if (!$udomain) { $udomain=$ENV{'user.domain'}; } |
if (!$udomain) { $udomain=$env{'user.domain'}; } |
if (!$uname) { $uname=$ENV{'user.name'}; } |
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); |
|
$key = &unescape($key); |
|
next if ($key =~ /^error: 2 /); |
|
$returnhash{$key}=&thaw_unescape($value); |
|
} |
|
return %returnhash; |
|
} |
|
|
|
# --------------------------------------------------------- dumpstore interface |
|
|
|
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); |
my $uhome=&homeserver($uname,$udomain); |
if ($regexp) { |
if ($regexp) { |
$regexp=&escape($regexp); |
$regexp=&escape($regexp); |
} else { |
} else { |
$regexp='.'; |
$regexp='.'; |
} |
} |
my $rep=reply("dump:$udomain:$uname:$namespace:$regexp",$uhome); |
my $rep=&reply("dump:$udomain:$uname:$namespace:$regexp:$range",$uhome); |
my @pairs=split(/\&/,$rep); |
my @pairs=split(/\&/,$rep); |
my %returnhash=(); |
my %returnhash=(); |
foreach (@pairs) { |
foreach my $item (@pairs) { |
my ($key,$value)=split(/=/,$_); |
my ($key,$value)=split(/=/,$item,2); |
$returnhash{unescape($key)}=&thaw_unescape($value); |
next if ($key =~ /^error: 2 /); |
|
$returnhash{$key}=&thaw_unescape($value); |
} |
} |
return %returnhash; |
return %returnhash; |
} |
} |
Line 2479 sub dump {
|
Line 3136 sub dump {
|
|
|
sub getkeys { |
sub getkeys { |
my ($namespace,$udomain,$uname)=@_; |
my ($namespace,$udomain,$uname)=@_; |
if (!$udomain) { $udomain=$ENV{'user.domain'}; } |
if (!$udomain) { $udomain=$env{'user.domain'}; } |
if (!$uname) { $uname=$ENV{'user.name'}; } |
if (!$uname) { $uname=$env{'user.name'}; } |
my $uhome=&homeserver($uname,$udomain); |
my $uhome=&homeserver($uname,$udomain); |
my $rep=reply("keys:$udomain:$uname:$namespace",$uhome); |
my $rep=reply("keys:$udomain:$uname:$namespace",$uhome); |
my @keyarray=(); |
my @keyarray=(); |
foreach (split(/\&/,$rep)) { |
foreach my $key (split(/\&/,$rep)) { |
push (@keyarray,&unescape($_)); |
next if ($key =~ /^error: 2 /); |
|
push(@keyarray,&unescape($key)); |
} |
} |
return @keyarray; |
return @keyarray; |
} |
} |
Line 2493 sub getkeys {
|
Line 3151 sub getkeys {
|
# --------------------------------------------------------------- currentdump |
# --------------------------------------------------------------- currentdump |
sub currentdump { |
sub currentdump { |
my ($courseid,$sdom,$sname)=@_; |
my ($courseid,$sdom,$sname)=@_; |
$courseid = $ENV{'request.course.id'} if (! defined($courseid)); |
$courseid = $env{'request.course.id'} if (! defined($courseid)); |
$sdom = $ENV{'user.domain'} if (! defined($sdom)); |
$sdom = $env{'user.domain'} if (! defined($sdom)); |
$sname = $ENV{'user.name'} if (! defined($sname)); |
$sname = $env{'user.name'} if (! defined($sname)); |
my $uhome = &homeserver($sname,$sdom); |
my $uhome = &homeserver($sname,$sdom); |
my $rep=reply('currentdump:'.$sdom.':'.$sname.':'.$courseid,$uhome); |
my $rep=reply('currentdump:'.$sdom.':'.$sname.':'.$courseid,$uhome); |
return if ($rep =~ /^(error:|no_such_host)/); |
return if ($rep =~ /^(error:|no_such_host)/); |
Line 2505 sub currentdump {
|
Line 3163 sub currentdump {
|
if ($rep eq "unknown_cmd") { |
if ($rep eq "unknown_cmd") { |
# an old lond will not know currentdump |
# an old lond will not know currentdump |
# Do a dump and make it look like a 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)/); |
return if ($tmp[0] =~ /^(error:|no_such_host)/); |
my %hash = @tmp; |
my %hash = @tmp; |
@tmp=(); |
@tmp=(); |
%returnhash = %{&convert_dump_to_currentdump(\%hash)}; |
%returnhash = %{&convert_dump_to_currentdump(\%hash)}; |
} else { |
} else { |
my @pairs=split(/\&/,$rep); |
my @pairs=split(/\&/,$rep); |
foreach (@pairs) { |
foreach my $pair (@pairs) { |
my ($key,$value)=split(/=/,$_); |
my ($key,$value)=split(/=/,$pair,2); |
my ($symb,$param) = split(/:/,$key); |
my ($symb,$param) = split(/:/,$key); |
$returnhash{&unescape($symb)}->{&unescape($param)} = |
$returnhash{&unescape($symb)}->{&unescape($param)} = |
&thaw_unescape($value); |
&thaw_unescape($value); |
Line 2530 sub convert_dump_to_currentdump{
|
Line 3188 sub convert_dump_to_currentdump{
|
# we might run in to problems with parameter names =~ /^v\./ |
# we might run in to problems with parameter names =~ /^v\./ |
while (my ($key,$value) = each(%hash)) { |
while (my ($key,$value) = each(%hash)) { |
my ($v,$symb,$param) = split(/:/,$key); |
my ($v,$symb,$param) = split(/:/,$key); |
|
$symb = &unescape($symb); |
|
$param = &unescape($param); |
next if ($v eq 'version' || $symb eq 'keys'); |
next if ($v eq 'version' || $symb eq 'keys'); |
next if (exists($returnhash{$symb}) && |
next if (exists($returnhash{$symb}) && |
exists($returnhash{$symb}->{$param}) && |
exists($returnhash{$symb}->{$param}) && |
Line 2549 sub convert_dump_to_currentdump{
|
Line 3209 sub convert_dump_to_currentdump{
|
return \%returnhash; |
return \%returnhash; |
} |
} |
|
|
|
# ------------------------------------------------------ critical inc interface |
|
|
|
sub cinc { |
|
return &inc(@_,'critical'); |
|
} |
|
|
# --------------------------------------------------------------- inc interface |
# --------------------------------------------------------------- inc interface |
|
|
sub inc { |
sub inc { |
my ($namespace,$store,$udomain,$uname) = @_; |
my ($namespace,$store,$udomain,$uname,$critical) = @_; |
if (!$udomain) { $udomain=$ENV{'user.domain'}; } |
if (!$udomain) { $udomain=$env{'user.domain'}; } |
if (!$uname) { $uname=$ENV{'user.name'}; } |
if (!$uname) { $uname=$env{'user.name'}; } |
my $uhome=&homeserver($uname,$udomain); |
my $uhome=&homeserver($uname,$udomain); |
my $items=''; |
my $items=''; |
if (! ref($store)) { |
if (! ref($store)) { |
Line 2570 sub inc {
|
Line 3236 sub inc {
|
} |
} |
} |
} |
$items=~s/\&$//; |
$items=~s/\&$//; |
return &reply("inc:$udomain:$uname:$namespace:$items",$uhome); |
if ($critical) { |
|
return &critical("inc:$udomain:$uname:$namespace:$items",$uhome); |
|
} else { |
|
return &reply("inc:$udomain:$uname:$namespace:$items",$uhome); |
|
} |
} |
} |
|
|
# --------------------------------------------------------------- put interface |
# --------------------------------------------------------------- put interface |
|
|
sub put { |
sub put { |
my ($namespace,$storehash,$udomain,$uname)=@_; |
my ($namespace,$storehash,$udomain,$uname)=@_; |
if (!$udomain) { $udomain=$ENV{'user.domain'}; } |
if (!$udomain) { $udomain=$env{'user.domain'}; } |
if (!$uname) { $uname=$ENV{'user.name'}; } |
if (!$uname) { $uname=$env{'user.name'}; } |
my $uhome=&homeserver($uname,$udomain); |
my $uhome=&homeserver($uname,$udomain); |
my $items=''; |
my $items=''; |
foreach (keys %$storehash) { |
foreach my $item (keys(%$storehash)) { |
$items.=&escape($_).'='.&freeze_escape($$storehash{$_}).'&'; |
$items.=&escape($item).'='.&freeze_escape($$storehash{$item}).'&'; |
} |
} |
$items=~s/\&$//; |
$items=~s/\&$//; |
return &reply("put:$udomain:$uname:$namespace:$items",$uhome); |
return &reply("put:$udomain:$uname:$namespace:$items",$uhome); |
} |
} |
|
|
# ---------------------------------------------------------- putstore interface |
# ------------------------------------------------------------ newput interface |
|
|
sub putstore { |
sub newput { |
my ($namespace,$storehash,$udomain,$uname)=@_; |
my ($namespace,$storehash,$udomain,$uname)=@_; |
if (!$udomain) { $udomain=$ENV{'user.domain'}; } |
if (!$udomain) { $udomain=$env{'user.domain'}; } |
if (!$uname) { $uname=$ENV{'user.name'}; } |
if (!$uname) { $uname=$env{'user.name'}; } |
my $uhome=&homeserver($uname,$udomain); |
my $uhome=&homeserver($uname,$udomain); |
my $items=''; |
my $items=''; |
my %allitems = (); |
foreach my $key (keys(%$storehash)) { |
foreach (keys %$storehash) { |
$items.=&escape($key).'='.&freeze_escape($$storehash{$key}).'&'; |
if ($_ =~ m/^([^\:]+):([^\:]+):([^\:]+)$/) { |
|
my $key = $1.':keys:'.$2; |
|
$allitems{$key} .= $3.':'; |
|
} |
|
$items.=$_.'='.&freeze_escape($$storehash{$_}).'&'; |
|
} |
} |
foreach (keys %allitems) { |
$items=~s/\&$//; |
$allitems{$_} =~ s/\:$//; |
return &reply("newput:$udomain:$uname:$namespace:$items",$uhome); |
$items.= $_.'='.$allitems{$_}.'&'; |
} |
|
|
|
# --------------------------------------------------------- putstore interface |
|
|
|
sub putstore { |
|
my ($namespace,$symb,$version,$storehash,$udomain,$uname)=@_; |
|
if (!$udomain) { $udomain=$env{'user.domain'}; } |
|
if (!$uname) { $uname=$env{'user.name'}; } |
|
my $uhome=&homeserver($uname,$udomain); |
|
my $items=''; |
|
foreach my $key (keys(%$storehash)) { |
|
$items.= &escape($key).'='.&freeze_escape($storehash->{$key}).'&'; |
} |
} |
$items=~s/\&$//; |
$items=~s/\&$//; |
return &reply("put:$udomain:$uname:$namespace:$items",$uhome); |
my $esc_symb=&escape($symb); |
|
my $esc_v=&escape($version); |
|
my $reply = |
|
&reply("putstore:$udomain:$uname:$namespace:$esc_symb:$esc_v:$items", |
|
$uhome); |
|
if ($reply eq 'unknown_cmd') { |
|
# gfall back to way things use to be done |
|
return &old_putstore($namespace,$symb,$version,$storehash,$udomain, |
|
$uname); |
|
} |
|
return $reply; |
|
} |
|
|
|
sub old_putstore { |
|
my ($namespace,$symb,$version,$storehash,$udomain,$uname)=@_; |
|
if (!$udomain) { $udomain=$env{'user.domain'}; } |
|
if (!$uname) { $uname=$env{'user.name'}; } |
|
my $uhome=&homeserver($uname,$udomain); |
|
my %newstorehash; |
|
foreach my $item (keys(%$storehash)) { |
|
my $key = $version.':'.&escape($symb).':'.$item; |
|
$newstorehash{$key} = $storehash->{$item}; |
|
} |
|
my $items=''; |
|
my %allitems = (); |
|
foreach my $item (keys(%newstorehash)) { |
|
if ($item =~ m/^([^\:]+):([^\:]+):([^\:]+)$/) { |
|
my $key = $1.':keys:'.$2; |
|
$allitems{$key} .= $3.':'; |
|
} |
|
$items.=$item.'='.&freeze_escape($newstorehash{$item}).'&'; |
|
} |
|
foreach my $item (keys(%allitems)) { |
|
$allitems{$item} =~ s/\:$//; |
|
$items.= $item.'='.$allitems{$item}.'&'; |
|
} |
|
$items=~s/\&$//; |
|
return &reply("put:$udomain:$uname:$namespace:$items",$uhome); |
} |
} |
|
|
# ------------------------------------------------------ critical put interface |
# ------------------------------------------------------ critical put interface |
|
|
sub cput { |
sub cput { |
my ($namespace,$storehash,$udomain,$uname)=@_; |
my ($namespace,$storehash,$udomain,$uname)=@_; |
if (!$udomain) { $udomain=$ENV{'user.domain'}; } |
if (!$udomain) { $udomain=$env{'user.domain'}; } |
if (!$uname) { $uname=$ENV{'user.name'}; } |
if (!$uname) { $uname=$env{'user.name'}; } |
my $uhome=&homeserver($uname,$udomain); |
my $uhome=&homeserver($uname,$udomain); |
my $items=''; |
my $items=''; |
foreach (keys %$storehash) { |
foreach my $item (keys(%$storehash)) { |
$items.=escape($_).'='.&freeze_escape($$storehash{$_}).'&'; |
$items.=&escape($item).'='.&freeze_escape($$storehash{$item}).'&'; |
} |
} |
$items=~s/\&$//; |
$items=~s/\&$//; |
return &critical("put:$udomain:$uname:$namespace:$items",$uhome); |
return &critical("put:$udomain:$uname:$namespace:$items",$uhome); |
Line 2632 sub cput {
|
Line 3345 sub cput {
|
sub eget { |
sub eget { |
my ($namespace,$storearr,$udomain,$uname)=@_; |
my ($namespace,$storearr,$udomain,$uname)=@_; |
my $items=''; |
my $items=''; |
foreach (@$storearr) { |
foreach my $item (@$storearr) { |
$items.=escape($_).'&'; |
$items.=&escape($item).'&'; |
} |
} |
$items=~s/\&$//; |
$items=~s/\&$//; |
if (!$udomain) { $udomain=$ENV{'user.domain'}; } |
if (!$udomain) { $udomain=$env{'user.domain'}; } |
if (!$uname) { $uname=$ENV{'user.name'}; } |
if (!$uname) { $uname=$env{'user.name'}; } |
my $uhome=&homeserver($uname,$udomain); |
my $uhome=&homeserver($uname,$udomain); |
my $rep=&reply("eget:$udomain:$uname:$namespace:$items",$uhome); |
my $rep=&reply("eget:$udomain:$uname:$namespace:$items",$uhome); |
my @pairs=split(/\&/,$rep); |
my @pairs=split(/\&/,$rep); |
my %returnhash=(); |
my %returnhash=(); |
my $i=0; |
my $i=0; |
foreach (@$storearr) { |
foreach my $item (@$storearr) { |
$returnhash{$_}=&thaw_unescape($pairs[$i]); |
$returnhash{$item}=&thaw_unescape($pairs[$i]); |
$i++; |
$i++; |
} |
} |
return %returnhash; |
return %returnhash; |
} |
} |
|
|
|
# ------------------------------------------------------------ tmpput interface |
|
sub tmpput { |
|
my ($storehash,$server,$context)=@_; |
|
my $items=''; |
|
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); |
|
} |
|
|
|
# ------------------------------------------------------------ tmpget interface |
|
sub tmpget { |
|
my ($token,$server)=@_; |
|
if (!defined($server)) { $server = $perlvar{'lonHostID'}; } |
|
my $rep=&reply("tmpget:$token",$server); |
|
my %returnhash; |
|
foreach my $item (split(/\&/,$rep)) { |
|
my ($key,$value)=split(/=/,$item); |
|
$returnhash{&unescape($key)}=&thaw_unescape($value); |
|
} |
|
return %returnhash; |
|
} |
|
|
|
# ------------------------------------------------------------ tmpget interface |
|
sub tmpdel { |
|
my ($token,$server)=@_; |
|
if (!defined($server)) { $server = $perlvar{'lonHostID'}; } |
|
return &reply("tmpdel:$token",$server); |
|
} |
|
|
|
# -------------------------------------------------- portfolio access checking |
|
|
|
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_/) { |
|
return 'A'; |
|
} |
|
return ''; |
|
} |
|
|
|
sub get_portfolio_access { |
|
my ($udom,$unum,$file_name,$group,$access_hash) = @_; |
|
|
|
if (!ref($access_hash)) { |
|
my $current_perms = &get_portfile_permissions($udom,$unum); |
|
my %access_controls = &get_access_controls($current_perms,$group, |
|
$file_name); |
|
$access_hash = $access_controls{$file_name}; |
|
} |
|
|
|
my ($public,$guest,@domains,@users,@courses,@groups); |
|
my $now = time; |
|
if (ref($access_hash) eq 'HASH') { |
|
foreach my $key (keys(%{$access_hash})) { |
|
my ($num,$scope,$end,$start) = ($key =~ /^([^:]+):([a-z]+)_(\d*)_?(\d*)$/); |
|
if ($start > $now) { |
|
next; |
|
} |
|
if ($end && $end<$now) { |
|
next; |
|
} |
|
if ($scope eq 'public') { |
|
$public = $key; |
|
last; |
|
} elsif ($scope eq 'guest') { |
|
$guest = $key; |
|
} elsif ($scope eq 'domains') { |
|
push(@domains,$key); |
|
} elsif ($scope eq 'users') { |
|
push(@users,$key); |
|
} elsif ($scope eq 'course') { |
|
push(@courses,$key); |
|
} elsif ($scope eq 'group') { |
|
push(@groups,$key); |
|
} |
|
} |
|
if ($public) { |
|
return 'ok'; |
|
} |
|
if ($env{'user.name'} eq 'public' && $env{'user.domain'} eq 'public') { |
|
if ($guest) { |
|
return $guest; |
|
} |
|
} else { |
|
if (@domains > 0) { |
|
foreach my $domkey (@domains) { |
|
if (ref($access_hash->{$domkey}{'dom'}) eq 'ARRAY') { |
|
if (grep(/^\Q$env{'user.domain'}\E$/,@{$access_hash->{$domkey}{'dom'}})) { |
|
return 'ok'; |
|
} |
|
} |
|
} |
|
} |
|
if (@users > 0) { |
|
foreach my $userkey (@users) { |
|
if (exists($access_hash->{$userkey}{'users'}{$env{'user.name'}.':'.$env{'user.domain'}})) { |
|
return 'ok'; |
|
} |
|
} |
|
} |
|
my %roleshash; |
|
my @courses_and_groups = @courses; |
|
push(@courses_and_groups,@groups); |
|
if (@courses_and_groups > 0) { |
|
my (%allgroups,%allroles); |
|
my ($start,$end,$role,$sec,$group); |
|
foreach my $envkey (%env) { |
|
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; |
|
$allgroups{$cid}{$group} = $env{$envkey}; |
|
} else { |
|
if ($4 eq '') { |
|
$sec = 'none'; |
|
} else { |
|
$sec = $4; |
|
} |
|
$allroles{$cid}{$1}{$sec} = $env{$envkey}; |
|
} |
|
} elsif ($envkey =~ m-^user\.role\./cr/($match_domain/$match_username/\w*)./($match_domain)/($match_courseid)/?([^/]*)$-) { |
|
my $cid = $2.'_'.$3; |
|
if ($4 eq '') { |
|
$sec = 'none'; |
|
} else { |
|
$sec = $4; |
|
} |
|
$allroles{$cid}{$1}{$sec} = $env{$envkey}; |
|
} |
|
} |
|
if (keys(%allroles) == 0) { |
|
return; |
|
} |
|
foreach my $key (@courses_and_groups) { |
|
my %content = %{$$access_hash{$key}}; |
|
my $cnum = $content{'number'}; |
|
my $cdom = $content{'domain'}; |
|
my $cid = $cdom.'_'.$cnum; |
|
if (!exists($allroles{$cid})) { |
|
next; |
|
} |
|
foreach my $role_id (keys(%{$content{'roles'}})) { |
|
my @sections = @{$content{'roles'}{$role_id}{'section'}}; |
|
my @groups = @{$content{'roles'}{$role_id}{'group'}}; |
|
my @status = @{$content{'roles'}{$role_id}{'access'}}; |
|
my @roles = @{$content{'roles'}{$role_id}{'role'}}; |
|
foreach my $role (keys(%{$allroles{$cid}})) { |
|
if ((grep/^all$/,@roles) || (grep/^\Q$role\E$/,@roles)) { |
|
foreach my $sec (keys(%{$allroles{$cid}{$role}})) { |
|
if (&course_group_datechecker($allroles{$cid}{$role}{$sec},$now,\@status) eq 'ok') { |
|
if (grep/^all$/,@sections) { |
|
return 'ok'; |
|
} else { |
|
if (grep/^$sec$/,@sections) { |
|
return 'ok'; |
|
} |
|
} |
|
} |
|
} |
|
if (keys(%{$allgroups{$cid}}) == 0) { |
|
if (grep/^none$/,@groups) { |
|
return 'ok'; |
|
} |
|
} else { |
|
if (grep/^all$/,@groups) { |
|
return 'ok'; |
|
} |
|
foreach my $group (keys(%{$allgroups{$cid}})) { |
|
if (grep/^$group$/,@groups) { |
|
return 'ok'; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if ($guest) { |
|
return $guest; |
|
} |
|
} |
|
} |
|
return; |
|
} |
|
|
|
sub course_group_datechecker { |
|
my ($dates,$now,$status) = @_; |
|
my ($start,$end) = split(/\./,$dates); |
|
if (!$start && !$end) { |
|
return 'ok'; |
|
} |
|
if (grep/^active$/,@{$status}) { |
|
if (((!$start) || ($start && $start <= $now)) && ((!$end) || ($end && $end >= $now))) { |
|
return 'ok'; |
|
} |
|
} |
|
if (grep/^previous$/,@{$status}) { |
|
if ($end > $now ) { |
|
return 'ok'; |
|
} |
|
} |
|
if (grep/^future$/,@{$status}) { |
|
if ($start > $now) { |
|
return 'ok'; |
|
} |
|
} |
|
return; |
|
} |
|
|
|
sub parse_portfolio_url { |
|
my ($url) = @_; |
|
|
|
my ($type,$udom,$unum,$group,$file_name); |
|
|
|
if ($url =~ m-^/*(?:uploaded|editupload)/($match_domain)/($match_username)/portfolio(/.+)$-) { |
|
$type = 1; |
|
$udom = $1; |
|
$unum = $2; |
|
$file_name = $3; |
|
} elsif ($url =~ m-^/*(?:uploaded|editupload)/($match_domain)/($match_courseid)/groups/([^/]+)/portfolio/(.+)$-) { |
|
$type = 2; |
|
$udom = $1; |
|
$unum = $2; |
|
$group = $3; |
|
$file_name = $3.'/'.$4; |
|
} |
|
if (wantarray) { |
|
return ($type,$udom,$unum,$file_name,$group); |
|
} |
|
return $type; |
|
} |
|
|
|
sub is_portfolio_url { |
|
my ($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 |
# ---------------------------------------------- Custom access rule evaluation |
|
|
sub customaccess { |
sub customaccess { |
my ($priv,$uri)=@_; |
my ($priv,$uri)=@_; |
my ($urole,$urealm)=split(/\./,$ENV{'request.role'}); |
my ($urole,$urealm)=split(/\./,$env{'request.role'},2); |
$urealm=~s/^\W//; |
my (undef,$udom,$ucrs,$usec)=split(/\//,$urealm); |
my ($udom,$ucrs,$usec)=split(/\//,$urealm); |
$udom = &LONCAPA::clean_domain($udom); |
|
$ucrs = &LONCAPA::clean_username($ucrs); |
my $access=0; |
my $access=0; |
foreach (split(/\s*\,\s*/,&metadata($uri,'rule_rights'))) { |
foreach my $right (split(/\s*\,\s*/,&metadata($uri,'rule_rights'))) { |
my ($effect,$realm,$role)=split(/\:/,$_); |
my ($effect,$realm,$role)=split(/\:/,$right); |
if ($role) { |
if ($role) { |
if ($role ne $urole) { next; } |
if ($role ne $urole) { next; } |
} |
} |
foreach (split(/\s*\,\s*/,$realm)) { |
foreach my $scope (split(/\s*\,\s*/,$realm)) { |
my ($tdom,$tcrs,$tsec)=split(/\_/,$_); |
my ($tdom,$tcrs,$tsec)=split(/\_/,$scope); |
if ($tdom) { |
if ($tdom) { |
if ($tdom ne $udom) { next; } |
if ($tdom ne $udom) { next; } |
} |
} |
Line 2687 sub customaccess {
|
Line 3672 sub customaccess {
|
# ------------------------------------------------- Check for a user privilege |
# ------------------------------------------------- Check for a user privilege |
|
|
sub allowed { |
sub allowed { |
my ($priv,$uri,$symb)=@_; |
my ($priv,$uri,$symb,$role)=@_; |
|
my $ver_orguri=$uri; |
$uri=&deversion($uri); |
$uri=&deversion($uri); |
my $orguri=$uri; |
my $orguri=$uri; |
$uri=&declutter($uri); |
$uri=&declutter($uri); |
|
|
|
if ($priv eq 'evb') { |
|
# Evade communication block restrictions for specified role in a course |
if (defined($ENV{'allowed.'.$priv})) { return $ENV{'allowed.'.$priv}; } |
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 |
# Free bre access to adm and meta resources |
if (((($uri=~/^adm\//) && ($uri !~ m|/bulletinboard$|)) |
if (((($uri=~/^adm\//) && ($uri !~ m{/(?:smppg|bulletinboard)$})) |
|| ($uri=~/\.meta$/)) && ($priv eq 'bre')) { |
|| (($uri=~/\.meta$/) && ($uri!~m|^uploaded/|) )) |
|
&& ($priv eq 'bre')) { |
return 'F'; |
return 'F'; |
} |
} |
|
|
# Free bre access to user's own portfolio contents |
# Free bre access to user's own portfolio contents |
my ($space,$domain,$name,$dir)=split('/',$uri); |
my ($space,$domain,$name,@dir)=split('/',$uri); |
if (('uploaded' eq $space) && ($ENV{'user.name'} eq $name) && |
if (($space=~/^(uploaded|editupload)$/) && ($env{'user.name'} eq $name) && |
($ENV{'user.domain'} eq $domain) && ('portfolio' eq $dir)) { |
($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. |
|
if (($space=~/^(uploaded|editupload)$/) && ($dir[0] eq 'groups') |
|
&& ($dir[2] eq 'portfolio') && ($priv eq 'bre')) { |
|
if (exists($env{'request.course.id'})) { |
|
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
if (($domain eq $cdom) && ($name eq $cnum)) { |
|
my $courseprivid=$env{'request.course.id'}; |
|
$courseprivid=~s/\_/\//; |
|
if ($env{'user.priv.'.$env{'request.role'}.'./'.$courseprivid |
|
.'/'.$dir[1]} =~/rgf\&([^\:]*)/) { |
|
return $1; |
|
} else { |
|
if ($env{'request.course.sec'}) { |
|
$courseprivid.='/'.$env{'request.course.sec'}; |
|
} |
|
if ($env{'user.priv.'.$env{'request.role'}.'./'. |
|
$courseprivid} =~/(mdg|vcg)\&([^\:]*)/) { |
|
return $2; |
|
} |
|
} |
|
} |
|
} |
} |
} |
|
|
# Free bre to public access |
# Free bre to public access |
|
|
if ($priv eq 'bre') { |
if ($priv eq 'bre') { |
my $copyright=&metadata($uri,'copyright'); |
my $copyright=&metadata($uri,'copyright'); |
if (($copyright eq 'public') && (!$ENV{'request.course.id'})) { |
if (($copyright eq 'public') && (!$env{'request.course.id'})) { |
return 'F'; |
return 'F'; |
} |
} |
if ($copyright eq 'priv') { |
if ($copyright eq 'priv') { |
$uri=~/([^\/]+)\/([^\/]+)\//; |
$uri=~/([^\/]+)\/([^\/]+)\//; |
unless (($ENV{'user.name'} eq $2) && ($ENV{'user.domain'} eq $1)) { |
unless (($env{'user.name'} eq $2) && ($env{'user.domain'} eq $1)) { |
return ''; |
return ''; |
} |
} |
} |
} |
if ($copyright eq 'domain') { |
if ($copyright eq 'domain') { |
$uri=~/([^\/]+)\/([^\/]+)\//; |
$uri=~/([^\/]+)\/([^\/]+)\//; |
unless (($ENV{'user.domain'} eq $1) || |
unless (($env{'user.domain'} eq $1) || |
($ENV{'course.'.$ENV{'request.course.id'}.'.domain'} eq $1)) { |
($env{'course.'.$env{'request.course.id'}.'.domain'} eq $1)) { |
return ''; |
return ''; |
} |
} |
} |
} |
if ($ENV{'request.role'}=~ /li\.\//) { |
if ($env{'request.role'}=~ /li\.\//) { |
# Library role, so allow browsing of resources in this domain. |
# Library role, so allow browsing of resources in this domain. |
return 'F'; |
return 'F'; |
} |
} |
Line 2737 sub allowed {
|
Line 3763 sub allowed {
|
} |
} |
} |
} |
# Domain coordinator is trying to create a course |
# Domain coordinator is trying to create a course |
if (($priv eq 'ccc') && ($ENV{'request.role'} =~ /^dc\./)) { |
if (($priv eq 'ccc') && ($env{'request.role'} =~ /^dc\./)) { |
# uri is the requested domain in this case. |
# uri is the requested domain in this case. |
# comparison to 'request.role.domain' shows if the user has selected |
# comparison to 'request.role.domain' shows if the user has selected |
# a role of dc for the domain in question. |
# a role of dc for the domain in question. |
return 'F' if ($uri eq $ENV{'request.role.domain'}); |
return 'F' if ($uri eq $env{'request.role.domain'}); |
} |
} |
|
|
my $thisallowed=''; |
my $thisallowed=''; |
Line 2750 sub allowed {
|
Line 3776 sub allowed {
|
|
|
# Course |
# Course |
|
|
if ($ENV{'user.priv.'.$ENV{'request.role'}.'./'}=~/\Q$priv\E\&([^\:]*)/) { |
if ($env{'user.priv.'.$env{'request.role'}.'./'}=~/\Q$priv\E\&([^\:]*)/) { |
$thisallowed.=$1; |
$thisallowed.=$1; |
} |
} |
|
|
# Domain |
# Domain |
|
|
if ($ENV{'user.priv.'.$ENV{'request.role'}.'./'.(split(/\//,$uri))[0].'/'} |
if ($env{'user.priv.'.$env{'request.role'}.'./'.(split(/\//,$uri))[0].'/'} |
=~/\Q$priv\E\&([^\:]*)/) { |
=~/\Q$priv\E\&([^\:]*)/) { |
$thisallowed.=$1; |
$thisallowed.=$1; |
} |
} |
Line 2766 sub allowed {
|
Line 3792 sub allowed {
|
$courseuri=~s/\_(\d)/\/$1/; |
$courseuri=~s/\_(\d)/\/$1/; |
$courseuri=~s/^([^\/])/\/$1/; |
$courseuri=~s/^([^\/])/\/$1/; |
|
|
if ($ENV{'user.priv.'.$ENV{'request.role'}.'.'.$courseuri} |
if ($env{'user.priv.'.$env{'request.role'}.'.'.$courseuri} |
=~/\Q$priv\E\&([^\:]*)/) { |
=~/\Q$priv\E\&([^\:]*)/) { |
$thisallowed.=$1; |
$thisallowed.=$1; |
} |
} |
|
|
# URI is an uploaded document for this course |
# URI is an uploaded document for this course, default permissions don't matter |
|
# not allowing 'edit' access (editupload) to uploaded course docs |
if (($priv eq 'bre') && ($uri=~m|^uploaded/|)) { |
if (($priv eq 'bre') && ($uri=~m|^uploaded/|)) { |
my $refuri=$ENV{'httpref.'.$orguri}; |
$thisallowed=''; |
if ($refuri) { |
my ($match)=&is_on_map($uri); |
if ($refuri =~ m|^/adm/|) { |
if ($match) { |
$thisallowed='F'; |
if ($env{'user.priv.'.$env{'request.role'}.'./'} |
} |
=~/\Q$priv\E\&([^\:]*)/) { |
} |
$thisallowed.=$1; |
|
} |
|
} else { |
|
my $refuri = $env{'httpref.'.$orguri} || $env{'httpref.'.$ver_orguri}; |
|
if ($refuri) { |
|
if ($refuri =~ m|^/adm/|) { |
|
$thisallowed='F'; |
|
} else { |
|
$refuri=&declutter($refuri); |
|
my ($match) = &is_on_map($refuri); |
|
if ($match) { |
|
$thisallowed='F'; |
|
} |
|
} |
|
} |
|
} |
} |
} |
|
|
|
if ($priv eq 'bre' |
|
&& $thisallowed ne 'F' |
|
&& $thisallowed ne '2' |
|
&& &is_portfolio_url($uri)) { |
|
$thisallowed = &portfolio_access($uri); |
|
} |
|
|
# Full access at system, domain or course-wide level? Exit. |
# Full access at system, domain or course-wide level? Exit. |
|
|
if ($thisallowed=~/F/) { |
if ($thisallowed=~/F/) { |
Line 2790 sub allowed {
|
Line 3838 sub allowed {
|
|
|
# If this is generating or modifying users, exit with special codes |
# If this is generating or modifying users, exit with special codes |
|
|
if (':csu:cdc:ccc:cin:cta:cep:ccr:cst:cad:cli:cau:cdg:cca:'=~/\:\Q$priv\E\:/) { |
if (':csu:cdc:ccc:cin:cta:cep:ccr:cst:cad:cli:cau:cdg:cca:caa:'=~/\:\Q$priv\E\:/) { |
|
if (($priv eq 'cca') || ($priv eq 'caa')) { |
|
my ($audom,$auname)=split('/',$uri); |
|
# no author name given, so this just checks on the general right to make a co-author in this domain |
|
unless ($auname) { return $thisallowed; } |
|
# an author name is given, so we are about to actually make a co-author for a certain account |
|
if (($auname ne $env{'user.name'} && $env{'request.role'} !~ /^dc\./) || |
|
(($audom ne $env{'user.domain'} && $env{'request.role'} !~ /^dc\./) && |
|
($audom ne $env{'request.role.domain'}))) { return ''; } |
|
} |
return $thisallowed; |
return $thisallowed; |
} |
} |
# |
# |
Line 2799 sub allowed {
|
Line 3856 sub allowed {
|
# Course: See if uri or referer is an individual resource that is part of |
# Course: See if uri or referer is an individual resource that is part of |
# the course |
# the course |
|
|
if ($ENV{'request.course.id'}) { |
if ($env{'request.course.id'}) { |
|
|
$courseprivid=$ENV{'request.course.id'}; |
$courseprivid=$env{'request.course.id'}; |
if ($ENV{'request.course.sec'}) { |
if ($env{'request.course.sec'}) { |
$courseprivid.='/'.$ENV{'request.course.sec'}; |
$courseprivid.='/'.$env{'request.course.sec'}; |
} |
} |
$courseprivid=~s/\_/\//; |
$courseprivid=~s/\_/\//; |
my $checkreferer=1; |
my $checkreferer=1; |
my ($match,$cond)=&is_on_map($uri); |
my ($match,$cond)=&is_on_map($uri); |
if ($match) { |
if ($match) { |
$statecond=$cond; |
$statecond=$cond; |
if ($ENV{'user.priv.'.$ENV{'request.role'}.'./'.$courseprivid} |
if ($env{'user.priv.'.$env{'request.role'}.'./'.$courseprivid} |
=~/\Q$priv\E\&([^\:]*)/) { |
=~/\Q$priv\E\&([^\:]*)/) { |
$thisallowed.=$1; |
$thisallowed.=$1; |
$checkreferer=0; |
$checkreferer=0; |
Line 2818 sub allowed {
|
Line 3875 sub allowed {
|
} |
} |
|
|
if ($checkreferer) { |
if ($checkreferer) { |
my $refuri=$ENV{'httpref.'.$orguri}; |
my $refuri=$env{'httpref.'.$orguri}; |
unless ($refuri) { |
unless ($refuri) { |
foreach (keys %ENV) { |
foreach my $key (keys(%env)) { |
if ($_=~/^httpref\..*\*/) { |
if ($key=~/^httpref\..*\*/) { |
my $pattern=$_; |
my $pattern=$key; |
$pattern=~s/^httpref\.\/res\///; |
$pattern=~s/^httpref\.\/res\///; |
$pattern=~s/\*/\[\^\/\]\+/g; |
$pattern=~s/\*/\[\^\/\]\+/g; |
$pattern=~s/\//\\\//g; |
$pattern=~s/\//\\\//g; |
if ($orguri=~/$pattern/) { |
if ($orguri=~/$pattern/) { |
$refuri=$ENV{$_}; |
$refuri=$env{$key}; |
} |
} |
} |
} |
} |
} |
Line 2838 sub allowed {
|
Line 3895 sub allowed {
|
my ($match,$cond)=&is_on_map($refuri); |
my ($match,$cond)=&is_on_map($refuri); |
if ($match) { |
if ($match) { |
my $refstatecond=$cond; |
my $refstatecond=$cond; |
if ($ENV{'user.priv.'.$ENV{'request.role'}.'./'.$courseprivid} |
if ($env{'user.priv.'.$env{'request.role'}.'./'.$courseprivid} |
=~/\Q$priv\E\&([^\:]*)/) { |
=~/\Q$priv\E\&([^\:]*)/) { |
$thisallowed.=$1; |
$thisallowed.=$1; |
$uri=$refuri; |
$uri=$refuri; |
Line 2878 sub allowed {
|
Line 3935 sub allowed {
|
|
|
my $envkey; |
my $envkey; |
if ($thisallowed=~/L/) { |
if ($thisallowed=~/L/) { |
foreach $envkey (keys %ENV) { |
foreach $envkey (keys %env) { |
if ($envkey=~/^user\.role\.(st|ta)\.([^\.]*)/) { |
if ($envkey=~/^user\.role\.(st|ta)\.([^\.]*)/) { |
my $courseid=$2; |
my $courseid=$2; |
my $roleid=$1.'.'.$2; |
my $roleid=$1.'.'.$2; |
$courseid=~s/^\///; |
$courseid=~s/^\///; |
my $expiretime=600; |
my $expiretime=600; |
if ($ENV{'request.role'} eq $roleid) { |
if ($env{'request.role'} eq $roleid) { |
$expiretime=120; |
$expiretime=120; |
} |
} |
my ($cdom,$cnum,$csec)=split(/\//,$courseid); |
my ($cdom,$cnum,$csec)=split(/\//,$courseid); |
my $prefix='course.'.$cdom.'_'.$cnum.'.'; |
my $prefix='course.'.$cdom.'_'.$cnum.'.'; |
if ((time-$ENV{$prefix.'last_cache'})>$expiretime) { |
if ((time-$env{$prefix.'last_cache'})>$expiretime) { |
&coursedescription($courseid); |
&coursedescription($courseid,{'freshen_cache' => 1}); |
} |
} |
if (($ENV{$prefix.'res.'.$uri.'.lock.sections'}=~/\,\Q$csec\E\,/) |
if (($env{$prefix.'res.'.$uri.'.lock.sections'}=~/\,\Q$csec\E\,/) |
|| ($ENV{$prefix.'res.'.$uri.'.lock.sections'} eq 'all')) { |
|| ($env{$prefix.'res.'.$uri.'.lock.sections'} eq 'all')) { |
if ($ENV{$prefix.'res.'.$uri.'.lock.expire'}>time) { |
if ($env{$prefix.'res.'.$uri.'.lock.expire'}>time) { |
&log($ENV{'user.domain'},$ENV{'user.name'}, |
&log($env{'user.domain'},$env{'user.name'}, |
$ENV{'user.home'}, |
$env{'user.home'}, |
'Locked by res: '.$priv.' for '.$uri.' due to '. |
'Locked by res: '.$priv.' for '.$uri.' due to '. |
$cdom.'/'.$cnum.'/'.$csec.' expire '. |
$cdom.'/'.$cnum.'/'.$csec.' expire '. |
$ENV{$prefix.'priv.'.$priv.'.lock.expire'}); |
$env{$prefix.'priv.'.$priv.'.lock.expire'}); |
return ''; |
return ''; |
} |
} |
} |
} |
if (($ENV{$prefix.'priv.'.$priv.'.lock.sections'}=~/\,\Q$csec\E\,/) |
if (($env{$prefix.'priv.'.$priv.'.lock.sections'}=~/\,\Q$csec\E\,/) |
|| ($ENV{$prefix.'priv.'.$priv.'.lock.sections'} eq 'all')) { |
|| ($env{$prefix.'priv.'.$priv.'.lock.sections'} eq 'all')) { |
if ($ENV{'priv.'.$priv.'.lock.expire'}>time) { |
if ($env{'priv.'.$priv.'.lock.expire'}>time) { |
&log($ENV{'user.domain'},$ENV{'user.name'}, |
&log($env{'user.domain'},$env{'user.name'}, |
$ENV{'user.home'}, |
$env{'user.home'}, |
'Locked by priv: '.$priv.' for '.$uri.' due to '. |
'Locked by priv: '.$priv.' for '.$uri.' due to '. |
$cdom.'/'.$cnum.'/'.$csec.' expire '. |
$cdom.'/'.$cnum.'/'.$csec.' expire '. |
$ENV{$prefix.'priv.'.$priv.'.lock.expire'}); |
$env{$prefix.'priv.'.$priv.'.lock.expire'}); |
return ''; |
return ''; |
} |
} |
} |
} |
Line 2922 sub allowed {
|
Line 3979 sub allowed {
|
# Rest of the restrictions depend on selected course |
# Rest of the restrictions depend on selected course |
# |
# |
|
|
unless ($ENV{'request.course.id'}) { |
unless ($env{'request.course.id'}) { |
return '1'; |
if ($thisallowed eq 'A') { |
|
return 'A'; |
|
} elsif ($thisallowed eq 'B') { |
|
return 'B'; |
|
} else { |
|
return '1'; |
|
} |
} |
} |
|
|
# |
# |
Line 2934 sub allowed {
|
Line 3997 sub allowed {
|
# Course preferences |
# Course preferences |
|
|
if ($thisallowed=~/C/) { |
if ($thisallowed=~/C/) { |
my $rolecode=(split(/\./,$ENV{'request.role'}))[0]; |
my $rolecode=(split(/\./,$env{'request.role'}))[0]; |
my $unamedom=$ENV{'user.name'}.':'.$ENV{'user.domain'}; |
my $unamedom=$env{'user.name'}.':'.$env{'user.domain'}; |
if ($ENV{'course.'.$ENV{'request.course.id'}.'.'.$priv.'.roles.denied'} |
if ($env{'course.'.$env{'request.course.id'}.'.'.$priv.'.roles.denied'} |
=~/\Q$rolecode\E/) { |
=~/\Q$rolecode\E/) { |
&log($ENV{'user.domain'},$ENV{'user.name'},$ENV{'user.host'}, |
if ($priv ne 'pch') { |
'Denied by role: '.$priv.' for '.$uri.' as '.$rolecode.' in '. |
&logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}.':'. |
$ENV{'request.course.id'}); |
'Denied by role: '.$priv.' for '.$uri.' as '.$rolecode.' in '. |
|
$env{'request.course.id'}); |
|
} |
return ''; |
return ''; |
} |
} |
|
|
if ($ENV{'course.'.$ENV{'request.course.id'}.'.'.$priv.'.users.denied'} |
if ($env{'course.'.$env{'request.course.id'}.'.'.$priv.'.users.denied'} |
=~/\Q$unamedom\E/) { |
=~/\Q$unamedom\E/) { |
&log($ENV{'user.domain'},$ENV{'user.name'},$ENV{'user.host'}, |
if ($priv ne 'pch') { |
'Denied by user: '.$priv.' for '.$uri.' as '.$unamedom.' in '. |
&logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}. |
$ENV{'request.course.id'}); |
'Denied by user: '.$priv.' for '.$uri.' as '.$unamedom.' in '. |
|
$env{'request.course.id'}); |
|
} |
return ''; |
return ''; |
} |
} |
} |
} |
Line 2956 sub allowed {
|
Line 4023 sub allowed {
|
# Resource preferences |
# Resource preferences |
|
|
if ($thisallowed=~/R/) { |
if ($thisallowed=~/R/) { |
my $rolecode=(split(/\./,$ENV{'request.role'}))[0]; |
my $rolecode=(split(/\./,$env{'request.role'}))[0]; |
if (&metadata($uri,'roledeny')=~/\Q$rolecode\E/) { |
if (&metadata($uri,'roledeny')=~/\Q$rolecode\E/) { |
&log($ENV{'user.domain'},$ENV{'user.name'},$ENV{'user.host'}, |
if ($priv ne 'pch') { |
'Denied by role: '.$priv.' for '.$uri.' as '.$rolecode); |
&logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}.':'. |
return ''; |
'Denied by role: '.$priv.' for '.$uri.' as '.$rolecode); |
|
} |
|
return ''; |
} |
} |
} |
} |
|
|
# Restricted by state or randomout? |
# Restricted by state or randomout? |
|
|
if ($thisallowed=~/X/) { |
if ($thisallowed=~/X/) { |
if ($ENV{'acc.randomout'}) { |
if ($env{'acc.randomout'}) { |
if (!$symb) { $symb=&symbread($uri,1); } |
if (!$symb) { $symb=&symbread($uri,1); } |
if (($symb) && ($ENV{'acc.randomout'}=~/\&\Q$symb\E\&/)) { |
if (($symb) && ($env{'acc.randomout'}=~/\&\Q$symb\E\&/)) { |
return ''; |
return ''; |
} |
} |
} |
} |
Line 2980 sub allowed {
|
Line 4049 sub allowed {
|
} |
} |
} |
} |
|
|
|
if ($thisallowed eq 'A') { |
|
return 'A'; |
|
} elsif ($thisallowed eq 'B') { |
|
return 'B'; |
|
} |
return 'F'; |
return 'F'; |
} |
} |
|
|
|
sub split_uri_for_cond { |
|
my $uri=&deversion(&declutter(shift)); |
|
my @uriparts=split(/\//,$uri); |
|
my $filename=pop(@uriparts); |
|
my $pathname=join('/',@uriparts); |
|
return ($pathname,$filename); |
|
} |
# --------------------------------------------------- Is a resource on the map? |
# --------------------------------------------------- Is a resource on the map? |
|
|
sub is_on_map { |
sub is_on_map { |
my $uri=&declutter(shift); |
my ($pathname,$filename) = &split_uri_for_cond(shift); |
$uri=~s/\.\d+\.(\w+)$/\.$1/; |
|
my @uriparts=split(/\//,$uri); |
|
my $filename=$uriparts[$#uriparts]; |
|
my $pathname=$uri; |
|
$pathname=~s|/\Q$filename\E$||; |
|
$pathname=~s/^adm\/wrapper\///; |
|
#Trying to find the conditional for the file |
#Trying to find the conditional for the file |
my $match=($ENV{'acc.res.'.$ENV{'request.course.id'}.'.'.$pathname}=~ |
my $match=($env{'acc.res.'.$env{'request.course.id'}.'.'.$pathname}=~ |
/\&\Q$filename\E\:([\d\|]+)\&/); |
/\&\Q$filename\E\:([\d\|]+)\&/); |
if ($match) { |
if ($match) { |
return (1,$1); |
return (1,$1); |
Line 3013 sub get_symb_from_alias {
|
Line 4088 sub get_symb_from_alias {
|
# Must be an alias |
# Must be an alias |
my $aliassymb=''; |
my $aliassymb=''; |
my %bighash; |
my %bighash; |
if (tie(%bighash,'GDBM_File',$ENV{'request.course.fn'}.'.db', |
if (tie(%bighash,'GDBM_File',$env{'request.course.fn'}.'.db', |
&GDBM_READER(),0640)) { |
&GDBM_READER(),0640)) { |
my $rid=$bighash{'mapalias_'.$symb}; |
my $rid=$bighash{'mapalias_'.$symb}; |
if ($rid) { |
if ($rid) { |
Line 3031 sub get_symb_from_alias {
|
Line 4106 sub get_symb_from_alias {
|
sub definerole { |
sub definerole { |
if (allowed('mcr','/')) { |
if (allowed('mcr','/')) { |
my ($rolename,$sysrole,$domrole,$courole)=@_; |
my ($rolename,$sysrole,$domrole,$courole)=@_; |
foreach (split(':',$sysrole)) { |
foreach my $role (split(':',$sysrole)) { |
my ($crole,$cqual)=split(/\&/,$_); |
my ($crole,$cqual)=split(/\&/,$role); |
if ($pr{'cr:s'}!~/\Q$crole\E/) { return "refused:s:$crole"; } |
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\&/) { |
if ($pr{'cr:s'}!~/\Q$crole\E\&\w*\Q$cqual\E/) { |
if ($pr{'cr:s'}!~/\Q$crole\E\&\w*\Q$cqual\E/) { |
Line 3040 sub definerole {
|
Line 4115 sub definerole {
|
} |
} |
} |
} |
} |
} |
foreach (split(':',$domrole)) { |
foreach my $role (split(':',$domrole)) { |
my ($crole,$cqual)=split(/\&/,$_); |
my ($crole,$cqual)=split(/\&/,$role); |
if ($pr{'cr:d'}!~/\Q$crole\E/) { return "refused:d:$crole"; } |
if ($pr{'cr:d'}!~/\Q$crole\E/) { return "refused:d:$crole"; } |
if ($pr{'cr:d'}=~/\Q$crole\E\&/) { |
if ($pr{'cr:d'}=~/\Q$crole\E\&/) { |
if ($pr{'cr:d'}!~/\Q$crole\W\&\w*\Q$cqual\E/) { |
if ($pr{'cr:d'}!~/\Q$crole\W\&\w*\Q$cqual\E/) { |
Line 3049 sub definerole {
|
Line 4124 sub definerole {
|
} |
} |
} |
} |
} |
} |
foreach (split(':',$courole)) { |
foreach my $role (split(':',$courole)) { |
my ($crole,$cqual)=split(/\&/,$_); |
my ($crole,$cqual)=split(/\&/,$role); |
if ($pr{'cr:c'}!~/\Q$crole\E/) { return "refused:c:$crole"; } |
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\&/) { |
if ($pr{'cr:c'}!~/\Q$crole\E\&\w*\Q$cqual\E/) { |
if ($pr{'cr:c'}!~/\Q$crole\E\&\w*\Q$cqual\E/) { |
Line 3058 sub definerole {
|
Line 4133 sub definerole {
|
} |
} |
} |
} |
} |
} |
my $command="encrypt:rolesput:$ENV{'user.domain'}:$ENV{'user.name'}:". |
my $command="encrypt:rolesput:$env{'user.domain'}:$env{'user.name'}:". |
"$ENV{'user.domain'}:$ENV{'user.name'}:". |
"$env{'user.domain'}:$env{'user.name'}:". |
"rolesdef_$rolename=". |
"rolesdef_$rolename=". |
escape($sysrole.'_'.$domrole.'_'.$courole); |
escape($sysrole.'_'.$domrole.'_'.$courole); |
return reply($command,$ENV{'user.home'}); |
return reply($command,$env{'user.home'}); |
} else { |
} else { |
return 'refused'; |
return 'refused'; |
} |
} |
Line 3097 sub log_query {
|
Line 4172 sub log_query {
|
my $uhome=&homeserver($uname,$udom); |
my $uhome=&homeserver($uname,$udom); |
if ($uhome eq 'no_host') { return 'error: no_host'; } |
if ($uhome eq 'no_host') { return 'error: no_host'; } |
my $uhost=$hostname{$uhome}; |
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, |
my $queryid=&reply("querysend:".$query.':'.$udom.':'.$uname.':'.$command, |
$uhome); |
$uhome); |
unless ($queryid=~/^\Q$uhost\E\_/) { return 'error: '.$queryid; } |
unless ($queryid=~/^\Q$uhost\E\_/) { return 'error: '.$queryid; } |
return get_query_reply($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) |
# ------- Request retrieval of institutional classlists for course(s) |
|
|
sub fetch_enrollment_query { |
sub fetch_enrollment_query { |
Line 3118 sub fetch_enrollment_query {
|
Line 4205 sub fetch_enrollment_query {
|
} |
} |
my $host=$hostname{$homeserver}; |
my $host=$hostname{$homeserver}; |
my $cmd = ''; |
my $cmd = ''; |
foreach (keys %{$affiliatesref}) { |
foreach my $affiliate (keys %{$affiliatesref}) { |
$cmd .= $_.'='.join(",",@{$$affiliatesref{$_}}).'%%'; |
$cmd .= $affiliate.'='.join(",",@{$$affiliatesref{$affiliate}}).'%%'; |
} |
} |
$cmd =~ s/%%$//; |
$cmd =~ s/%%$//; |
$cmd = &escape($cmd); |
$cmd = &escape($cmd); |
my $query = 'fetchenrollment'; |
my $query = 'fetchenrollment'; |
my $queryid=&reply("querysend:".$query.':'.$dom.':'.$ENV{'user.name'}.':'.$cmd,$homeserver); |
my $queryid=&reply("querysend:".$query.':'.$dom.':'.$env{'user.name'}.':'.$cmd,$homeserver); |
unless ($queryid=~/^\Q$host\E\_/) { |
unless ($queryid=~/^\Q$host\E\_/) { |
&logthis('fetch_enrollment_query: invalid queryid: '.$queryid.' for host: '.$host.' and homeserver: '.$homeserver.' context: '.$context.' '.$cnum); |
&logthis('fetch_enrollment_query: invalid queryid: '.$queryid.' for host: '.$host.' and homeserver: '.$homeserver.' context: '.$context.' '.$cnum); |
return 'error: '.$queryid; |
return 'error: '.$queryid; |
Line 3136 sub fetch_enrollment_query {
|
Line 4223 sub fetch_enrollment_query {
|
$tries ++; |
$tries ++; |
} |
} |
if ( ($reply =~/^timeout/) || ($reply =~/^error/) ) { |
if ( ($reply =~/^timeout/) || ($reply =~/^error/) ) { |
&logthis('fetch_enrollment_query error: '.$reply.' for '.$dom.' '.$ENV{'user.name'}.' for '.$queryid.' context: '.$context.' '.$cnum.' maxtries: '.$maxtries.' tries: '.$tries); |
&logthis('fetch_enrollment_query error: '.$reply.' for '.$dom.' '.$env{'user.name'}.' for '.$queryid.' context: '.$context.' '.$cnum.' maxtries: '.$maxtries.' tries: '.$tries); |
} else { |
} else { |
my @responses = split/:/,$reply; |
my @responses = split/:/,$reply; |
if ($homeserver eq $perlvar{'lonHostID'}) { |
if ($homeserver eq $perlvar{'lonHostID'}) { |
foreach (@responses) { |
foreach my $line (@responses) { |
my ($key,$value) = split/=/,$_; |
my ($key,$value) = split(/=/,$line,2); |
$$replyref{$key} = $value; |
$$replyref{$key} = $value; |
} |
} |
} else { |
} else { |
my $pathname = $perlvar{'lonDaemons'}.'/tmp'; |
my $pathname = $perlvar{'lonDaemons'}.'/tmp'; |
foreach (@responses) { |
foreach my $line (@responses) { |
my ($key,$value) = split/=/,$_; |
my ($key,$value) = split(/=/,$line); |
$$replyref{$key} = $value; |
$$replyref{$key} = $value; |
if ($value > 0) { |
if ($value > 0) { |
foreach (@{$$affiliatesref{$key}}) { |
foreach my $item (@{$$affiliatesref{$key}}) { |
my $filename = $dom.'_'.$key.'_'.$_.'_classlist.xml'; |
my $filename = $dom.'_'.$key.'_'.$item.'_classlist.xml'; |
my $destname = $pathname.'/'.$filename; |
my $destname = $pathname.'/'.$filename; |
my $xml_classlist = &reply("autoretrieve:".$filename,$homeserver); |
my $xml_classlist = &reply("autoretrieve:".$filename,$homeserver); |
if ($xml_classlist =~ /^error/) { |
if ($xml_classlist =~ /^error/) { |
Line 3201 sub courselog_query {
|
Line 4288 sub courselog_query {
|
# end: timestamp |
# end: timestamp |
# |
# |
my (%filters)=@_; |
my (%filters)=@_; |
unless ($ENV{'request.course.id'}) { return 'no_course'; } |
unless ($env{'request.course.id'}) { return 'no_course'; } |
if ($filters{'url'}) { |
if ($filters{'url'}) { |
$filters{'url'}=&symbclean(&declutter($filters{'url'})); |
$filters{'url'}=&symbclean(&declutter($filters{'url'})); |
$filters{'url'}=~s/\.(\w+)$/(\\.\\d+)*\\.$1/; |
$filters{'url'}=~s/\.(\w+)$/(\\.\\d+)*\\.$1/; |
$filters{'url'}=~s/\.(\w+)\_\_\_/(\\.\\d+)*\\.$1/; |
$filters{'url'}=~s/\.(\w+)\_\_\_/(\\.\\d+)*\\.$1/; |
} |
} |
my $cname=$ENV{'course.'.$ENV{'request.course.id'}.'.num'}; |
my $cname=$env{'course.'.$env{'request.course.id'}.'.num'}; |
my $cdom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; |
my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'}; |
return &log_query($cname,$cdom,'courselog',%filters); |
return &log_query($cname,$cdom,'courselog',%filters); |
} |
} |
|
|
Line 3225 sub auto_run {
|
Line 4312 sub auto_run {
|
my $response = &reply('autorun:'.$cdom,$homeserver); |
my $response = &reply('autorun:'.$cdom,$homeserver); |
return $response; |
return $response; |
} |
} |
|
|
sub auto_get_sections { |
sub auto_get_sections { |
my ($cnum,$cdom,$inst_coursecode) = @_; |
my ($cnum,$cdom,$inst_coursecode) = @_; |
my $homeserver = &homeserver($cnum,$cdom); |
my $homeserver = &homeserver($cnum,$cdom); |
Line 3236 sub auto_get_sections {
|
Line 4323 sub auto_get_sections {
|
} |
} |
return @secs; |
return @secs; |
} |
} |
|
|
sub auto_new_course { |
sub auto_new_course { |
my ($cnum,$cdom,$inst_course_id,$owner) = @_; |
my ($cnum,$cdom,$inst_course_id,$owner) = @_; |
my $homeserver = &homeserver($cnum,$cdom); |
my $homeserver = &homeserver($cnum,$cdom); |
my $response=&unescape(&reply('autonewcourse:'.$inst_course_id.':'.$owner.':'.$cdom,$homeserver)); |
my $response=&unescape(&reply('autonewcourse:'.$inst_course_id.':'.$owner.':'.$cdom,$homeserver)); |
return $response; |
return $response; |
} |
} |
|
|
sub auto_validate_courseID { |
sub auto_validate_courseID { |
my ($cnum,$cdom,$inst_course_id) = @_; |
my ($cnum,$cdom,$inst_course_id) = @_; |
my $homeserver = &homeserver($cnum,$cdom); |
my $homeserver = &homeserver($cnum,$cdom); |
my $response=&unescape(&reply('autovalidatecourse:'.$inst_course_id.':'.$cdom,$homeserver)); |
my $response=&unescape(&reply('autovalidatecourse:'.$inst_course_id.':'.$cdom,$homeserver)); |
return $response; |
return $response; |
} |
} |
|
|
sub auto_create_password { |
sub auto_create_password { |
my ($cnum,$cdom,$authparam) = @_; |
my ($cnum,$cdom,$authparam) = @_; |
my $homeserver = &homeserver($cnum,$cdom); |
my $homeserver = &homeserver($cnum,$cdom); |
Line 3265 sub auto_create_password {
|
Line 4352 sub auto_create_password {
|
return ($authparam,$create_passwd,$authchk); |
return ($authparam,$create_passwd,$authchk); |
} |
} |
|
|
|
sub auto_photo_permission { |
|
my ($cnum,$cdom,$students) = @_; |
|
my $homeserver = &homeserver($cnum,$cdom); |
|
my ($outcome,$perm_reqd,$conditions) = |
|
split(/:/,&unescape(&reply('autophotopermission:'.$cdom,$homeserver)),3); |
|
if ($outcome =~ /^(con_lost|unknown_cmd|no_such_host)$/) { |
|
return (undef,undef); |
|
} |
|
return ($outcome,$perm_reqd,$conditions); |
|
} |
|
|
|
sub auto_checkphotos { |
|
my ($uname,$udom,$pid) = @_; |
|
my $homeserver = &homeserver($uname,$udom); |
|
my ($result,$resulttype); |
|
my $outcome = &unescape(&reply('autophotocheck:'.&escape($udom).':'. |
|
&escape($uname).':'.&escape($pid), |
|
$homeserver)); |
|
if ($outcome =~ /^(con_lost|unknown_cmd|no_such_host)$/) { |
|
return (undef,undef); |
|
} |
|
if ($outcome) { |
|
($result,$resulttype) = split(/:/,$outcome); |
|
} |
|
return ($result,$resulttype); |
|
} |
|
|
|
sub auto_photochoice { |
|
my ($cnum,$cdom) = @_; |
|
my $homeserver = &homeserver($cnum,$cdom); |
|
my ($update,$comment) = split(/:/,&unescape(&reply('autophotochoice:'. |
|
&escape($cdom), |
|
$homeserver))); |
|
if ($update =~ /^(con_lost|unknown_cmd|no_such_host)$/) { |
|
return (undef,undef); |
|
} |
|
return ($update,$comment); |
|
} |
|
|
|
sub auto_photoupdate { |
|
my ($affiliatesref,$dom,$cnum,$photo) = @_; |
|
my $homeserver = &homeserver($cnum,$dom); |
|
my $host=$hostname{$homeserver}; |
|
my $cmd = ''; |
|
my $maxtries = 1; |
|
foreach my $affiliate (keys(%{$affiliatesref})) { |
|
$cmd .= $affiliate.'='.join(",",@{$$affiliatesref{$affiliate}}).'%%'; |
|
} |
|
$cmd =~ s/%%$//; |
|
$cmd = &escape($cmd); |
|
my $query = 'institutionalphotos'; |
|
my $queryid=&reply("querysend:".$query.':'.$dom.':'.$cnum.':'.$cmd,$homeserver); |
|
unless ($queryid=~/^\Q$host\E\_/) { |
|
&logthis('institutionalphotos: invalid queryid: '.$queryid.' for host: '.$host.' and homeserver: '.$homeserver.' and course: '.$cnum); |
|
return 'error: '.$queryid; |
|
} |
|
my $reply = &get_query_reply($queryid); |
|
my $tries = 1; |
|
while (($reply=~/^timeout/) && ($tries < $maxtries)) { |
|
$reply = &get_query_reply($queryid); |
|
$tries ++; |
|
} |
|
if ( ($reply =~/^timeout/) || ($reply =~/^error/) ) { |
|
&logthis('institutionalphotos error: '.$reply.' for '.$dom.' '.$env{'user.name'}.' for '.$queryid.' course: '.$cnum.' maxtries: '.$maxtries.' tries: '.$tries); |
|
} else { |
|
my @responses = split(/:/,$reply); |
|
my $outcome = shift(@responses); |
|
foreach my $item (@responses) { |
|
my ($key,$value) = split(/=/,$item); |
|
$$photo{$key} = $value; |
|
} |
|
return $outcome; |
|
} |
|
return 'error'; |
|
} |
|
|
sub auto_instcode_format { |
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 $courses = ''; |
my $homeserver; |
my @homeservers; |
if ($caller eq 'global') { |
if ($caller eq 'global') { |
foreach my $tryserver (keys %libserv) { |
foreach my $tryserver (keys(%libserv)) { |
if ($hostdom{$tryserver} eq $codedom) { |
if ($hostdom{$tryserver} eq $codedom) { |
$homeserver = $tryserver; |
if (!grep(/^\Q$tryserver\E$/,@homeservers)) { |
last; |
push(@homeservers,$tryserver); |
|
} |
} |
} |
} |
} |
if (($ENV{'user.name'}) && ($ENV{'user.domain'} eq $codedom)) { |
|
$homeserver = &homeserver($ENV{'user.name'},$codedom); |
|
} |
|
} else { |
} else { |
$homeserver = &homeserver($caller,$codedom); |
push(@homeservers,&homeserver($caller,$codedom)); |
} |
} |
foreach (keys %{$instcodes}) { |
foreach my $code (keys(%{$instcodes})) { |
$courses .= &escape($_).'='.&escape($$instcodes{$_}).'&'; |
$courses .= &escape($code).'='.&escape($$instcodes{$code}).'&'; |
} |
} |
chop($courses); |
chop($courses); |
my $response=&reply('autoinstcodeformat:'.$codedom.':'.$courses,$homeserver); |
my $ok_response = 0; |
unless ($response =~ /(con_lost|error|no_such_host|refused)/) { |
my $response; |
my ($codes_str,$codetitles_str,$cat_titles_str,$cat_order_str) = split/:/,$response; |
while (@homeservers > 0 && $ok_response == 0) { |
%{$codes} = &str2hash($codes_str); |
my $server = shift(@homeservers); |
@{$codetitles} = &str2array($codetitles_str); |
$response=&reply('autoinstcodeformat:'.$codedom.':'.$courses,$server); |
%{$cat_titles} = &str2hash($cat_titles_str); |
if ($response !~ /(con_lost|error|no_such_host|refused)/) { |
%{$cat_order} = &str2hash($cat_order_str); |
my ($codes_str,$codetitles_str,$cat_titles_str,$cat_order_str) = |
|
split/:/,$response; |
|
%{$codes} = (%{$codes},&str2hash($codes_str)); |
|
push(@{$codetitles},&str2array($codetitles_str)); |
|
%{$cat_titles} = (%{$cat_titles},&str2hash($cat_titles_str)); |
|
%{$cat_order} = (%{$cat_order},&str2hash($cat_order_str)); |
|
$ok_response = 1; |
|
} |
|
} |
|
if ($ok_response) { |
return 'ok'; |
return 'ok'; |
|
} else { |
|
return $response; |
} |
} |
|
} |
|
|
|
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.':'. |
|
&escape($owner).':'.$cdom,$homeserver); |
return $response; |
return $response; |
} |
} |
|
|
|
# ------------------------------------------------------- Course Group routines |
|
|
|
sub get_coursegroups { |
|
my ($cdom,$cnum,$group,$namespace) = @_; |
|
return(&dump($namespace,$cdom,$cnum,$group)); |
|
} |
|
|
|
sub modify_coursegroup { |
|
my ($cdom,$cnum,$groupsettings) = @_; |
|
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; |
|
my $role = 'gr/'.&escape($userprivs); |
|
my ($uname,$udom) = split(/:/,$user); |
|
my $result = &assignrole($udom,$uname,$url,$role,$end,$start); |
|
if ($result eq 'ok') { |
|
&devalidate_getgroups_cache($udom,$uname,$cdom,$cnum); |
|
} |
|
return $result; |
|
} |
|
|
|
sub modify_coursegroup_membership { |
|
my ($cdom,$cnum,$membership) = @_; |
|
my $result = &put('groupmembership',$membership,$cdom,$cnum); |
|
return $result; |
|
} |
|
|
|
sub get_active_groups { |
|
my ($udom,$uname,$cdom,$cnum) = @_; |
|
my $now = time; |
|
my %groups = (); |
|
foreach my $key (keys(%env)) { |
|
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; } |
|
if ($1 eq $cdom && $2 eq $cnum) { |
|
$groups{$3} = $env{$key} ; |
|
} |
|
} |
|
} |
|
return %groups; |
|
} |
|
|
|
sub get_group_membership { |
|
my ($cdom,$cnum,$group) = @_; |
|
return(&dump('groupmembership',$cdom,$cnum,$group)); |
|
} |
|
|
|
sub get_users_groups { |
|
my ($udom,$uname,$courseid) = @_; |
|
my @usersgroups; |
|
my $cachetime=1800; |
|
|
|
my $hashid="$udom:$uname:$courseid"; |
|
my ($grouplist,$cached)=&is_cached_new('getgroups',$hashid); |
|
if (defined($cached)) { |
|
@usersgroups = split(/:/,$grouplist); |
|
} else { |
|
$grouplist = ''; |
|
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); |
|
} |
|
} |
|
} |
|
@usersgroups = &sort_course_groups($courseid,@usersgroups); |
|
$grouplist = join(':',@usersgroups); |
|
&do_cache_new('getgroups',$hashid,$grouplist,$cachetime); |
|
} |
|
return @usersgroups; |
|
} |
|
|
|
sub devalidate_getgroups_cache { |
|
my ($udom,$uname,$cdom,$cnum)=@_; |
|
my $courseid = $cdom.'_'.$cnum; |
|
|
|
my $hashid="$udom:$uname:$courseid"; |
|
&devalidate_cache_new('getgroups',$hashid); |
|
} |
|
|
# ------------------------------------------------------------------ Plain Text |
# ------------------------------------------------------------------ Plain Text |
|
|
sub plaintext { |
sub plaintext { |
my $short=shift; |
my ($short,$type,$cid) = @_; |
return &mt($prp{$short}); |
if ($short =~ /^cr/) { |
|
return (split('/',$short))[-1]; |
|
} |
|
if (!defined($cid)) { |
|
$cid = $env{'request.course.id'}; |
|
} |
|
if (defined($cid) && defined($env{'course.'.$cid.'.'.$short.'.plaintext'})) { |
|
return &Apache::lonlocal::mt($env{'course.'.$cid.'.'.$short. |
|
'.plaintext'}); |
|
} |
|
my %rolenames = ( |
|
Course => 'std', |
|
Group => 'alt1', |
|
); |
|
if (defined($type) && |
|
defined($rolenames{$type}) && |
|
defined($prp{$short}{$rolenames{$type}})) { |
|
return &Apache::lonlocal::mt($prp{$short}{$rolenames{$type}}); |
|
} else { |
|
return &Apache::lonlocal::mt($prp{$short}{'std'}); |
|
} |
} |
} |
|
|
# ----------------------------------------------------------------- Assign Role |
# ----------------------------------------------------------------- Assign Role |
Line 3312 sub assignrole {
|
Line 4680 sub assignrole {
|
my $mrole; |
my $mrole; |
if ($role =~ /^cr\//) { |
if ($role =~ /^cr\//) { |
my $cwosec=$url; |
my $cwosec=$url; |
$cwosec=~s/^\/(\w+)\/(\w+)\/.*/$1\/$2/; |
$cwosec=~s/^\/($match_domain)\/($match_courseid)\/.*/$1\/$2/; |
unless (&allowed('ccr',$cwosec)) { |
unless (&allowed('ccr',$cwosec)) { |
&logthis('Refused custom assignrole: '. |
&logthis('Refused custom assignrole: '. |
$udom.' '.$uname.' '.$url.' '.$role.' '.$end.' '.$start.' by '. |
$udom.' '.$uname.' '.$url.' '.$role.' '.$end.' '.$start.' by '. |
$ENV{'user.name'}.' at '.$ENV{'user.domain'}); |
$env{'user.name'}.' at '.$env{'user.domain'}); |
return 'refused'; |
return 'refused'; |
} |
} |
$mrole='cr'; |
$mrole='cr'; |
|
} elsif ($role =~ /^gr\//) { |
|
my $cwogrp=$url; |
|
$cwogrp=~s{^/($match_domain)/($match_courseid)/.*}{$1/$2}; |
|
unless (&allowed('mdg',$cwogrp)) { |
|
&logthis('Refused group assignrole: '. |
|
$udom.' '.$uname.' '.$url.' '.$role.' '.$end.' '.$start.' by '. |
|
$env{'user.name'}.' at '.$env{'user.domain'}); |
|
return 'refused'; |
|
} |
|
$mrole='gr'; |
} else { |
} else { |
my $cwosec=$url; |
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)) { |
unless ((&allowed('c'.$role,$cwosec)) || &allowed('c'.$role,$udom)) { |
&logthis('Refused assignrole: '. |
&logthis('Refused assignrole: '. |
$udom.' '.$uname.' '.$url.' '.$role.' '.$end.' '.$start.' by '. |
$udom.' '.$uname.' '.$url.' '.$role.' '.$end.' '.$start.' by '. |
$ENV{'user.name'}.' at '.$ENV{'user.domain'}); |
$env{'user.name'}.' at '.$env{'user.domain'}); |
return 'refused'; |
return 'refused'; |
} |
} |
$mrole=$role; |
$mrole=$role; |
} |
} |
my $command="encrypt:rolesput:$ENV{'user.domain'}:$ENV{'user.name'}:". |
my $command="encrypt:rolesput:$env{'user.domain'}:$env{'user.name'}:". |
"$udom:$uname:$url".'_'."$mrole=$role"; |
"$udom:$uname:$url".'_'."$mrole=$role"; |
if ($end) { $command.='_'.$end; } |
if ($end) { $command.='_'.$end; } |
if ($start) { |
if ($start) { |
Line 3341 sub assignrole {
|
Line 4719 sub assignrole {
|
$command.='_0_'.$start; |
$command.='_0_'.$start; |
} |
} |
} |
} |
|
my $origstart = $start; |
|
my $origend = $end; |
# actually delete |
# actually delete |
if ($deleteflag) { |
if ($deleteflag) { |
if ((&allowed('dro',$udom)) || (&allowed('dro',$url))) { |
if ((&allowed('dro',$udom)) || (&allowed('dro',$url))) { |
# modify command to delete the role |
# modify command to delete the role |
$command="encrypt:rolesdel:$ENV{'user.domain'}:$ENV{'user.name'}:". |
$command="encrypt:rolesdel:$env{'user.domain'}:$env{'user.name'}:". |
"$udom:$uname:$url".'_'."$mrole"; |
"$udom:$uname:$url".'_'."$mrole"; |
&logthis("$ENV{'user.name'} at $ENV{'user.domain'} deletes $mrole in $url for $uname at $udom"); |
&logthis("$env{'user.name'} at $env{'user.domain'} deletes $mrole in $url for $uname at $udom"); |
# set start and finish to negative values for userrolelog |
# set start and finish to negative values for userrolelog |
$start=-1; |
$start=-1; |
$end=-1; |
$end=-1; |
Line 3357 sub assignrole {
|
Line 4737 sub assignrole {
|
my $answer=&reply($command,&homeserver($uname,$udom)); |
my $answer=&reply($command,&homeserver($uname,$udom)); |
# log new user role if status is ok |
# log new user role if status is ok |
if ($answer eq 'ok') { |
if ($answer eq 'ok') { |
&userrolelog($mrole,$uname,$udom,$url,$start,$end); |
&userrolelog($role,$uname,$udom,$url,$start,$end); |
|
# for course roles, perform group memberships changes triggered by role change. |
|
unless ($role =~ /^gr/) { |
|
&Apache::longroup::group_changes($udom,$uname,$url,$role,$origend, |
|
$origstart); |
|
} |
} |
} |
return $answer; |
return $answer; |
} |
} |
Line 3370 sub modifyuserauth {
|
Line 4755 sub modifyuserauth {
|
my $uhome=&homeserver($uname,$udom); |
my $uhome=&homeserver($uname,$udom); |
unless (&allowed('mau',$udom)) { return 'refused'; } |
unless (&allowed('mau',$udom)) { return 'refused'; } |
&logthis('Call to modify user authentication '.$udom.', '.$uname.', '. |
&logthis('Call to modify user authentication '.$udom.', '.$uname.', '. |
$umode.' by '.$ENV{'user.name'}.' at '.$ENV{'user.domain'}. |
$umode.' by '.$env{'user.name'}.' at '.$env{'user.domain'}. |
' in domain '.$ENV{'request.role.domain'}); |
' in domain '.$env{'request.role.domain'}); |
my $reply=&reply('encrypt:changeuserauth:'.$udom.':'.$uname.':'.$umode.':'. |
my $reply=&reply('encrypt:changeuserauth:'.$udom.':'.$uname.':'.$umode.':'. |
&escape($upass),$uhome); |
&escape($upass),$uhome); |
&log($ENV{'user.domain'},$ENV{'user.name'},$ENV{'user.home'}, |
&log($env{'user.domain'},$env{'user.name'},$env{'user.home'}, |
'Authentication changed for '.$udom.', '.$uname.', '.$umode. |
'Authentication changed for '.$udom.', '.$uname.', '.$umode. |
'(Remote '.$ENV{'REMOTE_ADDR'}.'): '.$reply); |
'(Remote '.$ENV{'REMOTE_ADDR'}.'): '.$reply); |
&log($udom,,$uname,$uhome, |
&log($udom,,$uname,$uhome, |
'Authentication changed by '.$ENV{'user.domain'}.', '. |
'Authentication changed by '.$env{'user.domain'}.', '. |
$ENV{'user.name'}.', '.$umode. |
$env{'user.name'}.', '.$umode. |
'(Remote '.$ENV{'REMOTE_ADDR'}.'): '.$reply); |
'(Remote '.$ENV{'REMOTE_ADDR'}.'): '.$reply); |
unless ($reply eq 'ok') { |
unless ($reply eq 'ok') { |
&logthis('Authentication mode error: '.$reply); |
&logthis('Authentication mode error: '.$reply); |
Line 3395 sub modifyuser {
|
Line 4780 sub modifyuser {
|
$umode, $upass, $first, |
$umode, $upass, $first, |
$middle, $last, $gene, |
$middle, $last, $gene, |
$forceid, $desiredhome, $email)=@_; |
$forceid, $desiredhome, $email)=@_; |
$udom=~s/\W//g; |
$udom= &LONCAPA::clean_domain($udom); |
$uname=~s/\W//g; |
$uname=&LONCAPA::clean_username($uname); |
&logthis('Call to modify user '.$udom.', '.$uname.', '.$uid.', '. |
&logthis('Call to modify user '.$udom.', '.$uname.', '.$uid.', '. |
$umode.', '.$first.', '.$middle.', '. |
$umode.', '.$first.', '.$middle.', '. |
$last.', '.$gene.'(forceid: '.$forceid.')'. |
$last.', '.$gene.'(forceid: '.$forceid.')'. |
(defined($desiredhome) ? ' desiredhome = '.$desiredhome : |
(defined($desiredhome) ? ' desiredhome = '.$desiredhome : |
' desiredhome not specified'). |
' desiredhome not specified'). |
' by '.$ENV{'user.name'}.' at '.$ENV{'user.domain'}. |
' by '.$env{'user.name'}.' at '.$env{'user.domain'}. |
' in domain '.$ENV{'request.role.domain'}); |
' in domain '.$env{'request.role.domain'}); |
my $uhome=&homeserver($uname,$udom,'true'); |
my $uhome=&homeserver($uname,$udom,'true'); |
# ----------------------------------------------------------------- Create User |
# ----------------------------------------------------------------- Create User |
if (($uhome eq 'no_host') && |
if (($uhome eq 'no_host') && |
Line 3411 sub modifyuser {
|
Line 4796 sub modifyuser {
|
my $unhome=''; |
my $unhome=''; |
if (defined($desiredhome) && $hostdom{$desiredhome} eq $udom) { |
if (defined($desiredhome) && $hostdom{$desiredhome} eq $udom) { |
$unhome = $desiredhome; |
$unhome = $desiredhome; |
} elsif($ENV{'course.'.$ENV{'request.course.id'}.'.domain'} eq $udom) { |
} elsif($env{'course.'.$env{'request.course.id'}.'.domain'} eq $udom) { |
$unhome=$ENV{'course.'.$ENV{'request.course.id'}.'.home'}; |
$unhome=$env{'course.'.$env{'request.course.id'}.'.home'}; |
} else { # load balancing routine for determining $unhome |
} else { # load balancing routine for determining $unhome |
my $tryserver; |
my $tryserver; |
my $loadm=10000000; |
my $loadm=10000000; |
Line 3480 sub modifyuser {
|
Line 4865 sub modifyuser {
|
} |
} |
my $reply = &put('environment', \%names, $udom,$uname); |
my $reply = &put('environment', \%names, $udom,$uname); |
if ($reply ne 'ok') { return 'error: '.$reply; } |
if ($reply ne 'ok') { return 'error: '.$reply; } |
|
&devalidate_cache_new('namescache',$uname.':'.$udom); |
&logthis('Success modifying user '.$udom.', '.$uname.', '.$uid.', '. |
&logthis('Success modifying user '.$udom.', '.$uname.', '.$uid.', '. |
$umode.', '.$first.', '.$middle.', '. |
$umode.', '.$first.', '.$middle.', '. |
$last.', '.$gene.' by '. |
$last.', '.$gene.' by '. |
$ENV{'user.name'}.' at '.$ENV{'user.domain'}); |
$env{'user.name'}.' at '.$env{'user.domain'}); |
return 'ok'; |
return 'ok'; |
} |
} |
|
|
Line 3493 sub modifystudent {
|
Line 4879 sub modifystudent {
|
my ($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene,$usec, |
my ($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene,$usec, |
$end,$start,$forceid,$desiredhome,$email,$type,$locktype,$cid)=@_; |
$end,$start,$forceid,$desiredhome,$email,$type,$locktype,$cid)=@_; |
if (!$cid) { |
if (!$cid) { |
unless ($cid=$ENV{'request.course.id'}) { |
unless ($cid=$env{'request.course.id'}) { |
return 'not_in_class'; |
return 'not_in_class'; |
} |
} |
} |
} |
Line 3514 sub modify_student_enrollment {
|
Line 4900 sub modify_student_enrollment {
|
my ($udom,$uname,$uid,$first,$middle,$last,$gene,$usec,$end,$start,$type,$locktype,$cid) = @_; |
my ($udom,$uname,$uid,$first,$middle,$last,$gene,$usec,$end,$start,$type,$locktype,$cid) = @_; |
my ($cdom,$cnum,$chome); |
my ($cdom,$cnum,$chome); |
if (!$cid) { |
if (!$cid) { |
unless ($cid=$ENV{'request.course.id'}) { |
unless ($cid=$env{'request.course.id'}) { |
return 'not_in_class'; |
return 'not_in_class'; |
} |
} |
$cdom=$ENV{'course.'.$cid.'.domain'}; |
$cdom=$env{'course.'.$cid.'.domain'}; |
$cnum=$ENV{'course.'.$cid.'.num'}; |
$cnum=$env{'course.'.$cid.'.num'}; |
} else { |
} else { |
($cdom,$cnum)=split(/_/,$cid); |
($cdom,$cnum)=split(/_/,$cid); |
} |
} |
$chome=$ENV{'course.'.$cid.'.home'}; |
$chome=$env{'course.'.$cid.'.home'}; |
if (!$chome) { |
if (!$chome) { |
$chome=&homeserver($cnum,$cdom); |
$chome=&homeserver($cnum,$cdom); |
} |
} |
Line 3544 sub modify_student_enrollment {
|
Line 4930 sub modify_student_enrollment {
|
['firstname','middlename','lastname', 'generation','id'] |
['firstname','middlename','lastname', 'generation','id'] |
,$udom,$uname); |
,$udom,$uname); |
|
|
#foreach (keys(%tmp)) { |
#foreach my $key (keys(%tmp)) { |
# &logthis("key $_ = ".$tmp{$_}); |
# &logthis("key $key = ".$tmp{$key}); |
#} |
#} |
$first = $tmp{'firstname'} if (!defined($first) || $first eq ''); |
$first = $tmp{'firstname'} if (!defined($first) || $first eq ''); |
$middle = $tmp{'middlename'} if (!defined($middle) || $middle eq ''); |
$middle = $tmp{'middlename'} if (!defined($middle) || $middle eq ''); |
Line 3560 sub modify_student_enrollment {
|
Line 4946 sub modify_student_enrollment {
|
$cdom,$cnum); |
$cdom,$cnum); |
unless (($reply eq 'ok') || ($reply eq 'delayed')) { |
unless (($reply eq 'ok') || ($reply eq 'delayed')) { |
return 'error: '.$reply; |
return 'error: '.$reply; |
|
} else { |
|
&devalidate_getsection_cache($udom,$uname,$cid); |
} |
} |
# Add student role to user |
# Add student role to user |
my $uurl='/'.$cid; |
my $uurl='/'.$cid; |
Line 3601 sub writecoursepref {
|
Line 4989 sub writecoursepref {
|
return 'error: no such course'; |
return 'error: no such course'; |
} |
} |
my $cstring=''; |
my $cstring=''; |
foreach (keys %prefs) { |
foreach my $pref (keys(%prefs)) { |
$cstring.=escape($_).'='.escape($prefs{$_}).'&'; |
$cstring.=&escape($pref).'='.&escape($prefs{$pref}).'&'; |
} |
} |
$cstring=~s/\&$//; |
$cstring=~s/\&$//; |
return reply('put:'.$cdomain.':'.$cnum.':environment:'.$cstring,$chome); |
return reply('put:'.$cdomain.':'.$cnum.':environment:'.$cstring,$chome); |
Line 3611 sub writecoursepref {
|
Line 4999 sub writecoursepref {
|
# ---------------------------------------------------------- Make/modify course |
# ---------------------------------------------------------- Make/modify course |
|
|
sub createcourse { |
sub createcourse { |
my ($udom,$description,$url,$course_server,$nonstandard,$inst_code,$course_owner)=@_; |
my ($udom,$description,$url,$course_server,$nonstandard,$inst_code, |
|
$course_owner,$crstype)=@_; |
$url=&declutter($url); |
$url=&declutter($url); |
my $cid=''; |
my $cid=''; |
unless (&allowed('ccc',$udom)) { |
unless (&allowed('ccc',$udom)) { |
return 'refused'; |
return 'refused'; |
} |
} |
# ------------------------------------------------------------------- Create ID |
# ------------------------------------------------------------------- Create ID |
my $uname=substr($$.time,0,5).unpack("H8",pack("I32",time)). |
my $uname=int(1+rand(9)). |
|
('a'..'z','A'..'Z','0'..'9')[int(rand(62))]. |
|
substr($$.time,0,5).unpack("H8",pack("I32",time)). |
unpack("H2",pack("I32",int(rand(255)))).$perlvar{'lonHostID'}; |
unpack("H2",pack("I32",int(rand(255)))).$perlvar{'lonHostID'}; |
# ----------------------------------------------- Make sure that does not exist |
# ----------------------------------------------- Make sure that does not exist |
my $uhome=&homeserver($uname,$udom,'true'); |
my $uhome=&homeserver($uname,$udom,'true'); |
Line 3631 sub createcourse {
|
Line 5022 sub createcourse {
|
} |
} |
} |
} |
# ------------------------------------------------ Check supplied server name |
# ------------------------------------------------ Check supplied server name |
$course_server = $ENV{'user.homeserver'} if (! defined($course_server)); |
$course_server = $env{'user.homeserver'} if (! defined($course_server)); |
if (! exists($libserv{$course_server})) { |
if (! exists($libserv{$course_server})) { |
return 'error:bad server name '.$course_server; |
return 'error:bad server name '.$course_server; |
} |
} |
Line 3646 sub createcourse {
|
Line 5037 sub createcourse {
|
# ----------------------------------------------------------------- Course made |
# ----------------------------------------------------------------- Course made |
# log existence |
# log existence |
&courseidput($udom,&escape($udom.'_'.$uname).'='.&escape($description). |
&courseidput($udom,&escape($udom.'_'.$uname).'='.&escape($description). |
':'.&escape($inst_code).':'.&escape($course_owner),$uhome); |
':'.&escape($inst_code).':'.&escape($course_owner).':'. |
|
&escape($crstype),$uhome); |
&flushcourselogs(); |
&flushcourselogs(); |
# set toplevel url |
# set toplevel url |
my $topurl=$url; |
my $topurl=$url; |
Line 3654 sub createcourse {
|
Line 5046 sub createcourse {
|
# ------------------------------------------ For standard courses, make top url |
# ------------------------------------------ For standard courses, make top url |
my $mapurl=&clutter($url); |
my $mapurl=&clutter($url); |
if ($mapurl eq '/res/') { $mapurl=''; } |
if ($mapurl eq '/res/') { $mapurl=''; } |
$ENV{'form.initmap'}=(<<ENDINITMAP); |
$env{'form.initmap'}=(<<ENDINITMAP); |
<map> |
<map> |
<resource id="1" type="start"></resource> |
<resource id="1" type="start"></resource> |
<resource id="2" src="$mapurl"></resource> |
<resource id="2" src="$mapurl"></resource> |
Line 3664 sub createcourse {
|
Line 5056 sub createcourse {
|
</map> |
</map> |
ENDINITMAP |
ENDINITMAP |
$topurl=&declutter( |
$topurl=&declutter( |
&finishuserfileupload($uname,$udom,$uhome,'initmap','default.sequence') |
&finishuserfileupload($uname,$udom,'initmap','default.sequence') |
); |
); |
} |
} |
# ----------------------------------------------------------- Write preferences |
# ----------------------------------------------------------- Write preferences |
Line 3674 ENDINITMAP
|
Line 5066 ENDINITMAP
|
return '/'.$udom.'/'.$uname; |
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 |
# ---------------------------------------------------------- Assign Custom Role |
|
|
sub assigncustomrole { |
sub assigncustomrole { |
Line 3712 sub is_locked {
|
Line 5114 sub is_locked {
|
my @check; |
my @check; |
my $is_locked; |
my $is_locked; |
push @check, $file_name; |
push @check, $file_name; |
my %locked = &Apache::lonnet::get('file_permissions',\@check, |
my %locked = &get('file_permissions',\@check, |
$ENV{'user.domain'},$ENV{'user.name'}); |
$env{'user.domain'},$env{'user.name'}); |
|
my ($tmp)=keys(%locked); |
|
if ($tmp=~/^error:/) { undef(%locked); } |
|
|
if (ref($locked{$file_name}) eq 'ARRAY') { |
if (ref($locked{$file_name}) eq 'ARRAY') { |
$is_locked = 'true'; |
$is_locked = 'false'; |
|
foreach my $entry (@{$locked{$file_name}}) { |
|
if (ref($entry) eq 'ARRAY') { |
|
$is_locked = 'true'; |
|
last; |
|
} |
|
} |
} else { |
} else { |
$is_locked = 'false'; |
$is_locked = 'false'; |
} |
} |
} |
} |
|
|
|
sub declutter_portfile { |
|
my ($file) = @_; |
|
$file =~ s{^(/portfolio/|portfolio/)}{/}; |
|
return $file; |
|
} |
|
|
# ------------------------------------------------------------- Mark as Read Only |
# ------------------------------------------------------------- Mark as Read Only |
|
|
sub mark_as_readonly { |
sub mark_as_readonly { |
my ($domain,$user,$files,$what) = @_; |
my ($domain,$user,$files,$what) = @_; |
my %current_permissions = &Apache::lonnet::dump('file_permissions',$domain,$user); |
my %current_permissions = &dump('file_permissions',$domain,$user); |
|
my ($tmp)=keys(%current_permissions); |
|
if ($tmp=~/^error:/) { undef(%current_permissions); } |
foreach my $file (@{$files}) { |
foreach my $file (@{$files}) { |
|
$file = &declutter_portfile($file); |
push(@{$current_permissions{$file}},$what); |
push(@{$current_permissions{$file}},$what); |
} |
} |
&Apache::lonnet::put('file_permissions',\%current_permissions,$domain,$user); |
&put('file_permissions',\%current_permissions,$domain,$user); |
return; |
return; |
} |
} |
|
|
Line 3741 sub save_selected_files {
|
Line 5161 sub save_selected_files {
|
my @other_files = &files_not_in_path($user, $path); |
my @other_files = &files_not_in_path($user, $path); |
open (OUT, '>'.$Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/'.$filename); |
open (OUT, '>'.$Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/'.$filename); |
foreach my $file (@files) { |
foreach my $file (@files) { |
print (OUT $ENV{'form.currentpath'}.$file."\n"); |
print (OUT $env{'form.currentpath'}.$file."\n"); |
} |
} |
foreach my $file (@other_files) { |
foreach my $file (@other_files) { |
print (OUT $file."\n"); |
print (OUT $file."\n"); |
Line 3785 sub files_not_in_path {
|
Line 5205 sub files_not_in_path {
|
my $filename = $user."savedfiles"; |
my $filename = $user."savedfiles"; |
my @return_files; |
my @return_files; |
my $path_part; |
my $path_part; |
open (IN, '<'.$Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/'.$filename); |
open(IN, '<'.$Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/'.$filename); |
while (<IN>) { |
while (my $line = <IN>) { |
#ok, I know it's clunky, but I want it to work |
#ok, I know it's clunky, but I want it to work |
my @paths_and_file = split m!/!, $_; |
my @paths_and_file = split(m|/|, $line); |
my $file_part = pop (@paths_and_file); |
my $file_part = pop(@paths_and_file); |
chomp ($file_part); |
chomp($file_part); |
my $path_part = join ('/', @paths_and_file); |
my $path_part = join('/', @paths_and_file); |
$path_part .= '/'; |
$path_part .= '/'; |
my $path_and_file = $path_part.$file_part; |
my $path_and_file = $path_part.$file_part; |
if ($path_part ne $path) { |
if ($path_part ne $path) { |
push (@return_files, ($path_and_file)); |
push(@return_files, ($path_and_file)); |
} |
} |
} |
} |
close (OUT); |
close(OUT); |
return (@return_files); |
return (@return_files); |
} |
} |
|
|
#--------------------------------------------------------------Get Marked as Read Only |
#----------------------------------------------Get portfolio file permissions |
|
|
|
sub get_portfile_permissions { |
|
my ($domain,$user) = @_; |
|
my %current_permissions = &dump('file_permissions',$domain,$user); |
|
my ($tmp)=keys(%current_permissions); |
|
if ($tmp=~/^error:/) { undef(%current_permissions); } |
|
return \%current_permissions; |
|
} |
|
|
|
#---------------------------------------------Get portfolio file access controls |
|
|
|
sub get_access_controls { |
|
my ($current_permissions,$group,$file) = @_; |
|
my %access; |
|
my $real_file = $file; |
|
$file =~ s/\.meta$//; |
|
if (defined($file)) { |
|
if (ref($$current_permissions{$file."\0".'accesscontrol'}) eq 'HASH') { |
|
foreach my $control (keys(%{$$current_permissions{$file."\0".'accesscontrol'}})) { |
|
$access{$real_file}{$control} = $$current_permissions{$file."\0".$control}; |
|
} |
|
} |
|
} else { |
|
foreach my $key (keys(%{$current_permissions})) { |
|
if ($key =~ /\0accesscontrol$/) { |
|
if (defined($group)) { |
|
if ($key !~ m-^\Q$group\E/-) { |
|
next; |
|
} |
|
} |
|
my ($fullpath) = split(/\0/,$key); |
|
if (ref($$current_permissions{$key}) eq 'HASH') { |
|
foreach my $control (keys(%{$$current_permissions{$key}})) { |
|
$access{$fullpath}{$control}=$$current_permissions{$fullpath."\0".$control}; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
return %access; |
|
} |
|
|
|
sub modify_access_controls { |
|
my ($file_name,$changes,$domain,$user)=@_; |
|
my ($outcome,$deloutcome); |
|
my %store_permissions; |
|
my %new_values; |
|
my %new_control; |
|
my %translation; |
|
my @deletions = (); |
|
my $now = time; |
|
if (exists($$changes{'activate'})) { |
|
if (ref($$changes{'activate'}) eq 'HASH') { |
|
my @newitems = sort(keys(%{$$changes{'activate'}})); |
|
my $numnew = scalar(@newitems); |
|
for (my $i=0; $i<$numnew; $i++) { |
|
my $newkey = $newitems[$i]; |
|
my $newid = &Apache::loncommon::get_cgi_id(); |
|
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; |
|
} |
|
} |
|
} |
|
my %todelete; |
|
my %changed_items; |
|
foreach my $action ('delete','update') { |
|
if (exists($$changes{$action})) { |
|
if (ref($$changes{$action}) eq 'HASH') { |
|
foreach my $key (keys(%{$$changes{$action}})) { |
|
my ($itemnum) = ($key =~ /^([^:]+):/); |
|
if ($action eq 'delete') { |
|
$todelete{$itemnum} = 1; |
|
} else { |
|
$changed_items{$itemnum} = $key; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
# get lock on access controls for file. |
|
my $lockhash = { |
|
$file_name."\0".'locked_access_records' => $env{'user.name'}. |
|
':'.$env{'user.domain'}, |
|
}; |
|
my $tries = 0; |
|
my $gotlock = &newput('file_permissions',$lockhash,$domain,$user); |
|
|
|
while (($gotlock ne 'ok') && $tries <3) { |
|
$tries ++; |
|
sleep 1; |
|
$gotlock = &newput('file_permissions',$lockhash,$domain,$user); |
|
} |
|
if ($gotlock eq 'ok') { |
|
my %curr_permissions = &dump('file_permissions',$domain,$user,$file_name); |
|
my ($tmp)=keys(%curr_permissions); |
|
if ($tmp=~/^error:/) { undef(%curr_permissions); } |
|
if (exists($curr_permissions{$file_name."\0".'accesscontrol'})) { |
|
my $curr_controls = $curr_permissions{$file_name."\0".'accesscontrol'}; |
|
if (ref($curr_controls) eq 'HASH') { |
|
foreach my $control_item (keys(%{$curr_controls})) { |
|
my ($itemnum) = ($control_item =~ /^([^:]+):/); |
|
if (defined($todelete{$itemnum})) { |
|
push(@deletions,$file_name."\0".$control_item); |
|
} else { |
|
if (defined($changed_items{$itemnum})) { |
|
$new_control{$changed_items{$itemnum}} = $now; |
|
push(@deletions,$file_name."\0".$control_item); |
|
$new_values{$file_name."\0".$changed_items{$itemnum}} = $$changes{'update'}{$changed_items{$itemnum}}; |
|
} else { |
|
$new_control{$control_item} = $$curr_controls{$control_item}; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
$deloutcome = &del('file_permissions',\@deletions,$domain,$user); |
|
$new_values{$file_name."\0".'accesscontrol'} = \%new_control; |
|
$outcome = &put('file_permissions',\%new_values,$domain,$user); |
|
# 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 { |
sub get_marked_as_readonly { |
my ($domain,$user,$what) = @_; |
my ($domain,$user,$what,$group) = @_; |
my %current_permissions = &Apache::lonnet::dump('file_permissions',$domain,$user); |
my $current_permissions = &get_portfile_permissions($domain,$user); |
my @readonly_files; |
my @readonly_files; |
while (my ($file_name,$value) = each(%current_permissions)) { |
my $cmp1=$what; |
|
if (ref($what)) { $cmp1=join('',@{$what}) }; |
|
while (my ($file_name,$value) = each(%{$current_permissions})) { |
|
if (defined($group)) { |
|
if ($file_name !~ m-^\Q$group\E/-) { |
|
next; |
|
} |
|
} |
if (ref($value) eq "ARRAY"){ |
if (ref($value) eq "ARRAY"){ |
foreach my $stored_what (@{$value}) { |
foreach my $stored_what (@{$value}) { |
if ($stored_what eq $what) { |
my $cmp2=$stored_what; |
|
if (ref($stored_what) eq 'ARRAY') { |
|
$cmp2=join('',@{$stored_what}); |
|
} |
|
if ($cmp1 eq $cmp2) { |
push(@readonly_files, $file_name); |
push(@readonly_files, $file_name); |
|
last; |
} elsif (!defined($what)) { |
} elsif (!defined($what)) { |
push(@readonly_files, $file_name); |
push(@readonly_files, $file_name); |
|
last; |
} |
} |
} |
} |
} |
} |
} |
} |
return @readonly_files; |
return @readonly_files; |
} |
} |
#-----------------------------------------------------------Get Marked as Read Only Hash |
#-----------------------------------------------------------Get Marked as Read Only Hash |
|
|
sub get_marked_as_readonly_hash { |
sub get_marked_as_readonly_hash { |
my ($domain,$user,$what) = @_; |
my ($current_permissions,$group,$what) = @_; |
my %current_permissions = &Apache::lonnet::dump('file_permissions',$domain,$user); |
|
my %readonly_files; |
my %readonly_files; |
while (my ($file_name,$value) = each(%current_permissions)) { |
while (my ($file_name,$value) = each(%{$current_permissions})) { |
|
if (defined($group)) { |
|
if ($file_name !~ m-^\Q$group\E/-) { |
|
next; |
|
} |
|
} |
if (ref($value) eq "ARRAY"){ |
if (ref($value) eq "ARRAY"){ |
foreach my $stored_what (@{$value}) { |
foreach my $stored_what (@{$value}) { |
if ($stored_what eq $what) { |
if (ref($stored_what) eq 'ARRAY') { |
$readonly_files{$file_name} = 'locked'; |
foreach my $lock_descriptor(@{$stored_what}) { |
} elsif (!defined($what)) { |
if ($lock_descriptor eq 'graded') { |
$readonly_files{$file_name} = 'locked'; |
$readonly_files{$file_name} = 'graded'; |
} |
} elsif ($lock_descriptor eq 'handback') { |
|
$readonly_files{$file_name} = 'handback'; |
|
} else { |
|
if (!exists($readonly_files{$file_name})) { |
|
$readonly_files{$file_name} = 'locked'; |
|
} |
|
} |
|
} |
|
} |
} |
} |
} |
} |
} |
} |
Line 3843 sub get_marked_as_readonly_hash {
|
Line 5480 sub get_marked_as_readonly_hash {
|
# ------------------------------------------------------------ Unmark as Read Only |
# ------------------------------------------------------------ Unmark as Read Only |
|
|
sub unmark_as_readonly { |
sub unmark_as_readonly { |
# unmarks all files locked by $what |
# unmarks $file_name (if $file_name is defined), or all files locked by $what |
# for portfolio submissions, $what contains $crsid and $symb |
# for portfolio submissions, $what contains [$symb,$crsid] |
my ($domain,$user,$what) = @_; |
my ($domain,$user,$what,$file_name,$group) = @_; |
my %current_permissions = &Apache::lonnet::dump('file_permissions',$domain,$user); |
$file_name = &declutter_portfile($file_name); |
my @readonly_files = &Apache::lonnet::get_marked_as_readonly($domain,$user,$what); |
my $symb_crs = $what; |
foreach my $file(@readonly_files){ |
if (ref($what)) { $symb_crs=join('',@$what); } |
my $current_locks = $current_permissions{$file}; |
my %current_permissions = &dump('file_permissions',$domain,$user,$group); |
|
my ($tmp)=keys(%current_permissions); |
|
if ($tmp=~/^error:/) { undef(%current_permissions); } |
|
my @readonly_files = &get_marked_as_readonly($domain,$user,$what,$group); |
|
foreach my $file (@readonly_files) { |
|
my $clean_file = &declutter_portfile($file); |
|
if (defined($file_name) && ($file_name ne $clean_file)) { next; } |
|
my $current_locks = $current_permissions{$file}; |
my @new_locks; |
my @new_locks; |
my @del_keys; |
my @del_keys; |
if (ref($current_locks) eq "ARRAY"){ |
if (ref($current_locks) eq "ARRAY"){ |
foreach my $locker (@{$current_locks}) { |
foreach my $locker (@{$current_locks}) { |
unless ($locker eq $what) { |
my $compare=$locker; |
push(@new_locks, $what); |
if (ref($locker) eq 'ARRAY') { |
|
$compare=join('',@{$locker}); |
|
if ($compare ne $symb_crs) { |
|
push(@new_locks, $locker); |
|
} |
} |
} |
} |
} |
if (@new_locks > 0) { |
if (scalar(@new_locks) > 0) { |
$current_permissions{$file} = \@new_locks; |
$current_permissions{$file} = \@new_locks; |
} else { |
} else { |
push(@del_keys, $file); |
push(@del_keys, $file); |
&Apache::lonnet::del('file_permissions',\@del_keys, $domain, $user); |
&del('file_permissions',\@del_keys, $domain, $user); |
delete $current_permissions{$file}; |
delete($current_permissions{$file}); |
} |
} |
} |
} |
} |
} |
&Apache::lonnet::put('file_permissions',\%current_permissions,$domain,$user); |
&put('file_permissions',\%current_permissions,$domain,$user); |
return; |
return; |
} |
} |
|
|
Line 3895 sub dirlist {
|
Line 5543 sub dirlist {
|
|
|
if($udom) { |
if($udom) { |
if($uname) { |
if($uname) { |
my $listing=reply('ls:'.$dirRoot.'/'.$uri, |
my $listing = &reply('ls2:'.$dirRoot.'/'.$uri, |
homeserver($uname,$udom)); |
&homeserver($uname,$udom)); |
return split(/:/,$listing); |
my @listing_results; |
|
if ($listing eq 'unknown_cmd') { |
|
$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)) { |
} elsif(!defined($alternateDirectoryRoot)) { |
my $tryserver; |
my %allusers; |
my %allusers=(); |
foreach my $tryserver (keys(%libserv)) { |
foreach $tryserver (keys %libserv) { |
|
if($hostdom{$tryserver} eq $udom) { |
if($hostdom{$tryserver} eq $udom) { |
my $listing=reply('ls:'.$perlvar{'lonDocRoot'}.'/res/'. |
my $listing = &reply('ls2:'.$perlvar{'lonDocRoot'}.'/res/'. |
$udom, $tryserver); |
$udom, $tryserver); |
if (($listing ne 'no_such_dir') && ($listing ne 'empty') |
my @listing_results; |
&& ($listing ne 'con_lost')) { |
if ($listing eq 'unknown_cmd') { |
foreach (split(/:/,$listing)) { |
$listing = &reply('ls:'.$perlvar{'lonDocRoot'}.'/res/'. |
my ($entry,@stat)=split(/&/,$_); |
$udom, $tryserver); |
$allusers{$entry}=1; |
@listing_results = split(/:/,$listing); |
|
} else { |
|
@listing_results = |
|
map { &unescape($_); } split(/:/,$listing); |
|
} |
|
if ($listing_results[0] ne 'no_such_dir' && |
|
$listing_results[0] ne 'empty' && |
|
$listing_results[0] ne 'con_lost') { |
|
foreach my $line (@listing_results) { |
|
my ($entry) = split(/&/,$line,2); |
|
$allusers{$entry} = 1; |
} |
} |
} |
} |
} |
} |
} |
} |
my $alluserstr=''; |
my $alluserstr=''; |
foreach (sort keys %allusers) { |
foreach my $user (sort(keys(%allusers))) { |
$alluserstr.=$_.'&user:'; |
$alluserstr.=$user.'&user:'; |
} |
} |
$alluserstr=~s/:$//; |
$alluserstr=~s/:$//; |
return split(/:/,$alluserstr); |
return split(/:/,$alluserstr); |
} else { |
} else { |
my @emptyResults = (); |
return ('missing user name'); |
push(@emptyResults, 'missing user name'); |
|
return split(':',@emptyResults); |
|
} |
} |
} elsif(!defined($alternateDirectoryRoot)) { |
} elsif(!defined($alternateDirectoryRoot)) { |
my $tryserver; |
my $tryserver; |
my %alldom=(); |
my %alldom=(); |
foreach $tryserver (keys %libserv) { |
foreach $tryserver (keys(%libserv)) { |
$alldom{$hostdom{$tryserver}}=1; |
$alldom{$hostdom{$tryserver}}=1; |
} |
} |
my $alldomstr=''; |
my $alldomstr=''; |
foreach (sort keys %alldom) { |
foreach my $domain (sort(keys(%alldom))) { |
$alldomstr.=$perlvar{'lonDocRoot'}.'/res/'.$_.'/&domain:'; |
$alldomstr.=$perlvar{'lonDocRoot'}.'/res/'.$domain.'/&domain:'; |
} |
} |
$alldomstr=~s/:$//; |
$alldomstr=~s/:$//; |
return split(/:/,$alldomstr); |
return split(/:/,$alldomstr); |
} else { |
} else { |
my @emptyResults = (); |
return ('missing domain'); |
push(@emptyResults, 'missing domain'); |
|
return split(':',@emptyResults); |
|
} |
} |
} |
} |
|
|
Line 3958 sub dirlist {
|
Line 5619 sub dirlist {
|
## |
## |
sub GetFileTimestamp { |
sub GetFileTimestamp { |
my ($studentDomain,$studentName,$filename,$root)=@_; |
my ($studentDomain,$studentName,$filename,$root)=@_; |
$studentDomain=~s/\W//g; |
$studentDomain = &LONCAPA::clean_domain($studentDomain); |
$studentName=~s/\W//g; |
$studentName = &LONCAPA::clean_username($studentName); |
my $subdir=$studentName.'__'; |
my $subdir=$studentName.'__'; |
$subdir =~ s/(.)(.)(.).*/$1\/$2\/$3/; |
$subdir =~ s/(.)(.)(.).*/$1\/$2\/$3/; |
my $proname="$studentDomain/$subdir/$studentName"; |
my $proname="$studentDomain/$subdir/$studentName"; |
Line 3975 sub GetFileTimestamp {
|
Line 5636 sub GetFileTimestamp {
|
} |
} |
} |
} |
|
|
|
sub stat_file { |
|
my ($uri) = @_; |
|
$uri = &clutter_with_no_wrapper($uri); |
|
|
|
my ($udom,$uname,$file,$dir); |
|
if ($uri =~ m-^/(uploaded|editupload)/-) { |
|
($udom,$uname,$file) = |
|
($uri =~ m-/(?:uploaded|editupload)/?($match_domain)/?($match_name)/?(.*)-); |
|
$file = 'userfiles/'.$file; |
|
$dir = &propath($udom,$uname); |
|
} |
|
if ($uri =~ m-^/res/-) { |
|
($udom,$uname) = |
|
($uri =~ m-/(?:res)/?($match_domain)/?($match_username)/-); |
|
$file = $uri; |
|
} |
|
|
|
if (!$udom || !$uname || !$file) { |
|
# unable to handle the uri |
|
return (); |
|
} |
|
|
|
my ($result) = &dirlist($file,$udom,$uname,$dir); |
|
my @stats = split('&', $result); |
|
|
|
if($stats[0] ne 'empty' && $stats[0] ne 'no_such_dir') { |
|
shift(@stats); #filename is first |
|
return @stats; |
|
} |
|
return (); |
|
} |
|
|
# -------------------------------------------------------- Value of a Condition |
# -------------------------------------------------------- Value of a Condition |
|
|
|
# gets the value of a specific preevaluated condition |
|
# stored in the string $env{user.state.<cid>} |
|
# or looks up a condition reference in the bighash and if if hasn't |
|
# already been evaluated recurses into docondval to get the value of |
|
# the condition, then memoizing it to |
|
# $env{user.state.<cid>.<condition>} |
sub directcondval { |
sub directcondval { |
my $number=shift; |
my $number=shift; |
if (!defined($ENV{'user.state.'.$ENV{'request.course.id'}})) { |
if (!defined($env{'user.state.'.$env{'request.course.id'}})) { |
&Apache::lonuserstate::evalstate(); |
&Apache::lonuserstate::evalstate(); |
} |
} |
if ($ENV{'user.state.'.$ENV{'request.course.id'}}) { |
if (exists($env{'user.state.'.$env{'request.course.id'}.".$number"})) { |
return substr($ENV{'user.state.'.$ENV{'request.course.id'}},$number,1); |
return $env{'user.state.'.$env{'request.course.id'}.".$number"}; |
|
} elsif ($number =~ /^_/) { |
|
my $sub_condition; |
|
if (tie(my %bighash,'GDBM_File',$env{'request.course.fn'}.'.db', |
|
&GDBM_READER(),0640)) { |
|
$sub_condition=$bighash{'conditions'.$number}; |
|
untie(%bighash); |
|
} |
|
my $value = &docondval($sub_condition); |
|
&appenv('user.state.'.$env{'request.course.id'}.".$number" => $value); |
|
return $value; |
|
} |
|
if ($env{'user.state.'.$env{'request.course.id'}}) { |
|
return substr($env{'user.state.'.$env{'request.course.id'}},$number,1); |
} else { |
} else { |
return 2; |
return 2; |
} |
} |
} |
} |
|
|
|
# get the collection of conditions for this resource |
sub condval { |
sub condval { |
my $condidx=shift; |
my $condidx=shift; |
my $result=0; |
|
my $allpathcond=''; |
my $allpathcond=''; |
foreach (split(/\|/,$condidx)) { |
foreach my $cond (split(/\|/,$condidx)) { |
if (defined($ENV{'acc.cond.'.$ENV{'request.course.id'}.'.'.$_})) { |
if (defined($env{'acc.cond.'.$env{'request.course.id'}.'.'.$cond})) { |
$allpathcond.= |
$allpathcond.= |
'('.$ENV{'acc.cond.'.$ENV{'request.course.id'}.'.'.$_}.')|'; |
'('.$env{'acc.cond.'.$env{'request.course.id'}.'.'.$cond}.')|'; |
} |
} |
} |
} |
$allpathcond=~s/\|$//; |
$allpathcond=~s/\|$//; |
if ($ENV{'request.course.id'}) { |
return &docondval($allpathcond); |
if ($allpathcond) { |
} |
my $operand='|'; |
|
my @stack; |
#evaluates an expression of conditions |
foreach ($allpathcond=~/(\d+|\(|\)|\&|\|)/g) { |
sub docondval { |
if ($_ eq '(') { |
my ($allpathcond) = @_; |
push @stack,($operand,$result) |
my $result=0; |
} elsif ($_ eq ')') { |
if ($env{'request.course.id'} |
my $before=pop @stack; |
&& defined($allpathcond)) { |
if (pop @stack eq '&') { |
my $operand='|'; |
$result=$result>$before?$before:$result; |
my @stack; |
} else { |
foreach my $chunk ($allpathcond=~/(\d+|_\d+\.\d+|\(|\)|\&|\|)/g) { |
$result=$result>$before?$result:$before; |
if ($chunk eq '(') { |
} |
push @stack,($operand,$result); |
} elsif (($_ eq '&') || ($_ eq '|')) { |
} elsif ($chunk eq ')') { |
$operand=$_; |
my $before=pop @stack; |
} else { |
if (pop @stack eq '&') { |
my $new=directcondval($_); |
$result=$result>$before?$before:$result; |
if ($operand eq '&') { |
} else { |
$result=$result>$new?$new:$result; |
$result=$result>$before?$result:$before; |
} else { |
} |
$result=$result>$new?$result:$new; |
} elsif (($chunk eq '&') || ($chunk eq '|')) { |
} |
$operand=$chunk; |
} |
} else { |
} |
my $new=directcondval($chunk); |
} |
if ($operand eq '&') { |
|
$result=$result>$new?$new:$result; |
|
} else { |
|
$result=$result>$new?$result:$new; |
|
} |
|
} |
|
} |
} |
} |
return $result; |
return $result; |
} |
} |
Line 4038 sub devalidatecourseresdata {
|
Line 5756 sub devalidatecourseresdata {
|
&devalidate_cache_new('courseres',$hashid); |
&devalidate_cache_new('courseres',$hashid); |
} |
} |
|
|
|
|
# --------------------------------------------------- Course Resourcedata Query |
# --------------------------------------------------- Course Resourcedata Query |
|
|
sub courseresdata { |
sub get_courseresdata { |
my ($coursenum,$coursedomain,@which)=@_; |
my ($coursenum,$coursedomain)=@_; |
my $coursehom=&homeserver($coursenum,$coursedomain); |
my $coursehom=&homeserver($coursenum,$coursedomain); |
my $hashid=$coursenum.':'.$coursedomain; |
my $hashid=$coursenum.':'.$coursedomain; |
my ($result,$cached)=&is_cached_new('courseres',$hashid); |
my ($result,$cached)=&is_cached_new('courseres',$hashid); |
|
my %dumpreply; |
unless (defined($cached)) { |
unless (defined($cached)) { |
my %dumpreply=&dump('resourcedata',$coursedomain,$coursenum); |
%dumpreply=&dump('resourcedata',$coursedomain,$coursenum); |
$result=\%dumpreply; |
$result=\%dumpreply; |
my ($tmp) = keys(%dumpreply); |
my ($tmp) = keys(%dumpreply); |
if ($tmp !~ /^(con_lost|error|no_such_host)/i) { |
if ($tmp !~ /^(con_lost|error|no_such_host)/i) { |
Line 4058 sub courseresdata {
|
Line 5778 sub courseresdata {
|
&do_cache_new('courseres',$hashid,$result,600); |
&do_cache_new('courseres',$hashid,$result,600); |
} |
} |
} |
} |
|
return $result; |
|
} |
|
|
|
sub devalidateuserresdata { |
|
my ($uname,$udom)=@_; |
|
my $hashid="$udom:$uname"; |
|
&devalidate_cache_new('userres',$hashid); |
|
} |
|
|
|
sub get_userresdata { |
|
my ($uname,$udom)=@_; |
|
#most student don\'t have any data set, check if there is some data |
|
if (&EXT_cache_status($udom,$uname)) { return undef; } |
|
|
|
my $hashid="$udom:$uname"; |
|
my ($result,$cached)=&is_cached_new('userres',$hashid); |
|
if (!defined($cached)) { |
|
my %resourcedata=&dump('resourcedata',$udom,$uname); |
|
$result=\%resourcedata; |
|
&do_cache_new('userres',$hashid,$result,600); |
|
} |
|
my ($tmp)=keys(%$result); |
|
if (($tmp!~/^error\:/) && ($tmp!~/^con_lost/)) { |
|
return $result; |
|
} |
|
#error 2 occurs when the .db doesn't exist |
|
if ($tmp!~/error: 2 /) { |
|
&logthis("<font color=\"blue\">WARNING:". |
|
" Trying to get resource data for ". |
|
$uname." at ".$udom.": ". |
|
$tmp."</font>"); |
|
} elsif ($tmp=~/error: 2 /) { |
|
#&EXT_cache_set($udom,$uname); |
|
&do_cache_new('userres',$hashid,undef,600); |
|
undef($tmp); # not really an error so don't send it back |
|
} |
|
return $tmp; |
|
} |
|
|
|
sub resdata { |
|
my ($name,$domain,$type,@which)=@_; |
|
my $result; |
|
if ($type eq 'course') { |
|
$result=&get_courseresdata($name,$domain); |
|
} elsif ($type eq 'user') { |
|
$result=&get_userresdata($name,$domain); |
|
} |
|
if (!ref($result)) { return $result; } |
foreach my $item (@which) { |
foreach my $item (@which) { |
if (defined($result->{$item})) { |
if (defined($result->{$item})) { |
return $result->{$item}; |
return $result->{$item}; |
Line 4077 sub clear_EXT_cache_status {
|
Line 5845 sub clear_EXT_cache_status {
|
sub EXT_cache_status { |
sub EXT_cache_status { |
my ($target_domain,$target_user) = @_; |
my ($target_domain,$target_user) = @_; |
my $cachename = 'cache.EXT.'.$target_user.'.'.$target_domain; |
my $cachename = 'cache.EXT.'.$target_user.'.'.$target_domain; |
if (exists($ENV{$cachename}) && ($ENV{$cachename}+600) > time) { |
if (exists($env{$cachename}) && ($env{$cachename}+600) > time) { |
# We know already the user has no data |
# We know already the user has no data |
return 1; |
return 1; |
} else { |
} else { |
Line 4088 sub EXT_cache_status {
|
Line 5856 sub EXT_cache_status {
|
sub EXT_cache_set { |
sub EXT_cache_set { |
my ($target_domain,$target_user) = @_; |
my ($target_domain,$target_user) = @_; |
my $cachename = 'cache.EXT.'.$target_user.'.'.$target_domain; |
my $cachename = 'cache.EXT.'.$target_user.'.'.$target_domain; |
&appenv($cachename => time); |
#&appenv($cachename => time); |
} |
} |
|
|
# --------------------------------------------------------- Value of a Variable |
# --------------------------------------------------------- Value of a Variable |
sub EXT { |
sub EXT { |
my ($varname,$symbparm,$udom,$uname,$usection,$recurse)=@_; |
|
|
|
|
my ($varname,$symbparm,$udom,$uname,$usection,$recurse)=@_; |
unless ($varname) { return ''; } |
unless ($varname) { return ''; } |
#get real user name/domain, courseid and symb |
#get real user name/domain, courseid and symb |
my $courseid; |
my $courseid; |
Line 4103 sub EXT {
|
Line 5871 sub EXT {
|
$symbparm=&get_symb_from_alias($symbparm); |
$symbparm=&get_symb_from_alias($symbparm); |
} |
} |
if (!($uname && $udom)) { |
if (!($uname && $udom)) { |
(my $cursymb,$courseid,$udom,$uname,$publicuser)= |
(my $cursymb,$courseid,$udom,$uname,$publicuser)= &whichuser($symbparm); |
&Apache::lonxml::whichuser($symbparm); |
|
if (!$symbparm) { $symbparm=$cursymb; } |
if (!$symbparm) { $symbparm=$cursymb; } |
} else { |
} else { |
$courseid=$ENV{'request.course.id'}; |
$courseid=$env{'request.course.id'}; |
} |
} |
my ($realm,$space,$qualifier,@therest)=split(/\./,$varname); |
my ($realm,$space,$qualifier,@therest)=split(/\./,$varname); |
my $rest; |
my $rest; |
Line 4124 sub EXT {
|
Line 5891 sub EXT {
|
if ($realm eq 'user') { |
if ($realm eq 'user') { |
# --------------------------------------------------------------- user.resource |
# --------------------------------------------------------------- user.resource |
if ($space eq 'resource') { |
if ($space eq 'resource') { |
if (defined($Apache::lonhomework::parsing_a_problem)) { |
if ( (defined($Apache::lonhomework::parsing_a_problem) |
return $Apache::lonhomework::history{$qualifierrest}; |
|| defined($Apache::lonhomework::parsing_a_task)) |
|
&& |
|
($symbparm eq &symbread()) ) { |
|
# if we are in the middle of processing the resource the |
|
# get the value we are planning on committing |
|
if (defined($Apache::lonhomework::results{$qualifierrest})) { |
|
return $Apache::lonhomework::results{$qualifierrest}; |
|
} else { |
|
return $Apache::lonhomework::history{$qualifierrest}; |
|
} |
} else { |
} else { |
my %restored; |
my %restored; |
if ($publicuser || $ENV{'request.state'} eq 'construct') { |
if ($publicuser || $env{'request.state'} eq 'construct') { |
%restored=&tmprestore($symbparm,$courseid,$udom,$uname); |
%restored=&tmprestore($symbparm,$courseid,$udom,$uname); |
} else { |
} else { |
%restored=&restore($symbparm,$courseid,$udom,$uname); |
%restored=&restore($symbparm,$courseid,$udom,$uname); |
Line 4141 sub EXT {
|
Line 5917 sub EXT {
|
return &allowed($qualifier,$rest); |
return &allowed($qualifier,$rest); |
# ------------------------------------------ user.preferences, user.environment |
# ------------------------------------------ user.preferences, user.environment |
} elsif (($space eq 'preferences') || ($space eq 'environment')) { |
} elsif (($space eq 'preferences') || ($space eq 'environment')) { |
if (($uname eq $ENV{'user.name'}) && |
if (($uname eq $env{'user.name'}) && |
($udom eq $ENV{'user.domain'})) { |
($udom eq $env{'user.domain'})) { |
return $ENV{join('.',('environment',$qualifierrest))}; |
return $env{join('.',('environment',$qualifierrest))}; |
} else { |
} else { |
my %returnhash; |
my %returnhash; |
if (!$publicuser) { |
if (!$publicuser) { |
Line 4155 sub EXT {
|
Line 5931 sub EXT {
|
# ----------------------------------------------------------------- user.course |
# ----------------------------------------------------------------- user.course |
} elsif ($space eq 'course') { |
} elsif ($space eq 'course') { |
# FIXME - not supporting calls for a specific user |
# FIXME - not supporting calls for a specific user |
return $ENV{join('.',('request.course',$qualifier))}; |
return $env{join('.',('request.course',$qualifier))}; |
# ------------------------------------------------------------------- user.role |
# ------------------------------------------------------------------- user.role |
} elsif ($space eq 'role') { |
} elsif ($space eq 'role') { |
# FIXME - not supporting calls for a specific user |
# FIXME - not supporting calls for a specific user |
my ($role,$where)=split(/\./,$ENV{'request.role'}); |
my ($role,$where)=split(/\./,$env{'request.role'}); |
if ($qualifier eq 'value') { |
if ($qualifier eq 'value') { |
return $role; |
return $role; |
} elsif ($qualifier eq 'extent') { |
} elsif ($qualifier eq 'extent') { |
Line 4183 sub EXT {
|
Line 5959 sub EXT {
|
# ---------------------------------------------- pull stuff out of query string |
# ---------------------------------------------- pull stuff out of query string |
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, |
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, |
[$spacequalifierrest]); |
[$spacequalifierrest]); |
return $ENV{'form.'.$spacequalifierrest}; |
return $env{'form.'.$spacequalifierrest}; |
} elsif ($realm eq 'request') { |
} elsif ($realm eq 'request') { |
# ------------------------------------------------------------- request.browser |
# ------------------------------------------------------------- request.browser |
if ($space eq 'browser') { |
if ($space eq 'browser') { |
if ($qualifier eq 'textremote') { |
if ($qualifier eq 'textremote') { |
if (&mt('textual_remote_display') eq 'on') { |
if (&Apache::lonlocal::mt('textual_remote_display') eq 'on') { |
return 1; |
return 1; |
} else { |
} else { |
return 0; |
return 0; |
} |
} |
} else { |
} else { |
return $ENV{'browser.'.$qualifier}; |
return $env{'browser.'.$qualifier}; |
} |
} |
# ------------------------------------------------------------ request.filename |
# ------------------------------------------------------------ request.filename |
} else { |
} else { |
return $ENV{'request.'.$spacequalifierrest}; |
return $env{'request.'.$spacequalifierrest}; |
} |
} |
} elsif ($realm eq 'course') { |
} elsif ($realm eq 'course') { |
# ---------------------------------------------------------- course.description |
# ---------------------------------------------------------- course.description |
return $ENV{'course.'.$courseid.'.'.$spacequalifierrest}; |
return $env{'course.'.$courseid.'.'.$spacequalifierrest}; |
} elsif ($realm eq 'resource') { |
} elsif ($realm eq 'resource') { |
|
|
my $section; |
if (defined($courseid) && $courseid eq $env{'request.course.id'}) { |
if (defined($courseid) && $courseid eq $ENV{'request.course.id'}) { |
|
if (!$symbparm) { $symbparm=&symbread(); } |
if (!$symbparm) { $symbparm=&symbread(); } |
} |
} |
|
|
|
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); |
|
} |
|
|
|
my ($section, $group, @groups); |
my ($courselevelm,$courselevel); |
my ($courselevelm,$courselevel); |
if ($symbparm && defined($courseid) && |
if ($symbparm && defined($courseid) && |
$courseid eq $ENV{'request.course.id'}) { |
$courseid eq $env{'request.course.id'}) { |
|
|
#print '<br>'.$space.' - '.$qualifier.' - '.$spacequalifierrest; |
#print '<br>'.$space.' - '.$qualifier.' - '.$spacequalifierrest; |
|
|
# ----------------------------------------------------- Cascading lookup scheme |
# ----------------------------------------------------- Cascading lookup scheme |
my $symbp=$symbparm; |
my $symbp=$symbparm; |
my $mapp=(&decode_symb($symbp))[0]; |
my $mapp=&deversion((&decode_symb($symbp))[0]); |
|
|
my $symbparm=$symbp.'.'.$spacequalifierrest; |
my $symbparm=$symbp.'.'.$spacequalifierrest; |
my $mapparm=$mapp.'___(all).'.$spacequalifierrest; |
my $mapparm=$mapp.'___(all).'.$spacequalifierrest; |
|
|
if (($ENV{'user.name'} eq $uname) && |
if (($env{'user.name'} eq $uname) && |
($ENV{'user.domain'} eq $udom)) { |
($env{'user.domain'} eq $udom)) { |
$section=$ENV{'request.course.sec'}; |
$section=$env{'request.course.sec'}; |
|
@groups = split(/:/,$env{'request.course.groups'}); |
|
@groups=&sort_course_groups($courseid,@groups); |
} else { |
} else { |
if (! defined($usection)) { |
if (! defined($usection)) { |
$section=&getsection($udom,$uname,$courseid); |
$section=&getsection($udom,$uname,$courseid); |
} else { |
} else { |
$section = $usection; |
$section = $usection; |
} |
} |
|
@groups = &get_users_groups($udom,$uname,$courseid); |
} |
} |
|
|
my $seclevel=$courseid.'.['.$section.'].'.$spacequalifierrest; |
my $seclevel=$courseid.'.['.$section.'].'.$spacequalifierrest; |
Line 4242 sub EXT {
|
Line 6032 sub EXT {
|
$courselevelm=$courseid.'.'.$mapparm; |
$courselevelm=$courseid.'.'.$mapparm; |
|
|
# ----------------------------------------------------------- first, check user |
# ----------------------------------------------------------- first, check user |
#most student don\'t have any data set, check if there is some data |
|
if (! &EXT_cache_status($udom,$uname)) { |
my $userreply=&resdata($uname,$udom,'user', |
my $hashid="$udom:$uname"; |
($courselevelr,$courselevelm, |
my ($result,$cached)=&is_cached_new('userres',$hashid); |
$courselevel)); |
if (!defined($cached)) { |
if (defined($userreply)) { return $userreply; } |
my %resourcedata=&dump('resourcedata',$udom,$uname); |
|
$result=\%resourcedata; |
|
&do_cache_new('userres',$hashid,$result); |
|
} |
|
my ($tmp)=keys(%$result); |
|
if (($tmp!~/^error\:/) && ($tmp!~/^con_lost/)) { |
|
if ($$result{$courselevelr}) { |
|
return $$result{$courselevelr}; } |
|
if ($$result{$courselevelm}) { |
|
return $$result{$courselevelm}; } |
|
if ($$result{$courselevel}) { |
|
return $$result{$courselevel}; } |
|
} else { |
|
#error 2 occurs when the .db doesn't exist |
|
if ($tmp!~/error: 2 /) { |
|
&logthis("<font color=blue>WARNING:". |
|
" Trying to get resource data for ". |
|
$uname." at ".$udom.": ". |
|
$tmp."</font>"); |
|
} elsif ($tmp=~/error: 2 /) { |
|
&EXT_cache_set($udom,$uname); |
|
} elsif ($tmp =~ /^(con_lost|no_such_host)/) { |
|
return $tmp; |
|
} |
|
} |
|
} |
|
|
|
# ------------------------------------------------ second, check some of course |
# ------------------------------------------------ second, check some of course |
|
my $coursereply; |
|
if (@groups > 0) { |
|
$coursereply = &check_group_parms($courseid,\@groups,$symbparm, |
|
$mapparm,$spacequalifierrest); |
|
if (defined($coursereply)) { return $coursereply; } |
|
} |
|
|
my $coursereply=&courseresdata($ENV{'course.'.$courseid.'.num'}, |
$coursereply=&resdata($env{'course.'.$courseid.'.num'}, |
$ENV{'course.'.$courseid.'.domain'}, |
$env{'course.'.$courseid.'.domain'}, |
($seclevelr,$seclevelm,$seclevel, |
'course', |
$courselevelr)); |
($seclevelr,$seclevelm,$seclevel, |
|
$courselevelr)); |
if (defined($coursereply)) { return $coursereply; } |
if (defined($coursereply)) { return $coursereply; } |
|
|
# ------------------------------------------------------ third, check map parms |
# ------------------------------------------------------ third, check map parms |
my %parmhash=(); |
my %parmhash=(); |
my $thisparm=''; |
my $thisparm=''; |
if (tie(%parmhash,'GDBM_File', |
if (tie(%parmhash,'GDBM_File', |
$ENV{'request.course.fn'}.'_parms.db', |
$env{'request.course.fn'}.'_parms.db', |
&GDBM_READER(),0640)) { |
&GDBM_READER(),0640)) { |
$thisparm=$parmhash{$symbparm}; |
$thisparm=$parmhash{$symbparm}; |
untie(%parmhash); |
untie(%parmhash); |
Line 4301 sub EXT {
|
Line 6072 sub EXT {
|
if ($symbparm) { |
if ($symbparm) { |
$filename=(&decode_symb($symbparm))[2]; |
$filename=(&decode_symb($symbparm))[2]; |
} else { |
} else { |
$filename=$ENV{'request.filename'}; |
$filename=$env{'request.filename'}; |
} |
} |
my $metadata=&metadata($filename,$spacequalifierrest); |
my $metadata=&metadata($filename,$spacequalifierrest); |
if (defined($metadata)) { return $metadata; } |
if (defined($metadata)) { return $metadata; } |
Line 4310 sub EXT {
|
Line 6081 sub EXT {
|
|
|
# ---------------------------------------------- fourth, look in rest pf course |
# ---------------------------------------------- fourth, look in rest pf course |
if ($symbparm && defined($courseid) && |
if ($symbparm && defined($courseid) && |
$courseid eq $ENV{'request.course.id'}) { |
$courseid eq $env{'request.course.id'}) { |
my $coursereply=&courseresdata($ENV{'course.'.$courseid.'.num'}, |
my $coursereply=&resdata($env{'course.'.$courseid.'.num'}, |
$ENV{'course.'.$courseid.'.domain'}, |
$env{'course.'.$courseid.'.domain'}, |
($courselevelm,$courselevel)); |
'course', |
|
($courselevelm,$courselevel)); |
if (defined($coursereply)) { return $coursereply; } |
if (defined($coursereply)) { return $coursereply; } |
} |
} |
# ------------------------------------------------------------------ Cascade up |
# ------------------------------------------------------------------ Cascade up |
Line 4333 sub EXT {
|
Line 6105 sub EXT {
|
# ---------------------------------------------------- Any other user namespace |
# ---------------------------------------------------- Any other user namespace |
} elsif ($realm eq 'environment') { |
} elsif ($realm eq 'environment') { |
# ----------------------------------------------------------------- environment |
# ----------------------------------------------------------------- environment |
if (($uname eq $ENV{'user.name'})&&($udom eq $ENV{'user.domain'})) { |
if (($uname eq $env{'user.name'})&&($udom eq $env{'user.domain'})) { |
return $ENV{'environment.'.$spacequalifierrest}; |
return $env{'environment.'.$spacequalifierrest}; |
} else { |
} else { |
|
if ($uname eq 'anonymous' && $udom eq '') { |
|
return ''; |
|
} |
my %returnhash=&userenvironment($udom,$uname, |
my %returnhash=&userenvironment($udom,$uname, |
$spacequalifierrest); |
$spacequalifierrest); |
return $returnhash{$spacequalifierrest}; |
return $returnhash{$spacequalifierrest}; |
Line 4345 sub EXT {
|
Line 6120 sub EXT {
|
if ($space eq 'time') { |
if ($space eq 'time') { |
return time; |
return time; |
} |
} |
|
} elsif ($realm eq 'server') { |
|
# ----------------------------------------------------------------- system.time |
|
if ($space eq 'name') { |
|
return $ENV{'SERVER_NAME'}; |
|
} |
} |
} |
return ''; |
return ''; |
} |
} |
|
|
|
sub check_group_parms { |
|
my ($courseid,$groups,$symbparm,$mapparm,$what) = @_; |
|
my @groupitems = (); |
|
my $resultitem; |
|
my @levels = ($symbparm,$mapparm,$what); |
|
foreach my $group (@{$groups}) { |
|
foreach my $level (@levels) { |
|
my $item = $courseid.'.['.$group.'].'.$level; |
|
push(@groupitems,$item); |
|
} |
|
} |
|
my $coursereply = &resdata($env{'course.'.$courseid.'.num'}, |
|
$env{'course.'.$courseid.'.domain'}, |
|
'course',@groupitems); |
|
return $coursereply; |
|
} |
|
|
|
sub sort_course_groups { # Sort groups based on defined rankings. Default is sort(). |
|
my ($courseid,@groups) = @_; |
|
@groups = sort(@groups); |
|
return @groups; |
|
} |
|
|
sub packages_tab_default { |
sub packages_tab_default { |
my ($uri,$varname)=@_; |
my ($uri,$varname)=@_; |
my (undef,$part,$name)=split(/\./,$varname); |
my (undef,$part,$name)=split(/\./,$varname); |
my $packages=&metadata($uri,'packages'); |
|
foreach my $package (split(/,/,$packages)) { |
my (@extension,@specifics,$do_default); |
|
foreach my $package (split(/,/,&metadata($uri,'packages'))) { |
my ($pack_type,$pack_part)=split(/_/,$package,2); |
my ($pack_type,$pack_part)=split(/_/,$package,2); |
|
if ($pack_type eq 'default') { |
|
$do_default=1; |
|
} elsif ($pack_type eq 'extension') { |
|
push(@extension,[$package,$pack_type,$pack_part]); |
|
} else { |
|
push(@specifics,[$package,$pack_type,$pack_part]); |
|
} |
|
} |
|
# first look for a package that matches the requested part id |
|
foreach my $package (@specifics) { |
|
my (undef,$pack_type,$pack_part)=@{$package}; |
|
next if ($pack_part ne $part); |
|
if (defined($packagetab{"$pack_type&$name&default"})) { |
|
return $packagetab{"$pack_type&$name&default"}; |
|
} |
|
} |
|
# look for any possible matching non extension_ package |
|
foreach my $package (@specifics) { |
|
my (undef,$pack_type,$pack_part)=@{$package}; |
if (defined($packagetab{"$pack_type&$name&default"})) { |
if (defined($packagetab{"$pack_type&$name&default"})) { |
return $packagetab{"$pack_type&$name&default"}; |
return $packagetab{"$pack_type&$name&default"}; |
} |
} |
Line 4363 sub packages_tab_default {
|
Line 6186 sub packages_tab_default {
|
return $packagetab{$pack_type."_".$pack_part."&$name&default"}; |
return $packagetab{$pack_type."_".$pack_part."&$name&default"}; |
} |
} |
} |
} |
|
# look for any posible extension_ match |
|
foreach my $package (@extension) { |
|
my ($package,$pack_type)=@{$package}; |
|
if (defined($packagetab{"$pack_type&$name&default"})) { |
|
return $packagetab{"$pack_type&$name&default"}; |
|
} |
|
if (defined($packagetab{$package."&$name&default"})) { |
|
return $packagetab{$package."&$name&default"}; |
|
} |
|
} |
|
# look for a global default setting |
|
if ($do_default && defined($packagetab{"default&$name&default"})) { |
|
return $packagetab{"default&$name&default"}; |
|
} |
return undef; |
return undef; |
} |
} |
|
|
Line 4393 sub metadata {
|
Line 6230 sub metadata {
|
(($uri =~ m|^/*adm/|) && |
(($uri =~ m|^/*adm/|) && |
($uri !~ m|^adm/includes|) && ($uri !~ m|/bulletinboard$|)) || |
($uri !~ m|^adm/includes|) && ($uri !~ m|/bulletinboard$|)) || |
($uri =~ m|/$|) || ($uri =~ m|/.meta$|) || ($uri =~ /^~/) || |
($uri =~ m|/$|) || ($uri =~ m|/.meta$|) || ($uri =~ /^~/) || |
($uri =~ m|home/[^/]+/public_html/|)) { |
($uri =~ m|home/$match_username/public_html/|)) { |
return undef; |
return undef; |
} |
} |
my $filename=$uri; |
my $filename=$uri; |
Line 4424 sub metadata {
|
Line 6261 sub metadata {
|
my %metathesekeys=(); |
my %metathesekeys=(); |
unless ($filename=~/\.meta$/) { $filename.='.meta'; } |
unless ($filename=~/\.meta$/) { $filename.='.meta'; } |
my $metastring; |
my $metastring; |
if ($uri !~ m|^uploaded/|) { |
if ($uri !~ m -^(editupload)/-) { |
my $file=&filelocation('',&clutter($filename)); |
my $file=&filelocation('',&clutter($filename)); |
#push(@{$metaentry{$uri.'.file'}},$file); |
#push(@{$metaentry{$uri.'.file'}},$file); |
$metastring=&getfile($file); |
$metastring=&getfile($file); |
Line 4448 sub metadata {
|
Line 6285 sub metadata {
|
} else { |
} else { |
$metaentry{':packages'}=$package.$keyroot; |
$metaentry{':packages'}=$package.$keyroot; |
} |
} |
foreach (keys %packagetab) { |
foreach my $pack_entry (keys(%packagetab)) { |
my $part=$keyroot; |
my $part=$keyroot; |
$part=~s/^\_//; |
$part=~s/^\_//; |
if ($_=~/^\Q$package\E\&/ || |
if ($pack_entry=~/^\Q$package\E\&/ || |
$_=~/^\Q$package\E_0\&/) { |
$pack_entry=~/^\Q$package\E_0\&/) { |
my ($pack,$name,$subp)=split(/\&/,$_); |
my ($pack,$name,$subp)=split(/\&/,$pack_entry); |
# ignore package.tab specified default values |
# ignore package.tab specified default values |
# here &package_tab_default() will fetch those |
# here &package_tab_default() will fetch those |
if ($subp eq 'default') { next; } |
if ($subp eq 'default') { next; } |
my $value=$packagetab{$_}; |
my $value=$packagetab{$pack_entry}; |
my $unikey; |
my $unikey; |
if ($pack =~ /_0$/) { |
if ($pack =~ /_0$/) { |
$unikey='parameter_0_'.$name; |
$unikey='parameter_0_'.$name; |
Line 4505 sub metadata {
|
Line 6342 sub metadata {
|
my $dir=$filename; |
my $dir=$filename; |
$dir=~s|[^/]*$||; |
$dir=~s|[^/]*$||; |
$location=&filelocation($dir,$location); |
$location=&filelocation($dir,$location); |
foreach (sort(split(/\,/,&metadata($uri,'keys', |
my $metadata = |
$location,$unikey, |
&metadata($uri,'keys', $location,$unikey, |
$depthcount+1)))) { |
$depthcount+1); |
$metaentry{':'.$_}=$metaentry{':'.$_}; |
foreach my $meta (split(',',$metadata)) { |
$metathesekeys{$_}=1; |
$metaentry{':'.$meta}=$metaentry{':'.$meta}; |
|
$metathesekeys{$meta}=1; |
} |
} |
} |
} |
} else { |
} else { |
Line 4518 sub metadata {
|
Line 6356 sub metadata {
|
$unikey.='_'.$token->[2]->{'name'}; |
$unikey.='_'.$token->[2]->{'name'}; |
} |
} |
$metathesekeys{$unikey}=1; |
$metathesekeys{$unikey}=1; |
foreach (@{$token->[3]}) { |
foreach my $param (@{$token->[3]}) { |
$metaentry{':'.$unikey.'.'.$_}=$token->[2]->{$_}; |
$metaentry{':'.$unikey.'.'.$param} = |
|
$token->[2]->{$param}; |
} |
} |
my $internaltext=&HTML::Entities::decode($parser->get_text('/'.$entry)); |
my $internaltext=&HTML::Entities::decode($parser->get_text('/'.$entry)); |
my $default=$metaentry{':'.$unikey.'.default'}; |
my $default=$metaentry{':'.$unikey.'.default'}; |
Line 4540 sub metadata {
|
Line 6379 sub metadata {
|
} |
} |
} |
} |
my ($extension) = ($uri =~ /\.(\w+)$/); |
my ($extension) = ($uri =~ /\.(\w+)$/); |
foreach my $key (sort(keys(%packagetab))) { |
foreach my $key (keys(%packagetab)) { |
#&logthis("extsion1 $extension $key !!"); |
|
#no specific packages #how's our extension |
#no specific packages #how's our extension |
if ($key!~/^extension_\Q$extension\E&/) { next; } |
if ($key!~/^extension_\Q$extension\E&/) { next; } |
&metadata_create_package_def($uri,$key,'extension_'.$extension, |
&metadata_create_package_def($uri,$key,'extension_'.$extension, |
\%metathesekeys); |
\%metathesekeys); |
} |
} |
if (!exists($metaentry{':packages'})) { |
if (!exists($metaentry{':packages'})) { |
foreach my $key (sort(keys(%packagetab))) { |
foreach my $key (keys(%packagetab)) { |
#no specific packages well let's get default then |
#no specific packages well let's get default then |
if ($key!~/^default&/) { next; } |
if ($key!~/^default&/) { next; } |
&metadata_create_package_def($uri,$key,'default', |
&metadata_create_package_def($uri,$key,'default', |
Line 4566 sub metadata {
|
Line 6404 sub metadata {
|
my $dir=$filename; |
my $dir=$filename; |
$dir=~s|[^/]*$||; |
$dir=~s|[^/]*$||; |
$location=&filelocation($dir,$location); |
$location=&filelocation($dir,$location); |
foreach (sort(split(/\,/,&metadata($uri,'keys', |
my $rights_metadata = |
$location,'_rights', |
&metadata($uri,'keys',$location,'_rights', |
$depthcount+1)))) { |
$depthcount+1); |
#$metaentry{':'.$_}=$metacache{$uri}->{':'.$_}; |
foreach my $rights (split(',',$rights_metadata)) { |
$metathesekeys{$_}=1; |
#$metaentry{':'.$rights}=$metacache{$uri}->{':'.$rights}; |
|
$metathesekeys{$rights}=1; |
} |
} |
} |
} |
} |
} |
$metaentry{':keys'}=join(',',keys %metathesekeys); |
# uniqifiy package listing |
|
my %seen; |
|
my @uniq_packages = |
|
grep { ! $seen{$_} ++ } (split(',',$metaentry{':packages'})); |
|
$metaentry{':packages'} = join(',',@uniq_packages); |
|
|
|
$metaentry{':keys'} = join(',',keys(%metathesekeys)); |
&metadata_generate_part0(\%metathesekeys,\%metaentry,$uri); |
&metadata_generate_part0(\%metathesekeys,\%metaentry,$uri); |
$metaentry{':allpossiblekeys'}=join(',',keys %metathesekeys); |
$metaentry{':allpossiblekeys'}=join(',',keys %metathesekeys); |
&do_cache_new('meta',$uri,\%metaentry); |
&do_cache_new('meta',$uri,\%metaentry,60*60); |
# this is the end of "was not already recently cached |
# this is the end of "was not already recently cached |
} |
} |
return $metaentry{':'.$what}; |
return $metaentry{':'.$what}; |
Line 4610 sub metadata_create_package_def {
|
Line 6455 sub metadata_create_package_def {
|
sub metadata_generate_part0 { |
sub metadata_generate_part0 { |
my ($metadata,$metacache,$uri) = @_; |
my ($metadata,$metacache,$uri) = @_; |
my %allnames; |
my %allnames; |
foreach my $metakey (sort keys %$metadata) { |
foreach my $metakey (keys(%$metadata)) { |
if ($metakey=~/^parameter\_(.*)/) { |
if ($metakey=~/^parameter\_(.*)/) { |
my $part=$$metacache{':'.$metakey.'.part'}; |
my $part=$$metacache{':'.$metakey.'.part'}; |
my $name=$$metacache{':'.$metakey.'.name'}; |
my $name=$$metacache{':'.$metakey.'.name'}; |
Line 4629 sub metadata_generate_part0 {
|
Line 6474 sub metadata_generate_part0 {
|
'.type'}; |
'.type'}; |
my $olddis=$$metacache{':parameter_'.$allnames{$name}.'_'.$name. |
my $olddis=$$metacache{':parameter_'.$allnames{$name}.'_'.$name. |
'.display'}; |
'.display'}; |
my $expr='\\[Part: '.$allnames{$name}.'\\]'; |
my $expr='[Part: '.$allnames{$name}.']'; |
$olddis=~s/\Q$expr\E/\[Part: 0\]/; |
$olddis=~s/\Q$expr\E/\[Part: 0\]/; |
$$metacache{"$key.display"}=$olddis; |
$$metacache{"$key.display"}=$olddis; |
} |
} |
} |
} |
|
|
|
# ------------------------------------------------------ Devalidate title cache |
|
|
|
sub devalidate_title_cache { |
|
my ($url)=@_; |
|
if (!$env{'request.course.id'}) { return; } |
|
my $symb=&symbread($url); |
|
if (!$symb) { return; } |
|
my $key=$env{'request.course.id'}."\0".$symb; |
|
&devalidate_cache_new('title',$key); |
|
} |
|
|
# ------------------------------------------------- Get the title of a resource |
# ------------------------------------------------- Get the title of a resource |
|
|
sub gettitle { |
sub gettitle { |
my $urlsymb=shift; |
my $urlsymb=shift; |
my $symb=&symbread($urlsymb); |
my $symb=&symbread($urlsymb); |
if ($symb) { |
if ($symb) { |
my $key=$ENV{'request.course.id'}."\0".$symb; |
my $key=$env{'request.course.id'}."\0".$symb; |
my ($result,$cached)=&is_cached_new('title',$key); |
my ($result,$cached)=&is_cached_new('title',$key); |
if (defined($cached)) { |
if (defined($cached)) { |
return $result; |
return $result; |
Line 4649 sub gettitle {
|
Line 6505 sub gettitle {
|
my ($map,$resid,$url)=&decode_symb($symb); |
my ($map,$resid,$url)=&decode_symb($symb); |
my $title=''; |
my $title=''; |
my %bighash; |
my %bighash; |
if (tie(%bighash,'GDBM_File',$ENV{'request.course.fn'}.'.db', |
if (tie(%bighash,'GDBM_File',$env{'request.course.fn'}.'.db', |
&GDBM_READER(),0640)) { |
&GDBM_READER(),0640)) { |
my $mapid=$bighash{'map_pc_'.&clutter($map)}; |
my $mapid=$bighash{'map_pc_'.&clutter($map)}; |
$title=$bighash{'title_'.$mapid.'.'.$resid}; |
$title=$bighash{'title_'.$mapid.'.'.$resid}; |
Line 4665 sub gettitle {
|
Line 6521 sub gettitle {
|
if (!$title) { $title=(split('/',$urlsymb))[-1]; } |
if (!$title) { $title=(split('/',$urlsymb))[-1]; } |
return $title; |
return $title; |
} |
} |
|
|
|
sub get_slot { |
|
my ($which,$cnum,$cdom)=@_; |
|
if (!$cnum || !$cdom) { |
|
(undef,my $courseid)=&whichuser(); |
|
$cdom=$env{'course.'.$courseid.'.domain'}; |
|
$cnum=$env{'course.'.$courseid.'.num'}; |
|
} |
|
my $key=join("\0",'slots',$cdom,$cnum,$which); |
|
my %slotinfo; |
|
if (exists($remembered{$key})) { |
|
$slotinfo{$which} = $remembered{$key}; |
|
} else { |
|
%slotinfo=&get('slots',[$which],$cdom,$cnum); |
|
&Apache::lonhomework::showhash(%slotinfo); |
|
my ($tmp)=keys(%slotinfo); |
|
if ($tmp=~/^error:/) { return (); } |
|
$remembered{$key} = $slotinfo{$which}; |
|
} |
|
if (ref($slotinfo{$which}) eq 'HASH') { |
|
return %{$slotinfo{$which}}; |
|
} |
|
return $slotinfo{$which}; |
|
} |
# ------------------------------------------------- Update symbolic store links |
# ------------------------------------------------- Update symbolic store links |
|
|
sub symblist { |
sub symblist { |
my ($mapname,%newhash)=@_; |
my ($mapname,%newhash)=@_; |
$mapname=&deversion(&declutter($mapname)); |
$mapname=&deversion(&declutter($mapname)); |
my %hash; |
my %hash; |
if (($ENV{'request.course.fn'}) && (%newhash)) { |
if (($env{'request.course.fn'}) && (%newhash)) { |
if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'_symb.db', |
if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db', |
&GDBM_WRCREAT(),0640)) { |
&GDBM_WRCREAT(),0640)) { |
foreach (keys %newhash) { |
foreach my $url (keys %newhash) { |
$hash{declutter($_)}=&encode_symb($mapname,$newhash{$_}->[1], |
next if ($url eq 'last_known' |
$newhash{$_}->[0]); |
&& $env{'form.no_update_last_known'}); |
|
$hash{declutter($url)}=&encode_symb($mapname, |
|
$newhash{$url}->[1], |
|
$newhash{$url}->[0]); |
} |
} |
if (untie(%hash)) { |
if (untie(%hash)) { |
return 'ok'; |
return 'ok'; |
Line 4692 sub symblist {
|
Line 6574 sub symblist {
|
sub symbverify { |
sub symbverify { |
my ($symb,$thisurl)=@_; |
my ($symb,$thisurl)=@_; |
my $thisfn=$thisurl; |
my $thisfn=$thisurl; |
# wrapper not part of symbs |
|
$thisfn=~s/^\/adm\/wrapper//; |
|
$thisfn=&declutter($thisfn); |
$thisfn=&declutter($thisfn); |
# direct jump to resource in page or to a sequence - will construct own symbs |
# direct jump to resource in page or to a sequence - will construct own symbs |
if ($thisfn=~/\.(page|sequence)$/) { return 1; } |
if ($thisfn=~/\.(page|sequence)$/) { return 1; } |
Line 4709 sub symbverify {
|
Line 6589 sub symbverify {
|
my %bighash; |
my %bighash; |
my $okay=0; |
my $okay=0; |
|
|
if (tie(%bighash,'GDBM_File',$ENV{'request.course.fn'}.'.db', |
if (tie(%bighash,'GDBM_File',$env{'request.course.fn'}.'.db', |
&GDBM_READER(),0640)) { |
&GDBM_READER(),0640)) { |
my $ids=$bighash{'ids_'.&clutter($thisurl)}; |
my $ids=$bighash{'ids_'.&clutter($thisurl)}; |
unless ($ids) { |
unless ($ids) { |
Line 4717 sub symbverify {
|
Line 6597 sub symbverify {
|
} |
} |
if ($ids) { |
if ($ids) { |
# ------------------------------------------------------------------- Has ID(s) |
# ------------------------------------------------------------------- Has ID(s) |
foreach (split(/\,/,$ids)) { |
foreach my $id (split(/\,/,$ids)) { |
my ($mapid,$resid)=split(/\./,$_); |
my ($mapid,$resid)=split(/\./,$id); |
if ( |
if ( |
&symbclean(&declutter($bighash{'map_id_'.$mapid}).'___'.$resid.'___'.$thisfn) |
&symbclean(&declutter($bighash{'map_id_'.$mapid}).'___'.$resid.'___'.$thisfn) |
eq $symb) { |
eq $symb) { |
if (($ENV{'request.role.adv'}) || |
if (($env{'request.role.adv'}) || |
$bighash{'encrypted_'.$_} eq $ENV{'request.enc'}) { |
$bighash{'encrypted_'.$id} eq $env{'request.enc'}) { |
$okay=1; |
$okay=1; |
} |
} |
} |
} |
Line 4748 sub symbclean {
|
Line 6628 sub symbclean {
|
# remove wrapper |
# remove wrapper |
|
|
$symb=~s/(\_\_\_\d+\_\_\_)adm\/wrapper\/(res\/)*/$1/; |
$symb=~s/(\_\_\_\d+\_\_\_)adm\/wrapper\/(res\/)*/$1/; |
|
$symb=~s/(\_\_\_\d+\_\_\_)adm\/coursedocs\/showdoc\/(res\/)*/$1/; |
return $symb; |
return $symb; |
} |
} |
|
|
Line 4767 sub decode_symb {
|
Line 6648 sub decode_symb {
|
|
|
sub fixversion { |
sub fixversion { |
my $fn=shift; |
my $fn=shift; |
if ($fn=~/^(adm|uploaded|public)/) { return $fn; } |
if ($fn=~/^(adm|uploaded|editupload|public)/) { return $fn; } |
my %bighash; |
my %bighash; |
my $uri=&clutter($fn); |
my $uri=&clutter($fn); |
my $key=$ENV{'request.course.id'}.'_'.$uri; |
my $key=$env{'request.course.id'}.'_'.$uri; |
# is this cached? |
# is this cached? |
my ($result,$cached)=&is_cached_new('courseresversion',$key); |
my ($result,$cached)=&is_cached_new('courseresversion',$key); |
if (defined($cached)) { return $result; } |
if (defined($cached)) { return $result; } |
# unfortunately not cached, or expired |
# unfortunately not cached, or expired |
if (tie(%bighash,'GDBM_File',$ENV{'request.course.fn'}.'.db', |
if (tie(%bighash,'GDBM_File',$env{'request.course.fn'}.'.db', |
&GDBM_READER(),0640)) { |
&GDBM_READER(),0640)) { |
if ($bighash{'version_'.$uri}) { |
if ($bighash{'version_'.$uri}) { |
my $version=$bighash{'version_'.$uri}; |
my $version=$bighash{'version_'.$uri}; |
Line 4800 sub deversion {
|
Line 6681 sub deversion {
|
sub symbread { |
sub symbread { |
my ($thisfn,$donotrecurse)=@_; |
my ($thisfn,$donotrecurse)=@_; |
my $cache_str='request.symbread.cached.'.$thisfn; |
my $cache_str='request.symbread.cached.'.$thisfn; |
if (defined($ENV{$cache_str})) { return $ENV{$cache_str}; } |
if (defined($env{$cache_str})) { return $env{$cache_str}; } |
# no filename provided? try from environment |
# no filename provided? try from environment |
unless ($thisfn) { |
unless ($thisfn) { |
if ($ENV{'request.symb'}) { |
if ($env{'request.symb'}) { |
return $ENV{$cache_str}=&symbclean($ENV{'request.symb'}); |
return $env{$cache_str}=&symbclean($env{'request.symb'}); |
} |
} |
$thisfn=$ENV{'request.filename'}; |
$thisfn=$env{'request.filename'}; |
} |
} |
if ($thisfn=~m|^/enc/|) { $thisfn=&Apache::lonenc::unencrypted($thisfn); } |
if ($thisfn=~m|^/enc/|) { $thisfn=&Apache::lonenc::unencrypted($thisfn); } |
# is that filename actually a symb? Verify, clean, and return |
# is that filename actually a symb? Verify, clean, and return |
if ($thisfn=~/\_\_\_\d+\_\_\_(.*)$/) { |
if ($thisfn=~/\_\_\_\d+\_\_\_(.*)$/) { |
if (&symbverify($thisfn,$1)) { |
if (&symbverify($thisfn,$1)) { |
return $ENV{$cache_str}=&symbclean($thisfn); |
return $env{$cache_str}=&symbclean($thisfn); |
} |
} |
} |
} |
$thisfn=declutter($thisfn); |
$thisfn=declutter($thisfn); |
my %hash; |
my %hash; |
my %bighash; |
my %bighash; |
my $syval=''; |
my $syval=''; |
if (($ENV{'request.course.fn'}) && ($thisfn)) { |
if (($env{'request.course.fn'}) && ($thisfn)) { |
my $targetfn = $thisfn; |
my $targetfn = $thisfn; |
if ( ($thisfn =~ m/^uploaded\//) && ($thisfn !~ m/\.(page|sequence)$/) ) { |
if ( ($thisfn =~ m/^(uploaded|editupload)\//) && ($thisfn !~ m/\.(page|sequence)$/) ) { |
$targetfn = 'adm/wrapper/'.$thisfn; |
$targetfn = 'adm/wrapper/'.$thisfn; |
} |
} |
if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'_symb.db', |
if ($targetfn =~ m|^adm/wrapper/(ext/.*)|) { |
|
$targetfn=$1; |
|
} |
|
if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db', |
&GDBM_READER(),0640)) { |
&GDBM_READER(),0640)) { |
$syval=$hash{$targetfn}; |
$syval=$hash{$targetfn}; |
untie(%hash); |
untie(%hash); |
Line 4832 sub symbread {
|
Line 6716 sub symbread {
|
# ---------------------------------------------------------- There was an entry |
# ---------------------------------------------------------- There was an entry |
if ($syval) { |
if ($syval) { |
#unless ($syval=~/\_\d+$/) { |
#unless ($syval=~/\_\d+$/) { |
#unless ($ENV{'form.request.prefix'}=~/\.(\d+)\_$/) { |
#unless ($env{'form.request.prefix'}=~/\.(\d+)\_$/) { |
#&appenv('request.ambiguous' => $thisfn); |
#&appenv('request.ambiguous' => $thisfn); |
#return $ENV{$cache_str}=''; |
#return $env{$cache_str}=''; |
#} |
#} |
#$syval.=$1; |
#$syval.=$1; |
#} |
#} |
} else { |
} else { |
# ------------------------------------------------------- Was not in symb table |
# ------------------------------------------------------- Was not in symb table |
if (tie(%bighash,'GDBM_File',$ENV{'request.course.fn'}.'.db', |
if (tie(%bighash,'GDBM_File',$env{'request.course.fn'}.'.db', |
&GDBM_READER(),0640)) { |
&GDBM_READER(),0640)) { |
# ---------------------------------------------- Get ID(s) for current resource |
# ---------------------------------------------- Get ID(s) for current resource |
my $ids=$bighash{'ids_'.&clutter($thisfn)}; |
my $ids=$bighash{'ids_'.&clutter($thisfn)}; |
Line 4857 sub symbread {
|
Line 6741 sub symbread {
|
if ($#possibilities==0) { |
if ($#possibilities==0) { |
# ----------------------------------------------- There is only one possibility |
# ----------------------------------------------- There is only one possibility |
my ($mapid,$resid)=split(/\./,$ids); |
my ($mapid,$resid)=split(/\./,$ids); |
$syval=declutter($bighash{'map_id_'.$mapid}).'___'.$resid; |
$syval=&encode_symb($bighash{'map_id_'.$mapid}, |
|
$resid,$thisfn); |
} elsif (!$donotrecurse) { |
} elsif (!$donotrecurse) { |
# ------------------------------------------ There is more than one possibility |
# ------------------------------------------ There is more than one possibility |
my $realpossible=0; |
my $realpossible=0; |
foreach (@possibilities) { |
foreach my $id (@possibilities) { |
my $file=$bighash{'src_'.$_}; |
my $file=$bighash{'src_'.$id}; |
if (&allowed('bre',$file)) { |
if (&allowed('bre',$file)) { |
my ($mapid,$resid)=split(/\./,$_); |
my ($mapid,$resid)=split(/\./,$id); |
if ($bighash{'map_type_'.$mapid} ne 'page') { |
if ($bighash{'map_type_'.$mapid} ne 'page') { |
$realpossible++; |
$realpossible++; |
$syval=declutter($bighash{'map_id_'.$mapid}). |
$syval=&encode_symb($bighash{'map_id_'.$mapid}, |
'___'.$resid; |
$resid,$thisfn); |
} |
} |
} |
} |
} |
} |
Line 4881 sub symbread {
|
Line 6766 sub symbread {
|
} |
} |
} |
} |
if ($syval) { |
if ($syval) { |
return $ENV{$cache_str}=$syval; |
return $env{$cache_str}=$syval; |
#return $ENV{$cache_str}=&symbclean($syval.'___'.$thisfn); |
|
} |
} |
} |
} |
&appenv('request.ambiguous' => $thisfn); |
&appenv('request.ambiguous' => $thisfn); |
return $ENV{$cache_str}=''; |
return $env{$cache_str}=''; |
} |
} |
|
|
# ---------------------------------------------------------- Return random seed |
# ---------------------------------------------------------- Return random seed |
Line 4937 sub numval3 {
|
Line 6821 sub numval3 {
|
return $total; |
return $total; |
} |
} |
|
|
|
sub digest { |
|
my ($data)=@_; |
|
my $digest=&Digest::MD5::md5($data); |
|
my ($a,$b,$c,$d)=unpack("iiii",$digest); |
|
my ($e,$f); |
|
{ |
|
use integer; |
|
$e=($a+$b); |
|
$f=($c+$d); |
|
if ($_64bit) { |
|
$e=(($e<<32)>>32); |
|
$f=(($f<<32)>>32); |
|
} |
|
} |
|
if (wantarray) { |
|
return ($e,$f); |
|
} else { |
|
my $g; |
|
{ |
|
use integer; |
|
$g=($e+$f); |
|
if ($_64bit) { |
|
$g=(($g<<32)>>32); |
|
} |
|
} |
|
return $g; |
|
} |
|
} |
|
|
sub latest_rnd_algorithm_id { |
sub latest_rnd_algorithm_id { |
return '64bit4'; |
return '64bit5'; |
} |
} |
|
|
sub get_rand_alg { |
sub get_rand_alg { |
my ($courseid)=@_; |
my ($courseid)=@_; |
if (!$courseid) { $courseid=(&Apache::lonxml::whichuser())[1]; } |
if (!$courseid) { $courseid=(&whichuser())[1]; } |
if ($courseid) { |
if ($courseid) { |
return $ENV{"course.$courseid.rndseed"}; |
return $env{"course.$courseid.rndseed"}; |
} |
} |
return &latest_rnd_algorithm_id(); |
return &latest_rnd_algorithm_id(); |
} |
} |
Line 4957 sub validCODE {
|
Line 6870 sub validCODE {
|
} |
} |
|
|
sub getCODE { |
sub getCODE { |
if (&validCODE($ENV{'form.CODE'})) { return $ENV{'form.CODE'}; } |
if (&validCODE($env{'form.CODE'})) { return $env{'form.CODE'}; } |
if (defined($Apache::lonhomework::parsing_a_problem) && |
if ( (defined($Apache::lonhomework::parsing_a_problem) || |
&validCODE($Apache::lonhomework::history{'resource.CODE'})) { |
defined($Apache::lonhomework::parsing_a_task) ) && |
|
&validCODE($Apache::lonhomework::history{'resource.CODE'})) { |
return $Apache::lonhomework::history{'resource.CODE'}; |
return $Apache::lonhomework::history{'resource.CODE'}; |
} |
} |
return undef; |
return undef; |
Line 4968 sub getCODE {
|
Line 6882 sub getCODE {
|
sub rndseed { |
sub rndseed { |
my ($symb,$courseid,$domain,$username)=@_; |
my ($symb,$courseid,$domain,$username)=@_; |
|
|
my ($wsymb,$wcourseid,$wdomain,$wusername)=&Apache::lonxml::whichuser(); |
my ($wsymb,$wcourseid,$wdomain,$wusername)=&whichuser(); |
if (!$symb) { |
if (!$symb) { |
unless ($symb=$wsymb) { return time; } |
unless ($symb=$wsymb) { return time; } |
} |
} |
Line 4976 sub rndseed {
|
Line 6890 sub rndseed {
|
if (!$domain) { $domain=$wdomain; } |
if (!$domain) { $domain=$wdomain; } |
if (!$username) { $username=$wusername } |
if (!$username) { $username=$wusername } |
my $which=&get_rand_alg(); |
my $which=&get_rand_alg(); |
|
|
if (defined(&getCODE())) { |
if (defined(&getCODE())) { |
if ($which eq '64bit4') { |
if ($which eq '64bit5') { |
|
return &rndseed_CODE_64bit5($symb,$courseid,$domain,$username); |
|
} elsif ($which eq '64bit4') { |
return &rndseed_CODE_64bit4($symb,$courseid,$domain,$username); |
return &rndseed_CODE_64bit4($symb,$courseid,$domain,$username); |
} else { |
} else { |
return &rndseed_CODE_64bit($symb,$courseid,$domain,$username); |
return &rndseed_CODE_64bit($symb,$courseid,$domain,$username); |
} |
} |
|
} elsif ($which eq '64bit5') { |
|
return &rndseed_64bit5($symb,$courseid,$domain,$username); |
} elsif ($which eq '64bit4') { |
} elsif ($which eq '64bit4') { |
return &rndseed_64bit4($symb,$courseid,$domain,$username); |
return &rndseed_64bit4($symb,$courseid,$domain,$username); |
} elsif ($which eq '64bit3') { |
} elsif ($which eq '64bit3') { |
Line 5005 sub rndseed_32bit {
|
Line 6924 sub rndseed_32bit {
|
my $domainseed=unpack("%32C*",$domain) << 7; |
my $domainseed=unpack("%32C*",$domain) << 7; |
my $courseseed=unpack("%32C*",$courseid); |
my $courseseed=unpack("%32C*",$courseid); |
my $num=$symbseed+$nameseed+$domainseed+$courseseed+$namechck+$symbchck; |
my $num=$symbseed+$nameseed+$domainseed+$courseseed+$namechck+$symbchck; |
#&Apache::lonxml::debug("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck"); |
#&logthis("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck"); |
#&Apache::lonxml::debug("rndseed :$num:$symb"); |
#&logthis("rndseed :$num:$symb"); |
if ($_64bit) { $num=(($num<<32)>>32); } |
if ($_64bit) { $num=(($num<<32)>>32); } |
return $num; |
return $num; |
} |
} |
Line 5026 sub rndseed_64bit {
|
Line 6945 sub rndseed_64bit {
|
|
|
my $num1=$symbchck+$symbseed+$namechck; |
my $num1=$symbchck+$symbseed+$namechck; |
my $num2=$nameseed+$domainseed+$courseseed; |
my $num2=$nameseed+$domainseed+$courseseed; |
#&Apache::lonxml::debug("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck"); |
#&logthis("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck"); |
#&Apache::lonxml::debug("rndseed :$num:$symb"); |
#&logthis("rndseed :$num:$symb"); |
if ($_64bit) { $num1=(($num1<<32)>>32); $num2=(($num2<<32)>>32); } |
|
if ($_64bit) { $num1=(($num1<<32)>>32); $num2=(($num2<<32)>>32); } |
if ($_64bit) { $num1=(($num1<<32)>>32); $num2=(($num2<<32)>>32); } |
return "$num1,$num2"; |
return "$num1,$num2"; |
} |
} |
Line 5050 sub rndseed_64bit2 {
|
Line 6968 sub rndseed_64bit2 {
|
|
|
my $num1=$symbchck+$symbseed+$namechck; |
my $num1=$symbchck+$symbseed+$namechck; |
my $num2=$nameseed+$domainseed+$courseseed; |
my $num2=$nameseed+$domainseed+$courseseed; |
#&Apache::lonxml::debug("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck"); |
#&logthis("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck"); |
#&Apache::lonxml::debug("rndseed :$num:$symb"); |
#&logthis("rndseed :$num:$symb"); |
|
if ($_64bit) { $num1=(($num1<<32)>>32); $num2=(($num2<<32)>>32); } |
return "$num1,$num2"; |
return "$num1,$num2"; |
} |
} |
} |
} |
Line 5072 sub rndseed_64bit3 {
|
Line 6991 sub rndseed_64bit3 {
|
|
|
my $num1=$symbchck+$symbseed+$namechck; |
my $num1=$symbchck+$symbseed+$namechck; |
my $num2=$nameseed+$domainseed+$courseseed; |
my $num2=$nameseed+$domainseed+$courseseed; |
#&Apache::lonxml::debug("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck"); |
#&logthis("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck"); |
#&Apache::lonxml::debug("rndseed :$num1:$num2:$_64bit"); |
#&logthis("rndseed :$num1:$num2:$_64bit"); |
if ($_64bit) { $num1=(($num1<<32)>>32); $num2=(($num2<<32)>>32); } |
if ($_64bit) { $num1=(($num1<<32)>>32); $num2=(($num2<<32)>>32); } |
|
|
return "$num1:$num2"; |
return "$num1:$num2"; |
Line 5096 sub rndseed_64bit4 {
|
Line 7015 sub rndseed_64bit4 {
|
|
|
my $num1=$symbchck+$symbseed+$namechck; |
my $num1=$symbchck+$symbseed+$namechck; |
my $num2=$nameseed+$domainseed+$courseseed; |
my $num2=$nameseed+$domainseed+$courseseed; |
#&Apache::lonxml::debug("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck"); |
#&logthis("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck"); |
#&Apache::lonxml::debug("rndseed :$num1:$num2:$_64bit"); |
#&logthis("rndseed :$num1:$num2:$_64bit"); |
if ($_64bit) { $num1=(($num1<<32)>>32); $num2=(($num2<<32)>>32); } |
if ($_64bit) { $num1=(($num1<<32)>>32); $num2=(($num2<<32)>>32); } |
|
|
return "$num1:$num2"; |
return "$num1:$num2"; |
} |
} |
} |
} |
|
|
|
sub rndseed_64bit5 { |
|
my ($symb,$courseid,$domain,$username)=@_; |
|
my ($num1,$num2)=&digest("$symb,$courseid,$domain,$username"); |
|
return "$num1:$num2"; |
|
} |
|
|
sub rndseed_CODE_64bit { |
sub rndseed_CODE_64bit { |
my ($symb,$courseid,$domain,$username)=@_; |
my ($symb,$courseid,$domain,$username)=@_; |
{ |
{ |
Line 5115 sub rndseed_CODE_64bit {
|
Line 7040 sub rndseed_CODE_64bit {
|
my $courseseed=unpack("%32S*",$courseid.' '); |
my $courseseed=unpack("%32S*",$courseid.' '); |
my $num1=$symbseed+$CODEchck; |
my $num1=$symbseed+$CODEchck; |
my $num2=$CODEseed+$courseseed+$symbchck; |
my $num2=$CODEseed+$courseseed+$symbchck; |
#&Apache::lonxml::debug("$symbseed:$CODEchck|$CODEseed:$courseseed:$symbchck"); |
#&logthis("$symbseed:$CODEchck|$CODEseed:$courseseed:$symbchck"); |
#&Apache::lonxml::debug("rndseed :$num1:$num2:$symb"); |
#&logthis("rndseed :$num1:$num2:$symb"); |
if ($_64bit) { $num1=(($num1<<32)>>32); } |
if ($_64bit) { $num1=(($num1<<32)>>32); } |
if ($_64bit) { $num2=(($num2<<32)>>32); } |
if ($_64bit) { $num2=(($num2<<32)>>32); } |
return "$num1:$num2"; |
return "$num1:$num2"; |
Line 5134 sub rndseed_CODE_64bit4 {
|
Line 7059 sub rndseed_CODE_64bit4 {
|
my $courseseed=unpack("%32S*",$courseid.' '); |
my $courseseed=unpack("%32S*",$courseid.' '); |
my $num1=$symbseed+$CODEchck; |
my $num1=$symbseed+$CODEchck; |
my $num2=$CODEseed+$courseseed+$symbchck; |
my $num2=$CODEseed+$courseseed+$symbchck; |
#&Apache::lonxml::debug("$symbseed:$CODEchck|$CODEseed:$courseseed:$symbchck"); |
#&logthis("$symbseed:$CODEchck|$CODEseed:$courseseed:$symbchck"); |
#&Apache::lonxml::debug("rndseed :$num1:$num2:$symb"); |
#&logthis("rndseed :$num1:$num2:$symb"); |
if ($_64bit) { $num1=(($num1<<32)>>32); } |
if ($_64bit) { $num1=(($num1<<32)>>32); } |
if ($_64bit) { $num2=(($num2<<32)>>32); } |
if ($_64bit) { $num2=(($num2<<32)>>32); } |
return "$num1:$num2"; |
return "$num1:$num2"; |
} |
} |
} |
} |
|
|
|
sub rndseed_CODE_64bit5 { |
|
my ($symb,$courseid,$domain,$username)=@_; |
|
my $code = &getCODE(); |
|
my ($num1,$num2)=&digest("$symb,$courseid,$code"); |
|
return "$num1:$num2"; |
|
} |
|
|
sub setup_random_from_rndseed { |
sub setup_random_from_rndseed { |
my ($rndseed)=@_; |
my ($rndseed)=@_; |
if ($rndseed =~/([,:])/) { |
if ($rndseed =~/([,:])/) { |
Line 5159 sub latest_receipt_algorithm_id {
|
Line 7091 sub latest_receipt_algorithm_id {
|
sub recunique { |
sub recunique { |
my $fucourseid=shift; |
my $fucourseid=shift; |
my $unique; |
my $unique; |
if ($ENV{"course.$fucourseid.receiptalg"} eq 'receipt2') { |
if ($env{"course.$fucourseid.receiptalg"} eq 'receipt2') { |
$unique=$ENV{"course.$fucourseid.internal.encseed"}; |
$unique=$env{"course.$fucourseid.internal.encseed"}; |
} else { |
} else { |
$unique=$perlvar{'lonReceipt'}; |
$unique=$perlvar{'lonReceipt'}; |
} |
} |
Line 5170 sub recunique {
|
Line 7102 sub recunique {
|
sub recprefix { |
sub recprefix { |
my $fucourseid=shift; |
my $fucourseid=shift; |
my $prefix; |
my $prefix; |
if ($ENV{"course.$fucourseid.receiptalg"} eq 'receipt2') { |
if ($env{"course.$fucourseid.receiptalg"} eq 'receipt2') { |
$prefix=$ENV{"course.$fucourseid.internal.encpref"}; |
$prefix=$env{"course.$fucourseid.internal.encpref"}; |
} else { |
} else { |
$prefix=$perlvar{'lonHostID'}; |
$prefix=$perlvar{'lonHostID'}; |
} |
} |
Line 5187 sub ireceipt {
|
Line 7119 sub ireceipt {
|
my $cunique=&recunique($fucourseid); |
my $cunique=&recunique($fucourseid); |
my $cpart=unpack("%32S*",$part); |
my $cpart=unpack("%32S*",$part); |
my $return =&recprefix($fucourseid).'-'; |
my $return =&recprefix($fucourseid).'-'; |
if ($ENV{"course.$fucourseid.receiptalg"} eq 'receipt2' || |
if ($env{"course.$fucourseid.receiptalg"} eq 'receipt2' || |
$ENV{'request.state'} eq 'construct') { |
$env{'request.state'} eq 'construct') { |
&Apache::lonxml::debug("doing receipt2 using parts $cpart, uname $cuname and udom $cudom gets ".($cpart%$cuname). |
#&logthis("doing receipt2 using parts $cpart, uname $cuname and udom $cudom gets ".($cpart%$cuname)." and ".($cpart%$cudom)); |
" and ".($cpart%$cudom)); |
|
|
|
$return.= ($cunique%$cuname+ |
$return.= ($cunique%$cuname+ |
$cunique%$cudom+ |
$cunique%$cudom+ |
Line 5213 sub ireceipt {
|
Line 7144 sub ireceipt {
|
|
|
sub receipt { |
sub receipt { |
my ($part)=@_; |
my ($part)=@_; |
my ($symb,$courseid,$domain,$name) = &Apache::lonxml::whichuser(); |
my ($symb,$courseid,$domain,$name) = &whichuser(); |
return &ireceipt($name,$domain,$courseid,$symb,$part); |
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 |
# ------------------------------------------------------------ Serves up a file |
# returns either the contents of the file or |
# returns either the contents of the file or |
# -1 if the file doesn't exist |
# -1 if the file doesn't exist |
Line 5229 sub receipt {
|
Line 7198 sub receipt {
|
|
|
sub getfile { |
sub getfile { |
my ($file) = @_; |
my ($file) = @_; |
|
if ($file =~ m -^/*(uploaded|editupload)/-) { $file=&filelocation("",$file); } |
if ($file =~ m|^/*uploaded/|) { $file=&filelocation("",$file); } |
|
&repcopy($file); |
&repcopy($file); |
return &readfile($file); |
return &readfile($file); |
} |
} |
|
|
sub repcopy_userfile { |
sub repcopy_userfile { |
my ($file)=@_; |
my ($file)=@_; |
if ($file =~ m|^/*uploaded/|) { $file=&filelocation("",$file); } |
if ($file =~ m -^/*(uploaded|editupload)/-) { $file=&filelocation("",$file); } |
if ($file =~ m|^/home/httpd/html/lonUsers/|) { return 'OK'; } |
if ($file =~ m|^/home/httpd/html/lonUsers/|) { return 'ok'; } |
my ($cdom,$cnum,$filename) = |
my ($cdom,$cnum,$filename) = |
($file=~m|^\Q$perlvar{'lonDocRoot'}\E/+userfiles/+([^/]+)/+([^/]+)/+(.*)|); |
($file=~m|^\Q$perlvar{'lonDocRoot'}\E/+userfiles/+($match_domain)/+($match_name)/+(.*)|); |
my ($info,$rtncode); |
|
my $uri="/uploaded/$cdom/$cnum/$filename"; |
my $uri="/uploaded/$cdom/$cnum/$filename"; |
if (-e "$file") { |
if (-e "$file") { |
|
# we already have a local copy, check it out |
my @fileinfo = stat($file); |
my @fileinfo = stat($file); |
|
my $rtncode; |
|
my $info; |
my $lwpresp = &getuploaded('HEAD',$uri,$cdom,$cnum,\$info,\$rtncode); |
my $lwpresp = &getuploaded('HEAD',$uri,$cdom,$cnum,\$info,\$rtncode); |
if ($lwpresp ne 'ok') { |
if ($lwpresp ne 'ok') { |
|
# there is no such file anymore, even though we had a local copy |
if ($rtncode eq '404') { |
if ($rtncode eq '404') { |
unlink($file); |
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; |
return -1; |
} |
} |
if ($info < $fileinfo[9]) { |
if ($info < $fileinfo[9]) { |
return 'OK'; |
# nice, the file we have is up-to-date, just say okay |
} |
return 'ok'; |
$info = ''; |
} else { |
$lwpresp = &getuploaded('GET',$uri,$cdom,$cnum,\$info,\$rtncode); |
# the file is outdated, get rid of it |
if ($lwpresp ne 'ok') { |
unlink($file); |
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|^(.+)/[^/]+$|) { |
# one way or the other, at this point, we don't have the file |
push @parts, split(/\//,$1); |
# construct the correct path for the file |
} |
my @parts = ($cdom,$cnum); |
my $path = $perlvar{'lonDocRoot'}.'/userfiles'; |
if ($filename =~ m|^(.+)/[^/]+$|) { |
foreach my $part (@parts) { |
push @parts, split(/\//,$1); |
$path .= '/'.$part; |
} |
if (!-e $path) { |
my $path = $perlvar{'lonDocRoot'}.'/userfiles'; |
mkdir($path,0770); |
foreach my $part (@parts) { |
} |
$path .= '/'.$part; |
|
if (!-e $path) { |
|
mkdir($path,0770); |
} |
} |
} |
} |
open(FILE,">$file"); |
# now the path exists for sure |
print FILE $info; |
# get a user agent |
close(FILE); |
my $ua=new LWP::UserAgent; |
return 'OK'; |
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'; |
} |
} |
|
|
sub tokenwrapper { |
sub tokenwrapper { |
my $uri=shift; |
my $uri=shift; |
$uri=~s|^http\://([^/]+)||; |
$uri=~s|^http\://([^/]+)||; |
$uri=~s|^/||; |
$uri=~s|^/||; |
$ENV{'user.environment'}=~/\/([^\/]+)\.id/; |
$env{'user.environment'}=~/\/([^\/]+)\.id/; |
my $token=$1; |
my $token=$1; |
my (undef,$udom,$uname,$file)=split('/',$uri,4); |
my (undef,$udom,$uname,$file)=split('/',$uri,4); |
if ($udom && $uname && $file) { |
if ($udom && $uname && $file) { |
$file=~s|(\?\.*)*$||; |
$file=~s|(\?\.*)*$||; |
&appenv("userfile.$udom/$uname/$file" => $ENV{'request.course.id'}); |
&appenv("userfile.$udom/$uname/$file" => $env{'request.course.id'}); |
return 'http://'.$hostname{ &homeserver($uname,$udom)}.'/'.$uri. |
return 'http://'.$hostname{ &homeserver($uname,$udom)}.'/'.$uri. |
(($uri=~/\?/)?'&':'?').'token='.$token. |
(($uri=~/\?/)?'&':'?').'token='.$token. |
'&tokenissued='.$perlvar{'lonHostID'}; |
'&tokenissued='.$perlvar{'lonHostID'}; |
Line 5316 sub tokenwrapper {
|
Line 7283 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 { |
sub getuploaded { |
my ($reqtype,$uri,$cdom,$cnum,$info,$rtncode) = @_; |
my ($reqtype,$uri,$cdom,$cnum,$info,$rtncode) = @_; |
$uri=~s/^\///; |
$uri=~s/^\///; |
Line 5341 sub readfile {
|
Line 7312 sub readfile {
|
my $fh; |
my $fh; |
open($fh,"<$file"); |
open($fh,"<$file"); |
my $a=''; |
my $a=''; |
while (<$fh>) { $a .=$_; } |
while (my $line = <$fh>) { $a .= $line; } |
return $a; |
return $a; |
} |
} |
|
|
Line 5349 sub filelocation {
|
Line 7320 sub filelocation {
|
my ($dir,$file) = @_; |
my ($dir,$file) = @_; |
my $location; |
my $location; |
$file=~ s/^\s*(\S+)\s*$/$1/; ## strip off leading and trailing spaces |
$file=~ s/^\s*(\S+)\s*$/$1/; ## strip off leading and trailing spaces |
|
|
|
if ($file =~ m-^/adm/-) { |
|
$file=~s-^/adm/wrapper/-/-; |
|
$file=~s-^/adm/coursedocs/showdoc/-/-; |
|
} |
if ($file=~m:^/~:) { # is a contruction space reference |
if ($file=~m:^/~:) { # is a contruction space reference |
$location = $file; |
$location = $file; |
$location =~ s:/~(.*?)/(.*):/home/$1/public_html/$2:; |
$location =~ s:/~(.*?)/(.*):/home/$1/public_html/$2:; |
} elsif ($file=~/^\/*uploaded/) { # is an uploaded file |
} 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)= |
my ($udom,$uname,$filename)= |
($file=~m|^/+uploaded/+([^/]+)/+([^/]+)/+(.*)$|); |
($file=~m -^/+(?:uploaded|editupload)/+($match_domain)/+($match_name)/+(.*)$-); |
my $home=&homeserver($uname,$udom); |
my $home=&homeserver($uname,$udom); |
my $is_me=0; |
my $is_me=0; |
my @ids=¤t_machine_ids(); |
my @ids=¤t_machine_ids(); |
foreach my $id (@ids) { if ($id eq $home) { $is_me=1; } } |
foreach my $id (@ids) { if ($id eq $home) { $is_me=1; } } |
if ($is_me) { |
if ($is_me) { |
$location=&Apache::loncommon::propath($udom,$uname). |
$location=&propath($udom,$uname). |
'/userfiles/'.$filename; |
'/userfiles/'.$filename; |
} else { |
} else { |
$location=$Apache::lonnet::perlvar{'lonDocRoot'}.'/userfiles/'. |
$location=$Apache::lonnet::perlvar{'lonDocRoot'}.'/userfiles/'. |
$udom.'/'.$uname.'/'.$filename; |
$udom.'/'.$uname.'/'.$filename; |
} |
} |
} elsif ($file =~ /^\/adm\/portfolio\//) { |
|
$file =~ s:^/adm/portfolio/::; |
|
$location = $location=&Apache::loncommon::propath($ENV{'user.domain'},$ENV{'user.name'}).'/userfiles/portfolio/'.$file; |
|
} else { |
} else { |
$file=~s/^\Q$perlvar{'lonDocRoot'}\E//; |
$file=~s/^\Q$perlvar{'lonDocRoot'}\E//; |
$file=~s:^/res/:/:; |
$file=~s:^/res/:/:; |
Line 5387 sub filelocation {
|
Line 7363 sub filelocation {
|
sub hreflocation { |
sub hreflocation { |
my ($dir,$file)=@_; |
my ($dir,$file)=@_; |
unless (($file=~m-^http://-i) || ($file=~m-^/-)) { |
unless (($file=~m-^http://-i) || ($file=~m-^/-)) { |
my $finalpath=filelocation($dir,$file); |
$file=filelocation($dir,$file); |
$finalpath=~s-^/home/httpd/html--; |
} elsif ($file=~m-^/adm/-) { |
$finalpath=~s-^/home/(\w+)/public_html/-/~$1/-; |
$file=~s-^/adm/wrapper/-/-; |
return $finalpath; |
$file=~s-^/adm/coursedocs/showdoc/-/-; |
} elsif ($file=~m-^/home-) { |
} |
$file=~s-^/home/httpd/html--; |
if ($file=~m-^\Q$perlvar{'lonDocRoot'}\E-) { |
$file=~s-^/home/(\w+)/public_html/-/~$1/-; |
$file=~s-^\Q$perlvar{'lonDocRoot'}\E--; |
return $file; |
} 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/($match_domain)/./././($match_name)/userfiles/ |
|
-/uploaded/$1/$2/-x; |
} |
} |
return $file; |
return $file; |
} |
} |
Line 5423 sub current_machine_ids {
|
Line 7403 sub current_machine_ids {
|
return @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 |
# ------------------------------------------------------------- Declutters URLs |
|
|
sub declutter { |
sub declutter { |
Line 5430 sub declutter {
|
Line 7433 sub declutter {
|
if ($thisfn=~m|^/enc/|) { $thisfn=&Apache::lonenc::unencrypted($thisfn); } |
if ($thisfn=~m|^/enc/|) { $thisfn=&Apache::lonenc::unencrypted($thisfn); } |
$thisfn=~s/^\Q$perlvar{'lonDocRoot'}\E//; |
$thisfn=~s/^\Q$perlvar{'lonDocRoot'}\E//; |
$thisfn=~s/^\///; |
$thisfn=~s/^\///; |
|
$thisfn=~s|^adm/wrapper/||; |
|
$thisfn=~s|^adm/coursedocs/showdoc/||; |
$thisfn=~s/^res\///; |
$thisfn=~s/^res\///; |
$thisfn=~s/\?.+$//; |
$thisfn=~s/\?.+$//; |
return $thisfn; |
return $thisfn; |
Line 5439 sub declutter {
|
Line 7444 sub declutter {
|
|
|
sub clutter { |
sub clutter { |
my $thisfn='/'.&declutter(shift); |
my $thisfn='/'.&declutter(shift); |
unless ($thisfn=~/^\/(uploaded|adm|userfiles|ext|raw|priv|public)\//) { |
unless ($thisfn=~/^\/(uploaded|editupload|adm|userfiles|ext|raw|priv|public)\//) { |
$thisfn='/res'.$thisfn; |
$thisfn='/res'.$thisfn; |
} |
} |
|
if ($thisfn !~m|/adm|) { |
|
if ($thisfn =~ m|/ext/|) { |
|
$thisfn='/adm/wrapper'.$thisfn; |
|
} else { |
|
my ($ext) = ($thisfn =~ /\.(\w+)$/); |
|
my $embstyle=&Apache::loncommon::fileembstyle($ext); |
|
if ($embstyle eq 'ssi' |
|
|| ($embstyle eq 'hdn') |
|
|| ($embstyle eq 'rat') |
|
|| ($embstyle eq 'prv') |
|
|| ($embstyle eq 'ign')) { |
|
#do nothing with these |
|
} elsif (($embstyle eq 'img') |
|
|| ($embstyle eq 'emb') |
|
|| ($embstyle eq 'wrp')) { |
|
$thisfn='/adm/wrapper'.$thisfn; |
|
} elsif ($embstyle eq 'unk' |
|
&& $thisfn!~/\.(sequence|page)$/) { |
|
$thisfn='/adm/coursedocs/showdoc'.$thisfn; |
|
} else { |
|
# &logthis("Got a blank emb style"); |
|
} |
|
} |
|
} |
return $thisfn; |
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 { |
sub freeze_escape { |
my ($value)=@_; |
my ($value)=@_; |
if (ref($value)) { |
if (ref($value)) { |
Line 5454 sub freeze_escape {
|
Line 7492 sub freeze_escape {
|
return &escape($value); |
return &escape($value); |
} |
} |
|
|
# -------------------------------------------------------- Escape Special Chars |
|
|
|
sub escape { |
|
my $str=shift; |
|
$str =~ s/(\W)/"%".unpack('H2',$1)/eg; |
|
return $str; |
|
} |
|
|
|
# ----------------------------------------------------- Un-Escape Special Chars |
|
|
|
sub unescape { |
|
my $str=shift; |
|
$str =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; |
|
return $str; |
|
} |
|
|
|
sub thaw_unescape { |
sub thaw_unescape { |
my ($value)=@_; |
my ($value)=@_; |
Line 5480 sub thaw_unescape {
|
Line 7503 sub thaw_unescape {
|
return &unescape($value); |
return &unescape($value); |
} |
} |
|
|
sub mod_perl_version { |
|
return 1; |
|
if (defined($perlvar{'MODPERL2'})) { |
|
return 2; |
|
} |
|
} |
|
|
|
sub correct_line_ends { |
sub correct_line_ends { |
my ($result)=@_; |
my ($result)=@_; |
$$result =~s/\r\n/\n/mg; |
$$result =~s/\r\n/\n/mg; |
Line 5513 sub goodbye {
|
Line 7529 sub goodbye {
|
&logthis(sprintf("%-20s is %s",'hits',$hits)); |
&logthis(sprintf("%-20s is %s",'hits',$hits)); |
&flushcourselogs(); |
&flushcourselogs(); |
&logthis("Shutting down"); |
&logthis("Shutting down"); |
return DONE; |
|
} |
} |
|
|
BEGIN { |
BEGIN { |
# ----------------------------------- Read loncapa.conf and loncapa_apache.conf |
# ----------------------------------- Read loncapa.conf and loncapa_apache.conf |
unless ($readit) { |
unless ($readit) { |
{ |
{ |
# FIXME: Use LONCAPA::Configuration::read_conf here and omit next block |
my $configvars = LONCAPA::Configuration::read_conf('loncapa.conf'); |
open(my $config,"</etc/httpd/conf/loncapa.conf"); |
%perlvar = (%perlvar,%{$configvars}); |
|
|
while (my $configline=<$config>) { |
|
if ($configline=~/\S/ && $configline =~ /^[^\#]*PerlSetVar/) { |
|
my ($dummy,$varname,$varvalue)=split(/\s+/,$configline); |
|
chomp($varvalue); |
|
$perlvar{$varname}=$varvalue; |
|
} |
|
} |
|
close($config); |
|
} |
|
{ |
|
open(my $config,"</etc/httpd/conf/loncapa_apache.conf"); |
|
|
|
while (my $configline=<$config>) { |
|
if ($configline =~ /^[^\#]*PerlSetVar/) { |
|
my ($dummy,$varname,$varvalue)=split(/\s+/,$configline); |
|
chomp($varvalue); |
|
$perlvar{$varname}=$varvalue; |
|
} |
|
} |
|
close($config); |
|
} |
} |
|
|
# ------------------------------------------------------------ Read domain file |
# ------------------------------------------------------------ Read domain file |
Line 5552 BEGIN {
|
Line 7546 BEGIN {
|
%domain_auth_arg_def = (); |
%domain_auth_arg_def = (); |
my $fh; |
my $fh; |
if (open($fh,"<".$Apache::lonnet::perlvar{'lonTabDir'}.'/domain.tab')) { |
if (open($fh,"<".$Apache::lonnet::perlvar{'lonTabDir'}.'/domain.tab')) { |
while (<$fh>) { |
while (my $line = <$fh>) { |
next if (/^(\#|\s*$)/); |
next if ($line =~ /^(\#|\s*$)/); |
# next if /^\#/; |
# next if /^\#/; |
chomp; |
chomp $line; |
my ($domain, $domain_description, $def_auth, $def_auth_arg, |
my ($domain, $domain_description, $def_auth, $def_auth_arg, |
$def_lang, $city, $longi, $lati) = split(/:/,$_); |
$def_lang, $city, $longi, $lati, $primary) = split(/:/,$line,9); |
$domain_auth_def{$domain}=$def_auth; |
$domain_auth_def{$domain}=$def_auth; |
$domain_auth_arg_def{$domain}=$def_auth_arg; |
$domain_auth_arg_def{$domain}=$def_auth_arg; |
$domaindescription{$domain}=$domain_description; |
$domaindescription{$domain}=$domain_description; |
Line 5565 BEGIN {
|
Line 7559 BEGIN {
|
$domain_city{$domain}=$city; |
$domain_city{$domain}=$city; |
$domain_longi{$domain}=$longi; |
$domain_longi{$domain}=$longi; |
$domain_lati{$domain}=$lati; |
$domain_lati{$domain}=$lati; |
|
$domain_primary{$domain}=$primary; |
|
|
# &logthis("Domain.tab: $domain, $domain_auth_def{$domain}, $domain_auth_arg_def{$domain},$domaindescription{$domain}"); |
# &logthis("Domain.tab: $domain, $domain_auth_def{$domain}, $domain_auth_arg_def{$domain},$domaindescription{$domain}"); |
# &logthis("Domain.tab: $domain ".$domaindescription{$domain} ); |
# &logthis("Domain.tab: $domain ".$domaindescription{$domain} ); |
Line 5590 BEGIN {
|
Line 7585 BEGIN {
|
} |
} |
} |
} |
close($config); |
close($config); |
|
# FIXME: dev server don't want this, production servers _do_ want this |
|
#&get_iphost(); |
} |
} |
|
|
sub get_iphost { |
sub get_iphost { |
if (%iphost) { return %iphost; } |
if (%iphost) { return %iphost; } |
|
my %name_to_ip; |
foreach my $id (keys(%hostname)) { |
foreach my $id (keys(%hostname)) { |
my $name=$hostname{$id}; |
my $name=$hostname{$id}; |
my $ip = gethostbyname($name); |
my $ip; |
if (!$ip || length($ip) ne 4) { |
if (!exists($name_to_ip{$name})) { |
&logthis("Skipping host $id name $name no IP found\n"); |
$ip = gethostbyname($name); |
next; |
if (!$ip || length($ip) ne 4) { |
|
&logthis("Skipping host $id name $name no IP found"); |
|
next; |
|
} |
|
$ip=inet_ntoa($ip); |
|
$name_to_ip{$name} = $ip; |
|
} else { |
|
$ip = $name_to_ip{$name}; |
} |
} |
$ip=inet_ntoa($ip); |
|
push(@{$iphost{$ip}},$id); |
push(@{$iphost{$ip}},$id); |
} |
} |
return %iphost; |
return %iphost; |
Line 5614 sub get_iphost {
|
Line 7618 sub get_iphost {
|
while (my $configline=<$config>) { |
while (my $configline=<$config>) { |
chomp($configline); |
chomp($configline); |
if ($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); |
close($config); |
Line 5640 sub get_iphost {
|
Line 7646 sub get_iphost {
|
while (my $configline=<$config>) { |
while (my $configline=<$config>) { |
chomp($configline); |
chomp($configline); |
if ($configline) { |
if ($configline) { |
my ($short,$plain)=split(/:/,$configline); |
my ($short,@plain)=split(/:/,$configline); |
if ($plain ne '') { $prp{$short}=$plain; } |
%{$prp{$short}} = (); |
|
if (@plain > 0) { |
|
$prp{$short}{'std'} = $plain[0]; |
|
for (my $i=1; $i<@plain; $i++) { |
|
$prp{$short}{'alt'.$i} = $plain[$i]; |
|
} |
|
} |
} |
} |
} |
} |
close($config); |
close($config); |
Line 5670 sub get_iphost {
|
Line 7682 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'}; |
$processmarker='_'.time.'_'.$perlvar{'lonHostID'}; |
$dumpcount=0; |
$dumpcount=0; |
|
|
&logtouch(); |
&logtouch(); |
&logthis('<font color=yellow>INFO: Read configuration</font>'); |
&logthis('<font color="yellow">INFO: Read configuration</font>'); |
$readit=1; |
$readit=1; |
{ |
{ |
use integer; |
use integer; |
Line 5858 that was requested
|
Line 7872 that was requested
|
X<appenv()> |
X<appenv()> |
B<appenv(%hash)>: the value of %hash is written to |
B<appenv(%hash)>: the value of %hash is written to |
the user envirnoment file, and will be restored for each access this |
the user envirnoment file, and will be restored for each access this |
user makes during this session, also modifies the %ENV for the current |
user makes during this session, also modifies the %env for the current |
process |
process |
|
|
=item * |
=item * |
X<delenv()> |
X<delenv()> |
B<delenv($regexp)>: removes all items from the session |
B<delenv($regexp)>: removes all items from the session |
environment file that matches the regular expression in $regexp. The |
environment file that matches the regular expression in $regexp. The |
values are also delted from the current processes %ENV. |
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 |
=back |
|
|
Line 5929 passed in @what from the requested user'
|
Line 7950 passed in @what from the requested user'
|
|
|
=item * |
=item * |
|
|
allowed($priv,$uri) : check for a user privilege; returns codes for allowed |
allowed($priv,$uri,$symb,$role) : check for a user privilege; returns codes for allowed actions |
actions |
|
F: full access |
F: full access |
U,I,K: authentication modes (cxx only) |
U,I,K: authentication modes (cxx only) |
'': forbidden |
'': forbidden |
1: user needs to choose course |
1: user needs to choose course |
2: browse allowed |
2: browse allowed |
|
A: passphrase authentication needed |
|
|
=item * |
=item * |
|
|
Line 5948 and course level
|
Line 7969 and course level
|
plaintext($short) : return value in %prp hash (rolesplain.tab); plain text |
plaintext($short) : return value in %prp hash (rolesplain.tab); plain text |
explanation of a user role term |
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 |
=back |
|
|
=head2 User Modification |
=head2 User Modification |
Line 6078 revokecustomrole($udom,$uname,$url,$role
|
Line 8102 revokecustomrole($udom,$uname,$url,$role
|
|
|
=item * |
=item * |
|
|
coursedescription($courseid) : course description |
coursedescription($courseid) : returns a hash of information about the |
|
specified course id, including all environment settings for the |
|
course, the description of the course will be in the hash under the |
|
key 'description' |
|
|
=item * |
=item * |
|
|
courseresdata($coursenum,$coursedomain,@which) : request for current |
resdata($name,$domain,$type,@which) : request for current parameter |
parameter setting for a specific course, @what should be a list of |
setting for a specific $type, where $type is either 'course' or 'user', |
parameters to ask about. This routine caches answers for 5 minutes. |
@what should be a list of parameters to ask about. This routine caches |
|
answers for 5 minutes. |
|
|
=back |
=back |
|
|
Line 6115 subscribe($fname) : subscribe to a resou
|
Line 8143 subscribe($fname) : subscribe to a resou
|
|
|
repcopy($filename) : subscribes to the requested file, and attempts to |
repcopy($filename) : subscribes to the requested file, and attempts to |
replicate from the owning library server, Might return |
replicate from the owning library server, Might return |
'HTTP_SERVICE_UNAVAILABLE', 'HTTP_NOT_FOUND', 'FORBIDDEN', 'OK', or |
'unavailable', 'not_found', 'forbidden', 'ok', or |
'HTTP_BAD_REQUEST', also attempts to grab the metadata for the |
'bad_request', also attempts to grab the metadata for the |
resource. Expects the local filesystem pathname |
resource. Expects the local filesystem pathname |
(/home/httpd/html/res/....) |
(/home/httpd/html/res/....) |
|
|
Line 6173 symbverify($symb,$thisfn) : verifies tha
|
Line 8201 symbverify($symb,$thisfn) : verifies tha
|
a possible symb for the URL in $thisfn, and if is an encryypted |
a possible symb for the URL in $thisfn, and if is an encryypted |
resource that the user accessed using /enc/ returns a 1 on success, 0 |
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 existance of |
on failure, user must be in a course, as it assumes the existance of |
the course initial hash, and uses $ENV('request.course.id'} |
the course initial hash, and uses $env('request.course.id'} |
|
|
|
|
=item * |
=item * |
Line 6204 unfakeable, receipt
|
Line 8232 unfakeable, receipt
|
|
|
=item * |
=item * |
|
|
receipt() : API to ireceipt working off of ENV values; given out to users |
receipt() : API to ireceipt working off of env values; given out to users |
|
|
=item * |
=item * |
|
|
Line 6238 forcing spreadsheet to reevaluate the re
|
Line 8266 forcing spreadsheet to reevaluate the re
|
store($storehash,$symb,$namespace,$udom,$uname) : stores hash permanently |
store($storehash,$symb,$namespace,$udom,$uname) : stores hash permanently |
for this url; hashref needs to be given and should be a \%hashname; the |
for this url; hashref needs to be given and should be a \%hashname; the |
remaining args aren't required and if they aren't passed or are '' they will |
remaining args aren't required and if they aren't passed or are '' they will |
be derived from the ENV |
be derived from the env |
|
|
=item * |
=item * |
|
|
Line 6252 all args are optional
|
Line 8280 all args are optional
|
|
|
=item * |
=item * |
|
|
|
dumpstore($namespace,$udom,$uname,$regexp,$range) : |
|
dumps the complete (or key matching regexp) namespace into a hash |
|
($udom, $uname, $regexp, $range are optional) for a namespace that is |
|
normally &store()ed into |
|
|
|
$range should be either an integer '100' (give me the first 100 |
|
matching records) |
|
or be two integers sperated by a - with no spaces |
|
'30-50' (give me the 30th through the 50th matching |
|
records) |
|
|
|
|
|
=item * |
|
|
|
putstore($namespace,$symb,$version,$storehash,$udomain,$uname) : |
|
replaces a &store() version of data with a replacement set of data |
|
for a particular resource in a namespace passed in the $storehash hash |
|
reference |
|
|
|
=item * |
|
|
tmpstore($storehash,$symb,$namespace,$udom,$uname) : storage that |
tmpstore($storehash,$symb,$namespace,$udom,$uname) : storage that |
works very similar to store/cstore, but all data is stored in a |
works very similar to store/cstore, but all data is stored in a |
temporary location and can be reset using tmpreset, $storehash should |
temporary location and can be reset using tmpreset, $storehash should |
Line 6281 namesp ($udom and $uname are optional)
|
Line 8330 namesp ($udom and $uname are optional)
|
|
|
=item * |
=item * |
|
|
dump($namespace,$udom,$uname,$regexp) : |
dump($namespace,$udom,$uname,$regexp,$range) : |
dumps the complete (or key matching regexp) namespace into a hash |
dumps the complete (or key matching regexp) namespace into a hash |
($udom, $uname and $regexp are optional) |
($udom, $uname, $regexp, $range are optional) |
|
|
|
$range should be either an integer '100' (give me the first 100 |
|
matching records) |
|
or be two integers sperated by a - with no spaces |
|
'30-50' (give me the 30th through the 50th matching |
|
records) |
=item * |
=item * |
|
|
inc($namespace,$store,$udom,$uname) : increments $store in $namespace. |
inc($namespace,$store,$udom,$uname) : increments $store in $namespace. |
Line 6300 put($namespace,$storehash,$udom,$uname)
|
Line 8354 put($namespace,$storehash,$udom,$uname)
|
|
|
=item * |
=item * |
|
|
putstore($namespace,$storehash,$udomain,$uname) : stores hash in namesp |
cput($namespace,$storehash,$udom,$uname) : critical put |
keys used in storehash include version information (e.g., 1:$symb:message etc.) as |
($udom and $uname are optional) |
used in records written by &store and retrieved by &restore. This function |
|
was created for use in editing discussion posts, without incrementing the |
|
version number included in the key for a particular post. The colon |
|
separated list of attribute names (e.g., the value associated with the key |
|
1:keys:$symb) is also generated and passed in the ampersand separated |
|
items sent to lonnet::reply(). |
|
|
|
=item * |
=item * |
|
|
cput($namespace,$storehash,$udom,$uname) : critical put |
newput($namespace,$storehash,$udom,$uname) : |
($udom and $uname are optional) |
|
|
Attempts to store the items in the $storehash, but only if they don't |
|
currently exist, if this succeeds you can be certain that you have |
|
successfully created a new key value pair in the $namespace db. |
|
|
|
|
|
Args: |
|
$namespace: name of database to store values to |
|
$storehash: hashref to store to the db |
|
$udom: (optional) domain of user containing the db |
|
$uname: (optional) name of user caontaining the db |
|
|
|
Returns: |
|
'ok' -> succeeded in storing all keys of $storehash |
|
'key_exists: <key>' -> failed to anything out of $storehash, as at |
|
least <key> already existed in the db (other |
|
requested keys may also already exist) |
|
'error: <msg>' -> unable to tie the DB or other erorr occured |
|
'con_lost' -> unable to contact request server |
|
'refused' -> action was not allowed by remote machine |
|
|
|
|
=item * |
=item * |
|
|
Line 6325 reference filled in from namesp (encrypt
|
Line 8393 reference filled in from namesp (encrypt
|
log($udom,$name,$home,$message) : write to permanent log for user; use |
log($udom,$name,$home,$message) : write to permanent log for user; use |
critical subroutine |
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 |
=back |
|
|
=head2 Network Status Functions |
=head2 Network Status Functions |
Line 6440 getfile($file,$caller) : two cases - req
|
Line 8517 getfile($file,$caller) : two cases - req
|
- returns the entire contents of a file or -1; |
- returns the entire contents of a file or -1; |
it properly subscribes to and replicates the file if neccessary. |
it properly subscribes to and replicates the file if neccessary. |
|
|
|
|
|
=item * |
|
|
|
stat_file($url) : $url is expected to be a /res/ or /uploaded/ style file |
|
reference |
|
|
|
returns either a stat() list of data about the file or an empty list |
|
if the file doesn't exist or couldn't find out about it (connection |
|
problems or user unknown) |
|
|
=item * |
=item * |
|
|
filelocation($dir,$file) : returns file system location of a file |
filelocation($dir,$file) : returns file system location of a file |
Line 6458 declutter() : declutters URLs (remove do
|
Line 8545 declutter() : declutters URLs (remove do
|
|
|
=back |
=back |
|
|
|
=head2 Usererfile file routines (/uploaded*) |
|
|
|
=over 4 |
|
|
|
=item * |
|
|
|
userfileupload(): main rotine for putting a file in a user or course's |
|
filespace, arguments are, |
|
|
|
formname - required - this is the name of the element in $env where the |
|
filename, and the contents of the file to create/modifed exist |
|
the filename is in $env{'form.'.$formname.'.filename'} and the |
|
contents of the file is located in $env{'form.'.$formname} |
|
coursedoc - if true, store the file in the course of the active role |
|
of the current user |
|
subdir - required - subdirectory to put the file in under ../userfiles/ |
|
if undefined, it will be placed in "unknown" |
|
|
|
(This routine calls clean_filename() to remove any dangerous |
|
characters from the filename, and then calls finuserfileupload() to |
|
complete the transaction) |
|
|
|
returns either the url of the uploaded file (/uploaded/....) if successful |
|
and /adm/notfound.html if unsuccessful |
|
|
|
=item * |
|
|
|
clean_filename(): routine for cleaing a filename up for storage in |
|
userfile space, argument is: |
|
|
|
filename - proposed filename |
|
|
|
returns: the new clean filename |
|
|
|
=item * |
|
|
|
finishuserfileupload(): routine that creaes and sends the file to |
|
userspace, probably shouldn't be called directly |
|
|
|
docuname: username or courseid of destination for the file |
|
docudom: domain of user/course of destination for the file |
|
formname: same as for userfileupload() |
|
fname: filename (inculding subdirectories) for the file |
|
|
|
returns either the url of the uploaded file (/uploaded/....) if successful |
|
and /adm/notfound.html if unsuccessful |
|
|
|
=item * |
|
|
|
renameuserfile(): renames an existing userfile to a new name |
|
|
|
Args: |
|
docuname: username or courseid of destination for the file |
|
docudom: domain of user/course of destination for the file |
|
old: current file name (including any subdirs under userfiles) |
|
new: desired file name (including any subdirs under userfiles) |
|
|
|
=item * |
|
|
|
mkdiruserfile(): creates a directory is a userfiles dir |
|
|
|
Args: |
|
docuname: username or courseid of destination for the file |
|
docudom: domain of user/course of destination for the file |
|
dir: dir to create (including any subdirs under userfiles) |
|
|
|
=item * |
|
|
|
removeuserfile(): removes a file that exists in userfiles |
|
|
|
Args: |
|
docuname: username or courseid of destination for the file |
|
docudom: domain of user/course of destination for the file |
|
fname: filname to delete (including any subdirs under userfiles) |
|
|
|
=item * |
|
|
|
removeuploadedurl(): convience function for removeuserfile() |
|
|
|
Args: |
|
url: a full /uploaded/... url to delete |
|
|
|
=item * |
|
|
|
get_portfile_permissions(): |
|
Args: |
|
domain: domain of user or course contain the portfolio files |
|
user: name of user or num of course contain the portfolio files |
|
Returns: |
|
hashref of a dump of the proper file_permissions.db |
|
|
|
|
|
=item * |
|
|
|
get_access_controls(): |
|
|
|
Args: |
|
current_permissions: the hash ref returned from get_portfile_permissions() |
|
group: (optional) the group you want the files associated with |
|
file: (optional) the file you want access info on |
|
|
|
Returns: |
|
a hash (keys are file names) of hashes containing |
|
keys are: path to file/file_name\0uniqueID:scope_end_start (see below) |
|
values are XML containing access control settings (see below) |
|
|
|
Internal notes: |
|
|
|
access controls are stored in file_permissions.db as key=value pairs. |
|
key -> path to file/file_name\0uniqueID:scope_end_start |
|
where scope -> public,guest,course,group,domains or users. |
|
end -> UNIX time for end of access (0 -> no end date) |
|
start -> UNIX time for start of access |
|
|
|
value -> XML description of access control |
|
<scope type=""> (type =1 of: public,guest,course,group,domains,users"> |
|
<start></start> |
|
<end></end> |
|
|
|
<password></password> for scope type = guest |
|
|
|
<domain></domain> for scope type = course or group |
|
<number></number> |
|
<roles id=""> |
|
<role></role> |
|
<access></access> |
|
<section></section> |
|
<group></group> |
|
</roles> |
|
|
|
<dom></dom> for scope type = domains |
|
|
|
<users> for scope type = users |
|
<user> |
|
<uname></uname> |
|
<udom></udom> |
|
</user> |
|
</users> |
|
</scope> |
|
|
|
Access data is also aggregated for each file in an additional key=value pair: |
|
key -> path to file/file_name\0accesscontrol |
|
value -> reference to hash |
|
hash contains key = value pairs |
|
where key = uniqueID:scope_end_start |
|
value = UNIX time record was last updated |
|
|
|
Used to improve speed of look-ups of access controls for each file. |
|
|
|
Locks on files (resulting from submission of portfolio file to a homework problem stored in array of arrays. |
|
|
|
modify_access_controls(): |
|
|
|
Modifies access controls for a portfolio file |
|
Args |
|
1. file name |
|
2. reference to hash of required changes, |
|
3. domain |
|
4. username |
|
where domain,username are the domain of the portfolio owner |
|
(either a user or a course) |
|
|
|
Returns: |
|
1. result of additions or updates ('ok' or 'error', with error message). |
|
2. result of deletions ('ok' or 'error', with error message). |
|
3. reference to hash of any new or updated access controls. |
|
4. reference to hash used to map incoming IDs to uniqueIDs assigned to control. |
|
key = integer (inbound ID) |
|
value = uniqueID |
|
|
|
=back |
|
|
=head2 HTTP Helper Routines |
=head2 HTTP Helper Routines |
|
|
=over 4 |
=over 4 |