[LON-CAPA-cvs] cvs: loncom /interface loncreateuser.pm /lonnet/perl lonnet.pm

raeburn raeburn@source.lon-capa.org
Sat, 28 Nov 2009 21:33:57 -0000


This is a MIME encoded message

--raeburn1259444037
Content-Type: text/plain

raeburn		Sat Nov 28 21:33:57 2009 EDT

  Modified files:              
    /loncom/interface	loncreateuser.pm 
    /loncom/lonnet/perl	lonnet.pm 
  Log:
  - Bug 3705.
    - Course Owner (if also a Course Coordinator) can assign CC role to other users.
  
  
--raeburn1259444037
Content-Type: text/plain
Content-Disposition: attachment; filename="raeburn-20091128213357.txt"

Index: loncom/interface/loncreateuser.pm
diff -u loncom/interface/loncreateuser.pm:1.328 loncom/interface/loncreateuser.pm:1.329
--- loncom/interface/loncreateuser.pm:1.328	Mon Nov 23 13:03:58 2009
+++ loncom/interface/loncreateuser.pm	Sat Nov 28 21:33:53 2009
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Create a user
 #
-# $Id: loncreateuser.pm,v 1.328 2009/11/23 13:03:58 wenzelju Exp $
+# $Id: loncreateuser.pm,v 1.329 2009/11/28 21:33:53 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1028,10 +1028,24 @@
 <input type="hidden" name="pres_type"   value="" />
 <input type="hidden" name="pres_marker" value="" />
 ENDFORMINFO
-    my %inccourses;
-    foreach my $key (keys(%env)) {
-	if ($key=~/^user\.priv\.cm\.\/($match_domain)\/($match_username)/) {
-	    $inccourses{$1.'_'.$2}=1;
+    my (%inccourses,$roledom);
+    if ($context eq 'course') {
+        $inccourses{$env{'request.course.id'}}=1;
+        $roledom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+    } elsif ($context eq 'author') {
+        $roledom = $env{'request.role.domain'};
+    } elsif ($context eq 'domain') {
+        foreach my $key (keys(%env)) {
+            $roledom = $env{'request.role.domain'};
+            if ($key=~/^user\.priv\.cm\.\/($roledom)\/($match_username)/) {
+                $inccourses{$1.'_'.$2}=1;
+            }
+        }
+    } else {
+        foreach my $key (keys(%env)) {
+	    if ($key=~/^user\.priv\.cm\.\/($match_domain)\/($match_username)/) {
+	        $inccourses{$1.'_'.$2}=1;
+            }
         }
     }
     if ($newuser) {
@@ -1268,10 +1282,10 @@
         }
         $r->print('</div><div class="LC_clear_float_footer"></div>');
         if ($env{'form.action'} ne 'singlestudent') {
-            &display_existing_roles($r,$ccuname,$ccdomain,\%inccourses);
+            &display_existing_roles($r,$ccuname,$ccdomain,\%inccourses,$context,
+                                    $roledom,$crstype);
         }
     } ## End of new user/old user logic
-
     if ($env{'form.action'} eq 'singlestudent') {
         my $btntxt;
         if ($crstype eq 'Community') {
@@ -1389,13 +1403,9 @@
 }
 
 sub display_existing_roles {
-    my ($r,$ccuname,$ccdomain,$inccourses) = @_;
-    my %rolesdump=&Apache::lonnet::dump('roles',$ccdomain,$ccuname);
-    # Build up table of user roles to allow revocation and re-enabling of roles.
-    my ($tmp) = keys(%rolesdump);
-    if ($tmp !~ /^(con_lost|error)/i) {
-        my $now=time;
-        my %lt=&Apache::lonlocal::texthash(
+    my ($r,$ccuname,$ccdomain,$inccourses,$context,$roledom,$crstype) = @_;
+    my $now=time;
+    my %lt=&Apache::lonlocal::texthash(
                     'rer'  => "Existing Roles",
                     'rev'  => "Revoke",
                     'del'  => "Delete",
@@ -1405,198 +1415,255 @@
                     'sta'  => "Start",
                     'end'  => "End",
                                        );
-        my (%roletext,%sortrole,%roleclass,%rolepriv);
-        foreach my $area (sort { my $a1=join('_',(split('_',$a))[1,0]);
-                                    my $b1=join('_',(split('_',$b))[1,0]);
-                                    return $a1 cmp $b1;
-                                } keys(%rolesdump)) {
-            next if ($area =~ /^rolesdef/);
-            my $envkey=$area;
-            my $role = $rolesdump{$area};
-            my $thisrole=$area;
-            $area =~ s/\_\w\w$//;
-            my ($role_code,$role_end_time,$role_start_time) =
-                split(/_/,$role);
+    my (%rolesdump,%roletext,%sortrole,%roleclass,%rolepriv);
+    if ($context eq 'course' || $context eq 'author') {
+        my @roles = &Apache::lonuserutils::roles_by_context($context,1,$crstype);
+        my %roleshash = 
+            &Apache::lonnet::get_my_roles($ccuname,$ccdomain,'userroles',
+                              ['active','previous','future'],\@roles,$roledom,1);
+        foreach my $key (keys(%roleshash)) {
+            my ($start,$end) = split(':',$roleshash{$key});
+            next if ($start eq '-1' || $end eq '-1');
+            my ($rnum,$rdom,$role,$sec) = split(':',$key);
+            if ($context eq 'course') {
+                next unless (($rnum eq $env{'course.'.$env{'request.course.id'}.'.num'})
+                             && ($rdom eq $env{'course.'.$env{'request.course.id'}.'.domain'}));
+            } elsif ($context eq 'author') {
+                next unless (($rnum eq $env{'user.name'}) && ($rdom eq $env{'request.role.domain'}));
+            }
+            my ($newkey,$newvalue,$newrole);
+            $newkey = '/'.$rdom.'/'.$rnum;
+            if ($sec ne '') {
+                $newkey .= '/'.$sec;
+            }
+            $newvalue = $role;
+            if ($role =~ /^cr/) {
+                $newrole = 'cr';
+            } else {
+                $newrole = $role;
+            }
+            $newkey .= '_'.$newrole;
+            if ($start ne '' && $end ne '') {
+                $newvalue .= '_'.$end.'_'.$start;
+            }
+            $rolesdump{$newkey} = $newvalue;
+        }
+    } else {
+        %rolesdump=&Apache::lonnet::dump('roles',$ccdomain,$ccuname);
+    }
+    # Build up table of user roles to allow revocation and re-enabling of roles.
+    my ($tmp) = keys(%rolesdump);
+    return if ($tmp =~ /^(con_lost|error)/i);
+    foreach my $area (sort { my $a1=join('_',(split('_',$a))[1,0]);
+                                my $b1=join('_',(split('_',$b))[1,0]);
+                                return $a1 cmp $b1;
+                            } keys(%rolesdump)) {
+        next if ($area =~ /^rolesdef/);
+        my $envkey=$area;
+        my $role = $rolesdump{$area};
+        my $thisrole=$area;
+        $area =~ s/\_\w\w$//;
+        my ($role_code,$role_end_time,$role_start_time) =
+            split(/_/,$role);
 # Is this a custom role? Get role owner and title.
-            my ($croleudom,$croleuname,$croletitle)=
-                ($role_code=~m{^cr/($match_domain)/($match_username)/(\w+)$});
-            my $allowed=0;
-            my $delallowed=0;
-            my $sortkey=$role_code;
-            my $class='Unknown';
-            if ($area =~ m{^/($match_domain)/($match_courseid)} ) {
-                $class='Course';
-                my ($coursedom,$coursedir) = ($1,$2);
-                $sortkey.="\0$coursedom";
-                # $1.'_'.$2 is the course id (eg. 103_12345abcef103l3).
-                my %coursedata=
-                    &Apache::lonnet::coursedescription($1.'_'.$2);
-                my $carea;
-                if (defined($coursedata{'description'})) {
-                    $carea=$coursedata{'description'}.
-                        '<br />'.&mt('Domain').': '.$coursedom.('&nbsp;'x8).
-     &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$coursedir,$coursedom);
-                    $sortkey.="\0".$coursedata{'description'};
-                    $class=$coursedata{'type'};
+        my ($croleudom,$croleuname,$croletitle)=
+            ($role_code=~m{^cr/($match_domain)/($match_username)/(\w+)$});
+        my $allowed=0;
+        my $delallowed=0;
+        my $sortkey=$role_code;
+        my $class='Unknown';
+        if ($area =~ m{^/($match_domain)/($match_courseid)} ) {
+            $class='Course';
+            my ($coursedom,$coursedir) = ($1,$2);
+            my $cid = $1.'_'.$2;
+            # $1.'_'.$2 is the course id (eg. 103_12345abcef103l3).
+            my %coursedata=
+                &Apache::lonnet::coursedescription($cid);
+            if ($coursedir =~ /^$match_community$/) {
+                $class='Community';
+            }
+            $sortkey.="\0$coursedom";
+            my $carea;
+            if (defined($coursedata{'description'})) {
+                $carea=$coursedata{'description'}.
+                    '<br />'.&mt('Domain').': '.$coursedom.('&nbsp;'x8).
+    &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$coursedir,$coursedom);
+                $sortkey.="\0".$coursedata{'description'};
+            } else {
+                if ($class eq 'Community') {
+                    $carea=&mt('Unavailable community').': '.$area;
+                    $sortkey.="\0".&mt('Unavailable community').': '.$area;
                 } else {
                     $carea=&mt('Unavailable course').': '.$area;
                     $sortkey.="\0".&mt('Unavailable course').': '.$area;
                 }
-                $sortkey.="\0$coursedir";
-                $inccourses->{$1.'_'.$2}=1;
-                if ((&Apache::lonnet::allowed('c'.$role_code,$1.'/'.$2)) ||
-                    (&Apache::lonnet::allowed('c'.$role_code,$ccdomain))) {
-                    $allowed=1;
-                }
-                if ((&Apache::lonnet::allowed('dro',$1)) ||
-                    (&Apache::lonnet::allowed('dro',$ccdomain))) {
-                    $delallowed=1;
+            }
+            $sortkey.="\0$coursedir";
+            $inccourses->{$cid}=1;
+            if ((&Apache::lonnet::allowed('c'.$role_code,$coursedom.'/'.$coursedir)) ||
+                (&Apache::lonnet::allowed('c'.$role_code,$ccdomain))) {
+                $allowed=1;
+            }
+            unless ($allowed) {
+                my $isowner = &is_courseowner($cid,$coursedata{'internal.courseowner'});
+                if ($isowner) {
+                    if (($role_code eq 'co') && ($class eq 'Community')) {
+                        $allowed = 1;
+                    } elsif (($role_code eq 'cc') && ($class eq 'Course')) {
+                        $allowed = 1;
+                    }
                 }
+            } 
+            if ((&Apache::lonnet::allowed('dro',$coursedom)) ||
+                (&Apache::lonnet::allowed('dro',$ccdomain))) {
+                $delallowed=1;
+            }
 # - custom role. Needs more info, too
-                if ($croletitle) {
-                    if (&Apache::lonnet::allowed('ccr',$1.'/'.$2)) {
-                        $allowed=1;
-                        $thisrole.='.'.$role_code;
-                    }
+            if ($croletitle) {
+                if (&Apache::lonnet::allowed('ccr',$coursedom.'/'.$coursedir)) {
+                    $allowed=1;
+                    $thisrole.='.'.$role_code;
                 }
-                # Compute the background color based on $area
-                if ($area=~m{^/($match_domain)/($match_courseid)/(\w+)}) {
-                    $carea.='<br />Section: '.$3;
-                    $sortkey.="\0$3";
-                    if (!$allowed) {
-                        if ($env{'request.course.sec'} eq $3) {
-                            if (&Apache::lonnet::allowed('c'.$role_code,$1.'/'.$2.'/'.$3)) {
-                                $allowed = 1;
-                            }
+            }
+            if ($area=~m{^/($match_domain)/($match_courseid)/(\w+)}) {
+                $carea.='<br />Section: '.$3;
+                $sortkey.="\0$3";
+                if (!$allowed) {
+                    if ($env{'request.course.sec'} eq $3) {
+                        if (&Apache::lonnet::allowed('c'.$role_code,$1.'/'.$2.'/'.$3)) {
+                            $allowed = 1;
                         }
                     }
                 }
-                $area=$carea;
-            } else {
-                $sortkey.="\0".$area;
-                # Determine if current user is able to revoke privileges
-                if ($area=~m{^/($match_domain)/}) {
-                    if ((&Apache::lonnet::allowed('c'.$role_code,$1)) ||
-                       (&Apache::lonnet::allowed('c'.$role_code,$ccdomain))) {
-                        $allowed=1;
-                    }
-                    if (((&Apache::lonnet::allowed('dro',$1))  ||
-                         (&Apache::lonnet::allowed('dro',$ccdomain))) &&
-                        ($role_code ne 'dc')) {
-                        $delallowed=1;
-                    }
-                } else {
-                    if (&Apache::lonnet::allowed('c'.$role_code,'/')) {
-                        $allowed=1;
-                    }
+            }
+            $area=$carea;
+        } else {
+            $sortkey.="\0".$area;
+            # Determine if current user is able to revoke privileges
+            if ($area=~m{^/($match_domain)/}) {
+                if ((&Apache::lonnet::allowed('c'.$role_code,$1)) ||
+                   (&Apache::lonnet::allowed('c'.$role_code,$ccdomain))) {
+                   $allowed=1;
                 }
-                if ($role_code eq 'ca' || $role_code eq 'au') {
-                    $class='Construction Space';
-                } elsif ($role_code eq 'su') {
-                    $class='System';
-                } else {
-                    $class='Domain';
+                if (((&Apache::lonnet::allowed('dro',$1))  ||
+                    (&Apache::lonnet::allowed('dro',$ccdomain))) &&
+                    ($role_code ne 'dc')) {
+                    $delallowed=1;
                 }
-            }
-            if (($role_code eq 'ca') || ($role_code eq 'aa')) {
-                $area=~m{/($match_domain)/($match_username)};
-                if (&Apache::lonuserutils::authorpriv($2,$1)) {
+            } else {
+                if (&Apache::lonnet::allowed('c'.$role_code,'/')) {
                     $allowed=1;
-                } else {
-                    $allowed=0;
                 }
             }
-            my $row = '';
-            $row.= '<td>';
-            my $active=1;
-            $active=0 if (($role_end_time) && ($now>$role_end_time));
-            if (($active) && ($allowed)) {
-                $row.= '<input type="checkbox" name="rev:'.$thisrole.'" />';
+            if ($role_code eq 'ca' || $role_code eq 'au') {
+                $class='Construction Space';
+            } elsif ($role_code eq 'su') {
+                $class='System';
             } else {
-                if ($active) {
-                   $row.='&nbsp;';
-                } else {
-                   $row.=&mt('expired or revoked');
-                }
+                $class='Domain';
             }
-            $row.='</td><td>';
-            if ($allowed && !$active) {
-                $row.= '<input type="checkbox" name="ren:'.$thisrole.'" />';
+        }
+        if (($role_code eq 'ca') || ($role_code eq 'aa')) {
+            $area=~m{/($match_domain)/($match_username)};
+            if (&Apache::lonuserutils::authorpriv($2,$1)) {
+                $allowed=1;
             } else {
-                $row.='&nbsp;';
+                $allowed=0;
             }
-            $row.='</td><td>';
-            if ($delallowed) {
-                $row.= '<input type="checkbox" name="del:'.$thisrole.'" />';
+        }
+        my $row = '';
+        $row.= '<td>';
+        my $active=1;
+        $active=0 if (($role_end_time) && ($now>$role_end_time));
+        if (($active) && ($allowed)) {
+            $row.= '<input type="checkbox" name="rev:'.$thisrole.'" />';
+        } else {
+            if ($active) {
+               $row.='&nbsp;';
             } else {
-                $row.='&nbsp;';
+               $row.=&mt('expired or revoked');
             }
-            my $plaintext='';
-            if (!$croletitle) {
-                $plaintext=&Apache::lonnet::plaintext($role_code,$class)
-            } else {
-                $plaintext=
+        }
+        $row.='</td><td>';
+        if ($allowed && !$active) {
+            $row.= '<input type="checkbox" name="ren:'.$thisrole.'" />';
+        } else {
+            $row.='&nbsp;';
+        }
+        $row.='</td><td>';
+        if ($delallowed) {
+            $row.= '<input type="checkbox" name="del:'.$thisrole.'" />';
+        } else {
+            $row.='&nbsp;';
+        }
+        my $plaintext='';
+        if (!$croletitle) {
+            $plaintext=&Apache::lonnet::plaintext($role_code,$class)
+        } else {
+            $plaintext=
         "Customrole '$croletitle'<br />defined by $croleuname\@$croleudom";
+        }
+        $row.= '</td><td>'.$plaintext.
+               '</td><td>'.$area.
+               '</td><td>'.($role_start_time?&Apache::lonlocal::locallocaltime($role_start_time)
+                                            : '&nbsp;' ).
+               '</td><td>'.($role_end_time  ?&Apache::lonlocal::locallocaltime($role_end_time)
+                                            : '&nbsp;' )
+               ."</td>";
+        $sortrole{$sortkey}=$envkey;
+        $roletext{$envkey}=$row;
+        $roleclass{$envkey}=$class;
+        $rolepriv{$envkey}=$allowed;
+    } # end of foreach        (table building loop)
+
+    my $rolesdisplay = 0;
+    my %output = ();
+    foreach my $type ('Construction Space','Course','Community','Domain','System','Unknown') {
+        $output{$type} = '';
+        foreach my $which (sort {uc($a) cmp uc($b)} (keys(%sortrole))) {
+            if ( ($roleclass{$sortrole{$which}} =~ /^\Q$type\E/ ) && ($rolepriv{$sortrole{$which}}) ) {
+                 $output{$type}.=
+                      &Apache::loncommon::start_data_table_row().
+                      $roletext{$sortrole{$which}}.
+                      &Apache::loncommon::end_data_table_row();
             }
-            $row.= '</td><td>'.$plaintext.
-                   '</td><td>'.$area.
-                   '</td><td>'.($role_start_time?&Apache::lonlocal::locallocaltime($role_start_time)
-                                                : '&nbsp;' ).
-                   '</td><td>'.($role_end_time  ?&Apache::lonlocal::locallocaltime($role_end_time)
-                                                : '&nbsp;' )
-                   ."</td>";
-            $sortrole{$sortkey}=$envkey;
-            $roletext{$envkey}=$row;
-            $roleclass{$envkey}=$class;
-            $rolepriv{$envkey}=$allowed;
-            #$r->print($row);
-        } # end of foreach        (table building loop)
-        my $rolesdisplay = 0;
-        my %output = ();
-        foreach my $type ('Construction Space','Course','Community','Domain','System','Unknown') {
-            $output{$type} = '';
-            foreach my $which (sort {uc($a) cmp uc($b)} (keys(%sortrole))) {
-                if ( ($roleclass{$sortrole{$which}} =~ /^\Q$type\E/ ) && ($rolepriv{$sortrole{$which}}) ) {
-                    $output{$type}.=
-                          &Apache::loncommon::start_data_table_row().
-                          $roletext{$sortrole{$which}}.
-                          &Apache::loncommon::end_data_table_row();
-                }
-            }
-            unless($output{$type} eq '') {
-                $output{$type} = '<tr class="LC_info_row">'.
-                          "<td align='center' colspan='7'>".&mt($type)."</td></tr>".
-                           $output{$type};
-                $rolesdisplay = 1;
-            }
-        }
-        if ($rolesdisplay == 1) {
-            my $contextrole='';
-            if ($env{'request.course.id'}) {
-                my $crstype = &Apache::loncommon::course_type();
-                $contextrole = "Existing Roles in this $crstype";
-            } elsif ($env{'request.role'} =~ /^au\./) {
-                $contextrole = 'Existing Co-Author Roles in your Construction Space';
+        }
+        unless($output{$type} eq '') {
+            $output{$type} = '<tr class="LC_info_row">'.
+                      "<td align='center' colspan='7'>".&mt($type)."</td></tr>".
+                      $output{$type};
+            $rolesdisplay = 1;
+        }
+    }
+    if ($rolesdisplay == 1) {
+        my $contextrole='';
+        if ($env{'request.course.id'}) {
+            if (&Apache::loncommon::course_type() eq 'Community') {
+                $contextrole = &mt('Existing Roles in this Community');
             } else {
-                $contextrole = 'Existing Roles in this Domain';
+                $contextrole = &mt('Existing Roles in this Course');
             }
-            $r->print('
+        } elsif ($env{'request.role'} =~ /^au\./) {
+            $contextrole = &mt('Existing Co-Author Roles in your Construction Space');
+        } else {
+            $contextrole = &mt('Existing Roles in this Domain');
+        }
+        $r->print('
 <h3>'.$lt{'rer'}.'</h3>'.
-'<div>'.&mt($contextrole).'</div>'.
+'<div>'.$contextrole.'</div>'.
 &Apache::loncommon::start_data_table("LC_createuser").
 &Apache::loncommon::start_data_table_header_row().
 '<th>'.$lt{'rev'}.'</th><th>'.$lt{'ren'}.'</th><th>'.$lt{'del'}.
 '</th><th>'.$lt{'rol'}.'</th><th>'.$lt{'ext'}.
 '</th><th>'.$lt{'sta'}.'</th><th>'.$lt{'end'}.'</th>'.
 &Apache::loncommon::end_data_table_header_row());
-           foreach my $type ('Construction Space','Course','Community','Domain','System','Unknown') {
-                if ($output{$type}) {
-                    $r->print($output{$type}."\n");
-                }
+        foreach my $type ('Construction Space','Course','Community','Domain','System','Unknown') {
+            if ($output{$type}) {
+                $r->print($output{$type}."\n");
             }
-            $r->print(&Apache::loncommon::end_data_table());
         }
-    }  # End of check for keys in rolesdump
+        $r->print(&Apache::loncommon::end_data_table());
+    }
     return;
 }
 
@@ -5976,10 +6043,11 @@
             'end'  => "End"
     );
 
-    foreach my $protectedcourse (sort( keys(%inccourses))) {
+    foreach my $protectedcourse (sort(keys(%inccourses))) {
 	my $thiscourse=$protectedcourse;
 	$thiscourse=~s:_:/:g;
 	my %coursedata=&Apache::lonnet::coursedescription($thiscourse);
+        my $isowner = &is_courseowner($protectedcourse,$coursedata{'internal.courseowner'});
 	my $area=$coursedata{'description'};
         my $crstype=$coursedata{'type'};
 	if (!defined($area)) { $area=&mt('Unavailable course').': '.$protectedcourse; }
@@ -5994,9 +6062,10 @@
         my @roles = &Apache::lonuserutils::roles_by_context('course','',$crstype);
 	foreach my $role (@roles) {
             my $plrole=&Apache::lonnet::plaintext($role,$crstype);
-	    if (&Apache::lonnet::allowed('c'.$role,$thiscourse)) {
+	    if ((&Apache::lonnet::allowed('c'.$role,$thiscourse)) ||
+                ((($role eq 'cc') || ($role eq 'co')) && ($isowner))) {
                 $table .= &course_level_row($protectedcourse,$role,$area,$domain,
-                                            $plrole,\%sections_count,\%lt);    
+                                            $plrole,\%sections_count,\%lt);
             } elsif ($env{'request.course.sec'} ne '') {
                 if (&Apache::lonnet::allowed('c'.$role,$thiscourse.'/'.
                                              $env{'request.course.sec'})) {
@@ -6499,6 +6568,21 @@
     return (\@row,\%lt);
 }
 
+sub is_courseowner {
+    my ($thiscourse,$courseowner) = @_;
+    if ($courseowner eq '') {
+        if ($env{'request.course.id'} eq $thiscourse) {
+            $courseowner = $env{'course.'.$env{'request.course.id'}.'.internal.courseowner'};
+        }
+    }
+    if ($courseowner ne '') {
+        if ($courseowner eq $env{'user.name'}.':'.$env{'user.domain'}) {
+                return 1;
+        }
+    }
+    return;
+}
+
 #---------------------------------------------- end functions for &phase_two
 
 #--------------------------------- functions for &phase_two and &phase_three
Index: loncom/lonnet/perl/lonnet.pm
diff -u loncom/lonnet/perl/lonnet.pm:1.1044 loncom/lonnet/perl/lonnet.pm:1.1045
--- loncom/lonnet/perl/lonnet.pm:1.1044	Sat Nov 28 19:03:36 2009
+++ loncom/lonnet/perl/lonnet.pm	Sat Nov 28 21:33:57 2009
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # TCP networking package
 #
-# $Id: lonnet.pm,v 1.1044 2009/11/28 19:03:36 raeburn Exp $
+# $Id: lonnet.pm,v 1.1045 2009/11/28 21:33:57 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -6231,12 +6231,32 @@
                 $refused = 1;
             }
             if ($refused) {
-                if (($selfenroll == 1) && ($role eq 'st') && ($udom eq $env{'user.domain'}) && ($uname eq $env{'user.name'})) {
+                my ($cdom,$cnum) = ($cwosec =~ m{^/?($match_domain)/($match_courseid)$});
+                if (!$selfenroll && $context eq 'course') {
+                    my %crsenv;
+                    if ($role eq 'cc' || $role eq 'co') {
+                        %crsenv = &userenvironment($cdom,$cnum,('internal.courseowner'));
+                        if (($role eq 'cc') && ($cnum !~ /^$match_community$/)) {
+                            if ($env{'request.role'} eq 'cc./'.$cdom.'/'.$cnum) {
+                                if ($crsenv{'internal.courseowner'} eq 
+                                    $env{'user.name'}.':'.$env{'user.domain'}) {
+                                    $refused = '';
+                                }
+                            }
+                        } elsif (($role eq 'co') && ($cnum =~ /^$match_community$/)) { 
+                            if ($env{'request.role'} eq 'co./'.$cdom.'/'.$cnum) {
+                                if ($crsenv{'internal.courseowner'} eq 
+                                    $env{'user.name'}.':'.$env{'user.domain'}) {
+                                    $refused = '';
+                                }
+                            }
+                        }
+                    }
+                } elsif (($selfenroll == 1) && ($role eq 'st') && ($udom eq $env{'user.domain'}) && ($uname eq $env{'user.name'})) {
                     $refused = '';
                 } elsif ($context eq 'requestcourses') {
                     my @possroles = ('st','ta','ep','in','cc','co');
                     if ((grep(/^\Q$role\E$/,@possroles)) && ($env{'user.name'} ne '' && $env{'user.domain'} ne '')) {
-                        my ($cdom,$cnum) = ($cwosec =~ m{^/?($match_domain)/($match_courseid)$});
                         my $wrongcc;
                         if ($cnum =~ /^$match_community$/) {
                             $wrongcc = 1 if ($role eq 'cc');

--raeburn1259444037--