|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00024 define('AJAX_SCRIPT', true); 00025 define('NO_MOODLE_COOKIES', true); 00026 00027 require_once(dirname(dirname(__FILE__)) . '/config.php'); 00028 00029 $username = required_param('username', PARAM_USERNAME); 00030 $password = required_param('password', PARAM_RAW); 00031 $serviceshortname = required_param('service', PARAM_ALPHANUMEXT); 00032 00033 echo $OUTPUT->header(); 00034 00035 if (!$CFG->enablewebservices) { 00036 throw new moodle_exception('enablewsdescription', 'webservice'); 00037 } 00038 $username = trim(moodle_strtolower($username)); 00039 if (is_restored_user($username)) { 00040 throw new moodle_exception('restoredaccountresetpassword', 'webservice'); 00041 } 00042 $user = authenticate_user_login($username, $password); 00043 if (!empty($user)) { 00044 00045 //Non admin can not authenticate if maintenance mode 00046 $hassiteconfig = has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM), $user); 00047 if (!empty($CFG->maintenance_enabled) and !$hassiteconfig) { 00048 throw new moodle_exception('sitemaintenance', 'admin'); 00049 } 00050 00051 if (isguestuser($user)) { 00052 throw new moodle_exception('noguest'); 00053 } 00054 if (empty($user->confirmed)) { 00055 throw new moodle_exception('usernotconfirmed', 'moodle', '', $user->username); 00056 } 00057 // check credential expiry 00058 $userauth = get_auth_plugin($user->auth); 00059 if (!empty($userauth->config->expiration) and $userauth->config->expiration == 1) { 00060 $days2expire = $userauth->password_expire($user->username); 00061 if (intval($days2expire) < 0 ) { 00062 throw new moodle_exception('passwordisexpired', 'webservice'); 00063 } 00064 } 00065 00066 // let enrol plugins deal with new enrolments if necessary 00067 enrol_check_plugins($user); 00068 00069 // setup user session to check capability 00070 session_set_user($user); 00071 00072 //check if the service exists and is enabled 00073 $service = $DB->get_record('external_services', array('shortname' => $serviceshortname, 'enabled' => 1)); 00074 if (empty($service)) { 00075 // will throw exception if no token found 00076 throw new moodle_exception('servicenotavailable', 'webservice'); 00077 } 00078 00079 //check if there is any required system capability 00080 if ($service->requiredcapability and !has_capability($service->requiredcapability, get_context_instance(CONTEXT_SYSTEM), $user)) { 00081 throw new moodle_exception('missingrequiredcapability', 'webservice', '', $service->requiredcapability); 00082 } 00083 00084 //specific checks related to user restricted service 00085 if ($service->restrictedusers) { 00086 $authoriseduser = $DB->get_record('external_services_users', 00087 array('externalserviceid' => $service->id, 'userid' => $user->id)); 00088 00089 if (empty($authoriseduser)) { 00090 throw new moodle_exception('usernotallowed', 'webservice', '', $serviceshortname); 00091 } 00092 00093 if (!empty($authoriseduser->validuntil) and $authoriseduser->validuntil < time()) { 00094 throw new moodle_exception('invalidtimedtoken', 'webservice'); 00095 } 00096 00097 if (!empty($authoriseduser->iprestriction) and !address_in_subnet(getremoteaddr(), $authoriseduser->iprestriction)) { 00098 throw new moodle_exception('invalidiptoken', 'webservice'); 00099 } 00100 } 00101 00102 //Check if a token has already been created for this user and this service 00103 //Note: this could be an admin created or an user created token. 00104 // It does not really matter we take the first one that is valid. 00105 $tokenssql = "SELECT t.id, t.sid, t.token, t.validuntil, t.iprestriction 00106 FROM {external_tokens} t 00107 WHERE t.userid = ? AND t.externalserviceid = ? AND t.tokentype = ? 00108 ORDER BY t.timecreated ASC"; 00109 $tokens = $DB->get_records_sql($tokenssql, array($user->id, $service->id, EXTERNAL_TOKEN_PERMANENT)); 00110 00111 //A bit of sanity checks 00112 foreach ($tokens as $key=>$token) { 00113 00115 $unsettoken = false; 00116 //if sid is set then there must be a valid associated session no matter the token type 00117 if (!empty($token->sid)) { 00118 $session = session_get_instance(); 00119 if (!$session->session_exists($token->sid)){ 00120 //this token will never be valid anymore, delete it 00121 $DB->delete_records('external_tokens', array('sid'=>$token->sid)); 00122 $unsettoken = true; 00123 } 00124 } 00125 00126 //remove token if no valid anymore 00127 //Also delete this wrong token (similar logic to the web service servers 00128 // /webservice/lib.php/webservice_server::authenticate_by_token()) 00129 if (!empty($token->validuntil) and $token->validuntil < time()) { 00130 $DB->delete_records('external_tokens', array('token'=>$token->token, 'tokentype'=> EXTERNAL_TOKEN_PERMANENT)); 00131 $unsettoken = true; 00132 } 00133 00134 // remove token if its ip not in whitelist 00135 if (isset($token->iprestriction) and !address_in_subnet(getremoteaddr(), $token->iprestriction)) { 00136 $unsettoken = true; 00137 } 00138 00139 if ($unsettoken) { 00140 unset($tokens[$key]); 00141 } 00142 } 00143 00144 // if some valid tokens exist then use the most recent 00145 if (count($tokens) > 0) { 00146 $token = array_pop($tokens); 00147 } else { 00148 if ( ($serviceshortname == MOODLE_OFFICIAL_MOBILE_SERVICE and has_capability('moodle/webservice:createmobiletoken', get_system_context())) 00149 //Note: automatically token generation is not available to admin (they must create a token manually) 00150 or (!is_siteadmin($user) && has_capability('moodle/webservice:createtoken', get_system_context()))) { 00151 // if service doesn't exist, dml will throw exception 00152 $service_record = $DB->get_record('external_services', array('shortname'=>$serviceshortname, 'enabled'=>1), '*', MUST_EXIST); 00153 // create a new token 00154 $token = new stdClass; 00155 $token->token = md5(uniqid(rand(), 1)); 00156 $token->userid = $user->id; 00157 $token->tokentype = EXTERNAL_TOKEN_PERMANENT; 00158 $token->contextid = get_context_instance(CONTEXT_SYSTEM)->id; 00159 $token->creatorid = $user->id; 00160 $token->timecreated = time(); 00161 $token->externalserviceid = $service_record->id; 00162 $tokenid = $DB->insert_record('external_tokens', $token); 00163 add_to_log(SITEID, 'webservice', get_string('createtokenforuserauto', 'webservice'), '' , 'User ID: ' . $user->id); 00164 $token->id = $tokenid; 00165 } else { 00166 throw new moodle_exception('cannotcreatetoken', 'webservice', '', $serviceshortname); 00167 } 00168 } 00169 00170 // log token access 00171 $DB->set_field('external_tokens', 'lastaccess', time(), array('id'=>$token->id)); 00172 00173 add_to_log(SITEID, 'webservice', 'user request webservice token', '' , 'User ID: ' . $user->id); 00174 00175 $usertoken = new stdClass; 00176 $usertoken->token = $token->token; 00177 echo json_encode($usertoken); 00178 } else { 00179 throw new moodle_exception('usernamenotfound', 'moodle'); 00180 }