function answer($allow, $server_url = null, $identity = null, $claimed_id = null)
{
if (!$this->return_to) {
return new Auth_OpenID_NoReturnToError();
}
if (!$server_url) {
if (!$this->message->isOpenID1() && !$this->server->op_endpoint) {
return new Auth_OpenID_ServerError(null, "server should be constructed with op_endpoint to " . "respond to OpenID 2.0 messages.");
}
$server_url = $this->server->op_endpoint;
}
if ($allow) {
$mode = 'id_res';
} else {
if ($this->message->isOpenID1()) {
if ($this->immediate) {
$mode = 'id_res';
} else {
$mode = 'cancel';
}
} else {
if ($this->immediate) {
$mode = 'setup_needed';
} else {
$mode = 'cancel';
}
}
}
if (!$this->trustRootValid()) {
return new Auth_OpenID_UntrustedReturnURL(null, $this->return_to, $this->trust_root);
}
$response = new Auth_OpenID_ServerResponse($this);
if ($claimed_id && $this->message->isOpenID1()) {
return new Auth_OpenID_ServerError(null, "claimed_id is new in OpenID 2.0 and not " . "available for " . $this->namespace);
}
if ($identity && !$claimed_id) {
$claimed_id = $identity;
}
if ($allow) {
if ($this->identity == Auth_OpenID_IDENTIFIER_SELECT) {
if (!$identity) {
return new Auth_OpenID_ServerError(null, "This request uses IdP-driven identifier selection. " . "You must supply an identifier in the response.");
}
$response_identity = $identity;
$response_claimed_id = $claimed_id;
} else {
if ($this->identity) {
if ($identity && $this->identity != $identity) {
$fmt = "Request was for %s, cannot reply with identity %s";
return new Auth_OpenID_ServerError(null, sprintf($fmt, $this->identity, $identity));
}
$response_identity = $this->identity;
$response_claimed_id = $this->claimed_id;
} else {
if ($identity) {
return new Auth_OpenID_ServerError(null, "This request specified no identity and " . "you supplied " . $identity);
}
$response_identity = null;
}
}
if ($this->message->isOpenID1() && $response_identity === null) {
return new Auth_OpenID_ServerError(null, "Request was an OpenID 1 request, so response must " . "include an identifier.");
}
$response->fields->updateArgs(Auth_OpenID_OPENID_NS, array('mode' => $mode, 'return_to' => $this->return_to, 'response_nonce' => Auth_OpenID_mkNonce()));
if (!$this->message->isOpenID1()) {
$response->fields->setArg(Auth_OpenID_OPENID_NS, 'op_endpoint', $server_url);
}
if ($response_identity !== null) {
$response->fields->setArg(Auth_OpenID_OPENID_NS, 'identity', $response_identity);
if ($this->message->isOpenID2()) {
$response->fields->setArg(Auth_OpenID_OPENID_NS, 'claimed_id', $response_claimed_id);
}
}
} else {
$response->fields->setArg(Auth_OpenID_OPENID_NS, 'mode', $mode);
if ($this->immediate) {
if ($this->message->isOpenID1() && !$server_url) {
return new Auth_OpenID_ServerError(null, 'setup_url is required for $allow=false \\
in OpenID 1.x immediate mode.');
}
$setup_request = new Auth_OpenID_CheckIDRequest($this->identity, $this->return_to, $this->trust_root, false, $this->assoc_handle, $this->server, $this->claimed_id);
$setup_request->message = $this->message;
$setup_url = $setup_request->encodeToURL($server_url);
if ($setup_url === null) {
return new Auth_OpenID_NoReturnToError();
}
$response->fields->setArg(Auth_OpenID_OPENID_NS, 'user_setup_url', $setup_url);
}
}
return $response;
}