[LON-CAPA-cvs] cvs: loncom /interface portfolio.pm

raeburn lon-capa-cvs@mail.lon-capa.org
Fri, 23 Jun 2006 20:15:27 -0000


This is a MIME encoded message

--raeburn1151093727
Content-Type: text/plain

raeburn		Fri Jun 23 16:15:27 2006 EDT

  Modified files:              
    /loncom/interface	portfolio.pm 
  Log:
  Enforcing privileges for actions on course group portfolio files. Tabular display of access controls provided for group members with access to group repository, but without privilege needed to add/delete/update access controls for group files. Some text improvements, and case fixes for triggering correct roles nomenclature when dependent on Course/Group context.
  
  
--raeburn1151093727
Content-Type: text/plain
Content-Disposition: attachment; filename="raeburn-20060623161527.txt"

Index: loncom/interface/portfolio.pm
diff -u loncom/interface/portfolio.pm:1.119 loncom/interface/portfolio.pm:1.120
--- loncom/interface/portfolio.pm:1.119	Thu Jun 22 16:09:51 2006
+++ loncom/interface/portfolio.pm	Fri Jun 23 16:15:24 2006
@@ -49,29 +49,32 @@
 }
 my $dirptr=16384;
 sub display_common {
-    my ($r,$url,$current_path,$is_empty,$dir_list,$group)=@_;
-    my $groupitem;
+    my ($r,$url,$current_path,$is_empty,$dir_list,$group,$can_upload)=@_;
     my $namespace = &get_namespace($group);
     my $port_path = &get_port_path($group);
-    if (defined($group)) {
-        $groupitem = '<input type="hidden" name="group" value="'.$group.'" />';
-    } 
-    my $iconpath= $r->dir_config('lonIconsURL') . "/";
-    my %text=&Apache::lonlocal::texthash('upload' => 'Upload',
+    if ($can_upload) {
+        my $groupitem;
+        if (defined($group)) {
+            $groupitem = '<input type="hidden" name="group" value="'.$group.'" />';
+        } 
+        my $iconpath= $r->dir_config('lonIconsURL') . "/";
+        my %text=&Apache::lonlocal::texthash(
+					 'upload' => 'Upload',
 					 'upload_label' =>  
 					 'Upload file to current directory:',
 					 'createdir' => 'Create Subdirectory',
 					 'createdir_label' => 
 					 'Create subdirectory in current directory:');
-    my $escuri = &HTML::Entities::encode($r->uri,'&<>"');
-    $r->print(<<"TABLE"); 
+        my $escuri = &HTML::Entities::encode($r->uri,'&<>"');
+        $r->print(<<"TABLE"); 
 <table id="LC_portfolio_actions">
   <tr id="LC_portfolio_upload">
     <td class="LC_label">
       $text{'upload_label'}
     </td>
-    <td class="LC_value">$groupitem
+    <td class="LC_value">
       <form method="post" enctype="multipart/form-data" action="$escuri">
+        $groupitem 
         <input name="uploaddoc" type="file" />
 	<input type="hidden" name="currentpath" value="$current_path" />
 	<input type="hidden" name="action" value="$env{"form.action"}" />
@@ -98,6 +101,7 @@
   </tr>
 </table>
 TABLE
+    }
     my @tree = split (/\//,$current_path);
     $r->print('<span class="LC_current_location">'.&make_anchor($url,$port_path,'/',$env{"form.mode"},$env{"form.fieldname"},$env{"form.continue"},$group).'/');
     if (@tree > 1){
@@ -119,7 +123,8 @@
     $r->print("</form>");
 }
 sub display_directory {
-    my ($r,$url,$current_path,$is_empty,$dir_list,$group)=@_;
+    my ($r,$url,$current_path,$is_empty,$dir_list,$group,$can_upload,
+        $can_modify,$can_delete,$can_setacl)=@_;
     my $iconpath= $r->dir_config('lonIconsURL') . "/";
     my ($groupitem,$groupecho);
     my $display_out;
@@ -127,10 +132,15 @@
     my $checked_files;
     my $port_path = &get_port_path($group);
     my ($uname,$udom) = &get_name_dom($group);
-    if (defined($group)) {
+    my $access_admin_text = &mt('View Status');
+    if ($can_setacl) {
+        $access_admin_text = &mt('View/Change Status');
+    }
+    if ((defined($group)) && (defined($env{'request.course.id'}))) {
        $groupitem = '<input type="hidden" name="group" value="'.$group.'" />'; 
        $groupecho = '&amp;group='.$group;
     }
+
     my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom,
                                                                         $uname);
     my %locked_files = &Apache::lonnet::get_marked_as_readonly_hash(
@@ -142,7 +152,7 @@
 	$checked_files =&Apache::lonnet::files_in_path($uname,$env{'form.currentpath'});
 	$select_mode = 'true';
     } 
-    if ($is_empty && ($current_path ne '/')) {
+    if ($is_empty && ($current_path ne '/') && $can_delete) {
         $display_out = '<form method="post" action="'.$url.'">'.$groupitem.
         '<input type="hidden" name="action" value="deletedir" />'.
         '<input type="submit" name="deletedir" value="'.&mt("Delete Directory").'" />'.
@@ -220,12 +230,21 @@
                         $line.='<td colspan="2"><a href="'.$url.'?lockinfo='.$current_path.$filename.$groupecho.'">Locked</a></td>';
 			$css_class= 'LC_browser_file_locked';
                     } else {
-			my $cat='<img alt="'.&mt('Catalog Information').
-			    '" src="'.&Apache::loncommon::lonhttpdurl('/res/adm/pages/catalog.gif').'" />';
-                        $line.='<td><input type="checkbox" name="selectfile" value="'.$filename.'" />
-                            <a href="'.$url.'?rename='.$filename.'&amp;currentpath='.$current_path.$groupecho.'">Rename</a></td>
-                            <td><a href="'.$href_edit_location.$filename.'.meta">'.$cat.'</a>
-                            </td>';
+                        if (!$can_modify) {
+                            $line .= '<td colspan="2">';
+                        } else {
+                            $line .= '<td>';
+                        }
+                        if ($can_delete) {
+                            $line .= '<input type="checkbox" name="selectfile" value="'.$filename.'" />';
+                        }
+                        if ($can_modify) {
+                            my $cat='<img alt="'.&mt('Catalog Information').
+                            '" src="'.&Apache::loncommon::lonhttpdurl('/res/adm/pages/catalog.gif').'" />';
+                            $line .= '<a href="'.$url.'?rename='.$filename.'&amp;currentpath='.$current_path.$groupecho.'">Rename</a>';
+                            $line .= '</td><td><a href="'.$href_edit_location.$filename.'.meta">'.$cat.'</a>';
+                        }
+                        $line .= '</td>';
                     }
 		    $r->print('<tr class="'.$css_class.'">');
 		    $r->print($line);
@@ -254,7 +273,7 @@
                         push(@allaccesses,&mt('Public'));
                     }
                     if ($guest_access) {
-                        push(@allaccesses,&mt('Password-protected'));
+                        push(@allaccesses,&mt('Passphrase-protected'));
                     }
                     if ($cond_access) {
                         push(@allaccesses,&mt('Conditional'));
@@ -266,11 +285,12 @@
 			    $filename.'</a></td>'); 
                 $r->print('<td>'.$size.'</td>');
                 $r->print('<td>'.&Apache::lonlocal::locallocaltime($mtime).'</td>');
-                $r->print('<td><span style="white-space: nowrap">'.&mt($curr_access).'&nbsp;&nbsp;&nbsp;'.
-                          '<a href="'.$url.'?access='.$filename.
-                          '&amp;currentpath='.$current_path.$groupecho.
-                          '">'.&mt('View/Change').'</a></span></td>');
-                $r->print('</tr>'); 
+                $r->print('<td><span style="white-space: nowrap">'.
+                          &mt($curr_access).'&nbsp;&nbsp;&nbsp;');
+                $r->print('<a href="'.$url.'?access='.$filename.
+                              '&amp;currentpath='.$current_path.$groupecho.
+                              '">'.$access_admin_text.'</a>');
+                $r->print('</span></td></tr>');
             }
         }
     }
@@ -284,11 +304,15 @@
             <input type="hidden" name="currentpath" value="'.$current_path.'" />
         </form>');        
     } else {
-        $r->print('</table>
+        $r->print('</table>');
+        if ($can_delete) {
+            $r->print('
         <input type="submit" name="doit" value="Delete Checked Files" />
         <input type="hidden" name="action" value="delete" />
         <input type="hidden" name="currentpath" value="'.$current_path.'" />
-        </form>');
+        </form>'
+            );
+        }
     }
 }
 
@@ -493,24 +517,169 @@
 }
 
 sub display_access {
-    my ($r,$url,$group) = @_;
+    my ($r,$url,$group,$can_setacl) = @_;
     my ($uname,$udom) = &get_name_dom($group);
     my $file_name = $env{'form.currentpath'}.$env{'form.access'};
     $file_name = &prepend_group($file_name,$group);
     my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom,
                                                                         $uname);
     my %access_controls = &Apache::lonnet::get_access_controls($current_permissions,$group,$file_name);
-    &open_form($r,$url);
-    $r->print('<h3>'.&mt('Allowing others to retrieve portfolio file: [_1]',$env{'form.currentpath'}.$env{'form.access'}).'</h3>'."\n");
-    $r->print(&mt('Access to this file by others can be set to be one or more of the following types: public, password-protected or conditional.').'<br /><ul><li>'.&mt('Public files are available to anyone without the need for login.').'</li><li>'.&mt('Password-protected files do not require log-in, but will require the viewer to enter the password you set.').'</li><li>'.&mt('Conditional files are accessible to logged-in users with accounts in the LON-CAPA network, who satify the conditions you set.').'<br />'.&mt('The conditions can include affiliation with a particular course or group, or a user account in a specific domain.').'<br />'.&mt('Alternatively you can grant access to people with specific LON-CAPA usernames and domains.').'</li></ul>');
-    &access_setting_table($r,$access_controls{$file_name});
-    my $button_text = {
+    my $aclcount = keys(%access_controls);
+    my $header = '<h3>'.&mt('Allowing others to retrieve portfolio file: [_1]',$env{'form.currentpath'}.$env{'form.access'}).'</h3>';
+    my $info .= &mt('Access to this file by others can be set to be one or more of the following types: public, passphrase-protected or conditional.').'<br /><ul><li>'.&mt('Public files are available to anyone without the need for login.').'</li><li>'.&mt('Passphrase-protected files do not require log-in, but will require the viewer to enter the passphrase you set.').'</li><li>'.&mt('Conditional files are accessible to logged-in users with accounts in the LON-CAPA network, who satisfy the conditions you set.').'<br />'.&mt('The conditions can include affiliation with a particular course or group, or a user account in a specific domain.').'<br />'.&mt('Alternatively access can be granted to people with specific LON-CAPA usernames and domains.').'</li></ul>';
+    if ($can_setacl) {
+        &open_form($r,$url);
+        $r->print($header.$info);
+        &access_setting_table($r,$access_controls{$file_name});
+        my $button_text = {
                         'continue' => &mt('Proceed'),
                         'cancel' => &mt('Back to directory listing'),
                       };
-    &close_form($r,$url,$group,$button_text);
+        &close_form($r,$url,$group,$button_text);
+    } else {
+        $r->print($header);
+        if ($aclcount) {  
+            $r->print($info);
+        }
+        &view_access_settings($r,$url,$group,$access_controls{$file_name},
+                              $aclcount);
+    }
+}
+
+sub view_access_settings {
+    my ($r,$url,$group,$access_controls,$aclcount) = @_;
+    my ($showstart,$showend);
+    my %todisplay;
+    foreach my $key (sort(keys(%{$access_controls}))) {
+        my ($num,$scope,$end,$start) = &unpack_acc_key($key);
+        $todisplay{$scope}{$key} = $$access_controls{$key};
+    }
+    if ($aclcount) {
+        $r->print(&mt('<h4>Current access controls defined for this file:</h4>'));
+        $r->print(&Apache::loncommon::start_data_table());
+        $r->print(&Apache::loncommon::start_data_table_header_row());
+        $r->print('<th>'.&mt('Access control').'</th><th>'.&mt('Dates available').
+                  '</th><th>'.&mt('Additional information').'</th>');
+        $r->print(&Apache::loncommon::end_data_table_header_row());
+        my $count = 1;
+        my $chg = 'none';
+        &build_access_summary($r,$count,$chg,%todisplay);
+        $r->print(&Apache::loncommon::end_data_table());
+    } else {
+        $r->print(&mt('No access control settings currently exist for this file.<br />' ));
+    }
+    my $group_arg;
+    if ($group) {
+        $group_arg = '&amp;group='.$group;
+    }
+    $r->print('<br /><a href="'.$url.'?currentpath='.$env{'form.currentpath'}.
+              $group_arg.'">'.&mt('Return to directory listing').'</a>');
+    return;
 }
 
+sub build_access_summary {
+    my ($r,$count,$chg,%todisplay) = @_; 
+    my ($showstart,$showend);
+    my %scope_desc = (
+                      public => 'Public',
+                      guest => 'Passphrase-protected',
+                      domains => 'Conditional: domain-based',
+                      users => 'Conditional: user-based',
+                      course => 'Conditional: course-based',
+                      group => 'Conditional: group-based',
+                     );
+    my @allscopes = ('public','guest','domains','users','course','group');
+    foreach my $scope (@allscopes) {
+        if ((!(exists($todisplay{$scope}))) || (ref($todisplay{$scope}) ne 'HASH')) {
+            next;
+        }
+        foreach my $key (sort(keys(%{$todisplay{$scope}}))) {
+            if ($count) {
+                $r->print(&Apache::loncommon::start_data_table_row());
+            }
+            my ($num,$scope,$end,$start) = &unpack_acc_key($key);
+            my $content = $todisplay{$scope}{$key};
+            if ($chg eq 'delete') {
+                $showstart = &mt('Deleted');
+                $showend = $showstart;
+            } else {
+                $showstart = localtime($start);
+                if ($end == 0) {
+                    $showend = &mt('No end date');
+                } else {
+                    $showend = localtime($end);
+                }
+            }
+            $r->print('<td>'.&mt($scope_desc{$scope}));
+            if (($scope eq 'course') || ($scope eq 'group')) {
+                if ($chg ne 'delete') {
+                    my $cid = $content->{'domain'}.'_'.$content->{'number'};
+                    my %course_description = &Apache::lonnet::coursedescription($cid);
+                    $r->print('<br />('.$course_description{'description'}.')');
+                }
+            }
+            $r->print('</td><td>'.&mt('Start: ').$showstart.
+                  '<br />'.&mt('End: ').$showend.'</td><td>');
+            if ($chg ne 'delete') {
+                if ($scope eq 'guest') {
+                    $r->print(&mt('Passphrase').': '.$content->{'password'});
+                } elsif ($scope eq 'course' || $scope eq 'group') {
+                    $r->print('<table><tr>');
+                    $r->print('<th>'.&mt('Roles').'</th><th>'.
+                          &mt('Access').'</th><th>'.
+                                          &mt('Sections').'</th>');
+                    if ($scope eq 'course') {
+                        $r->print('<th>'.&mt('Groups').'</th>');
+                    } else {
+                        $r->print('<th>'.&mt('Teams').'</th>');
+                    }
+                    $r->print('</tr>');
+                    foreach my $id (sort(keys(%{$content->{'roles'}}))) {
+                        $r->print('<tr>');
+                        foreach my $item ('role','access','section','group') {
+                            $r->print('<td>');
+                            if ($item eq 'role') {
+                                my $ucscope = $scope;
+                                $ucscope =~ s/^(\w)/uc($1)/e;
+                                my $role_output;
+                                foreach my $role (@{$content->{'roles'}{$id}{$item}}) {
+                                    if ($role eq 'all') {
+                                        $role_output .= $role.',';
+                                    } elsif ($role =~ /^cr/) {
+                                        $role_output .= (split('/',$role))[3].',';
+                                    } else {
+                                        $role_output .= &Apache::lonnet::plaintext($role,$ucscope).',';
+                                    }
+                                }
+                                $role_output =~ s/,$//;
+                                $r->print($role_output);
+                            } else {
+                                $r->print(join(',',@{$content->{'roles'}{$id}{$item}}));
+                            }
+                            $r->print('</td>');
+                        }
+                    }
+                    $r->print(&Apache::loncommon::end_data_table_row());
+                    $r->print(&Apache::loncommon::end_data_table());
+                } elsif ($scope eq 'domains') {
+                    $r->print(&mt('Domains: ').join(',',@{$content->{'dom'}}));
+                } elsif ($scope eq 'users') {
+                    my $curr_user_list = &sort_users($content->{'users'});
+                    $r->print(&mt('Users: ').$curr_user_list);
+                } else {
+                    $r->print('&nbsp;');
+                }
+            } else {
+                $r->print('&nbsp;');
+            }
+            $r->print('</td>');
+            $r->print(&Apache::loncommon::end_data_table_row());
+            $count ++;
+        }
+    }
+}
+
+
 sub update_access {
     my ($r,$url,$group) = @_;
     my $totalprocessed = 0;
@@ -577,93 +746,16 @@
                     $r->print('<td rowspan="'.$numchgs.'">'.&mt($title{$chg}).
                               '.</td>');
                     my $count = 0;
+                    my %todisplay;
                     foreach my $key (sort(keys(%{$$changes{$chg}}))) {
-                        if ($count) {
-                            $r->print(&Apache::loncommon::start_data_table_row());
-                        }
-                        my ($num,$scope,$end,$start) = &unpack_acc_key($key); 
+                        my ($num,$scope,$end,$start) = &unpack_acc_key($key);
                         my $newkey = $key;
                         if ($chg eq 'activate') {
                             $newkey =~ s/^(\d+)/$$translation{$1}/;
                         }
-                        my $content = $$updated_controls{$newkey};
-                        if ($chg eq 'delete') {
-                            $showstart = &mt('Deleted');
-                            $showend = $showstart;
-                        } else {
-                            $showstart = localtime($start);
-                            if ($end == 0) {
-                                $showend = &mt('No end date');
-                            } else {
-                                $showend = localtime($end);
-                            }
-                        }
-                        $r->print('<td>'.&mt($scope));
-                        if (($scope eq 'course') || ($scope eq 'group')) {
-                            if ($chg ne 'delete') {
-                                my $cid = $content->{'domain'}.'_'.$content->{'number'};
-                                my %course_description = &Apache::lonnet::coursedescription($cid);
-                                $r->print('<br />('.$course_description{'description'}.')');
-                            }
-                        }  
-                        $r->print('</td><td>'.&mt('Start: ').$showstart.
-                                  '<br />'.&mt('End: ').$showend.'</td><td>');
-                        if ($chg ne 'delete') {
-                            if ($scope eq 'guest') {
-                                $r->print(&mt('Password').': '.$content->{'password'});
-                            } elsif ($scope eq 'course' || $scope eq 'group') {
-                                $r->print('<table><tr>');
-                                $r->print('<th>'.&mt('Roles').'</th><th>'.
-                                          &mt('Access').'</th><th>'.
-                                          &mt('Sections').'</th>');
-                                if ($scope eq 'course') {
-                                    $r->print('<th>'.&mt('Groups').'</th>');
-                                } else {
-                                    $r->print('<th>'.&mt('Teams').'</th>');
-                                }
-                                $r->print('</tr>');
-                                foreach my $id (sort(keys(%{$content->{'roles'}}))) {
-                                    $r->print('<tr>');
-                                    foreach my $item ('role','access','section','group') {
-                                        $r->print('<td>');
-                                        if ($item eq 'role') {
-                                            my $ucscope = $scope;
-                                            $ucscope =~ s/^(\w)/uc($1)/;
-                                            my $role_output;  
-                                            foreach my $role (@{$content->{'roles'}{$id}{$item}}) {
-                                                if ($role eq 'all') {
-                                                    $role_output .= $role.',';
-                                                } elsif ($role =~ /^cr/) {
-                                                    $role_output .= (split('/',$role))[3].',';
-                                                } else {
-                                                    $role_output .= &Apache::lonnet::plaintext($role,$ucscope).',';
-                                                }
-                                            }
-                                            $role_output =~ s/,$//;
-                                            $r->print($role_output);  
-                                        } else {
-                                            $r->print(join(',',@{$content->{'roles'}{$id}{$item}}));
-                                        }
-                                        $r->print('</td>');
-                                    }
-                                }
-                                $r->print(&Apache::loncommon::end_data_table_row());
-                                $r->print(&Apache::loncommon::end_data_table());
-                            } elsif ($scope eq 'domains') {
-                                $r->print(&mt('Domains: ').join(',',@{$content->{'dom'}}));
-                            } elsif ($scope eq 'users') {
-                                my $curr_user_list = &sort_users($content->{'users'});
-                                $r->print(&mt('Users: ').$curr_user_list);
-                            } else {
-                                $r->print('&nbsp;');
-                            }
-                        } else {
-                            $r->print('&nbsp;');
-                        }
-                        $r->print('</td>');
-                        $r->print(&Apache::loncommon::end_data_table_row());
-                        $count ++;
+                        $todisplay{$scope}{$newkey} = $$updated_controls{$newkey};
                     }
+                    &build_access_summary($r,$count,$chg,%todisplay);  
                 }
             }
             $r->print(&Apache::loncommon::end_data_table());
@@ -705,8 +797,12 @@
         }
         &close_form($r,$url,$group);
     } else {
+        my $group_arg;
+        if ($group) {
+            $group_arg = '&amp;group='.$group;
+        }
         $r->print('<br /><a href="'.$url.'?access='.$env{'form.selectfile'}.
-                  '&amp;currentpath='.$env{'form.currentpath'}.'">'.
+                  '&amp;currentpath='.$env{'form.currentpath'}.$group_arg.'">'.
                    &mt('Display all access settings for this file').'</a>');
     }
     return;
@@ -857,11 +953,11 @@
     $r->print(&Apache::loncommon::end_data_table_row());
     $r->print(&Apache::loncommon::end_data_table());
     $r->print('</td><td width="40">&nbsp;</td><td valign="top">');
-    $r->print('<h3>'.&mt('Password-protected access:').' '.$guesttext.'</h3>');
+    $r->print('<h3>'.&mt('Passphrase-protected access:').' '.$guesttext.'</h3>');
     $r->print(&Apache::loncommon::start_data_table());
     $r->print(&Apache::loncommon::start_data_table_header_row());
     $r->print('<th>'.&mt('Action').'</th><th>'.&mt('Dates available').
-              '</th><th>'. &mt('Password').'</th>');
+              '</th><th>'. &mt('Passphrase').'</th>');
     $r->print(&Apache::loncommon::end_data_table_header_row());
     $r->print(&Apache::loncommon::start_data_table_row());
     my $passwd;
@@ -1032,6 +1128,8 @@
     if ($type eq 'group') {
         $crsgrptext = 'Teams';
     }
+    my $uctype = $type;
+    $uctype =~ s/^(\w)/uc($1)/e;
     my ($num,$scope,$end,$start) = &set_identifiers($status,$item,$now,$then,
                                                     $type);
     $r->print('<td>'.$js.&actionbox($status,$num,$scope).'</td>');
@@ -1040,8 +1138,6 @@
         my %course_description = &Apache::lonnet::coursedescription($cid);
         $r->print('<td><input type="hidden" name="crsdom_'.$num.'" value="'.$content->{'domain'}.'" /><input type="hidden" name="crsnum_'.$num.'" value="'.$content->{'number'}.'" />'.$course_description{'description'}.'</td>');
     } elsif ($status eq 'new') {
-        my $uctype = $type;
-        $uctype =~ s/^(\w)/uc($1)/e;
         $r->print('<td>'.&Apache::loncommon::selectcourse_link('portform','crsnum_'.$num,'crsdom_'.$num,'description_'.$num,undef,undef,$uctype).'&nbsp;&nbsp;<input type="text" name="description_'.$num.'" size="30" /><input type="hidden" name="crsdom_'.$num.'" /><input type="hidden" name="crsnum_'.$num.'" /></td>');
     }
     $r->print('<td>'.&dateboxes($num,$start,$end).'</td>');
@@ -1059,7 +1155,7 @@
             my $role_selects = &role_selectors($num,$role_id,$status,$type,$content,'display');
             $r->print('<tr><td><span style="white-space: nowrap"><label><input type="checkbox" name="delete_role_'.$num.'" value="'.$role_id.'" />'.&mt('Delete').'</label></span><br /><input type="hidden" name="preserve_role_'.$num.'" value="'.$role_id.'" /></td>'.$role_selects.'</tr>');
         }
-        $r->print('</table><br />'.&mt('Add a roles-based condition').'&nbsp;<input type="checkbox" name ="add_role_'.$num.'" onClick="javascript:setRoleOptions(this,'."'$num','$content->{'domain'}','$content->{'number'}','Course'".')" value="'.$max_id.'" /><input type="hidden" name="role_'.$num.'_'.$max_id.'" /><input type="hidden" name="access_'.$num.'_'.$max_id.'" /><input type="hidden" name="section_'.$num.'_'.$max_id.'" /><input type="hidden" name="group_'.$num.'_'.$max_id.'" /></td>');
+        $r->print('</table><br />'.&mt('Add a roles-based condition').'&nbsp;<input type="checkbox" name ="add_role_'.$num.'" onClick="javascript:setRoleOptions(this,'."'$num','$content->{'domain'}','$content->{'number'}','$uctype'".')" value="'.$max_id.'" /><input type="hidden" name="role_'.$num.'_'.$max_id.'" /><input type="hidden" name="access_'.$num.'_'.$max_id.'" /><input type="hidden" name="section_'.$num.'_'.$max_id.'" /><input type="hidden" name="group_'.$num.'_'.$max_id.'" /></td>');
     } elsif ($status eq 'new') {
         my $role_id = 1;
         my $role_selects = &role_selectors($num,$role_id,$status,$type,undef,'display');
@@ -1185,8 +1281,10 @@
          $cdom = $env{'form.cdom'};
          $cnum = $env{'form.cnum'};
     }
+    my $uctype = $type;
+    $uctype =~ s/^(\w)/uc($1)/e;
     my ($sections,$groups,$allroles,$rolehash,$accesshash) =
-            &Apache::loncommon::get_secgrprole_info($cdom,$cnum,1,$type);
+            &Apache::loncommon::get_secgrprole_info($cdom,$cnum,1,$uctype);
     if (!@{$sections}) {
         @{$sections} = ('none');
     } else {
@@ -1244,6 +1342,10 @@
     my $cnum = $env{'form.cnum'};
     my $type = $env{'form.type'};
     my $addindex = $env{'form.setroles'};
+    my $grouptitle = 'Groups';
+    if ($type eq 'Group') {
+         $grouptitle = 'Teams';
+    } 
     my $role_selects = &role_selectors(1,1,'new',$type,undef,'rolepicker');
     $r->print(<<"END_SCRIPT");
 <script type="text/javascript">
@@ -1264,7 +1366,7 @@
 </script>
 END_SCRIPT
     $r->print(&mt('Select roles, course status, section(s) and group(s) for users who will be able to access the portfolio file.'));
-    $r->print('<form name="rolepicker" action="/adm/portfolio" method="post"><table><tr><th>'.&mt('Roles').'</th><th>'.&mt('[_1] status',$type).'</th><th>'.&mt('Sections').'</th><th>'.&mt('Groups').'</th></tr><tr>'.$role_selects.'</tr></table><br /><input type="button" name="rolepickbutton" value="Save selections" onclick="setRoles()" />');
+    $r->print('<form name="rolepicker" action="/adm/portfolio" method="post"><table><tr><th>'.&mt('Roles').'</th><th>'.&mt('[_1] status',$type).'</th><th>'.&mt('Sections').'</th><th>'.&mt($grouptitle).'</th></tr><tr>'.$role_selects.'</tr></table><br /><input type="button" name="rolepickbutton" value="Save selections" onclick="setRoles()" />');
     return;
 }
 
@@ -1478,7 +1580,7 @@
 sub prepend_group {
     my ($filename,$group) = @_;
     if (defined($group)) {
-        $filename = $group.'/'.$filename;
+        $filename = $group.$filename;
     }
     return $filename;
 }
@@ -1504,6 +1606,37 @@
     return $port_path;
 }
 
+sub missing_priv {
+    my ($r,$url,$priv,$group) = @_;
+    my $longtext = {
+                      upload => 'upload files',
+                      delete => 'delete files',
+                      rename => 'rename files',
+                      setacl => 'set access controls for files',
+                   };
+    my $escpath = &HTML::Entities::encode($env{'form.currentpath'},'&<>"');
+    my $rtnlink = '<a href="'.$url;
+    if ($url =~ /\?/) {
+        $rtnlink .= '&';
+    } else {
+        $rtnlink .= '?';
+    }
+    $rtnlink .= 'currentpath='.$escpath;
+    $r->print(&mt('<h3>Action disallowed</h3>'));
+    $r->print(&mt('You do not have sufficient privileges to [_1] ',
+                  $longtext->{$priv}));
+    if ($group) {
+        $r->print(&mt("in the group's file repository."));
+        $rtnlink .= '&group='.$group;
+    } else {
+        $r->print(&mt('in this portfolio.'));
+    }
+    $rtnlink .= '">'.&mt('Return to directory listing page').'</a>';
+    $r->print('<br />'.$rtnlink);
+    $r->print(&Apache::loncommon::end_page());
+    return;
+}
+
 sub handler {
     # this handles file management
     my $r = shift;
@@ -1516,6 +1649,7 @@
         $url = $1.$2;
         $caller = $2;
     }
+    my ($can_modify,$can_delete,$can_upload,$can_setacl);
     if ($caller eq 'coursegrp_portfolio') {
     #  Needs to be in a course
         if (! ($env{'request.course.fn'})) {
@@ -1551,10 +1685,26 @@
             $earlyout = 1;
         }
         if ($earlyout) { return OK; }
+        if (&Apache::lonnet::allowed('agf',$env{'request.course.id'}.'/'.$group)) {
+            $can_setacl = 1;
+        }
+        if (&Apache::lonnet::allowed('ugf',$env{'request.course.id'}.'/'.$group)) {
+            $can_upload = 1;
+        }
+        if (&Apache::lonnet::allowed('mgf',$env{'request.course.id'}.'/'.$group)) {
+            $can_modify = 1;
+        }
+        if (&Apache::lonnet::allowed('dgf',$env{'request.course.id'}.'/'.$group)) {
+            $can_delete = 1;
+        }
     } else {
         ($uname,$udom) = &get_name_dom();
         $portfolio_root = &get_portfolio_root();
         $title = &mt('Portfolio Manager');
+        $can_modify = 1;
+        $can_delete = 1;
+        $can_upload = 1;
+        $can_setacl = 1;
     }
 
     &Apache::loncommon::no_cache($r);
@@ -1588,31 +1738,71 @@
     }
 
     if ($env{'form.uploaddoc.filename'}) {
-	&upload($r,$url,$group);
+        if ($can_upload) {
+	    &upload($r,$url,$group);
+        } else {
+            &missing_priv($r,$url,'upload',$group),
+        }
     } elsif ($env{'form.action'} eq 'delete' && $env{'form.confirmed'}) {
-	&delete_confirmed($r,$url,$group);
+        if ($can_delete) {
+	    &delete_confirmed($r,$url,$group);
+        } else {
+            &missing_priv($r,$url,'delete',$group);
+        }
     } elsif ($env{'form.action'} eq 'delete') {
-	&delete($r,$url,$group);
+        if ($can_delete) {
+	    &delete($r,$url,$group);
+        } else {
+            &missing_priv($r,$url,'delete',$group);
+        }
     } elsif ($env{'form.action'} eq 'deletedir' && $env{'form.confirmed'}) {
-	&delete_dir_confirmed($r,$url,$group);
-    } elsif ($env{'form.action'} eq 'deletedir'){
-	&delete_dir($r,$url,$group);
+        if ($can_delete) {
+	    &delete_dir_confirmed($r,$url,$group);
+        } else {
+            &missing_priv($r,$url,'delete',$group);
+        }
+    } elsif ($env{'form.action'} eq 'deletedir') {
+        if ($can_delete) {
+	    &delete_dir($r,$url,$group);
+        } else {
+            &missing_priv($r,$url,'delete',$group);
+        }
     } elsif ($env{'form.action'} eq 'rename' && $env{'form.confirmed'}) {
-	&rename_confirmed($r,$url,$group);
+        if ($can_modify) {
+	    &rename_confirmed($r,$url,$group);
+        } else {
+            &missing_priv($r,$url,'rename',$group);
+        }
     } elsif ($env{'form.rename'}) {
         $env{'form.selectfile'} = $env{'form.rename'};
         $env{'form.action'} = 'rename';
-	&rename($r,$url,$group);
+        if ($can_modify) {
+	    &rename($r,$url,$group);
+        } else {
+            &missing_priv($r,$url,'rename',$group);
+        }
     } elsif ($env{'form.access'}) {
         $env{'form.selectfile'} = $env{'form.access'};
         $env{'form.action'} = 'chgaccess';
-        &display_access($r,$url,$group);
+        &display_access($r,$url,$group,$can_setacl);
     } elsif ($env{'form.action'} eq 'chgaccess') {
-        &update_access($r,$url,$group);
+        if ($can_setacl) {
+            &update_access($r,$url,$group);
+        } else {
+            &missing_priv($r,$url,'setacl',$group);
+        }
     } elsif ($env{'form.action'} eq 'rolepicker') {
-        &role_options_window($r);
+        if ($can_setacl) { 
+            &role_options_window($r);
+        } else {
+            &missing_priv($r,$url,'setacl',$group);
+        }
     } elsif ($env{'form.createdir'}) {
-	&createdir($r,$url,$group);
+        if ($can_upload) {
+	    &createdir($r,$url,$group);
+        } else {
+            &missing_priv($r,$url,'upload',$group);
+        }
     } elsif ($env{'form.lockinfo'}) {
         &lock_info($r,$url,$group);
     } else {
@@ -1641,11 +1831,14 @@
         }
 	# need to know if directory is empty so it can be removed if desired
 	my $is_empty=(@dir_list == 2);
-	&display_common($r,$url,$current_path,$is_empty,\@dir_list,$group);
-        &display_directory($r,$url,$current_path,$is_empty,\@dir_list,$group);
+	&display_common($r,$url,$current_path,$is_empty,\@dir_list,$group,
+                        $can_upload);
+        &display_directory($r,$url,$current_path,$is_empty,\@dir_list,$group,
+                           $can_upload,$can_modify,$can_delete,$can_setacl);
 	$r->print(&Apache::loncommon::end_page());
     }
     return OK;
 }
+
 1;
 __END__

--raeburn1151093727--