diff options
| author | Sem <sembrestels@riseup.net> | 2013-11-09 16:25:34 +0100 | 
|---|---|---|
| committer | Sem <sembrestels@riseup.net> | 2013-11-09 16:25:34 +0100 | 
| commit | 2161e2335c9c650b8e44a56f6c9b0bd37546ae1f (patch) | |
| tree | 91bef55b773a7a80b5f6a065411574bdbe9fe522 /mod/openid_client/classes/ElggOpenIDConsumer.php | |
| parent | a9ac4c861335e60373c1e99b61372e6e0d6ac9f4 (diff) | |
| parent | 11ea6ae4734a0e722c6ecaaee90e9ab772e8d2cc (diff) | |
| download | elgg-2161e2335c9c650b8e44a56f6c9b0bd37546ae1f.tar.gz elgg-2161e2335c9c650b8e44a56f6c9b0bd37546ae1f.tar.bz2 | |
Add 'mod/openid_client/' from commit '11ea6ae4734a0e722c6ecaaee90e9ab772e8d2cc'
git-subtree-dir: mod/openid_client
git-subtree-mainline: a9ac4c861335e60373c1e99b61372e6e0d6ac9f4
git-subtree-split: 11ea6ae4734a0e722c6ecaaee90e9ab772e8d2cc
Diffstat (limited to 'mod/openid_client/classes/ElggOpenIDConsumer.php')
| -rw-r--r-- | mod/openid_client/classes/ElggOpenIDConsumer.php | 238 | 
1 files changed, 238 insertions, 0 deletions
| diff --git a/mod/openid_client/classes/ElggOpenIDConsumer.php b/mod/openid_client/classes/ElggOpenIDConsumer.php new file mode 100644 index 000000000..098201343 --- /dev/null +++ b/mod/openid_client/classes/ElggOpenIDConsumer.php @@ -0,0 +1,238 @@ +<?php +/** + * Consumer for OpenID + */ + +class ElggOpenIDConsumer { + +	protected $openIdUrl; +	protected $returnURL; + +	protected $store; +	protected $consumer; +	protected $request; + +	/** +	 * Constructor +	 * +	 * @param Auth_OpenID_OpenIDStore $store Optional persistence store +	 */ +	public function __construct(Auth_OpenID_OpenIDStore $store = null) { +		if ($store) { +			$this->store = $store; +		} else { +			// use the default store +			$this->store = new OpenID_ElggStore(); +		} +	} + +	/** +	 * Set the OpenID username +	 * +	 * @param string $username +	 */ +	public function setURL($url) { +		$this->openIdUrl = $url; +	} + +	/** +	 * Set the return URL +	 * +	 * @param string $url The URL the OpenID provider returns the user to +	 */ +	public function setReturnURL($url) { +		$this->returnURL = $url; +	} + +	/** +	 * Send a request to the provider for authentication +	 * +	 * @return mixed HTMl form on success and false for failure +	 */ +	public function requestAuthentication() { + +		if (!$this->store) { +			return false; +		} + +		$this->consumer = new Auth_OpenID_Consumer($this->store); +		if (!$this->consumer) { +			return false; +		} + +		$url = $this->openIdUrl; +		if (!$url) { +			return false; +		} + +		// discovers the identity server +		$this->request = $this->consumer->begin($url); +		if (!$this->request) { +			return false; +		} + +		// request user information +		if (!$this->addAttributeRequests()) { +			return false; +		} + +		// send browser for authentication +		return $this->getForm(); +	} + +	/** +	 * Complete the OpenID authentication by parsing the response +	 * +	 * This returns an array of key value pairs about the user. +	 *  +	 * @return array +	 */ +	public function completeAuthentication() { + +		if (!$this->store) { +			return false; +		} + +		$this->consumer = new Auth_OpenID_Consumer($this->store); +		if (!$this->consumer) { +			return false; +		} + +		$response = $this->consumer->complete($this->returnURL); +		switch ($response->status) { +			case Auth_OpenID_SUCCESS: +				$data = $this->getUserData($response); +				break; +			case Auth_OpenID_FAILURE: +			case Auth_OpenID_CANCEL: +				$data = array(); +				break; +		} + +		return $data; +	} + +	/** +	 * Add attribute requests to the OpenID authentication request +	 *  +	 * @return bool +	 */ +	protected function addAttributeRequests() { + +		// Simple Registration +		$required = array(); +		$optional = array('email', 'nickname', 'fullname', 'language'); +		$sregRequest = Auth_OpenID_SRegRequest::build($required, $optional); +		if (!$sregRequest) { +			return false; +		} +		$this->request->addExtension($sregRequest); + +		// Attribute Exchange +		$axRequest = new Auth_OpenID_AX_FetchRequest(); +		$attributes[] = Auth_OpenID_AX_AttrInfo::make('http://axschema.org/contact/email', 1, true, 'email'); +		$attributes[] = Auth_OpenID_AX_AttrInfo::make('http://axschema.org/namePerson/first', 1, true, 'firstname'); +		$attributes[] = Auth_OpenID_AX_AttrInfo::make('http://axschema.org/namePerson/last', 1, true, 'lastname'); +		foreach ($attributes as $attribute) { +			$axRequest->add($attribute); +		} +		$this->request->addExtension($axRequest); + +		return true; +	} + +	/** +	 * Gets the form to send the user to the provider to authenticate +	 * +	 * This implements OpenID 2.0 by submitting a form through JavaScript against +	 * the provider. If JavaScript is not enabled, a plain html form with a +	 * continue button is displayed. +	 * +	 * This also supports OpenID 1.x but has not been tested as thoroughly. +	 * +	 * @return mixed +	 */ +	protected function getForm() { +		if (!$this->request->shouldSendRedirect()) { +			// OpenID 2.0 +			$html = $this->request->htmlMarkup(elgg_get_site_url(), $this->returnURL, false); +			return $html; +		} else { +			// OpenID 1.x +			$redirect_url = $this->request->redirectURL(elgg_get_site_url(), $this->returnURL); + +			if (Auth_OpenID::isFailure($redirect_url)) { +				return false; +			} else { +				forward($redirect_url); +			} +		} +	} + +	/** +	 * Get user data from the OpenID response +	 *  +	 * @param Auth_OpenID_ConsumerResponse $response +	 * @return array +	 */ +	protected function getUserData($response) { +		if (!$response) { +			return array(); +		} + +		$sregResponse = Auth_OpenID_SRegResponse::fromSuccessResponse($response); +		$sreg = $sregResponse->contents(); + +		$axResponse = Auth_OpenID_AX_FetchResponse::fromSuccessResponse($response); +		$ax = $axResponse->data; + +		$data = $this->extractUserData($sreg, $ax); +		$data['openid_identifier'] = $response->getDisplayIdentifier(); + +		return $data; +	} + +	/** +	 * Extract user data from the extensions in the response +	 * +	 * @param array $sreg Simple Registration data +	 * @param array $ax   Attribute Exchange data +	 * @return array +	 */ +	protected function extractUserData($sreg, $ax) { +		$data = array(); + +		// email +		if (isset($sreg['email'])) { +			$data['email'] = $sreg['email']; +		} +		if (isset($ax['http://axschema.org/contact/email'])) { +			$data['email'] = $ax['http://axschema.org/contact/email'][0]; +		} + +		// display name +		if (isset($sreg['fullname'])) { +			$data['name'] = $sreg['fullname']; +		} +		if (isset($ax['http://axschema.org/namePerson/first'])) { +			$data['name'] = $ax['http://axschema.org/namePerson/first'][0]; +		} +		if (isset($ax['http://axschema.org/namePerson/last'])) { +			$data['name'] .= ' ' . $ax['http://axschema.org/namePerson/last'][0]; +			$data['name'] = trim($data['name']); +		} + +		// username +		if (isset($sreg['nickname'])) { +			$data['username'] = $sreg['nickname']; +		} + +		// language +		if (isset($sreg['language'])) { +			$languages = get_installed_translations(); +			// @todo - find out format +		} + +		return $data; +	} +} | 
