this exception happens for one or more of the following reasons (every if statement is a reason):
if (!is_enabled_auth('webservice')) {
throw new webservice_access_exception(get_string('wsauthnotenabled', 'webservice'));
}
if (!$auth = get_auth_plugin('webservice')) {
throw new webservice_access_exception(get_string('wsauthmissing', 'webservice'));
}
$this->restricted_context = get_context_instance(CONTEXT_SYSTEM);
if (!$this->username) {
throw new webservice_access_exception(get_string('missingusername', 'webservice'));
}
if (!$this->password) {
throw new webservice_access_exception(get_string('missingpassword', 'webservice'));
}
if (!$auth->user_login_webservice($this->username, $this->password)) {
// log failed login attempts
add_to_log(SITEID, 'webservice', get_string('simpleauthlog', 'webservice'), '' , get_string('failedtolog', 'webservice').": ".$this->username."/".$this->password." - ".getremoteaddr() , 0);
throw new webservice_access_exception(get_string('wrongusernamepassword', 'webservice'));
}
if ($this->authmethod != WEBSERVICE_AUTHMETHOD_SESSION_TOKEN && !has_capability("webservice/$this->wsname:use", $this->restricted_context)) {
throw new webservice_access_exception(get_string('accessnotallowed', 'webservice'));
}
if (!$token = $DB->get_record('external_tokens', array('token'=>$this->token, 'tokentype'=>$tokentype))) {
// log failed login attempts
add_to_log(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '' , get_string('failedtolog', 'webservice').": ".$this->token. " - ".getremoteaddr() , 0);
throw new webservice_access_exception(get_string('invalidtoken', 'webservice'));
}
if ($token->validuntil and $token->validuntil < time()) {
$DB->delete_records('external_tokens', array('token'=>$this->token, 'tokentype'=>$tokentype));
throw new webservice_access_exception(get_string('invalidtimedtoken', 'webservice'));
}
if ($token->sid){//assumes that if sid is set then there must be a valid associated session no matter the token type
$session = session_get_instance();
if (!$session->session_exists($token->sid)){
$DB->delete_records('external_tokens', array('sid'=>$token->sid));
throw new webservice_access_exception(get_string('invalidtokensession', 'webservice'));
}
}
if ($token->iprestriction and !address_in_subnet(getremoteaddr(), $token->iprestriction)) {
add_to_log(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '' , get_string('failedtolog', 'webservice').": ".getremoteaddr() , 0);
throw new webservice_access_exception(get_string('invalidiptoken', 'webservice'));
}
the last reason is little large:
$sql = "SELECT s.*, NULL AS iprestriction
FROM {external_services} s
JOIN {external_services_functions} sf ON (sf.externalserviceid = s.id AND s.restrictedusers = 0 AND sf.functionname = :name1)
WHERE s.enabled = 1 $wscond1
UNION
SELECT s.*, su.iprestriction
FROM {external_services} s
JOIN {external_services_functions} sf ON (sf.externalserviceid = s.id AND s.restrictedusers = 1 AND sf.functionname = :name2)
JOIN {external_services_users} su ON (su.externalserviceid = s.id AND su.userid = :userid)
WHERE s.enabled = 1 AND su.validuntil IS NULL OR su.validuntil < :now $wscond2";
$params = array_merge($params, array('userid'=>$USER->id, 'name1'=>$function->name, 'name2'=>$function->name, 'now'=>time()));
$rs = $DB->get_recordset_sql($sql, $params);
// now make sure user may access at least one service
$remoteaddr = getremoteaddr();
$allowed = false;
foreach ($rs as $service) {
if ($service->requiredcapability and !has_capability($service->requiredcapability, $this->restricted_context)) {
continue; // cap required, sorry
}
if ($service->iprestriction and !address_in_subnet($remoteaddr, $service->iprestriction)) {
continue; // wrong request source ip, sorry
}
$allowed = true;
break; // one service is enough, no need to continue
}
$rs->close();
if (!$allowed) {
throw new webservice_access_exception('Access to external function not allowed');
}