--- loncom/interface/loncoursequeueadmin.pm 2020/07/01 20:08:54 1.59 +++ 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.59 2020/07/01 20:08:54 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').''. @@ -541,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); @@ -557,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); @@ -571,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'; @@ -592,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"; @@ -610,7 +847,25 @@ sub build_queue_display { } elsif ($context eq 'requestusername') { $row .= ''.$showtime.''."\n". ''.$detailslink.''."\n"; - } else { + } 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"; } else { @@ -639,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+:/) { @@ -649,7 +905,6 @@ sub update_request_queue { } $count ++; } - $now = time; $sender = $env{'user.name'}.':'.$env{'user.domain'}; if ($context eq 'course') { @@ -723,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'; @@ -948,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') { @@ -1093,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) { @@ -1147,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') { @@ -1329,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) { @@ -1594,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); @@ -1647,7 +2111,7 @@ sub course_creation { $owneremail = $emails{$email}; last if ($owneremail ne ''); } - my %reqdetails = &build_batchcreatehash($dom,$context,$details,$owneremail,$domdefs); + my %reqdetails = &build_batchcreatehash($dom,$cnum,$context,$details,$owneremail,$domdefs); my $cid = &LONCAPA::batchcreatecourse::build_course($dom,$cnum,'requestcourses', \%reqdetails,$longroles,$logmsg,$clonemsg,$newusermsg,$addresult, $enrollcount,$output,$keysmsg,$ownerdom,$ownername,$cnum,$crstype, @@ -1669,15 +2133,30 @@ sub course_creation { } sub build_batchcreatehash { - my ($dom,$context,$details,$owneremail,$domdefs) = @_; + my ($dom,$cnum,$context,$details,$owneremail,$domdefs) = @_; my %batchhash; - my @items = qw{owner domain coursehome clonecrs clonedom datemode dateshift tinyurls enrollstart enrollend accessstart accessend sections crosslists users uniquecode}; + my @items = qw{owner domain coursehome clonecrs clonedom datemode dateshift tinyurls enrollstart enrollend accessstart accessend sections users uniquecode}; if ((ref($details) eq 'HASH') && (ref($domdefs) eq 'HASH')) { my $emailenc = &escape($owneremail); my $owner = $details->{'owner'}.':'.$details->{'domain'}; foreach my $item (@items) { $batchhash{$item} = $details->{$item}; } + if (ref($details->{'crosslists'}) eq 'HASH') { + foreach my $key (keys(%{$details->{'crosslists'}})) { + if (ref($details->{'crosslists'}->{$key}) eq 'HASH') { + my $instsec = $details->{crosslists}->{$key}->{instsec}; + $batchhash{'crosslists'}{$key}{'inst'} = $details->{crosslists}->{$key}->{instcode}; + my $crskey = $cnum.':'.$batchhash{'crosslists'}{$key}{'inst'}; + my %formatted = &Apache::lonnet::auto_instsec_reformat($dom,'clutter', + {$crskey => [$instsec]}); + if (ref($formatted{$crskey}) eq 'ARRAY') { + $batchhash{'crosslists'}{$key}{'inst'} .= $formatted{$crskey}->[0]; + } + $batchhash{'crosslists'}{$key}{'loncapa'} = $details->{crosslists}->{$key}->{loncapa}; + } + } + } $batchhash{'title'} = $details->{'cdescr'}; $batchhash{'coursecode'} = $details->{'instcode'}; if ($domdefs->{'officialcredits'} || $domdefs->{'unofficialcredits'}) { @@ -1698,6 +2177,8 @@ sub build_batchcreatehash { my %clonedfrom = &Apache::lonnet::coursedescription($details->{'clonedom'}.'_'.$details->{'clonecrs'}); $batchhash{'textbook'} = $clonedfrom{'description'}; } + } elsif ($details->{'crstype'} eq 'lti') { + $batchhash{'lti'} = 1; } $batchhash{'crstype'} = 'Course'; }