function refresh_key()
 {
     global $CFG;
     // set up an RPC request
     require_once $CFG->dirroot . '/mnet/xmlrpc/client.php';
     $mnetrequest = new mnet_xmlrpc_client();
     // Use any method - listServices is pretty lightweight.
     $mnetrequest->set_method('system/listServices');
     // Do RPC call and store response
     if ($mnetrequest->send($this) === true) {
         // Ok - we actually don't care about the result
         $temp = new mnet_peer();
         $temp->set_id($this->id);
         if ($this->public_key != $temp->public_key) {
             $newkey = clean_param($temp->public_key, PARAM_PEM);
             if (!empty($newkey)) {
                 $this->public_key = $newkey;
                 $this->updateparams->public_key = $newkey;
                 $this->commit();
                 return true;
             }
         }
     }
     return false;
 }
 function refresh_key()
 {
     // set up an RPC request
     $mnetrequest = new mnet_xmlrpc_client();
     // Use any method - listServices is pretty lightweight.
     $mnetrequest->set_method('system/listServices');
     // Do RPC call and store response
     if ($mnetrequest->send($this) === true) {
         // Ok - we actually don't care about the result
         $temp = new mnet_peer();
         $temp->set_id($this->id);
         if ($this->public_key != $temp->public_key) {
             $newkey = param_clean($temp->public_key, PARAM_PEM);
             if (!empty($newkey)) {
                 $this->public_key = $newkey;
                 return true;
             }
         }
     }
     return false;
 }
示例#3
0
 /**
  * Work out the theme this page should use.
  *
  * This depends on numerous $CFG settings, and the properties of this page.
  *
  * @return string the name of the theme that should be used on this page.
  */
 protected function resolve_theme()
 {
     global $CFG, $USER, $SESSION;
     if (empty($CFG->themeorder)) {
         $themeorder = array('course', 'category', 'session', 'user', 'site');
     } else {
         $themeorder = $CFG->themeorder;
         // Just in case, make sure we always use the site theme if nothing else matched.
         $themeorder[] = 'site';
     }
     $mnetpeertheme = '';
     if (isloggedin() and isset($CFG->mnet_localhost_id) and $USER->mnethostid != $CFG->mnet_localhost_id) {
         require_once $CFG->dirroot . '/mnet/peer.php';
         $mnetpeer = new mnet_peer();
         $mnetpeer->set_id($USER->mnethostid);
         if ($mnetpeer->force_theme == 1 && $mnetpeer->theme != '') {
             $mnetpeertheme = $mnetpeer->theme;
         }
     }
     $devicetheme = core_useragent::get_device_type_theme($this->devicetypeinuse);
     // The user is using another device than default, and we have a theme for that, we should use it.
     $hascustomdevicetheme = core_useragent::DEVICETYPE_DEFAULT != $this->devicetypeinuse && !empty($devicetheme);
     foreach ($themeorder as $themetype) {
         switch ($themetype) {
             case 'course':
                 if (!empty($CFG->allowcoursethemes) && !empty($this->_course->theme) && !$hascustomdevicetheme) {
                     return $this->_course->theme;
                 }
                 break;
             case 'category':
                 if (!empty($CFG->allowcategorythemes) && !$hascustomdevicetheme) {
                     $categories = $this->categories;
                     foreach ($categories as $category) {
                         if (!empty($category->theme)) {
                             return $category->theme;
                         }
                     }
                 }
                 break;
             case 'session':
                 if (!empty($SESSION->theme)) {
                     return $SESSION->theme;
                 }
                 break;
             case 'user':
                 if (!empty($CFG->allowuserthemes) && !empty($USER->theme) && !$hascustomdevicetheme) {
                     if ($mnetpeertheme) {
                         return $mnetpeertheme;
                     } else {
                         return $USER->theme;
                     }
                 }
                 break;
             case 'site':
                 if ($mnetpeertheme) {
                     return $mnetpeertheme;
                 }
                 // First try for the device the user is using.
                 if (!empty($devicetheme)) {
                     return $devicetheme;
                 }
                 // Next try for the default device (as a fallback).
                 $devicetheme = core_useragent::get_device_type_theme(core_useragent::DEVICETYPE_DEFAULT);
                 if (!empty($devicetheme)) {
                     return $devicetheme;
                 }
                 // The default device theme isn't set up - use the overall default theme.
                 return theme_config::DEFAULT_THEME;
         }
     }
     // We should most certainly have resolved a theme by now. Something has gone wrong.
     debugging('Error resolving the theme to use for this page.', DEBUG_DEVELOPER);
     return theme_config::DEFAULT_THEME;
 }
示例#4
0
 /**
  * Send the request to the server - decode and return the response
  *
  * @param  object   $mnet_peer      A mnet_peer object with details of the
  *                                  remote host we're connecting to
  * @return mixed                    A PHP variable, as returned by the
  *                                  remote function
  */
 function send($mnet_peer)
 {
     global $CFG, $MNET;
     $this->uri = $mnet_peer->wwwroot . $mnet_peer->application->xmlrpc_server_url;
     // Initialize with the target URL
     $ch = curl_init($this->uri);
     $system_methods = array('system/listMethods', 'system/methodSignature', 'system/methodHelp', 'system/listServices');
     if (in_array($this->method, $system_methods)) {
         // Executing any system method is permitted.
     } else {
         $id_list = $mnet_peer->id;
         if (!empty($CFG->mnet_all_hosts_id)) {
             $id_list .= ', ' . $CFG->mnet_all_hosts_id;
         }
         // At this point, we don't care if the remote host implements the
         // method we're trying to call. We just want to know that:
         // 1. The method belongs to some service, as far as OUR host knows
         // 2. We are allowed to subscribe to that service on this mnet_peer
         // Find methods that we subscribe to on this host
         $sql = "\n                SELECT\n                    r.id\n                FROM\n                    {$CFG->prefix}mnet_rpc r,\n                    {$CFG->prefix}mnet_service2rpc s2r,\n                    {$CFG->prefix}mnet_host2service h2s\n                WHERE\n                    r.xmlrpc_path = '{$this->method}' AND\n                    s2r.rpcid = r.id AND\n                    s2r.serviceid = h2s.serviceid AND\n                    h2s.subscribe = '1' AND\n                    h2s.hostid in ({$id_list})";
         if (!record_exists_sql($sql)) {
             global $USER;
             $this->error[] = '7:User with ID ' . $USER->id . ' attempted to call unauthorised method ' . $this->method . ' on host ' . $mnet_peer->wwwroot;
             return false;
         }
     }
     $this->requesttext = xmlrpc_encode_request($this->method, $this->params, array("encoding" => "utf-8", "escaping" => "markup"));
     $rq = $this->requesttext;
     $rq = mnet_sign_message($this->requesttext);
     $this->signedrequest = $rq;
     $rq = mnet_encrypt_message($rq, $mnet_peer->public_key);
     $this->encryptedrequest = $rq;
     curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($ch, CURLOPT_POST, true);
     curl_setopt($ch, CURLOPT_USERAGENT, 'Moodle');
     curl_setopt($ch, CURLOPT_POSTFIELDS, $rq);
     curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: text/xml charset=UTF-8"));
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
     curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
     $timestamp_send = time();
     $this->rawresponse = curl_exec($ch);
     $timestamp_receive = time();
     if ($this->rawresponse === false) {
         $this->error[] = curl_errno($ch) . ':' . curl_error($ch);
         return false;
     }
     $this->rawresponse = trim($this->rawresponse);
     $mnet_peer->touch();
     $crypt_parser = new mnet_encxml_parser();
     $crypt_parser->parse($this->rawresponse);
     if ($crypt_parser->payload_encrypted) {
         $key = array_pop($crypt_parser->cipher);
         $data = array_pop($crypt_parser->cipher);
         $crypt_parser->free_resource();
         // Initialize payload var
         $payload = '';
         //                                          &$payload
         $isOpen = openssl_open(base64_decode($data), $payload, base64_decode($key), $MNET->get_private_key());
         if (!$isOpen) {
             // Decryption failed... let's try our archived keys
             $openssl_history = get_config('mnet', 'openssl_history');
             if (empty($openssl_history)) {
                 $openssl_history = array();
                 set_config('openssl_history', serialize($openssl_history), 'mnet');
             } else {
                 $openssl_history = unserialize($openssl_history);
             }
             foreach ($openssl_history as $keyset) {
                 $keyresource = openssl_pkey_get_private($keyset['keypair_PEM']);
                 $isOpen = openssl_open(base64_decode($data), $payload, base64_decode($key), $keyresource);
                 if ($isOpen) {
                     // It's an older code, sir, but it checks out
                     break;
                 }
             }
         }
         if (!$isOpen) {
             trigger_error("None of our keys could open the payload from host {$mnet_peer->wwwroot} with id {$mnet_peer->id}.");
             $this->error[] = '3:No key match';
             return false;
         }
         if (strpos(substr($payload, 0, 100), '<signedMessage>')) {
             $sig_parser = new mnet_encxml_parser();
             $sig_parser->parse($payload);
         } else {
             $this->error[] = '2:Payload not signed: ' . $payload;
             return false;
         }
     } else {
         if (!empty($crypt_parser->remoteerror)) {
             $this->error[] = '4: remote server error: ' . $crypt_parser->remoteerror;
         } else {
             if (!empty($crypt_parser->error)) {
                 $crypt_parser_error = $crypt_parser->error[0];
                 $message = '3:XML Parse error in payload: ' . $crypt_parser_error['string'] . "\n";
                 if (array_key_exists('lineno', $crypt_parser_error)) {
                     $message .= 'At line number: ' . $crypt_parser_error['lineno'] . "\n";
                 }
                 if (array_key_exists('line', $crypt_parser_error)) {
                     $message .= 'Which reads: ' . $crypt_parser_error['line'] . "\n";
                 }
                 $this->error[] = $message;
             } else {
                 $this->error[] = '1:Payload not encrypted ';
             }
         }
         $crypt_parser->free_resource();
         return false;
     }
     // Margin of error is the time it took the request to complete.
     $margin_of_error = $timestamp_receive - $timestamp_send;
     // Guess the time gap between sending the request and the remote machine
     // executing the time() function. Marginally better than nothing.
     $hysteresis = $margin_of_error / 2;
     $remote_timestamp = $sig_parser->remote_timestamp - $hysteresis;
     $time_offset = $remote_timestamp - $timestamp_send;
     if ($time_offset > 0) {
         $threshold = get_config('mnet', 'drift_threshold');
         if (empty($threshold)) {
             // We decided 15 seconds was a pretty good arbitrary threshold
             // for time-drift between servers, but you can customize this in
             // the config_plugins table. It's not advised though.
             set_config('drift_threshold', 15, 'mnet');
             $threshold = 15;
         }
         if ($time_offset > $threshold) {
             $this->error[] = '6:Time gap with ' . $mnet_peer->name . ' (' . $time_offset . ' seconds) is greater than the permitted maximum of ' . $threshold . ' seconds';
             return false;
         }
     }
     $this->xmlrpcresponse = base64_decode($sig_parser->data_object);
     $this->response = xmlrpc_decode($this->xmlrpcresponse);
     curl_close($ch);
     // xmlrpc errors are pushed onto the $this->error stack
     if (is_array($this->response) && array_key_exists('faultCode', $this->response)) {
         // The faultCode 7025 means we tried to connect with an old SSL key
         // The faultString is the new key - let's save it and try again
         // The re_key attribute stops us from getting into a loop
         if ($this->response['faultCode'] == 7025 && empty($mnet_peer->re_key)) {
             $record = new stdClass();
             $record->id = $mnet_peer->id;
             if ($this->response['faultString'] == clean_param($this->response['faultString'], PARAM_PEM)) {
                 $record->public_key = $this->response['faultString'];
                 $details = openssl_x509_parse($record->public_key);
                 if (is_array($details) && isset($details['validTo_time_t'])) {
                     $record->public_key_expires = $details['validTo_time_t'];
                     update_record('mnet_host', $record);
                     $mnet_peer2 = new mnet_peer();
                     $mnet_peer2->set_id($record->id);
                     $mnet_peer2->re_key = true;
                     $this->send($mnet_peer2);
                 } else {
                     $this->error[] = $this->response['faultCode'] . " : " . $this->response['faultString'];
                 }
             } else {
                 $this->error[] = $this->response['faultCode'] . " : " . $this->response['faultString'];
             }
         } else {
             if (!empty($CFG->mnet_rpcdebug)) {
                 $guidance = get_string('error' . $this->response['faultCode'], 'mnet');
             } else {
                 $guidance = '';
             }
             $this->error[] = $this->response['faultCode'] . " : " . $this->response['faultString'];
         }
     }
     // ok, it's signed, but is it signed with the right certificate ?
     // do this *after* we check for an out of date key
     $verified = openssl_verify($this->xmlrpcresponse, base64_decode($sig_parser->signature), $mnet_peer->public_key);
     if ($verified != 1) {
         $this->error[] = 'Invalid signature';
     }
     return empty($this->error);
 }
示例#5
0
            }
        }
        if ('input' == $form->step) {
            include './mnet_review.html';
        } elseif ('commit' == $form->step) {
            $bool = $mnet_peer->commit();
            if ($bool) {
                redirect('peers.php?step=update&amp;hostid=' . $mnet_peer->id, get_string('changessaved'));
            } else {
                print_error('invalidaction', 'error', 'index.php');
            }
        }
    }
} elseif (is_int($hostid)) {
    $mnet_peer = new mnet_peer();
    $mnet_peer->set_id($hostid);
    $currentkey = mnet_get_public_key($mnet_peer->wwwroot, $mnet_peer->application);
    if ($currentkey == $mnet_peer->public_key) {
        unset($currentkey);
    }
    $form = new stdClass();
    if ($hostid != $CFG->mnet_all_hosts_id) {
        $credentials = $mnet_peer->check_credentials($mnet_peer->public_key);
        include './mnet_review.html';
    } else {
        include './mnet_review_allhosts.html';
    }
} else {
    $hosts = $DB->get_records_sql('  SELECT 
                                    h.id, 
                                    h.wwwroot, 
 /**
  * The IdP uses this function to kill child sessions on other hosts
  *
  * @param   string  $username       Username for session to kill
  * @param   string  $useragent      SHA1 hash of user agent to look for
  * @return  string                  A plaintext report of what has happened
  */
 function kill_children($username, $useragent)
 {
     global $CFG, $USER, $DB;
     $remoteclient = null;
     if (defined('MNET_SERVER')) {
         $remoteclient = get_mnet_remote_client();
     }
     require_once $CFG->dirroot . '/mnet/xmlrpc/client.php';
     $userid = $DB->get_field('user', 'id', array('mnethostid' => $CFG->mnet_localhost_id, 'username' => $username));
     $returnstring = '';
     $mnetsessions = $DB->get_records('mnet_session', array('userid' => $userid, 'useragent' => $useragent));
     if (false == $mnetsessions) {
         $returnstring .= "Could find no remote sessions\n";
         $mnetsessions = array();
     }
     foreach ($mnetsessions as $mnetsession) {
         // If this script is being executed by a remote peer, that means the user has clicked
         // logout on that peer, and the session on that peer can be deleted natively.
         // Skip over it.
         if (isset($remoteclient->id) && $mnetsession->mnethostid == $remoteclient->id) {
             continue;
         }
         $returnstring .= "Deleting session\n";
         $mnet_peer = new mnet_peer();
         $mnet_peer->set_id($mnetsession->mnethostid);
         $mnet_request = new mnet_xmlrpc_client();
         $mnet_request->set_method('auth/mnet/auth.php/kill_child');
         // set $token and $useragent parameters
         $mnet_request->add_param($username);
         $mnet_request->add_param($useragent);
         if ($mnet_request->send($mnet_peer) === false) {
             debugging("Server side error has occured on host {$mnetsession->mnethostid}: " . join("\n", $mnet_request->error));
         }
     }
     $ignore = $DB->delete_records('mnet_session', array('useragent' => $useragent, 'userid' => $userid));
     if (isset($remoteclient) && isset($remoteclient->id)) {
         session_kill_user($userid);
     }
     return $returnstring;
 }
示例#7
0
/**
 * Returns the name of the current theme
 *
 * @uses $CFG
 * @uses $USER
 * @uses $SESSION
 * @uses $COURSE
 * @uses $SCRIPT
 * @return string
 */
function current_theme()
{
    global $CFG, $USER, $SESSION, $COURSE, $SCRIPT;
    if (empty($CFG->themeorder)) {
        $themeorder = array('page', 'course', 'category', 'session', 'user', 'site');
    } else {
        $themeorder = $CFG->themeorder;
    }
    if (isloggedin() and isset($CFG->mnet_localhost_id) and $USER->mnethostid != $CFG->mnet_localhost_id) {
        require_once $CFG->dirroot . '/mnet/peer.php';
        $mnet_peer = new mnet_peer();
        $mnet_peer->set_id($USER->mnethostid);
    }
    $theme = '';
    foreach ($themeorder as $themetype) {
        if (!empty($theme)) {
            continue;
        }
        switch ($themetype) {
            case 'page':
                // Page theme is for special page-only themes set by code
                if (!empty($CFG->pagetheme)) {
                    $theme = $CFG->pagetheme;
                }
                break;
            case 'course':
                if (!empty($CFG->allowcoursethemes) and !empty($COURSE->theme)) {
                    $theme = $COURSE->theme;
                }
                break;
            case 'category':
                if (!empty($CFG->allowcategorythemes)) {
                    /// Nasty hack to check if we're in a category page
                    if ($SCRIPT == '/course/category.php') {
                        global $id;
                        if (!empty($id)) {
                            $theme = current_category_theme($id);
                        }
                        /// Otherwise check if we're in a course that has a category theme set
                    } else {
                        if (!empty($COURSE->category)) {
                            $theme = current_category_theme($COURSE->category);
                        }
                    }
                }
                break;
            case 'session':
                if (!empty($SESSION->theme)) {
                    $theme = $SESSION->theme;
                }
                break;
            case 'user':
                if (!empty($CFG->allowuserthemes) and !empty($USER->theme)) {
                    if (isloggedin() and $USER->mnethostid != $CFG->mnet_localhost_id && $mnet_peer->force_theme == 1 && $mnet_peer->theme != '') {
                        $theme = $mnet_peer->theme;
                    } else {
                        $theme = $USER->theme;
                    }
                }
                break;
            case 'site':
                if (isloggedin() and isset($CFG->mnet_localhost_id) and $USER->mnethostid != $CFG->mnet_localhost_id && $mnet_peer->force_theme == 1 && $mnet_peer->theme != '') {
                    $theme = $mnet_peer->theme;
                } else {
                    $theme = $CFG->theme;
                }
                break;
            default:
                /// do nothing
        }
    }
    /// A final check in case 'site' was not included in $CFG->themeorder
    if (empty($theme)) {
        $theme = $CFG->theme;
    }
    return $theme;
}
 /**
  * Describes the form, with the triplet (service_name, publish, subscribe).
  */
 public function definition()
 {
     global $CFG, $SESSION, $DB;
     // Settings variables.
     $mform =& $this->_form;
     // Master services.
     $defaultservices = $DB->get_records('mnet_service', array('offer' => 1), 'name');
     // get version info to get real names
     $self_mnet_peer = new mnet_peer();
     $self_mnet_peer->set_id($CFG->mnet_localhost_id);
     $myservices = mnet_get_service_info($self_mnet_peer);
     if (!empty($defaultservices)) {
         // Services fieldset.
         $mform->addElement('header', 'servicesform', get_string('servicesformselection', 'local_vmoodle'));
         $grid =& $mform->addElement('elementgrid', 'grid', get_string('mainservicesformselection', 'local_vmoodle'));
         $row = array();
         $row[] = get_string('publish', 'local_vmoodle');
         $row[] = get_string('subscribe', 'local_vmoodle');
         $row[] = '';
         $row[] = '';
         $grid->setColumnNames($row);
         foreach ($defaultservices as $defaultservice) {
             $row = array();
             $row[] = $mform->createElement('advcheckbox', 'main_' . $defaultservice->name . '_publish');
             $row[] = $mform->createElement('advcheckbox', 'main_' . $defaultservice->name . '_subscribe');
             $row[] = $mform->createElement('static', 'main_' . $defaultservice->name . '_description');
             $row[] = $mform->createElement('hidden', 'main_' . $defaultservice->name . '_id');
             $description = $defaultservice->description;
             if (empty($description)) {
                 $version = current($myservices[$defaultservice->name]);
                 $langmodule = ($version['plugintype'] == 'mod' ? '' : $version['plugintype'] . '_') . $version['pluginname'];
                 // TODO there should be a moodle-wide way to do this
                 $description = get_string($defaultservice->name . '_name', $langmodule);
             }
             $mform->setDefault('main_' . $defaultservice->name . '_description', $description);
             $mform->setDefault('main_' . $defaultservice->name . '_id', $defaultservice->id);
             $mform->setType('main_' . $defaultservice->name . '_id', PARAM_INT);
             $grid->addRow($row);
         }
         // Services fieldset.
         $grid =& $mform->addElement('elementgrid', 'grid', get_string('peerservicesformselection', 'local_vmoodle'));
         $row = array();
         $row[] = get_string('publish', 'local_vmoodle');
         $row[] = get_string('subscribe', 'local_vmoodle');
         $row[] = '';
         $row[] = '';
         $grid->setColumnNames($row);
         foreach ($defaultservices as $defaultservice) {
             $row = array();
             $row[] = $mform->createElement('advcheckbox', 'peer_' . $defaultservice->name . '_publish');
             $row[] = $mform->createElement('advcheckbox', 'peer_' . $defaultservice->name . '_subscribe');
             $row[] = $mform->createElement('static', 'peer_' . $defaultservice->name . '_description');
             $row[] = $mform->createElement('hidden', 'peer_' . $defaultservice->name . '_id');
             $description = $defaultservice->description;
             if (empty($description)) {
                 $version = current($myservices[$defaultservice->name]);
                 $langmodule = ($version['plugintype'] == 'mod' ? '' : $version['plugintype'] . '_') . $version['pluginname'];
                 // TODO there should be a moodle-wide way to do this
                 $description = get_string($defaultservice->name . '_name', $langmodule);
             }
             $mform->setDefault('peer_' . $defaultservice->name . '_description', $description);
             $mform->setDefault('peer_' . $defaultservice->name . '_id', $defaultservice->id);
             $mform->setType('peer_' . $defaultservice->name . '_id', PARAM_INT);
             $grid->addRow($row);
         }
         // Submit button.
         $mform->addElement('submit', 'submitbutton', get_string('edit'));
     } else {
         // Confirmation message.
         $message_object = new stdclass();
         $message_object->message = get_string('badservicesnumber', 'local_vmoodle');
         $message_object->style = 'notifyproblem';
         // Save confirm message before redirection.
         $SESSION->vmoodle_ma['confirm_message'] = $message_object;
         new moodle_url('/local/vmoodle/view.php', array('view' => 'management'));
     }
 }
示例#9
0
 /**
  * Send request to unenrol our user from the remote course
  *
  * Updates our remote enrolments cache if the unenrolment was successful.
  *
  * @uses mnet_xmlrpc_client Invokes XML-RPC request
  * @param object $user our user
  * @param object $remotecourse record from mnetservice_enrol_courses table
  * @return true|string true if success, error message from the remote host otherwise
  */
 public function req_unenrol_user(stdclass $user, stdclass $remotecourse)
 {
     global $CFG, $DB;
     require_once $CFG->dirroot . '/mnet/xmlrpc/client.php';
     $peer = new mnet_peer();
     $peer->set_id($remotecourse->hostid);
     $request = new mnet_xmlrpc_client();
     $request->set_method('enrol/mnet/enrol.php/unenrol_user');
     $request->add_param($user->username);
     $request->add_param($remotecourse->remoteid);
     if ($request->send($peer) === true) {
         if ($request->response === true) {
             // clear the cached information
             $DB->delete_records('mnetservice_enrol_enrolments', array('hostid' => $peer->id, 'userid' => $user->id, 'remotecourseid' => $remotecourse->remoteid, 'enroltype' => 'mnet'));
             return true;
         } else {
             return serialize(array('invalid response: ' . print_r($request->response, true)));
         }
     } else {
         return serialize($request->error);
     }
 }
示例#10
0
文件: enrol.php 项目: r007/PMoodle
 /**
  * Does Foo
  *
  * @param int    $mnethostid The id of the remote mnethost
  * @return array              Whether the user can login from the remote host
  */
 function req_unenrol_user($userid, $courseid)
 {
     global $CFG;
     global $USER;
     global $MNET;
     require_once $CFG->dirroot . '/mnet/xmlrpc/client.php';
     // in case the remote host doesn't have it
     $username = get_field('user', 'username', 'id', $userid);
     $course = get_record('mnet_enrol_course', 'id', $courseid);
     // get the Service Provider info
     $mnet_sp = new mnet_peer();
     $mnet_sp->set_id($course->hostid);
     // set up the RPC request
     $mnetrequest = new mnet_xmlrpc_client();
     $mnetrequest->set_method('enrol/mnet/enrol.php/unenrol_user');
     $mnetrequest->add_param($username);
     $mnetrequest->add_param($course->remoteid);
     // TODO - prevent removal of enrolments that are not of
     // type mnet...
     // Thunderbirds are go! Do RPC call and store response
     if ($mnetrequest->send($mnet_sp) === true) {
         if ($mnetrequest->response == true) {
             // remove enrolment cached in mnet_enrol_assignments
             delete_records_select('mnet_enrol_assignments', "userid={$userid} AND courseid={$course->id}");
             return true;
         }
     }
     return false;
 }
示例#11
0
 /**
  * The IdP uses this function to kill child sessions on other hosts
  *
  * @param   string  $username       Username for session to kill
  * @param   string  $useragent      SHA1 hash of user agent to look for
  * @return  string                  A plaintext report of what has happened
  */
 function kill_children($username, $useragent)
 {
     global $CFG, $USER, $MNET_REMOTE_CLIENT, $DB;
     require_once $CFG->dirroot . '/mnet/xmlrpc/client.php';
     $userid = $DB->get_field('user', 'id', array('mnethostid' => $CFG->mnet_localhost_id, 'username' => $username));
     $returnstring = '';
     $mnetsessions = $DB->get_records('mnet_session', array('userid' => $userid, 'useragent' => $useragent));
     if (false == $mnetsessions) {
         $returnstring .= "Could find no remote sessions\n";
         $mnetsessions = array();
     }
     foreach ($mnetsessions as $mnetsession) {
         // If this script is being executed by a remote peer, that means the user has clicked
         // logout on that peer, and the session on that peer can be deleted natively.
         // Skip over it.
         if (isset($MNET_REMOTE_CLIENT->id) && $mnetsession->mnethostid == $MNET_REMOTE_CLIENT->id) {
             continue;
         }
         $returnstring .= "Deleting session\n";
         $mnet_peer = new mnet_peer();
         $mnet_peer->set_id($mnetsession->mnethostid);
         $mnet_request = new mnet_xmlrpc_client();
         $mnet_request->set_method('auth/mnet/auth.php/kill_child');
         // set $token and $useragent parameters
         $mnet_request->add_param($username);
         $mnet_request->add_param($useragent);
         if ($mnet_request->send($mnet_peer) === false) {
             debugging("Server side error has occured on host {$mnetsession->mnethostid}: " . join("\n", $mnet_request->error));
         }
     }
     $ignore = $DB->delete_records('mnet_session', array('useragent' => $useragent, 'userid' => $userid));
     if (isset($MNET_REMOTE_CLIENT) && isset($MNET_REMOTE_CLIENT->id)) {
         $start = ob_start();
         // Save current session and cookie-use status
         $cookieuse = ini_get('session.use_cookies');
         ini_set('session.use_cookies', false);
         $sesscache = $_SESSION;
         $sessidcache = session_id();
         // Replace existing mnet session with user session & unset
         session_write_close();
         unset($_SESSION);
         session_id($mnetsession->session_id);
         session_start();
         session_unregister("USER");
         session_unregister("SESSION");
         unset($_SESSION);
         $_SESSION = array();
         session_write_close();
         // Restore previous info
         ini_set('session.use_cookies', $cookieuse);
         session_name('MoodleSession' . $CFG->sessioncookie);
         session_id($sessidcache);
         session_start();
         $_SESSION = $sesscache;
         session_write_close();
         $end = ob_end_clean();
     } else {
         $_SESSION = array();
     }
     return $returnstring;
 }
示例#12
0
 /**
  * The IdP uses this function to kill child sessions on other hosts
  *
  * @param   string  $username       Username for session to kill
  * @param   string  $useragent      SHA1 hash of user agent to look for
  * @return  string                  A plaintext report of what has happened
  */
 function kill_children($username, $useragent)
 {
     global $CFG, $USER, $MNET_REMOTE_CLIENT;
     require_once $CFG->dirroot . '/mnet/xmlrpc/client.php';
     $userid = get_field('user', 'id', 'mnethostid', $CFG->mnet_localhost_id, 'username', addslashes($username));
     $returnstring = '';
     $sql = "\n            select\n                *\n            from\n                {$CFG->prefix}mnet_session s\n            where\n                s.userid     = '{$userid}' AND\n                s.useragent  = '{$useragent}'";
     // If we are being executed from a remote machine (client) we don't have
     // to kill the moodle session on that machine.
     if (isset($MNET_REMOTE_CLIENT) && isset($MNET_REMOTE_CLIENT->id)) {
         $excludeid = $MNET_REMOTE_CLIENT->id;
     } else {
         $excludeid = -1;
     }
     $mnetsessions = get_records_sql($sql);
     if (false == $mnetsessions) {
         $returnstring .= "Could find no remote sessions\n{$sql}\n";
         $mnetsessions = array();
     }
     foreach ($mnetsessions as $mnetsession) {
         $returnstring .= "Deleting session\n";
         if ($mnetsession->mnethostid == $excludeid) {
             continue;
         }
         $mnet_peer = new mnet_peer();
         $mnet_peer->set_id($mnetsession->mnethostid);
         $mnet_request = new mnet_xmlrpc_client();
         $mnet_request->set_method('auth/mnet/auth.php/kill_child');
         // set $token and $useragent parameters
         $mnet_request->add_param($username);
         $mnet_request->add_param($useragent);
         if ($mnet_request->send($mnet_peer) === false) {
             debugging("Server side error has occured on host {$mnetsession->mnethostid}: " . join("\n", $mnet_request->error));
         }
     }
     $ignore = delete_records('mnet_session', 'useragent', $useragent, 'userid', $userid);
     if (isset($MNET_REMOTE_CLIENT) && isset($MNET_REMOTE_CLIENT->id)) {
         $start = ob_start();
         $uc = ini_get('session.use_cookies');
         ini_set('session.use_cookies', false);
         $sesscache = clone $_SESSION;
         $sessidcache = session_id();
         session_write_close();
         unset($_SESSION);
         session_id($mnetsession->session_id);
         session_start();
         session_unregister("USER");
         session_unregister("SESSION");
         unset($_SESSION);
         $_SESSION = array();
         session_write_close();
         ini_set('session.use_cookies', $uc);
         session_name('MoodleSession' . $CFG->sessioncookie);
         session_id($sessidcache);
         session_start();
         $_SESSION = clone $sesscache;
         session_write_close();
         $end = ob_end_clean();
     } else {
         $_SESSION = array();
     }
     return $returnstring;
 }
示例#13
0
 /**
  * Send the request to the server - decode and return the response
  *
  * @param  object   $mnet_peer      A mnet_peer object with details of the
  *                                  remote host we're connecting to
  * @return mixed                    A PHP variable, as returned by the
  *                                  remote function
  */
 function send($mnet_peer)
 {
     global $CFG, $DB;
     if (!$this->permission_to_call($mnet_peer)) {
         mnet_debug("tried and wasn't allowed to call a method on {$mnet_peer->wwwroot}");
         return false;
     }
     $this->requesttext = xmlrpc_encode_request($this->method, $this->params, array("encoding" => "utf-8", "escaping" => "markup"));
     $this->signedrequest = mnet_sign_message($this->requesttext);
     $this->encryptedrequest = mnet_encrypt_message($this->signedrequest, $mnet_peer->public_key);
     $httprequest = $this->prepare_http_request($mnet_peer);
     curl_setopt($httprequest, CURLOPT_POSTFIELDS, $this->encryptedrequest);
     $timestamp_send = time();
     mnet_debug("about to send the curl request");
     $this->rawresponse = curl_exec($httprequest);
     mnet_debug("managed to complete a curl request");
     $timestamp_receive = time();
     if ($this->rawresponse === false) {
         $this->error[] = curl_errno($httprequest) . ':' . curl_error($httprequest);
         return false;
     }
     curl_close($httprequest);
     $this->rawresponse = trim($this->rawresponse);
     $mnet_peer->touch();
     $crypt_parser = new mnet_encxml_parser();
     $crypt_parser->parse($this->rawresponse);
     // If we couldn't parse the message, or it doesn't seem to have encrypted contents,
     // give the most specific error msg available & return
     if (!$crypt_parser->payload_encrypted) {
         if (!empty($crypt_parser->remoteerror)) {
             $this->error[] = '4: remote server error: ' . $crypt_parser->remoteerror;
         } else {
             if (!empty($crypt_parser->error)) {
                 $crypt_parser_error = $crypt_parser->error[0];
                 $message = '3:XML Parse error in payload: ' . $crypt_parser_error['string'] . "\n";
                 if (array_key_exists('lineno', $crypt_parser_error)) {
                     $message .= 'At line number: ' . $crypt_parser_error['lineno'] . "\n";
                 }
                 if (array_key_exists('line', $crypt_parser_error)) {
                     $message .= 'Which reads: ' . $crypt_parser_error['line'] . "\n";
                 }
                 $this->error[] = $message;
             } else {
                 $this->error[] = '1:Payload not encrypted ';
             }
         }
         $crypt_parser->free_resource();
         return false;
     }
     $key = array_pop($crypt_parser->cipher);
     $data = array_pop($crypt_parser->cipher);
     $crypt_parser->free_resource();
     // Initialize payload var
     $decryptedenvelope = '';
     //                                          &$decryptedenvelope
     $isOpen = openssl_open(base64_decode($data), $decryptedenvelope, base64_decode($key), $this->mnet->get_private_key());
     if (!$isOpen) {
         // Decryption failed... let's try our archived keys
         $openssl_history = get_config('mnet', 'openssl_history');
         if (empty($openssl_history)) {
             $openssl_history = array();
             set_config('openssl_history', serialize($openssl_history), 'mnet');
         } else {
             $openssl_history = unserialize($openssl_history);
         }
         foreach ($openssl_history as $keyset) {
             $keyresource = openssl_pkey_get_private($keyset['keypair_PEM']);
             $isOpen = openssl_open(base64_decode($data), $decryptedenvelope, base64_decode($key), $keyresource);
             if ($isOpen) {
                 // It's an older code, sir, but it checks out
                 break;
             }
         }
     }
     if (!$isOpen) {
         trigger_error("None of our keys could open the payload from host {$mnet_peer->wwwroot} with id {$mnet_peer->id}.");
         $this->error[] = '3:No key match';
         return false;
     }
     if (strpos(substr($decryptedenvelope, 0, 100), '<signedMessage>')) {
         $sig_parser = new mnet_encxml_parser();
         $sig_parser->parse($decryptedenvelope);
     } else {
         $this->error[] = '2:Payload not signed: ' . $decryptedenvelope;
         return false;
     }
     // Margin of error is the time it took the request to complete.
     $margin_of_error = $timestamp_receive - $timestamp_send;
     // Guess the time gap between sending the request and the remote machine
     // executing the time() function. Marginally better than nothing.
     $hysteresis = $margin_of_error / 2;
     $remote_timestamp = $sig_parser->remote_timestamp - $hysteresis;
     $time_offset = $remote_timestamp - $timestamp_send;
     if ($time_offset > 0) {
         $threshold = get_config('mnet', 'drift_threshold');
         if (empty($threshold)) {
             // We decided 15 seconds was a pretty good arbitrary threshold
             // for time-drift between servers, but you can customize this in
             // the config_plugins table. It's not advised though.
             set_config('drift_threshold', 15, 'mnet');
             $threshold = 15;
         }
         if ($time_offset > $threshold) {
             $this->error[] = '6:Time gap with ' . $mnet_peer->name . ' (' . $time_offset . ' seconds) is greater than the permitted maximum of ' . $threshold . ' seconds';
             return false;
         }
     }
     $this->xmlrpcresponse = base64_decode($sig_parser->data_object);
     $this->response = xmlrpc_decode($this->xmlrpcresponse);
     // xmlrpc errors are pushed onto the $this->error stack
     if (is_array($this->response) && array_key_exists('faultCode', $this->response)) {
         // The faultCode 7025 means we tried to connect with an old SSL key
         // The faultString is the new key - let's save it and try again
         // The re_key attribute stops us from getting into a loop
         if ($this->response['faultCode'] == 7025 && empty($mnet_peer->re_key)) {
             mnet_debug('recieved an old-key fault, so trying to get the new key and update our records');
             // If the new certificate doesn't come thru clean_param() unmolested, error out
             if ($this->response['faultString'] != clean_param($this->response['faultString'], PARAM_PEM)) {
                 $this->error[] = $this->response['faultCode'] . " : " . $this->response['faultString'];
             }
             $record = new stdClass();
             $record->id = $mnet_peer->id;
             $record->public_key = $this->response['faultString'];
             $details = openssl_x509_parse($record->public_key);
             if (!isset($details['validTo_time_t'])) {
                 $this->error[] = $this->response['faultCode'] . " : " . $this->response['faultString'];
             }
             $record->public_key_expires = $details['validTo_time_t'];
             $DB->update_record('mnet_host', $record);
             // Create a new peer object populated with the new info & try re-sending the request
             $rekeyed_mnet_peer = new mnet_peer();
             $rekeyed_mnet_peer->set_id($record->id);
             $rekeyed_mnet_peer->re_key = true;
             return $this->send($rekeyed_mnet_peer);
         }
         if (!empty($CFG->mnet_rpcdebug)) {
             if (get_string_manager()->string_exists('error' . $this->response['faultCode'], 'mnet')) {
                 $guidance = get_string('error' . $this->response['faultCode'], 'mnet');
             } else {
                 $guidance = '';
             }
         } else {
             $guidance = '';
         }
         $this->error[] = $this->response['faultCode'] . " : " . $this->response['faultString'] . "\n" . $guidance;
     }
     // ok, it's signed, but is it signed with the right certificate ?
     // do this *after* we check for an out of date key
     if (!openssl_verify($this->xmlrpcresponse, base64_decode($sig_parser->signature), $mnet_peer->public_key)) {
         $this->error[] = 'Invalid signature';
     }
     return empty($this->error);
 }
示例#14
0
文件: pagelib.php 项目: nuckey/moodle
    /**
     * Work out the theme this page should use.
     *
     * This depends on numerous $CFG settings, and the properties of this page.
     *
     * @return string the name of the theme that should be used on this page.
     */
    protected function resolve_theme() {
        global $CFG, $USER, $SESSION;

        if (empty($CFG->themeorder)) {
            $themeorder = array('course', 'category', 'session', 'user', 'site');
        } else {
            $themeorder = $CFG->themeorder;
            // Just in case, make sure we always use the site theme if nothing else matched.
            $themeorder[] = 'site';
        }

        $mnetpeertheme = '';
        if (isloggedin() and isset($CFG->mnet_localhost_id) and $USER->mnethostid != $CFG->mnet_localhost_id) {
            require_once($CFG->dirroot.'/mnet/peer.php');
            $mnetpeer = new mnet_peer();
            $mnetpeer->set_id($USER->mnethostid);
            if ($mnetpeer->force_theme == 1 && $mnetpeer->theme != '') {
                $mnetpeertheme = $mnetpeer->theme;
            }
        }

        $theme = '';
        foreach ($themeorder as $themetype) {
            switch ($themetype) {
                case 'course':
                    if (!empty($CFG->allowcoursethemes) and !empty($this->course->theme)) {
                        return $this->course->theme;
                    }

                case 'category':
                    if (!empty($CFG->allowcategorythemes)) {
                        $categories = $this->categories;
                        foreach ($categories as $category) {
                            if (!empty($category->theme)) {
                                return $category->theme;
                            }
                        }
                    }

                case 'session':
                    if (!empty($SESSION->theme)) {
                        return $SESSION->theme;
                    }

                case 'user':
                    if (!empty($CFG->allowuserthemes) and !empty($USER->theme)) {
                        if ($mnetpeertheme) {
                            return $mnetpeertheme;
                        } else {
                            return $USER->theme;
                        }
                    }

                case 'site':
                    if ($mnetpeertheme) {
                        return $mnetpeertheme;
                    } else if(!empty($CFG->themelegacy) && $this->browser_is_outdated()) {
                        $this->_legacythemeinuse = true;
                        return $CFG->themelegacy;
                    } else {
                    	return $CFG->theme;
                    }
            }
        }
    }
示例#15
0
 public function callRemoteMethod($method, $parameters, $server = null)
 {
     global $CFG, $SynchServerController;
     require_once $CFG->dirroot . '/mnet/xmlrpc/client.php';
     // For the demo, our 'remote' host is actually our local host.
     $wwwroot = $CFG->wwwroot;
     //$method = 'synch/mnet/synch.php/getBackupById';
     // Get local server.
     $localServer = $SynchServerController->checkAndCreateLocalServer();
     global $Out;
     //$Out->print_r($localServer, '$localServer = ');
     // Cannot continue without a local server
     if (empty($localServer)) {
         return null;
     }
     if (empty($server)) {
         //$Out->append('Generating default remote server');
         //$server = new synch_modal_Server();
         //$server->mnetHostId = 1020000003;
         $server = $SynchServerController->getRemoteServer();
     }
     //$Out->print_r($server, '$server = ');
     // Cannot continue without a remote server to call
     if (empty($server) || synch_empty($server->mnetHostId)) {
         return null;
     }
     // mnet_peer pulls information about a remote host from the database.
     $mnet_peer = new mnet_peer();
     $mnet_peer->set_wwwroot($wwwroot);
     $mnethostid = $server->mnetHostId;
     $mnet_peer->set_id($mnethostid);
     // Create a new request object
     $mnet_request = new mnet_xmlrpc_client();
     // Tell it the path to the method that we want to execute
     $mnet_request->set_method($method);
     // Set the time out to something decent in seconds
     //$mnet_request->set_timeout(600);
     //set_time_limit(120);
     // Add parameters for your function. The mnet_concatenate_strings takes three
     // parameters, like mnet_concatenate_strings($string1, $string2, $string3)
     // PHP is weakly typed, so you can get away with calling most things strings,
     // unless it's non-scalar (i.e. an array or object or something).
     foreach ($parameters as $param) {
         $mnet_request->add_param($param[0], $param[1]);
     }
     // We send the request:
     $mnet_request->send($mnet_peer);
     return $mnet_request->response;
 }
示例#16
0
    /**
     * Work out the theme this page should use.
     *
     * This depends on numerous $CFG settings, and the properties of this page.
     *
     * @return string the name of the theme that should be used on this page.
     */
    protected function resolve_theme() {
        global $CFG, $USER, $SESSION;

        if (empty($CFG->themeorder)) {
            $themeorder = array('course', 'category', 'session', 'user', 'site');
        } else {
            $themeorder = $CFG->themeorder;
            // Just in case, make sure we always use the site theme if nothing else matched.
            $themeorder[] = 'site';
        }

        $mnetpeertheme = '';
        if (isloggedin() and isset($CFG->mnet_localhost_id) and $USER->mnethostid != $CFG->mnet_localhost_id) {
            require_once($CFG->dirroot.'/mnet/peer.php');
            $mnetpeer = new mnet_peer();
            $mnetpeer->set_id($USER->mnethostid);
            if ($mnetpeer->force_theme == 1 && $mnetpeer->theme != '') {
                $mnetpeertheme = $mnetpeer->theme;
            }
        }

        foreach ($themeorder as $themetype) {
            switch ($themetype) {
                case 'course':
                    if (!empty($CFG->allowcoursethemes) && !empty($this->_course->theme) && $this->devicetypeinuse == 'default') {
                        return $this->_course->theme;
                    }

                case 'category':
                    if (!empty($CFG->allowcategorythemes) && $this->devicetypeinuse == 'default') {
                        $categories = $this->categories;
                        foreach ($categories as $category) {
                            if (!empty($category->theme)) {
                                return $category->theme;
                            }
                        }
                    }

                case 'session':
                    if (!empty($SESSION->theme)) {
                        return $SESSION->theme;
                    }

                case 'user':
                    if (!empty($CFG->allowuserthemes) && !empty($USER->theme) && $this->devicetypeinuse == 'default') {
                        if ($mnetpeertheme) {
                            return $mnetpeertheme;
                        } else {
                            return $USER->theme;
                        }
                    }

                case 'site':
                    if ($mnetpeertheme) {
                        return $mnetpeertheme;
                    }
                    // First try for the device the user is using.
                    $devicetheme = get_selected_theme_for_device_type($this->devicetypeinuse);
                    if (!empty($devicetheme)) {
                        return $devicetheme;
                    }
                    // Next try for the default device (as a fallback)
                    $devicetheme = get_selected_theme_for_device_type('default');
                    if (!empty($devicetheme)) {
                        return $devicetheme;
                    }
                    // The default device theme isn't set up - use the overall default theme.
                    return theme_config::DEFAULT_THEME;
            }
        }
    }
//                    Yes, enrol is correct English spelling.
require_once dirname(__FILE__) . "/../../config.php";
require_once $CFG->libdir . '/adminlib.php';
include_once $CFG->dirroot . '/mnet/xmlrpc/client.php';
if (!confirm_sesskey()) {
    error(get_string('confirmsesskeybad', 'error'));
}
admin_externalpage_setup('mnetenrol');
$CFG->pagepath = 'admin/mnet';
require_once "{$CFG->dirroot}/enrol/enrol.class.php";
/// Open the factory class
$enrolment = enrolment_factory::factory('mnet');
$mnethostid = required_param('host', PARAM_INT);
$courseid = required_param('courseid', PARAM_INT);
$mnet_peer = new mnet_peer();
if (!$mnet_peer->set_id($mnethostid)) {
    print_error('hostcoursenotfound', 'mnet');
}
$course = get_record('mnet_enrol_course', 'id', $courseid, 'hostid', $mnet_peer->id);
if (empty($course)) {
    print_error('hostcoursenotfound', 'mnet');
}
define("MAX_USERS_PER_PAGE", 5000);
$add = optional_param('add', 0, PARAM_BOOL);
$remove = optional_param('remove', 0, PARAM_BOOL);
$showall = optional_param('showall', 0, PARAM_BOOL);
$searchtext = optional_param('searchtext', '', PARAM_RAW);
// search string
$previoussearch = optional_param('previoussearch', 0, PARAM_BOOL);
$userid = optional_param('userid', 0, PARAM_INT);
// needed for user tabs
示例#18
0
/**
 * This function is used to generate and display Mnet selector form
 *
 * @global stdClass $USER
 * @global stdClass $CFG
 * @global stdClass $SITE
 * @global moodle_database $DB
 * @global core_renderer $OUTPUT
 * @global stdClass $SESSION
 * @uses CONTEXT_SYSTEM
 * @uses COURSE_MAX_COURSES_PER_DROPDOWN
 * @uses CONTEXT_COURSE
 * @uses SEPARATEGROUPS
 * @param  int      $hostid host id
 * @param  stdClass $course course instance
 * @param  int      $selecteduser id of the selected user
 * @param  string   $selecteddate Date selected
 * @param  string   $modname course_module->id
 * @param  string   $modid number or 'site_errors'
 * @param  string   $modaction an action as recorded in the logs
 * @param  int      $selectedgroup Group to display
 * @param  int      $showcourses whether to show courses if we're over our limit.
 * @param  int      $showusers whether to show users if we're over our limit.
 * @param  string   $logformat Format of the logs (downloadascsv, showashtml, downloadasods, downloadasexcel)
 * @return void
 */
function report_log_print_mnet_selector_form($hostid, $course, $selecteduser = 0, $selecteddate = 'today', $modname = "", $modid = 0, $modaction = '', $selectedgroup = -1, $showcourses = 0, $showusers = 0, $logformat = 'showashtml')
{
    global $USER, $CFG, $SITE, $DB, $OUTPUT, $SESSION;
    require_once $CFG->dirroot . '/mnet/peer.php';
    $mnet_peer = new mnet_peer();
    $mnet_peer->set_id($hostid);
    $sql = "SELECT DISTINCT course, hostid, coursename FROM {mnet_log}";
    $courses = $DB->get_records_sql($sql);
    $remotecoursecount = count($courses);
    // first check to see if we can override showcourses and showusers
    $numcourses = $remotecoursecount + $DB->count_records('course');
    if ($numcourses < COURSE_MAX_COURSES_PER_DROPDOWN && !$showcourses) {
        $showcourses = 1;
    }
    $sitecontext = get_context_instance(CONTEXT_SYSTEM);
    // Context for remote data is always SITE
    // Groups for remote data are always OFF
    if ($hostid == $CFG->mnet_localhost_id) {
        $context = get_context_instance(CONTEXT_COURSE, $course->id);
        /// Setup for group handling.
        if ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
            $selectedgroup = -1;
            $showgroups = false;
        } else {
            if ($course->groupmode) {
                $showgroups = true;
            } else {
                $selectedgroup = 0;
                $showgroups = false;
            }
        }
        if ($selectedgroup === -1) {
            if (isset($SESSION->currentgroup[$course->id])) {
                $selectedgroup = $SESSION->currentgroup[$course->id];
            } else {
                $selectedgroup = groups_get_all_groups($course->id, $USER->id);
                if (is_array($selectedgroup)) {
                    $selectedgroup = array_shift(array_keys($selectedgroup));
                    $SESSION->currentgroup[$course->id] = $selectedgroup;
                } else {
                    $selectedgroup = 0;
                }
            }
        }
    } else {
        $context = $sitecontext;
    }
    // Get all the possible users
    $users = array();
    // Define limitfrom and limitnum for queries below
    // If $showusers is enabled... don't apply limitfrom and limitnum
    $limitfrom = empty($showusers) ? 0 : '';
    $limitnum = empty($showusers) ? COURSE_MAX_USERS_PER_DROPDOWN + 1 : '';
    // If looking at a different host, we're interested in all our site users
    if ($hostid == $CFG->mnet_localhost_id && $course->id != SITEID) {
        $courseusers = get_enrolled_users($context, '', $selectedgroup, 'u.id, u.firstname, u.lastname, u.idnumber', 'lastname ASC, firstname ASC', $limitfrom, $limitnum);
    } else {
        // this may be a lot of users :-(
        $courseusers = $DB->get_records('user', array('deleted' => 0), 'lastaccess DESC', 'id, firstname, lastname, idnumber', $limitfrom, $limitnum);
    }
    if (count($courseusers) < COURSE_MAX_USERS_PER_DROPDOWN && !$showusers) {
        $showusers = 1;
    }
    if ($showusers) {
        if ($courseusers) {
            foreach ($courseusers as $courseuser) {
                $users[$courseuser->id] = fullname($courseuser, has_capability('moodle/site:viewfullnames', $context));
            }
        }
        $users[$CFG->siteguest] = get_string('guestuser');
    }
    // Get all the hosts that have log records
    $sql = "select distinct\n                h.id,\n                h.name\n            from\n                {mnet_host} h,\n                {mnet_log} l\n            where\n                h.id = l.hostid\n            order by\n                h.name";
    if ($hosts = $DB->get_records_sql($sql)) {
        foreach ($hosts as $host) {
            $hostarray[$host->id] = $host->name;
        }
    }
    $hostarray[$CFG->mnet_localhost_id] = $SITE->fullname;
    asort($hostarray);
    $dropdown = array();
    foreach ($hostarray as $hostid => $name) {
        $courses = array();
        $sites = array();
        if ($CFG->mnet_localhost_id == $hostid) {
            if (has_capability('report/log:view', $sitecontext) && $showcourses) {
                if ($ccc = $DB->get_records("course", null, "fullname", "id,shortname,fullname,category")) {
                    foreach ($ccc as $cc) {
                        if ($cc->id == SITEID) {
                            $sites["{$hostid}/{$cc->id}"] = format_string($cc->fullname) . ' (' . get_string('site') . ')';
                        } else {
                            $courses["{$hostid}/{$cc->id}"] = format_string(get_course_display_name_for_list($cc));
                        }
                    }
                }
            }
        } else {
            if (has_capability('report/log:view', $sitecontext) && $showcourses) {
                $sql = "SELECT DISTINCT course, coursename FROM {mnet_log} where hostid = ?";
                if ($ccc = $DB->get_records_sql($sql, array($hostid))) {
                    foreach ($ccc as $cc) {
                        if (1 == $cc->course) {
                            // TODO: this might be wrong - site course may have another id
                            $sites["{$hostid}/{$cc->course}"] = $cc->coursename . ' (' . get_string('site') . ')';
                        } else {
                            $courses["{$hostid}/{$cc->course}"] = $cc->coursename;
                        }
                    }
                }
            }
        }
        asort($courses);
        $dropdown[] = array($name => $sites + $courses);
    }
    $activities = array();
    $selectedactivity = "";
    /// Casting $course->modinfo to string prevents one notice when the field is null
    if ($modinfo = unserialize((string) $course->modinfo)) {
        $section = 0;
        $sections = get_all_sections($course->id);
        foreach ($modinfo as $mod) {
            if ($mod->mod == "label") {
                continue;
            }
            if ($mod->section > 0 and $section != $mod->section) {
                $activities["section/{$mod->section}"] = '--- ' . get_section_name($course, $sections[$mod->section]) . ' ---';
            }
            $section = $mod->section;
            $mod->name = strip_tags(format_string($mod->name, true));
            if (textlib::strlen($mod->name) > 55) {
                $mod->name = textlib::substr($mod->name, 0, 50) . "...";
            }
            if (!$mod->visible) {
                $mod->name = "(" . $mod->name . ")";
            }
            $activities["{$mod->cm}"] = $mod->name;
            if ($mod->cm == $modid) {
                $selectedactivity = "{$mod->cm}";
            }
        }
    }
    if (has_capability('report/log:view', $sitecontext) && !$course->category) {
        $activities["site_errors"] = get_string("siteerrors");
        if ($modid === "site_errors") {
            $selectedactivity = "site_errors";
        }
    }
    $strftimedate = get_string("strftimedate");
    $strftimedaydate = get_string("strftimedaydate");
    asort($users);
    // Prepare the list of action options.
    $actions = array('view' => get_string('view'), 'add' => get_string('add'), 'update' => get_string('update'), 'delete' => get_string('delete'), '-view' => get_string('allchanges'));
    // Get all the possible dates
    // Note that we are keeping track of real (GMT) time and user time
    // User time is only used in displays - all calcs and passing is GMT
    $timenow = time();
    // GMT
    // What day is it now for the user, and when is midnight that day (in GMT).
    $timemidnight = $today = usergetmidnight($timenow);
    // Put today up the top of the list
    $dates = array("0" => get_string('alldays'), "{$timemidnight}" => get_string("today") . ", " . userdate($timenow, $strftimedate));
    if (!$course->startdate or $course->startdate > $timenow) {
        $course->startdate = $course->timecreated;
    }
    $numdates = 1;
    while ($timemidnight > $course->startdate and $numdates < 365) {
        $timemidnight = $timemidnight - 86400;
        $timenow = $timenow - 86400;
        $dates["{$timemidnight}"] = userdate($timenow, $strftimedaydate);
        $numdates++;
    }
    if ($selecteddate === "today") {
        $selecteddate = $today;
    }
    echo "<form class=\"logselectform\" action=\"{$CFG->wwwroot}/report/log/index.php\" method=\"get\">\n";
    echo "<div>\n";
    //invisible fieldset here breaks wrapping
    echo "<input type=\"hidden\" name=\"chooselog\" value=\"1\" />\n";
    echo "<input type=\"hidden\" name=\"showusers\" value=\"{$showusers}\" />\n";
    echo "<input type=\"hidden\" name=\"showcourses\" value=\"{$showcourses}\" />\n";
    if (has_capability('report/log:view', $sitecontext) && $showcourses) {
        $cid = empty($course->id) ? '1' : $course->id;
        echo html_writer::label(get_string('selectacoursesite'), 'menuhost_course', false, array('class' => 'accesshide'));
        echo html_writer::select($dropdown, "host_course", $hostid . '/' . $cid);
    } else {
        $courses = array();
        $courses[$course->id] = get_course_display_name_for_list($course) . (empty($course->category) ? ' (' . get_string('site') . ') ' : '');
        echo html_writer::label(get_string('selectacourse'), 'menuid', false, array('class' => 'accesshide'));
        echo html_writer::select($courses, "id", $course->id, false);
        if (has_capability('report/log:view', $sitecontext)) {
            $a = new stdClass();
            $a->url = "{$CFG->wwwroot}/report/log/index.php?chooselog=0&group={$selectedgroup}&user={$selecteduser}" . "&id={$course->id}&date={$selecteddate}&modid={$selectedactivity}&showcourses=1&showusers={$showusers}";
            print_string('logtoomanycourses', 'moodle', $a);
        }
    }
    if ($showgroups) {
        if ($cgroups = groups_get_all_groups($course->id)) {
            foreach ($cgroups as $cgroup) {
                $groups[$cgroup->id] = $cgroup->name;
            }
        } else {
            $groups = array();
        }
        echo html_writer::label(get_string('selectagroup'), 'menugroup', false, array('class' => 'accesshide'));
        echo html_writer::select($groups, "group", $selectedgroup, get_string("allgroups"));
    }
    if ($showusers) {
        echo html_writer::label(get_string('participantslist'), 'menuuser', false, array('class' => 'accesshide'));
        echo html_writer::select($users, "user", $selecteduser, get_string("allparticipants"));
    } else {
        $users = array();
        if (!empty($selecteduser)) {
            $user = $DB->get_record('user', array('id' => $selecteduser));
            $users[$selecteduser] = fullname($user);
        } else {
            $users[0] = get_string('allparticipants');
        }
        echo html_writer::label(get_string('participantslist'), 'menuuser', false, array('class' => 'accesshide'));
        echo html_writer::select($users, "user", $selecteduser, false);
        $a->url = "{$CFG->wwwroot}/report/log/index.php?chooselog=0&group={$selectedgroup}&user={$selecteduser}" . "&id={$course->id}&date={$selecteddate}&modid={$selectedactivity}&showusers=1&showcourses={$showcourses}";
        print_string('logtoomanyusers', 'moodle', $a);
    }
    echo html_writer::label(get_string('date'), 'menudate', false, array('class' => 'accesshide'));
    echo html_writer::select($dates, "date", $selecteddate, false);
    echo html_writer::label(get_string('showreports'), 'menumodid', false, array('class' => 'accesshide'));
    echo html_writer::select($activities, "modid", $selectedactivity, get_string("allactivities"));
    echo html_writer::label(get_string('actions'), 'menumodaction', false, array('class' => 'accesshide'));
    echo html_writer::select($actions, 'modaction', $modaction, get_string("allactions"));
    $logformats = array('showashtml' => get_string('displayonpage'), 'downloadascsv' => get_string('downloadtext'), 'downloadasods' => get_string('downloadods'), 'downloadasexcel' => get_string('downloadexcel'));
    echo html_writer::label(get_string('logsformat', 'report_log'), 'menulogformat', false, array('class' => 'accesshide'));
    echo html_writer::select($logformats, 'logformat', $logformat, false);
    echo '<input type="submit" value="' . get_string('gettheselogs') . '" />';
    echo '</div>';
    echo '</form>';
}
示例#19
0
function print_mnet_log_selector_form($hostid, $course, $selecteduser = 0, $selecteddate = 'today', $modname = "", $modid = 0, $modaction = '', $selectedgroup = -1, $showcourses = 0, $showusers = 0, $logformat = 'showashtml')
{
    global $USER, $CFG, $SITE;
    require_once $CFG->dirroot . '/mnet/peer.php';
    $mnet_peer = new mnet_peer();
    $mnet_peer->set_id($hostid);
    $sql = "select distinct course, hostid, coursename from {$CFG->prefix}mnet_log";
    $courses = get_records_sql($sql);
    $remotecoursecount = count($courses);
    // first check to see if we can override showcourses and showusers
    $numcourses = $remotecoursecount + count_records_select("course", "", "COUNT(id)");
    if ($numcourses < COURSE_MAX_COURSES_PER_DROPDOWN && !$showcourses) {
        $showcourses = 1;
    }
    $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
    // Context for remote data is always SITE
    // Groups for remote data are always OFF
    if ($hostid == $CFG->mnet_localhost_id) {
        $context = get_context_instance(CONTEXT_COURSE, $course->id);
        /// Setup for group handling.
        if ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
            $selectedgroup = get_current_group($course->id);
            $showgroups = false;
        } else {
            if ($course->groupmode) {
                $selectedgroup = $selectedgroup == -1 ? get_current_group($course->id) : $selectedgroup;
                $showgroups = true;
            } else {
                $selectedgroup = 0;
                $showgroups = false;
            }
        }
    } else {
        $context = $sitecontext;
    }
    // Get all the possible users
    $users = array();
    // If looking at a different host, we're interested in all our site users
    if ($hostid == $CFG->mnet_localhost_id && $course->id != SITEID) {
        if ($selectedgroup) {
            // If using a group, only get users in that group.
            $courseusers = get_group_users($selectedgroup, 'u.lastname ASC', '', 'u.id, u.firstname, u.lastname, u.idnumber');
        } else {
            $courseusers = get_course_users($course->id, '', '', 'u.id, u.firstname, u.lastname, u.idnumber');
        }
    } else {
        $courseusers = get_site_users("u.lastaccess DESC", "u.id, u.firstname, u.lastname, u.idnumber");
    }
    if (count($courseusers) < COURSE_MAX_USERS_PER_DROPDOWN && !$showusers) {
        $showusers = 1;
    }
    if ($showusers) {
        if ($courseusers) {
            foreach ($courseusers as $courseuser) {
                $users[$courseuser->id] = fullname($courseuser, has_capability('moodle/site:viewfullnames', $context));
            }
        }
        if ($guest = get_guest()) {
            $users[$guest->id] = fullname($guest);
        }
    }
    // Get all the hosts that have log records
    $sql = "select distinct\n                h.id,\n                h.name\n            from\n                {$CFG->prefix}mnet_host h,\n                {$CFG->prefix}mnet_log l\n            where\n                h.id = l.hostid\n            order by\n                h.name";
    if ($hosts = get_records_sql($sql)) {
        foreach ($hosts as $host) {
            $hostarray[$host->id] = $host->name;
        }
    }
    $hostarray[$CFG->mnet_localhost_id] = $SITE->fullname;
    asort($hostarray);
    foreach ($hostarray as $hostid => $name) {
        $courses = array();
        $sites = array();
        if ($CFG->mnet_localhost_id == $hostid) {
            if (has_capability('moodle/site:viewreports', $sitecontext) && $showcourses) {
                if ($ccc = get_records("course", "", "", "fullname", "id,fullname,category")) {
                    foreach ($ccc as $cc) {
                        if ($cc->id == SITEID) {
                            $sites["{$hostid}/{$cc->id}"] = format_string($cc->fullname) . ' (' . get_string('site') . ')';
                        } else {
                            $courses["{$hostid}/{$cc->id}"] = format_string($cc->fullname);
                        }
                    }
                }
            }
        } else {
            if (has_capability('moodle/site:viewreports', $sitecontext) && $showcourses) {
                $sql = "select distinct course, coursename from {$CFG->prefix}mnet_log where hostid = '{$hostid}'";
                if ($ccc = get_records_sql($sql)) {
                    foreach ($ccc as $cc) {
                        if (1 == $cc->course) {
                            // TODO: this might be wrong - site course may have another id
                            $sites["{$hostid}/{$cc->course}"] = $cc->coursename . ' (' . get_string('site') . ')';
                        } else {
                            $courses["{$hostid}/{$cc->course}"] = $cc->coursename;
                        }
                    }
                }
            }
        }
        asort($courses);
        $dropdown[$name] = $sites + $courses;
    }
    $activities = array();
    $selectedactivity = "";
    /// Casting $course->modinfo to string prevents one notice when the field is null
    if ($modinfo = unserialize((string) $course->modinfo)) {
        $section = 0;
        if ($course->format == 'weeks') {
            // Bodgy
            $strsection = get_string("week");
        } else {
            $strsection = get_string("topic");
        }
        foreach ($modinfo as $mod) {
            if ($mod->mod == "label") {
                continue;
            }
            if ($mod->section > 0 and $section != $mod->section) {
                $activities["section/{$mod->section}"] = "-------------- {$strsection} {$mod->section} --------------";
            }
            $section = $mod->section;
            $mod->name = strip_tags(format_string(urldecode($mod->name), true));
            if (strlen($mod->name) > 55) {
                $mod->name = substr($mod->name, 0, 50) . "...";
            }
            if (!$mod->visible) {
                $mod->name = "(" . $mod->name . ")";
            }
            $activities["{$mod->cm}"] = $mod->name;
            if ($mod->cm == $modid) {
                $selectedactivity = "{$mod->cm}";
            }
        }
    }
    if (has_capability('moodle/site:viewreports', $sitecontext) && !$course->category) {
        $activities["site_errors"] = get_string("siteerrors");
        if ($modid === "site_errors") {
            $selectedactivity = "site_errors";
        }
    }
    $strftimedate = get_string("strftimedate");
    $strftimedaydate = get_string("strftimedaydate");
    asort($users);
    // Prepare the list of action options.
    $actions = array('view' => get_string('view'), 'add' => get_string('add'), 'update' => get_string('update'), 'delete' => get_string('delete'), '-view' => get_string('allchanges'));
    // Get all the possible dates
    // Note that we are keeping track of real (GMT) time and user time
    // User time is only used in displays - all calcs and passing is GMT
    $timenow = time();
    // GMT
    // What day is it now for the user, and when is midnight that day (in GMT).
    $timemidnight = $today = usergetmidnight($timenow);
    // Put today up the top of the list
    $dates = array("{$timemidnight}" => get_string("today") . ", " . userdate($timenow, $strftimedate));
    if (!$course->startdate or $course->startdate > $timenow) {
        $course->startdate = $course->timecreated;
    }
    $numdates = 1;
    while ($timemidnight > $course->startdate and $numdates < 365) {
        $timemidnight = $timemidnight - 86400;
        $timenow = $timenow - 86400;
        $dates["{$timemidnight}"] = userdate($timenow, $strftimedaydate);
        $numdates++;
    }
    if ($selecteddate == "today") {
        $selecteddate = $today;
    }
    echo "<form class=\"logselectform\" action=\"{$CFG->wwwroot}/course/report/log/index.php\" method=\"get\">\n";
    echo "<div>\n";
    //invisible fieldset here breaks wrapping
    echo "<input type=\"hidden\" name=\"chooselog\" value=\"1\" />\n";
    echo "<input type=\"hidden\" name=\"showusers\" value=\"{$showusers}\" />\n";
    echo "<input type=\"hidden\" name=\"showcourses\" value=\"{$showcourses}\" />\n";
    if (has_capability('moodle/site:viewreports', $sitecontext) && $showcourses) {
        $cid = empty($course->id) ? '1' : $course->id;
        choose_from_menu_nested($dropdown, "host_course", $hostid . '/' . $cid, "");
    } else {
        $courses = array();
        $courses[$course->id] = $course->fullname . (empty($course->category) ? ' (' . get_string('site') . ') ' : '');
        choose_from_menu($courses, "id", $course->id, false);
        if (has_capability('moodle/site:viewreports', $sitecontext)) {
            $a = new object();
            $a->url = "{$CFG->wwwroot}/course/report/log/index.php?chooselog=0&group={$selectedgroup}&user={$selecteduser}" . "&id={$course->id}&date={$selecteddate}&modid={$selectedactivity}&showcourses=1&showusers={$showusers}";
            print_string('logtoomanycourses', 'moodle', $a);
        }
    }
    if ($showgroups) {
        if ($cgroups = groups_get_all_groups($course->id)) {
            foreach ($cgroups as $cgroup) {
                $groups[$cgroup->id] = $cgroup->name;
            }
        } else {
            $groups = array();
        }
        choose_from_menu($groups, "group", $selectedgroup, get_string("allgroups"));
    }
    if ($showusers) {
        choose_from_menu($users, "user", $selecteduser, get_string("allparticipants"));
    } else {
        $users = array();
        if (!empty($selecteduser)) {
            $user = get_record('user', 'id', $selecteduser);
            $users[$selecteduser] = fullname($user);
        } else {
            $users[0] = get_string('allparticipants');
        }
        choose_from_menu($users, 'user', $selecteduser, false);
        $a->url = "{$CFG->wwwroot}/course/report/log/index.php?chooselog=0&group={$selectedgroup}&user={$selecteduser}" . "&id={$course->id}&date={$selecteddate}&modid={$selectedactivity}&showusers=1&showcourses={$showcourses}";
        print_string('logtoomanyusers', 'moodle', $a);
    }
    choose_from_menu($dates, "date", $selecteddate, get_string("alldays"));
    choose_from_menu($activities, "modid", $selectedactivity, get_string("allactivities"), "", "");
    choose_from_menu($actions, 'modaction', $modaction, get_string("allactions"));
    $logformats = array('showashtml' => get_string('displayonpage'), 'downloadascsv' => get_string('downloadtext'), 'downloadasods' => get_string('downloadods'), 'downloadasexcel' => get_string('downloadexcel'));
    choose_from_menu($logformats, 'logformat', $logformat, false);
    echo '<input type="submit" value="' . get_string('gettheselogs') . '" />';
    echo '</div>';
    echo '</form>';
}
 /**
  * Send Mnet request to Mahara portfolio.
  *
  * @global stdClass $CFG
  * @param string $methodname name of remote method to call
  * @param array $parameters list of method parameters
  * @return mixed $responsedata Mnet response
  */
 private function mnet_send_request($methodname, $parameters)
 {
     global $CFG;
     $error = false;
     $responsedata = false;
     if (!is_enabled_auth('mnet')) {
         $error = get_string('authmnetdisabled', 'mnet');
     } else {
         if (!has_capability('moodle/site:mnetlogintoremote', context_system::instance())) {
             $error = get_string('notpermittedtojump', 'mnet');
         } else {
             // Set up the RPC request.
             require_once $CFG->dirroot . '/mnet/xmlrpc/client.php';
             require_once $CFG->dirroot . '/mnet/peer.php';
             $mnetpeer = new mnet_peer();
             $mnetpeer->set_id($this->get_config('mnethostid'));
             $mnetrequest = new mnet_xmlrpc_client();
             $mnetrequest->set_method('mod/mahara/rpclib.php/' . $methodname);
             foreach ($parameters as $parameter) {
                 $mnetrequest->add_param($parameter);
             }
             if ($mnetrequest->send($mnetpeer) === true) {
                 $responsedata = $mnetrequest->response;
             } else {
                 $error = "RPC mod/mahara/rpclib.php/" . $methodname . ":<br/>";
                 foreach ($mnetrequest->error as $errormessage) {
                     list($code, $errormessage) = array_map('trim', explode(':', $errormessage, 2));
                     $error .= "ERROR {$code}:<br/>{$errormessage}<br/>";
                 }
             }
         }
     }
     if ($error) {
         $this->set_error($error);
     }
     return $responsedata;
 }