tao-test/app/tao/models/classes/oauth/DataStore.php

204 lines
7.4 KiB
PHP

<?php
/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2002-2008 (original work) Public Research Centre Henri Tudor & University of Luxembourg (under the project TAO & TAO2);
* 2008-2010 (update and modification) Deutsche Institut für Internationale Pädagogische Forschung (under the project TAO-TRANSFER);\n * 2009-2012 (update and modification) Public Research Centre Henri Tudor (under the project TAO-SUSTAIN & TAO-DEV);
* 2013 (update and modification) Open Assessment Technologies SA (under the project TAO-PRODUCT);
*
*/
namespace oat\tao\model\oauth;
use oat\tao\model\oauth\lockout\LockoutInterface;
use oat\tao\model\TaoOntology;
use IMSGlobal\LTI\OAuth\OAuthDataStore;
use IMSGlobal\LTI\OAuth\OAuthConsumer;
use IMSGlobal\LTI\OAuth\OAuthToken;
use oat\oatbox\service\ConfigurableService;
use oat\generis\model\OntologyAwareTrait;
/**
* Tao Implementation of an OAuthDatastore
* Does not yet implement the nonce and request/access token
*
* @access public
* @author Joel Bout, <joel@taotesting.com>
* @package tao
*/
class DataStore extends ConfigurableService implements ImsOauthDataStoreInterface
{
use OntologyAwareTrait;
const OPTION_NONCE_STORE = 'nonce';
const CLASS_URI_OAUTH_CONSUMER = 'http://www.tao.lu/Ontologies/TAO.rdf#OauthConsumer';
const PROPERTY_OAUTH_KEY = 'http://www.tao.lu/Ontologies/TAO.rdf#OauthKey';
const PROPERTY_OAUTH_SECRET = 'http://www.tao.lu/Ontologies/TAO.rdf#OauthSecret';
const PROPERTY_OAUTH_CALLBACK = 'http://www.tao.lu/Ontologies/TAO.rdf#OauthCallbackUrl';
/**
* Helper function to find the OauthConsumer RDF Resource
*
* @access public
* @author Joel Bout, <joel@taotesting.com>
* @param string consumer_key
* @return \core_kernel_classes_Resource
*/
public function findOauthConsumerResource($consumer_key)
{
$returnValue = null;
$class = $this->getClass(self::CLASS_URI_OAUTH_CONSUMER);
$instances = $class->searchInstances([self::PROPERTY_OAUTH_KEY => $consumer_key], ['like' => false, 'recursive' => true]);
if (count($instances) == 0) {
$oauthService = $this->getServiceLocator()->get(OauthService::SERVICE_ID);
/** @var LockoutInterface $lockoutService */
$lockoutService = $oauthService->getSubService(OauthService::OPTION_LOCKOUT_SERVICE);
$lockoutService->logFailedAttempt();
throw new \tao_models_classes_oauth_Exception('No Credentials for consumer key ' . $consumer_key);
}
if (count($instances) > 1) {
throw new \tao_models_classes_oauth_Exception('Multiple Credentials for consumer key ' . $consumer_key);
}
$returnValue = current($instances);
return $returnValue;
}
/**
* Returns the OAuthConsumer for the provided credentials
*
* @param \common_http_Credentials $consumer
* @throws \tao_models_classes_oauth_Exception
* @return \IMSGlobal\LTI\OAuth\OAuthConsumer
*/
public function getOauthConsumer(\common_http_Credentials $credentials)
{
if (!$credentials instanceof \core_kernel_classes_Resource) {
throw new \tao_models_classes_oauth_Exception('Unsupported credential type ' . get_class($credentials));
}
$values = $credentials->getPropertiesValues([
self::PROPERTY_OAUTH_KEY,
self::PROPERTY_OAUTH_SECRET,
self::PROPERTY_OAUTH_CALLBACK
]);
if (empty($values[self::PROPERTY_OAUTH_KEY]) || empty($values[self::PROPERTY_OAUTH_SECRET])) {
throw new \tao_models_classes_oauth_Exception('Incomplete oauth consumer definition for ' . $credentials->getUri());
}
$consumer_key = (string)current($values[self::PROPERTY_OAUTH_KEY]);
$secret = (string)current($values[self::PROPERTY_OAUTH_SECRET]);
if (!empty($values[self::PROPERTY_OAUTH_CALLBACK])) {
$callbackUrl = (string)current($values[self::PROPERTY_OAUTH_CALLBACK]);
if (empty($callbackUrl)) {
$callbackUrl = null;
}
} else {
$callbackUrl = null;
}
return new OAuthConsumer($consumer_key, $secret, $callbackUrl);
}
/**
* returns the OauthConsumer for the specified key
*
* @access public
* @author Joel Bout, <joel@taotesting.com>
* @param consumer_key
* @return OAuthConsumer
*/
public function lookup_consumer($consumer_key)
{
$returnValue = null;
$consumer = $this->findOauthConsumerResource($consumer_key);
$secret = (string)$consumer->getUniquePropertyValue($this->getProperty(self::PROPERTY_OAUTH_SECRET));
$callbackUrl = null;
$returnValue = new OAuthConsumer($consumer_key, $secret, $callbackUrl);
return $returnValue;
}
/**
* Should verify if the token exists and return it
* Always returns an token with an empty secret for now
*
* @access public
* @author Joel Bout, <joel@taotesting.com>
* @param consumer
* @param token_type
* @param token
* @return mixed
*/
public function lookup_token($consumer, $token_type, $token)
{
\common_Logger::d(__CLASS__ . '::' . __FUNCTION__ . ' called for token ' . $token . ' of type ' . $token_type);
return new OAuthToken($consumer, "");
}
/**
* Should verify if a nonce has already been used
* always return NULL, meaning that nonces can be reused
*
* @access public
* @author Joel Bout, <joel@taotesting.com>
* @param OAuthConsumer $consumer
* @param OAuthToken $token
* @param string $nonce
* @param string $timestamp
* @return mixed
*/
public function lookup_nonce($consumer, $token, $nonce, $timestamp)
{
$store = $this->getSubService(self::OPTION_NONCE_STORE);
return $store->isValid($timestamp . '_' . $consumer->key . '_' . $nonce) ? null : true;
}
/**
* Should create a new request token
* not implemented
*
* @access public
* @author Joel Bout, <joel@taotesting.com>
* @param consumer
* @param callback
* @return mixed
*/
function new_request_token($consumer, $callback = null)
{
\common_Logger::d(__CLASS__ . '::' . __FUNCTION__ . ' called');
return null;
}
/**
* Should create a new access token
* not implemented
*
* @access public
* @author Joel Bout, <joel@taotesting.com>
* @param token
* @param consumer
* @return mixed
*/
public function new_access_token($token, $consumer, $verifier = null)
{
\common_Logger::d(__CLASS__ . '::' . __FUNCTION__ . ' called');
return null;
}
}