[LON-CAPA-cvs] cvs: loncom /auth lonacc.pm

raeburn lon-capa-cvs@mail.lon-capa.org
Thu, 22 Jun 2006 13:20:47 -0000


This is a MIME encoded message

--raeburn1150982447
Content-Type: text/plain

raeburn		Thu Jun 22 09:20:47 2006 EDT

  Modified files:              
    /loncom/auth	lonacc.pm 
  Log:
  Portfolio file access control now allows for domain-based, user-based, and course/group-based controls.  Passphrase-protected access (without login) yet to be enabled.
  
  
--raeburn1150982447
Content-Type: text/plain
Content-Disposition: attachment; filename="raeburn-20060622092047.txt"

Index: loncom/auth/lonacc.pm
diff -u loncom/auth/lonacc.pm:1.80 loncom/auth/lonacc.pm:1.81
--- loncom/auth/lonacc.pm:1.80	Fri Jun 16 18:54:30 2006
+++ loncom/auth/lonacc.pm	Thu Jun 22 09:20:46 2006
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Cookie Based Access Handler
 #
-# $Id: lonacc.pm,v 1.80 2006/06/16 22:54:30 albertel Exp $
+# $Id: lonacc.pm,v 1.81 2006/06/22 13:20:46 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -140,7 +140,7 @@
     my $current_perms = &Apache::lonnet::get_portfile_permissions($udom,$unum);
     my %access_controls = &Apache::lonnet::get_access_controls(
                                              $current_perms,$group,$file_name);
-    my ($public);
+    my ($public,$guest,@domains,@users,@courses,@groups);
     my $now = time;
     my $access_hash = $access_controls{$file_name};
     if (ref($access_hash) eq 'HASH') {
@@ -155,15 +155,154 @@
             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:'.$guest;
+            }
+        } else {
+            if (@domains > 0) {
+                foreach my $domkey (@domains) {
+                    my %content = &Apache::lonnet::parse_access_controls($$access_hash{$domkey});
+                    if (ref($content{'dom'}) eq 'ARRAY') {
+                        if (grep(/^\Q$env{'user.domain'}\E$/,@{$content{'dom'}})) {
+                            return 'ok';
+                        }
+                    }
+                }
+            }
+            if (@users > 0) {
+                foreach my $userkey (@users) {
+                    my %content = &Apache::lonnet::parse_access_controls($$access_hash{$userkey});
+                    if (exists($content{'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)\./([^/]+)/([^/]+)/?([^/]*)$-) {
+                        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/(\w+/\w+/\w*)./([^/]+)/([^/]+)/?([^/]*)$-) {
+                        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 = &Apache::lonnet::parse_access_controls($$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:'.$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 handler {
     my $r = shift;
     my $requrl=$r->uri;
@@ -230,12 +369,18 @@
                 my $result = &portfolio_access($1,$2,$3);
                 if ($result eq 'ok') {
                     return OK;
+                } elsif ($result =~ /^guest:(\w+)$/) {
+                    my $guestkey = $1;
+                    #FIXME need to cause generation of an intermediate page
                 }
             } elsif ($requrl =~ m|/+uploaded/([^/]+)/([^/]+)/groups/([^/]+)/portfolio/(.+)$|) {
-                my $result = &portfolio_access($1,$2,$4.'/'.$3,$3);
+                my $result = &portfolio_access($1,$2,$3.'/'.$4,$3);
                 if ($result eq 'ok') {
                     return OK;
-                }
+                } elsif ($result =~ /^guest:(\w+)$/) {
+                    my $guestkey = $1;
+                    #FIXME need to cause generation of an intermediate page
+}
             }
             if ($requrl!~/^\/adm|public|prtspool\//) {
 		my $access=&Apache::lonnet::allowed('bre',$requrl);
@@ -354,11 +499,17 @@
         my $result = &portfolio_access($1,$2,$3);
         if ($result eq 'ok') {
             return OK;
+        } elsif ($result =~ /^guest:(\w+)$/) {
+            my $guestkey = $1;
+            #FIXME need to cause generation of an intermediate page
         }
     } elsif ($requrl =~ m|/+uploaded/([^/]+)/([^/]+)/groups/([^/]+)/portfolio/(.+)$|) {
         my $result = &portfolio_access($1,$2,$4.'/'.$3,$3);
         if ($result eq 'ok') {
             return OK;
+        } elsif ($result =~ /^guest:(\w+)$/) {
+            my $guestkey = $1;
+            #FIXME need to cause generation of an intermediate page
         }
     }
 # -------------------------------------------------------------- Not authorized

--raeburn1150982447--