--- loncom/interface/loncoursequeueadmin.pm 2023/09/04 17:10:13 1.52.2.5.2.3 +++ loncom/interface/loncoursequeueadmin.pm 2022/11/23 02:55:37 1.63 @@ -1,7 +1,7 @@ # The LearningOnline Network # Utilities to administer domain course requests and course self-enroll requests # -# $Id: loncoursequeueadmin.pm,v 1.52.2.5.2.3 2023/09/04 17:10:13 raeburn Exp $ +# $Id: loncoursequeueadmin.pm,v 1.63 2022/11/23 02:55:37 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -144,7 +144,6 @@ sub send_selfserve_notification { push(@rawmsg,{ mt => $msgtxt, args => ["\n ".$contextdesc.",\n",$timestamp.",\n"], - }); if (ref($textstr) eq 'ARRAY') { push(@rawmsg,@{$textstr}); @@ -270,6 +269,32 @@ sub send_selfserve_notification { if (ref($textstr) eq 'ARRAY') { push(@rawmsg,@{$textstr}); } + } elsif ($context eq 'othdomroleuser') { + my $linktext = 'Roles'; + if (&Apache::loncommon::show_course()) { + $linktext = 'Courses'; + } + $rawsubj = 'Role Assignment Approval'; + push(@rawmsg,{ + mt => 'A domain different to your own LON-CAPA domain ([_1]) wants to assign you a role in their domain.', + args => ["\n$contextdesc\n"], + }, + { + mt =>"[_1]Click $linktext at top right, then click 'Manage Role Requests' in the gray Functions bar ". + "to display a list of pending role assignments in other domain(s), which you can either accept or reject.", + args => ["\n\n"], + }); + } elsif ($context eq 'othdomroledc') { + $rawsubj = 'Role Assignment Authorization'; + push(@rawmsg,{ + mt => 'Another LON-CAPA domain wants to assign a role in their domain to a user from your domain.', + args => [], + }, + { + mt =>'[_1]As Domain Coordinator, use: [_2]Main Menu -> Create users or modify the roles and privileges of users + -> Queued Role Assignments (this domain) [_3]to display a list of pending requests, which you can either approve or reject.', + args => ["\n","\n\n ","\n\n"], + }); } my @to_notify = split(/,/,$notifylist); my $numsent = 0; @@ -371,7 +396,7 @@ sub send_selfserve_notification { } sub display_queued_requests { - my ($context,$dom,$cnum) = @_; + my ($context,$dom,$cnum,$secondary) = @_; my ($namespace,$formaction,$nextelement,%requesthash); if ($context eq 'course') { $formaction = '/adm/createuser'; @@ -388,6 +413,34 @@ sub display_queued_requests { $namespace = 'usernamequeue'; %requesthash = &Apache::lonnet::dump_dom($namespace,$dom); $nextelement = ''; + } elsif ($context eq 'othdomqueue') { + $formaction = '/adm/createuser'; + $namespace = 'othdomqueued'; + if ($secondary eq 'domain') { + %requesthash = &Apache::lonnet::dump_dom($namespace,$dom); + foreach my $key (keys(%requesthash)) { + delete($requesthash{$key}) if ($key =~ /:(ca|aa)$/); + } + } elsif ($secondary eq 'author') { + %requesthash = &Apache::lonnet::dump($namespace,$dom,$cnum); + if ($cnum eq &Apache::lonnet::get_domainconfiguser($dom)) { + foreach my $key (keys(%requesthash)) { + delete($requesthash{$key}) if ($key !~ /:(ca|aa)$/); + } + } + } else { + %requesthash = &Apache::lonnet::dump($namespace,$dom,$cnum); + } + } elsif ($context eq 'othdomaction') { + $formaction = '/adm/createuser'; + $namespace = 'queuedrolereqs'; + if ($secondary eq 'domain') { + my $confname = &Apache::lonnet::get_domainconfiguser($dom); + %requesthash = &Apache::lonnet::dump($namespace,$dom,$confname); + } else { + %requesthash = &Apache::lonnet::dump($namespace,$dom,$cnum); + } + $nextelement = ''; } else { $formaction = '/adm/createcourse'; $namespace = 'courserequestqueue'; @@ -418,9 +471,23 @@ sub display_queued_requests { } elsif ($context eq 'requestusername') { $timestamp = $requesthash{$item}; ($entry) = (&unescape($item) =~ /^($match_username)_approval$/); + } elsif ($context eq 'othdomqueue') { + if (ref($requesthash{$item}) eq 'HASH') { + my ($puname,$pudom,$prole,$psec) = split(/:/,$item); + $timestamp = $requesthash{$item}{'timestamp'}; + my $adj = $requesthash{$item}{'adj'}; + $entry = join(':',$puname,$pudom,$prole,$adj, + &escape($requesthash{$item}{'requester'}), + $psec); + } + } elsif ($context eq 'othdomaction') { + if (ref($requesthash{$item}) eq 'HASH') { + $timestamp = $requesthash{$item}{'timestamp'}; + $entry = &escape($item).':'.&escape($requesthash{$item}{'requester'}); + } } else { - $timestamp = $requesthash{$item}{'timestamp'}; if (ref($requesthash{$item}) eq 'HASH') { + $timestamp = $requesthash{$item}{'timestamp'}; my ($cnum,$disposition) = split('_',$item); $entry = $cnum.':'.$requesthash{$item}{'ownername'}.':'. $requesthash{$item}{'ownerdom'}.':'; @@ -453,10 +520,26 @@ sub display_queued_requests { $output .= '

'.&mt('Requests for Authoring Space queued pending approval by a Domain Coordinator').'

'; } elsif ($context eq 'requestusername') { $output .= '

'.&mt('Requests for LON-CAPA accounts queued pending approval by a Domain Coordinator').'

'; + } elsif ($context eq 'othdomqueue') { + if ($secondary eq 'domain') { + $output .= '

'.&mt('Domain role assignments for users from another domain, queued pending approval').'

'; + } elsif ($secondary eq 'author') { + $output .= '

'.&mt('Co-author role assignments for users from another domain, queued pending approval').'

'; + } elsif ($secondary eq 'course') { + $output .= '

'.&mt('Course role assignments for users from another domain, queued pending approval').'

'; + } elsif ($secondary eq 'community') { + $output .= '

'.&mt('Community role assignments for users from another domain, queued pending approval').'

'; + } + } elsif ($context eq 'othdomaction') { + if ($secondary eq 'user') { + $output .= '

'.&mt('Role assignments for you in other domains, queued pending your acceptance of the role.').'

'; + } elsif ($secondary eq 'domain') { + $output .= '

'.&mt('Role assignments in other domains, queued pending domain coordinator approval in this domain.').'

'; + } } else { $output .= '

'.&mt('Course/Community requests queued pending approval by a Domain Coordinator').'

'; } - $output .= &build_queue_display($dom,$context,\%queue_by_date). + $output .= &build_queue_display($dom,$context,\%queue_by_date,$secondary). ''; } else { $output .= '
'; @@ -470,15 +553,31 @@ sub display_queued_requests { $output .= &mt('There are currently no requests for LON-CAPA accounts awaiting approval.'); } elsif ($context eq 'domain') { $output .= &mt('There are currently no course or community requests awaiting approval.'); + } elsif ($context eq 'othdomqueue') { + if ($secondary eq 'domain') { + $output .= &mt('There are currently no domain role assignment(s) for user(s) from another domain queued pending approval'); + } elsif ($secondary eq 'author') { + $output .= &mt('There are currently no co-author role assignment(s) for user(s) from another domain queued pending approval'); + } elsif ($secondary eq 'course') { + $output .= &mt('There are currently no course role assignment(s) for user(s) from another domain queued pending approval'); + } elsif ($secondary eq 'community') { + $output .= &mt('There are currently no community role assignment(s) for user(s) from another domain queued pending approval'); + } + } elsif ($context eq 'othdomaction') { + if ($secondary eq 'user') { + $output .= &mt('There are currently no pending role assignments for you in other domains, queued pending your acceptance of the role.'); + } elsif ($secondary eq 'domain') { + $output .= &mt('There are currently no pending role assignments in other domains, queued pending domain coordinator approval in this domain.'); + } } - $output .= '
'; + $output .= ''; } if ($context eq 'pending') { $output .= '

'."\n". '

'.&mt('Any course/community requests which are successfully validated will be created immediately.').' '. &mt('Unvalidated requests will be listed for manual approval/rejection.').'

'; - } elsif (($context ne 'helpdesk') && ($context ne 'displaypending')) { + } elsif (($context ne 'helpdesk') && ($context ne 'displaypending') && ($context ne 'othdomqueue')) { $output .= '
'; } $output .= ''; @@ -492,6 +591,22 @@ sub display_queued_requests { $output .= &mt('There are currently no requests for Authoring Space awaiting approval.'); } elsif ($context eq 'requestusername') { $output .= &mt('There are currently no requests for LON-CAPA accounts awaiting approval.'); + } elsif ($context eq 'othdomqueue') { + if ($secondary eq 'domain') { + $output .= &mt('There are currently no domain role assignment(s) for user(s) from another domain queued pending approval'); + } elsif ($secondary eq 'author') { + $output .= &mt('There are currently no co-author role assignment(s) for user(s) from another domain queued pending approval'); + } elsif ($secondary eq 'course') { + $output .= &mt('There are currently no course role assignment(s) for user(s) from another domain queued pending approval'); + } elsif ($secondary eq 'community') { + $output .= &mt('There are currently no community role assignment(s) for user(s) from another domain queued pending approval'); + } + } elsif ($context eq 'othdomaction') { + if ($secondary eq 'user') { + $output .= &mt('There are currently no pending role assignments for you in other domains, queued pending your acceptance of the role.'); + } elsif ($secondary eq 'domain') { + $output .= &mt('There are currently no pending role assignments in other domains, queued pending domain coordinator approval in this domain.'); + } } else { $output .= &mt('There are currently no course or community requests awaiting approval.'); } @@ -501,15 +616,18 @@ sub display_queued_requests { } sub build_queue_display { - my ($dom,$context,$queue) = @_; + my ($dom,$context,$queue,$secondary) = @_; return unless (ref($queue) eq 'HASH'); - my %crstypes; - my $output = &Apache::loncommon::start_data_table(). - &Apache::loncommon::start_data_table_header_row(); - unless (($context eq 'pending') || ($context eq 'displaypending') || ($context eq 'helpdesk')) { + my (%crstypes,%roles_by_context); + my $output = &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(); + unless (($context eq 'pending') || ($context eq 'displaypending') || + ($context eq 'helpdesk') || ($context eq 'othdomqueue')) { $output .= ''.&mt('Action').''; } - $output .= ''.&mt('Requestor').''; + unless (($context eq 'othdomqueue') || (($context eq 'othdomaction') && ($secondary eq 'user'))) { + $output .= ''.&mt('Requestor').''; + } if ($context eq 'course') { $output .= ''.&mt('Section').''. ''.&mt('Date requested').''; @@ -518,6 +636,25 @@ sub build_queue_display { } elsif ($context eq 'requestusername') { $output .= ''.&mt('Date requested').''. ''.&mt('Details').''; + } elsif ($context eq 'othdomqueue') { + $output .= ''.&mt('Date requested').''. + ''.&mt('Role').''; + if ($secondary eq 'course') { + $output .= ''.&mt('Section').''; + } + $output .= ''.&mt('Requested for').''. + ''.&mt('Approval needed from').''; + } elsif ($context eq 'othdomaction') { + $output .= ''.&mt('Date requested').''. + ''.&mt('Role type').''. + ''.&mt('Location').''; + if ($secondary eq 'domain') { + $output .= ''.&mt('Affected User').''; + } + foreach my $type ('domain','course') { + my @possroles = &Apache::lonuserutils::roles_by_context($type); + $roles_by_context{$type} = \@possroles; + } } elsif ($context eq 'pending' || $context eq 'displaypending' || $context eq 'stillpending') { $output .= ''.&mt('Institutional code').''. ''.&mt('Date requested').''. @@ -528,6 +665,7 @@ sub build_queue_display { unofficial => 'Unofficial course', community => 'Community', textbook => 'Textbook course', + placement => 'Placement test', ); $output .= ''.&mt('Type').''. ''.&mt('Date requested').''. @@ -540,7 +678,8 @@ sub build_queue_display { if (ref($queue->{$item}) eq 'ARRAY') { foreach my $request (sort(@{$queue->{$item}})) { my ($row,$approve,$reject,$showtime,$showsec,$namelink, - $detailslink,$crstype,$instcode); + $detailslink,$crstype,$instcode,$showrole,$adjudicator, + $location,$showrequester); $showtime = &Apache::lonlocal::locallocaltime($item); if ($context eq 'course') { my ($puname,$pudom,$pusec) = split(/:/,$request); @@ -556,7 +695,7 @@ sub build_queue_display { } elsif ($context eq 'requestauthor') { if (&Apache::lonnet::homeserver($request,$dom) ne 'no_host') { $approve = $count.':'.$request; - $reject = $request; + $reject = $request; $namelink = &Apache::loncommon::aboutmewrapper( &Apache::loncommon::plainname($request,$dom), $request,$dom); @@ -570,6 +709,102 @@ sub build_queue_display { "'$dom','$request','$queued'".');">'.$request.''; $namelink = $request; } + } elsif ($context eq 'othdomqueue') { + my ($uname,$udom,$role,$adj,$requester,$sec) = split(/:/,$request); + if ($adj eq 'user') { + $adjudicator = &mt('Role Assignee'); + } elsif ($adj eq 'domain') { + $adjudicator = &mt("[_1] in user's domain", + &Apache::lonnet::plaintext('dc')); + } + my $crstype; + $showrole = &Apache::lonnet::plaintext($role,$crstype); + unless (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') { + $namelink = &Apache::loncommon::plainname($uname,$udom)." ($uname:$udom)"; + } + if ($secondary eq 'course') { + $showsec = $sec; + if ($showsec eq '') { + $showsec = &mt('none'); + } + } + } elsif ($context eq 'othdomaction') { + my ($extent,$role,$crstype); + my ($info,$requester) = map { &unescape($_); } split(/:/,$request); + if ($secondary eq 'user') { + ($extent,$role) = split(/:/,$info); + $approve = $count.':'.$extent.':'.$role; + $reject = $extent.':'.$role; + } elsif ($secondary eq 'domain') { + (my $uname,$extent,$role) = split(/:/,$info); + $approve = $count.':'.$extent.':'.$role.':'.$uname.':'.$dom; + $reject = $extent.':'.$role.':'.$uname.':'.$dom; + unless (&Apache::lonnet::homeserver($uname,$dom) eq 'no_host') { + $namelink = &Apache::loncommon::plainname($uname,$dom); + unless ($namelink eq $uname.':'.$dom) { + $namelink .= ' ('.$uname.':'.$dom.')'; + } + } + } + if (($role eq 'ca') || ($role eq 'aa')) { + my ($audom,$auname) = ($extent =~ m{^/($match_domain)/($match_username)$}); + $location = &mt('Author').': '.&Apache::loncommon::plainname($auname,$audom); + } elsif ($role eq 'co') { + my ($cdom,$cnum) = ($extent =~ m{^/($match_domain)/($match_courseid)}); + if (&Apache::lonnet::is_course($cdom,$cnum)) { + my %info = &Apache::lonnet::coursedescription("$cdom/$cnum",{'one_time' => 1}); + $crstype = $info{'type'}; + $location = &mt('Community').': '.$info{'description'}; + $showrole = &Apache::lonnet::plaintext($role,'Community'); + } + } elsif ($role =~ m{^cr/}) { + $showrole = &Apache::lonnet::plaintext($role,$crstype); + my ($cdom,$cnum,$csec) = ($extent =~ m{^/($match_domain)/($match_courseid)(?:|/(\w+))$}); + if (&Apache::lonnet::is_course($cdom,$cnum)) { + my %info = &Apache::lonnet::coursedescription("$cdom/$cnum",{'one_time' => 1}); + $crstype = $info{'type'}; + $location = &mt($crstype).': '.$info{'description'}; + if ($csec ne '') { + $location .= ' '.&mt('Section').': '.$csec; + } + } + } else { + foreach my $type ('course','domain') { + if (grep(/^\Q$role\E$/,@{$roles_by_context{$type}})) { + if ($type eq 'course') { + my ($cdom,$cnum,$csec) = ($extent =~ m{^/($match_domain)/($match_courseid)(?:|/(\w+))$}); + if (&Apache::lonnet::is_course($cdom,$cnum)) { + my %info = &Apache::lonnet::coursedescription("$cdom/$cnum",{'one_time' => 1}); + $crstype = $info{'type'}; + $location = &mt($crstype).': '.$info{'description'}; + if ($csec ne '') { + $location .= ' '.&mt('Section').': '.$csec; + } + } + } else { + my ($domain) = ($extent =~ m{^/($match_domain)/}); + $location = &mt('Domain').': '.&Apache::lonnet::domain($domain,'description'); + } + last; + } + } + } + if ($role =~ m{^cr/($match_domain)/($match_username)/(\w+)$}) { + my ($crudom,$cruname,$rolename) = ($1,$2,$3); + my $creator = &Apache::loncommon::plainname($cruname,$crudom); + unless ($creator eq $cruname.':'.$crudom) { + $creator .= ' ('.$cruname.':'.$crudom.')'; + } + $showrole = &mt('Custom role').': '.$rolename.'
'. + &mt('Created by').' '.$creator; + } else { + $showrole = &Apache::lonnet::plaintext($role,$crstype); + } + my ($requname,$requdom) = split(/:/,$requester); + $showrequester = &Apache::loncommon::plainname($requname,$requdom); + unless ($showrequester eq $requname.':'.$requdom) { + $showrequester .= ' ('.$requname.':'.$requdom.')'; + } } else { my ($cnum,$ownername,$ownerdom,$type,$cdesc); my $queued = 'approval'; @@ -591,7 +826,8 @@ sub build_queue_display { &Apache::loncommon::plainname($ownername,$ownerdom), $ownername,$ownerdom); } - unless (($context eq 'pending') || ($context eq 'displaypending') || ($context eq 'helpdesk')) { + unless (($context eq 'pending') || ($context eq 'displaypending') || + ($context eq 'helpdesk') || ($context eq 'othdomqueue')) { $row = ''. '
'; } - $row .= ''.$namelink.''."\n"; + unless (($context eq 'othdomqueue') || ($context eq 'othdomaction')) { + $row .= ''.$namelink.''."\n"; + } if ($context eq 'course') { $row .= ''.$showsec.''."\n". ''.$showtime.''."\n"; @@ -609,6 +847,24 @@ sub build_queue_display { } elsif ($context eq 'requestusername') { $row .= ''.$showtime.''."\n". ''.$detailslink.''."\n"; + } elsif ($context eq 'othdomqueue') { + $row .= ''.$showtime.''."\n". + ''.$showrole.''."\n"; + if ($secondary eq 'course') { + $row .= ''.$showsec.''."\n"; + } + $row .= ''.$namelink.''."\n". + ''.$adjudicator.''."\n"; + } elsif ($context eq 'othdomaction') { + if ($secondary eq 'domain') { + $row .= ''.$showrequester.''."\n"; + } + $row .= ''.$showtime.''."\n". + ''.$showrole.''."\n". + ''.$location.''."\n"; + if ($secondary eq 'domain') { + $row .= ''.$namelink.''."\n"; + } } else { if ($context eq 'pending' || $context eq 'displaypending' || $context eq 'stillpending') { $row .= ''.$instcode.''."\n"; @@ -638,7 +894,8 @@ sub update_request_queue { @processing_errors,@warn_approves,@warn_rejects,@approvals,@warn_dels, @rejections,@rejectionerrors,@nopermissions,%courseroles,@toremove, %communityroles,%domdefs,%approvalmsg,%rejectionmsg,$crstype,$queue, - $firsturl,$uniquecode,%codes); + $firsturl,$uniquecode,%codes,%roles_by_context,%requesteractive, + %gotroles); my $count=0; while (my $item = $env{'form.'.$count.'radioreq'}) { if ($item =~ /^\d+:/) { @@ -648,7 +905,6 @@ sub update_request_queue { } $count ++; } - $now = time; $sender = $env{'user.name'}.':'.$env{'user.domain'}; if ($context eq 'course') { @@ -722,6 +978,32 @@ sub update_request_queue { mt => 'Your request for a LON-CAPA account has not been approved.', }]; $domdesc = &Apache::lonnet::domain($cdom); + } elsif (($context eq 'othdombydc') || ($context eq 'othdombyuser')) { + $namespace = 'queuedrolereqs'; + $beneficiary = 'requester'; + foreach my $type ('domain','course') { + my @possroles = &Apache::lonuserutils::roles_by_context($type); + $roles_by_context{$type} = \@possroles; + } + if ($context eq 'othdombydc') { + my $confname = &Apache::lonnet::get_domainconfiguser($cdom); + %requesthash = &Apache::lonnet::dump($namespace,$cdom,$confname); + $approvedmsg = [{ + mt => 'The role assignment you requested for a user from another domain has been approved and the role assigned.', + }]; + $rejectedmsg = [{ + mt => 'The role assignment you requested for a user from another domain has not been approved.', + }]; + } else { + %requesthash = &Apache::lonnet::dump($namespace,$cdom,$cnum); + $approvedmsg = [{ + mt => 'The role assignment you requested for a user from another domain has been has been agreed to by the user.', + }]; + $rejectedmsg = [{ + mt => 'The role assignment you requested for a user from another domain has not been agreed to by the user.', + }]; + } + $domdesc = &Apache::lonnet::domain($cdom); } else { $domdesc = &Apache::lonnet::domain($cdom); $namespace = 'courserequestqueue'; @@ -947,6 +1229,146 @@ sub update_request_queue { push(@invalidusers,$uname); } push(@toremove,@invalidusers); + } elsif (($context eq 'othdombydc') || ($context eq 'othdombyuser')) { + if ($context eq 'othdombydc') { + my ($num,$extent,$role,$uname,$udom) = split(/:/,$item); + my ($logmsg,$result); + if ($udom eq $cdom) { + my $key = $uname.':'.$extent.':'.$role; + if (exists($requesthash{$key})) { + if (ref($requesthash{$key}) eq 'HASH') { + my $requester = $requesthash{$key}->{'requester'}; + my ($requname,$requdom) = split(/:/,$requester); + my $start = $requesthash{$key}->{'start'}; + my $end = $requesthash{$key}->{'end'}; + my $credits = $requesthash{$key}->{'credits'}; + my $reqcontext = $requesthash{$key}->{'context'}; + if ((&Apache::lonnet::homeserver($uname,$udom) ne 'no_host') && + (&Apache::lonnet::homeserver($requname,$requdom) ne 'no_host')) { + if (($role eq 'ca') || ($role eq 'aa')) { + my ($audom,$auname) = ($extent =~ m{^/($match_domain)/($match_username)$}); + if (&Apache::lonnet::homeserver($auname,$audom) ne 'no_host') { + if ($requester eq $auname.':'.$audom) { + unless ($gotroles{$requester}) { + &requester_roles($auname,$audom,\%requesteractive); + $gotroles{$requester} = 1; + } + if (ref($requesteractive{$requester}) eq 'HASH') { + if ($requesteractive{$requester}{':'.$audom.':au'}) { + $result = &Apache::lonnet::assignrole($udom,$uname,$extent,$role, + $end,$start,'','',$reqcontext); + } + } + } + } + } elsif (($role eq 'co') || ($role eq 'cc')) { + my ($crsdom,$crsnum) = ($extent =~ m{^/($match_domain)/($match_courseid)}); + if (&Apache::lonnet::is_course($crsdom,$crsnum)) { + my %info = &Apache::lonnet::coursedescription("$crsdom/$crsnum",{'one_time' => 1}); + if ((($role eq 'co') && ($info{'type'} eq 'Community')) || + (($role eq 'cc') && ($info{'type'} ne 'Community'))) { + if ($info{'internal.courseowner'} eq $requester) { + unless ($gotroles{$requester}) { + &requester_roles($requname,$requdom,\%requesteractive); + $gotroles{$requester} = 1; + } + if (ref($requesteractive{$requester}) eq 'HASH') { + if ($requesteractive{$requester}{"$crsnum:$crsdom:$role"}) { + $result = + &Apache::loncommon::commit_standardrole($udom,$uname,$extent,$role,$start, + $end,$crsdom,$crsnum,'', + $reqcontext); + } + } + } + } + } + } elsif ($role =~ m{^(cr)/($match_domain)/($match_username)/(\w+)$}) { + my ($mrole,$crudom,$cruname,$rolename) = ($1,$2,$3,$4); + my ($crsdom,$crsnum,$csec) = + ($extent =~ m{^/($match_domain)/($match_courseid)(?:|/(\w+))$}); + if (&Apache::lonnet::is_course($crsdom,$crsnum)) { + my ($rdummy,$roledef) = + &Apache::lonnet::get('roles',["rolesdef_$rolename"],$crudom,$cruname); + if (($rdummy ne 'con_lost') && ($roledef ne '')) { + unless ($gotroles{$requester}) { + &requester_roles($requname,$requdom,\%requesteractive); + $gotroles{$requester} = 1; + } + if (ref($requesteractive{$requester}) eq 'HASH') { + if (&requester_has_perm($crsdom,$crsnum,$mrole,$requesteractive{$requester})) { + $result = &Apache::loncommon::commit_customrole($udom,$uname,$extent,$crudom,$cruname, + $rolename,$start,$end,$reqcontext); + } + } + } + } + } else { + my $process; + foreach my $type ('course','domain') { + if (grep(/^\Q$role\E$/,@{$roles_by_context{$type}})) { + if ($type eq 'course') { + my ($crsdom,$crsnum,$csec) = ($extent =~ m{^/($match_domain)/($match_courseid)(?:|/(\w+))$}); + if (&Apache::lonnet::is_course($crsdom,$crsnum)) { + my $typeok; + if ($role eq 'cc') { + my %info = &Apache::lonnet::coursedescription("$crsdom/$crsnum",{'one_time' => 1}); + if ($info{'type'} eq 'Course') { + $typeok = 1; + } + } else { + $typeok = 1; + } + if ($typeok) { + unless ($gotroles{$requester}) { + &requester_roles($requname,$requdom,\%requesteractive); + $gotroles{$requester} = 1; + } + if (ref($requesteractive{$requester}) eq 'HASH') { + if (&requester_has_perm($crsdom,$crsnum,$role,$requesteractive{$requester})) { + $result = + &Apache::loncommon::commit_standardrole($udom,$uname,$extent,$role,$start, + $end,$crsdom,$crsnum,$csec, + $reqcontext,$credits); + } + } + } + } + } else { + my ($domain) = ($extent =~ m{^/($match_domain)/}); + if (&Apache::lonnet::domain($domain) ne '') { + unless ($gotroles{$requester}) { + &requester_roles($requname,$requdom,\%requesteractive); + $gotroles{$requester} = 1; + } + if (&requester_has_perm($domain,'',$role,$requesteractive{$requester})) { + $result = &Apache::lonnet::assignrole($udom,$uname,$extent,$role, + $end,$start,'','',$reqcontext); + } + } + } + last; + } + } + } + } + } + } + } + if ($result eq 'ok') { + push(@completed,$item); + } + } else { + my ($num,$extent,$role) = split(/:/,$item); + if (exists($requesthash{$extent.':'.$role})) { + if (ref($requesthash{$extent.':'.$role}) eq 'HASH') { +#FIXME +#check if extent is valid +#check if role is valid +#check requester privs + } + } + } } else { my ($num,$cnum) = split(':',$item); if (ref($requesthash{$cnum.'_'.$queue}) eq 'HASH') { @@ -1092,6 +1514,8 @@ sub update_request_queue { @changes = map {$_.'_approval'} (@changes); } elsif ($context eq 'requestusername') { @changes = map {&escape($_).'_approval'} (@changes); + } elsif (($context eq 'othdombydc') || ($context eq 'othdombyuser')) { + @changes = (); } if (@rejections) { foreach my $item (@rejections) { @@ -1146,6 +1570,8 @@ sub update_request_queue { if ($userresult ne 'ok') { push(@warn_rejects,$uname); } + } elsif (($context eq 'othdombydc') || ($context eq 'othdombyuser')) { +#FIXME } else { my $cnum = $item; if (ref($requesthash{$cnum.'_'.$queue}) eq 'HASH') { @@ -1328,6 +1754,8 @@ sub update_request_queue { $now,'usernamemanagers',$sender, $approvedlist,$rejectedlist); } + } elsif (($context eq 'othdombydc') || ($context eq 'othdombyuser')) { +#FIXME } else { $chgmsg = "'Action was taken on the following course and community requests by [_1].',$namelink"; if (@completed) { @@ -1593,6 +2021,43 @@ sub update_request_queue { return $output; } +sub requester_roles { + my ($requname,$requdom,$activeroles) = @_; + if (ref($activeroles) eq 'HASH') { + my %roleshash = &Apache::lonnet::get_my_roles($requname,$requdom,'userroles'); + $activeroles->{$requname.':'.$requdom} = \%roleshash; + } + return; +} + +sub requester_has_perm { + my ($crsdom,$crsnum,$mrole,$requesterroles) = @_; + return unless (ref($requesterroles) eq 'HASH'); + my $has_perm; + foreach my $key (keys(%{$requesterroles})) { + if ($crsnum eq '') { + next unless ($key =~ /^\Q:$crsdom:\E/); + } else { + next unless (($key =~ /^\Q$crsnum:$crsdom:\E/) || ($key =~ /^\Q:$crsdom:\E/)); + } + my ($keycrs,$keydom,$keyrole) = split(/:/,$key); + if (($keycrs ne '') && ($crsnum ne '')) { + if ($keycrs eq $crsnum) { + if ($Apache::lonnet::pr{$keyrole.':c'} =~ /(^|:)c\Q$mrole\E(&|:)/) { + $has_perm = 1; + last; + } + } + } else { + if ($Apache::lonnet::pr{$keyrole.':d'} =~ /(^|:)c\Q$mrole\E(&|:)/) { + $has_perm = 1; + last; + } + } + } + return $has_perm; +} + sub get_student_counts { my ($cdom,$cnum) = @_; my (%idx,%stucounts); @@ -1619,12 +2084,12 @@ sub course_creation { (ref($longroles) eq 'HASH')) { return ('error: Invalid request'); } - my ($result,$ownername,$ownerdom,$autocoowner); + my ($result,$ownername,$ownerdom); my $crstype = $details->{'crstype'}; my $coursedesc = $details->{'cdescr'}; my $accessstart = $details->{'accessstart'}; my $accessend = $details->{'accessend'}; - my %domconfig = &Apache::lonnet::get_dom('configuration',['requestcourses','autoenroll'],$dom); + my %domconfig = &Apache::lonnet::get_dom('configuration',['requestcourses'],$dom); if (ref($domconfig{'requestcourses'}) eq 'HASH') { if (ref($domconfig{'requestcourses'}{'uniquecode'}) eq 'HASH') { if ($domconfig{'requestcourses'}{'uniquecode'}{$crstype}) { @@ -1632,9 +2097,6 @@ sub course_creation { } } } - if (ref($domconfig{'autoenroll'}) eq 'HASH') { - $autocoowner = $domconfig{'autoenroll'}{'co-owners'}; - } if ($context eq 'domain') { $ownername = $details->{'owner'}; $ownerdom = $details->{'domain'}; @@ -1664,66 +2126,6 @@ sub course_creation { $postprocess = &Apache::lonnet::auto_crsreq_update($dom,$cnum,$crstype,$result,$ownername, $ownerdom,$fullname,$coursedesc,$code, $accessstart,$accessend,$customhash); - if ($autocoowner) { - my $instcode = $details->{'instcode'}; - if (($instcode ne '') && (ref($reqdetails{'users'}) eq 'HASH')) { - my @posscoowners; - my $now = time; - foreach my $person (keys(%{$reqdetails{'users'}})) { - my ($uname,$udom) = split(/:/,$person); - next if (($udom ne $dom) || (($uname eq $ownername) && ($udom eq $ownerdom))); - if ((&Apache::lonnet::homeserver($uname,$udom,1) ne 'no_host') && - (ref($reqdetails{'users'}{$person}) eq 'HASH')) { - if ((grep(/^cc$/,keys(%{$reqdetails{'users'}{$person}}))) && - (ref($reqdetails{'users'}{$person}{'cc'}) eq 'HASH')) { - my $start = $reqdetails{'users'}{$person}{'cc'}{'start'}; - my $end = $reqdetails{'users'}{$person}{'cc'}{'end'}; - if ((($start eq '') || ($start <= $now)) && - (($end eq '') || ($end >= $now))) { - push(@posscoowners,$person); - } - } - } - } - my @coowners; - if (@posscoowners) { - foreach my $user (@posscoowners) { - my ($checkcc,$desc) = - &Apache::lonnet::auto_validate_instcode($cnum,$dom,$instcode,$user); - unless ($checkcc eq 'valid') { - if (ref($reqdetails{'crosslists'}) eq 'HASH') { - foreach my $key (keys(%{$reqdetails{'crosslists'}})) { - if (ref($reqdetails{'crosslists'}{$key}) eq 'HASH') { - my $inst_crosslist = $reqdetails{'crosslists'}{$key}{'inst'}; - if ($inst_crosslist ne '') { - $checkcc = - &Apache::lonnet::auto_validate_inst_crosslist($cnum,$dom,$instcode, - $inst_crosslist,$user); - last if ($checkcc eq 'valid'); - } - } - } - } - } - if ($checkcc eq 'valid') { - if (@coowners > 0) { - unless (grep(/^\Q$user\E$/,@coowners)) { - push(@coowners,$user); - } - } else { - push(@coowners,$user); - } - } - } - } - if (@coowners > 0) { - my $chome = &Apache::lonnet::homeserver($cnum,$dom); - unless ($chome eq 'no_host') { - &Apache::lonnet::store_coowners($dom,$cnum,$chome,'',@coowners); - } - } - } - } } else { $result = 'error: '.$cid; } @@ -1767,6 +2169,8 @@ sub build_batchcreatehash { $batchhash{'authparam'} = $domdefs->{'auth_arg_def'}; if ($details->{'crstype'} eq 'community') { $batchhash{'crstype'} = 'Community'; + } elsif ($details->{'crstype'} eq 'placement') { + $batchhash{'crstype'} = 'Placement'; } else { if ($details->{'crstype'} eq 'textbook') { if ($details->{'clonecrs'} && $details->{'clonedom'}) { @@ -2318,7 +2722,7 @@ sub postprocess_crsenv { my %needcrsidput = ( 'internal.selfenroll_types' => 1, 'internal.selfenroll_start_date' => 1, - 'internal.selfenroll_end_date' => 1, + 'internal. selfenroll_end_date' => 1, ); my (@needupdate,%newcrsenv); foreach my $key (keys(%{$postprocessenv})) {