<?php defined('SYSPATH') or die('No direct access allowed.');

/**
 * This class extends Auth_ORM to enable external authentication
 *
 * @package    OAuth
 * @category   Classes
 * @author     Deon George
 * @copyright  (c) 2009-2013 Deon George
 * @license    http://dev.leenooks.net/license.html
 */
abstract class Auth_ORM_External_OAuth extends Auth_ORM_External {
	// OAuth Objects
	protected $consumer;
	protected $provider;
	protected $token;

	public function __construct(Model_Oauth $oo) {
		// If our user refused, then no point continuing
		if ($problem = Arr::get($_REQUEST,'oauth_problem'))
			switch ($problem) {
				case 'user_refused':
					HTTP::redirect('login');
				default:
					throw HTTP_Exception::factory(501,'Unknown OAuth Problem :problem',array(':problem'=>$problem));
			}
			
		parent::__construct($oo);

		// Load the provider
		$this->provider = OAuth_Provider::factory($this->oo->name);

		// Load the consumer for this provider
		$this->consumer = OAuth_Consumer::factory(array(
			'key'=>$this->oo->app_id,
			'secret'=>$this->oo->secret,
		));
	}

	protected function _login($user,$password,$remember) {
		// During login, we dont need to keep out token anymore
		Session::instance()->delete('oauth.token');

		return parent::_login($user,$password,$remember);
	}

	/**
	 * Is user currently log in??
	 * If we have a valid token, then we are.
	 */
	public function logged_in($role=NULL,$debug=NULL) {
		// Attempt to complete signin
		if ($verifier = Arr::get($_REQUEST,'oauth_verifier')) {
			// Restart the login process
			if (! $token = Session::instance()->get_once('oauth.request') OR $token->token !== Arr::get($_REQUEST,'oauth_token'))
				return FALSE;

			// Store the verifier in the token
			$token->verifier($verifier);

			// Exchange the request token for an access token
			$this->token = $this->provider->access_token($this->consumer,$token);

			// Store the access token
			Session::instance()->set('oauth.token',$this->token);

		// Otherwise try and get our token from our session.
		} else {
			$this->token = Session::instance()->get('oauth.token');
		}

		// @todo We need to check that the token is still valid.
		return $this->token ? TRUE : FALSE;
	}

	/**
	 * Our URL that starts the login process
	 */
	public function login_url() {
		// Add the callback URL to the consumer
		$this->consumer->callback(URL::site('oauth/login/'.$this->oo->name,TRUE));

		// Get a request token for the consumer
		$token = $this->provider->request_token($this->consumer);

		// Store the token
		Session::instance()->set('oauth.request',$token);

		// Get the login URL from the provider
		return $this->provider->authorize_url($token);
	}

	public function user_id() {
		return $this->provider->user_details($this->consumer,$this->token)->id();
	}
}
?>
