V 3.5 RC 1

This commit is contained in:
Romain Neutron
2011-12-05 00:23:28 +01:00
parent 6f1ee368aa
commit 4c5b7eb658
5563 changed files with 466984 additions and 985416 deletions

View File

@@ -0,0 +1,298 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Account
{
/**
*
* @var appbox
*/
protected $appbox;
/**
*
* @var int
*/
protected $id;
/**
*
* @var User_Adapter
*/
protected $user;
/**
*
* @var API_OAuth2_Application
*/
protected $application;
/**
*
* @var int
*/
protected $application_id;
/**
*
* @var string
*/
protected $api_version;
/**
*
* @var boolean
*/
protected $revoked;
/**
*
* @var DateTime
*/
protected $created_on;
/**
*
* @var string
*/
protected $token;
/**
* Constructor
*
* @param appbox $appbox
* @param int $account_id
* @return API_OAuth2_Account
*/
public function __construct(appbox &$appbox, $account_id)
{
$this->appbox = $appbox;
$this->id = (int) $account_id;
$sql = 'SELECT api_account_id, usr_id, api_version, revoked
, application_id, created
FROM api_accounts
WHERE api_account_id = :api_account_id';
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute(array(':api_account_id' => $this->id));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$this->application_id = (int) $row['application_id'];
$this->user = User_Adapter::getInstance($row['usr_id'], $this->appbox);
$this->api_version = $row['api_version'];
$this->revoked = !!$row['revoked'];
$this->created_on = new DateTime($row['created']);
return $this;
}
/**
*
* @return int
*/
public function get_id()
{
return $this->id;
}
/**
*
* @return User_Adapter
*/
public function get_user()
{
return $this->user;
}
/**
*
* @return string
*/
public function get_api_version()
{
return $this->api_version;
}
/**
*
* @return boolean
*/
public function is_revoked()
{
return $this->revoked;
}
/**
*
* @param boolean $boolean
* @return API_OAuth2_Account
*/
public function set_revoked($boolean)
{
$this->revoked = !!$boolean;
$sql = 'UPDATE api_accounts SET revoked = :revoked
WHERE api_account_id = :account_id';
$params = array(
':revoked' => ($boolean ? '1' : '0')
, 'account_id' => $this->id
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
return $this;
}
/**
*
* @return DateTime
*/
public function get_created_on()
{
return $this->created_on;
}
/**
*
* @return API_OAuth2_Token
*/
public function get_token()
{
if (!$this->token)
{
try
{
$this->token = new API_OAuth2_Token($this->appbox, $this);
}
catch (Exception_NotFound $e)
{
$this->token = API_OAuth2_Token::create($this->appbox, $this);
}
}
return $this->token;
}
/**
*
* @return API_OAuth2_Application
*/
public function get_application()
{
if (!$this->application)
$this->application = new API_OAuth2_Application($this->appbox, $this->application_id);
return $this->application;
}
/**
*
* @return void
*/
public function delete()
{
$this->get_token()->delete();
foreach(API_OAuth2_AuthCode::load_codes_by_account($this->appbox, $this) as $code)
{
$code->delete();
}
foreach(API_OAuth2_RefreshToken::load_by_account($this->appbox, $this) as $token)
{
$token->delete();
}
$sql = 'DELETE FROM api_accounts WHERE api_account_id = :account_id';
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute(array('account_id' => $this->id));
$stmt->closeCursor();
return;
}
/**
*
* @param appbox $appbox
* @param User_Adapter $user
* @param API_OAuth2_Application $application
* @return API_OAuth2_Account
*/
public static function create(appbox &$appbox, User_Adapter $user, API_OAuth2_Application $application)
{
$sql = 'INSERT INTO api_accounts
(api_account_id, usr_id, revoked, api_version, application_id, created)
VALUES (null, :usr_id, :revoked, :api_version, :application_id, :created)';
$datetime = new Datetime();
$params = array(
':usr_id' => $user->get_id()
, ':application_id' => $application->get_id()
, ':api_version' => API_OAuth2_Adapter::API_VERSION
, ':revoked' => 0
, ':created' => $datetime->format("Y-m-d H:i:s")
);
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$account_id = $appbox->get_connection()->lastInsertId();
return new self($appbox, $account_id);
}
/**
*
* @param appbox $appbox
* @param API_OAuth2_Application $application
* @param User_Adapter $user
* @return API_OAuth2_Account
*/
public static function load_with_user(appbox &$appbox, API_OAuth2_Application $application, User_Adapter $user)
{
$sql = 'SELECT api_account_id FROM api_accounts
WHERE usr_id = :usr_id AND application_id = :application_id';
$params = array(
":usr_id" => $user->get_id(),
":application_id" => $application->get_id()
);
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if (!$row)
throw new Exception_NotFound();
return new self($appbox, $row['api_account_id']);
}
}

View File

@@ -0,0 +1,829 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
require_once dirname(__FILE__) . '/../../../vendor/oauth2/lib/OAuth2.inc';
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Adapter extends OAuth2
{
/**
* Version
*/
const API_VERSION = "1.0";
/**
*
* @var API_OAuth2_Application
*/
protected $client;
/**
*
* @var appbox
*/
protected $appbox;
/**
* request parameter
* @var array
*/
protected $params;
/**
*
* @var array
*/
protected $token_type = array("bearer" => "Bearer");
/**
* @var array
*/
protected $authentication_scheme = array("authorization", "uri", "body");
/**
*
* do we enable expiration on access_token
* @param boolean
*/
protected $enable_expire = false;
/**
*
* @var string
*/
protected $session_id;
/**
*
* @var string
*/
protected $usr_id_requested;
/**
* access token of current request
* @var string
*/
protected $token;
/**
*
* @param appbox $appbox
* @return API_OAuth2_Adapter
*/
public function __construct(appbox $appbox)
{
parent::__construct();
$this->params = array();
$this->appbox = $appbox;
return $this;
}
/**
*
* @return array
*/
public function getParams()
{
return $this->params;
}
/**
*
* @return API_OAuth2_Application
*/
public function getClient()
{
return $this->client;
}
/**
*
* @param array $params
* @return API_OAuth2_Adapter
*/
public function setParams(array $params)
{
$this->params = $params;
return $this;
}
public function getToken()
{
return $this->token;
}
/**
*
* @param API_OAuth2_Application $client
*/
public function setClient(API_OAuth2_Application $client)
{
$this->client = $client;
return $this;
}
/**
*
* @return boolean
*/
public function has_ses_id()
{
return $this->session_id !== null;
}
/**
*
* @return int
*/
public function get_ses_id()
{
return $this->session_id;
}
/**
*
* @return int
*/
public function get_usr_id()
{
return $this->usr_id;
}
/**
*
* @param string $secret
* @param string $nonce
* @return string
*/
protected static function crypt_secret($secret, $nonce)
{
$registry = registry::get_instance();
return hash_hmac('sha512', $secret . $nonce, $registry->get('GV_sit'));
}
/**
*
* Implements OAuth2::checkClientCredentials().
*
* @param string $client_id
* @param string $client_secret
* @return boolean
*/
protected function checkClientCredentials($client_id, $client_secret = NULL)
{
try
{
$application = API_OAuth2_Application::load_from_client_id($this->appbox, $client_id);
if ($client_secret === NULL)
return true;
$crypted = $this->crypt_secret($client_secret, $application->get_nonce());
return ($result["client_secret"] === $crypted);
}
catch (Exception $e)
{
}
return false;
}
/**
*
* Implements OAuth2::getRedirectUri().
*
* @param string $client_id
* @return string
*/
protected function getRedirectUri($client_id)
{
$application = API_OAuth2_Application::load_from_client_id($this->appbox, $client_id);
return $application->get_redirect_uri();
}
/**
*
* Implements OAuth2::getAccessToken().
*
* @param string $oauth_token
* @return array
*/
protected function getAccessToken($oauth_token)
{
$result = null;
try
{
$token = API_OAuth2_Token::load_by_oauth_token($this->appbox, $oauth_token);
$result = array(
'scope' => $token->get_scope()
, 'expires' => $token->get_expires()
, 'client_id' => $token->get_account()->get_application()->get_client_id()
, 'session_id' => $token->get_session_id()
, 'revoked' => ($token->get_account()->is_revoked() ? '1' : '0')
, 'usr_id' => $token->get_account()->get_user()->get_id()
, 'oauth_token' => $token->get_value()
);
}
catch (Exception $e)
{
}
return $result;
}
/**
* Implements OAuth2::setAccessToken().
*/
/**
*
* @param type $oauth_token
* @param type $account_id
* @param type $expires
* @param string $scope
* @return API_OAuth2_Adapter
*/
protected function setAccessToken($oauth_token, $account_id, $expires, $scope = NULL)
{
$account = new API_OAuth2_Account($this->appbox, $account_id);
$token = API_OAuth2_Token::create($this->appbox, $account, $scope);
$token->set_value($oauth_token)->set_expires($expires);
return $this;
}
/**
*
* Overrides OAuth2::getSupportedGrantTypes().
*
* @return array
*/
protected function getSupportedGrantTypes()
{
return array(
OAUTH2_GRANT_TYPE_AUTH_CODE
);
}
/**
*
* Overrides OAuth2::getSupportedScopes().
*
* @return array
*/
protected function getSupportedScopes()
{
return array();
}
/**
*
* Overrides OAuth2::getAuthCode().
*
* @return array
*/
protected function getAuthCode($code)
{
try
{
$code = new API_OAuth2_AuthCode($this->appbox, $code);
return array(
'redirect_uri' => $code->get_redirect_uri()
, 'client_id' => $code->get_account()->get_application()->get_client_id()
, 'expires' => $code->get_expires()
, 'account_id' => $code->get_account()->get_id()
);
}
catch (Exception $e)
{
}
return null;
}
/**
*
* Overrides OAuth2::setAuthCode().
*
* @param string $code
* @param int $account_id
* @param string $redirect_uri
* @param string $expires
* @param string $scope
* @return API_OAuth2_Adapter
*/
protected function setAuthCode($code, $account_id, $redirect_uri, $expires, $scope = NULL)
{
$account = new API_OAuth2_Account($this->appbox, $account_id);
$code = API_OAuth2_AuthCode::create($this->appbox, $account, $code, $expires);
$code->set_redirect_uri($redirect_uri)->set_scope($scope);
return $this;
}
/**
* Overrides OAuth2::setRefreshToken().
*/
protected function setRefreshToken($refresh_token, $account_id, $expires, $scope = NULL)
{
$account = new API_OAuth2_Account($this->appbox, $account_id);
API_OAuth2_RefreshToken::create($this->appbox, $account, $expires, $refresh_token, $scope);
return $this;
}
/**
* Overrides OAuth2::getRefreshToken().
*/
protected function getRefreshToken($refresh_token)
{
try
{
$token = new API_OAuth2_RefreshToken($this->appbox, $refresh_token);
return array(
'token' => $token->get_value()
, 'expires' => $token->get_expires()->format('U')
, 'client_id' => $token->get_account()->get_application()->get_client_id()
);
}
catch (Exception $e)
{
}
return null;
}
/**
* Overrides OAuth2::unsetRefreshToken().
*/
protected function unsetRefreshToken($refresh_token)
{
$token = new API_OAuth2_RefreshToken($this->appbox, $refresh_token);
$token->delete();
return $this;
}
/**
*
* @param Symfony\Component\HttpFoundation\Request $request
* @return array
*/
public function getAuthorizationRequestParameters(Symfony\Component\HttpFoundation\Request $request)
{
$datas = array(
'response_type' => $request->get('response_type', false)
, 'client_id' => $request->get('client_id', false)
, 'redirect_uri' => $request->get('redirect_uri', false)
, 'scope' => $request->get('scope', false)
, 'state' => $request->get('state', false)
);
$filters = array(
"client_id" => array(
"filter" => FILTER_VALIDATE_REGEXP
, "options" => array("regexp" => OAUTH2_CLIENT_ID_REGEXP)
, "flags" => FILTER_REQUIRE_SCALAR
)
, "response_type" => array(
"filter" => FILTER_VALIDATE_REGEXP
, "options" => array("regexp" => OAUTH2_AUTH_RESPONSE_TYPE_REGEXP)
, "flags" => FILTER_REQUIRE_SCALAR
)
, "redirect_uri" => array("filter" => FILTER_SANITIZE_URL)
, "state" => array("flags" => FILTER_REQUIRE_SCALAR)
, "scope" => array("flags" => FILTER_REQUIRE_SCALAR)
);
$input = filter_var_array($datas, $filters);
/**
* check for valid client_id
* check for valid redirect_uri
*/
if (!$input["client_id"])
{
if ($input["redirect_uri"])
$this->errorDoRedirectUriCallback(
$input["redirect_uri"], OAUTH2_ERROR_INVALID_CLIENT, NULL, NULL, $input["state"]
);
// We don't have a good URI to use
$this->errorJsonResponse(OAUTH2_HTTP_FOUND, OAUTH2_ERROR_INVALID_CLIENT);
}
/**
* redirect_uri is not required if already established via other channels
* check an existing redirect URI against the one supplied
*/
$redirect_uri = $this->getRedirectUri($input["client_id"]);
/**
* At least one of: existing redirect URI or input redirect URI must be specified
*/
if (!$redirect_uri && !$input["redirect_uri"])
$this->errorJsonResponse(
OAUTH2_HTTP_FOUND, OAUTH2_ERROR_INVALID_REQUEST);
/**
* getRedirectUri() should return FALSE if the given client ID is invalid
* this probably saves us from making a separate db call, and simplifies the method set
*/
if ($redirect_uri === FALSE)
$this->errorDoRedirectUriCallback(
$input["redirect_uri"], OAUTH2_ERROR_INVALID_CLIENT, NULL, NULL, $input["state"]);
/**
* If there's an existing uri and one from input, verify that they match
*/
if ($redirect_uri && $input["redirect_uri"])
{
/**
* Ensure that the input uri starts with the stored uri
*/
$compare = strcasecmp(
substr(
$input["redirect_uri"], 0, strlen($redirect_uri)
), $redirect_uri);
if ($compare !== 0)
$this->errorDoRedirectUriCallback($input["redirect_uri"], OAUTH2_ERROR_REDIRECT_URI_MISMATCH, NULL, NULL, $input["state"]);
}
elseif ($redirect_uri)
{
/**
* They did not provide a uri from input, so use the stored one
*/
$input["redirect_uri"] = $redirect_uri;
}
/**
* Check response_type
*/
if (!$input["response_type"])
{
$this->errorDoRedirectUriCallback($input["redirect_uri"], OAUTH2_ERROR_INVALID_REQUEST, 'Invalid response type.', NULL, $input["state"]);
}
/**
* Check requested auth response type against the list of supported types
*/
if (array_search($input["response_type"], $this->getSupportedAuthResponseTypes()) === FALSE)
$this->errorDoRedirectUriCallback($input["redirect_uri"], OAUTH2_ERROR_UNSUPPORTED_RESPONSE_TYPE, NULL, NULL, $input["state"]);
/**
* Restrict clients to certain authorization response types
*/
if ($this->checkRestrictedAuthResponseType($input["client_id"], $input["response_type"]) === FALSE)
$this->errorDoRedirectUriCallback($input["redirect_uri"], OAUTH2_ERROR_UNAUTHORIZED_CLIENT, NULL, NULL, $input["state"]);
/**
* Validate that the requested scope is supported
*/
if ($input["scope"] && !$this->checkScope($input["scope"], $this->getSupportedScopes()))
$this->errorDoRedirectUriCallback($input["redirect_uri"], OAUTH2_ERROR_INVALID_SCOPE, NULL, NULL, $input["state"]);
/**
* at this point all params are ok
*/
$this->params = $input;
return $input;
}
/**
*
* @param usr_id $usr_id
* @return API_OAuth2_Account
*/
public function updateAccount($usr_id)
{
if ($this->client === null)
throw new logicalException("Client property must be set before update an account");
try
{
$user = User_Adapter::getInstance($usr_id, $this->appbox);
$account = API_OAuth2_Account::load_with_user($this->appbox, $this->client, $user);
}
catch (Exception $e)
{
$account = $this->createAccount($usr_id);
}
return $account;
}
/**
*
* @param int $usr_id
* @return API_OAuth2_Account
*/
private function createAccount($usr_id)
{
$user = User_Adapter::getInstance($usr_id, $this->appbox);
return API_OAuth2_Account::create($this->appbox, $user, $this->client);
}
/**
*
* @param <type> $is_authorized
* @param array $params
* @return string
*/
public function finishNativeClientAuthorization($is_authorized, $params = array())
{
$result = array();
$params += array(
'scope' => NULL,
'state' => NULL,
);
extract($params);
if ($state !== NULL)
$result["query"]["state"] = $state;
if ($is_authorized === FALSE)
{
$result["error"] = OAUTH2_ERROR_USER_DENIED;
}
else
{
if ($response_type == OAUTH2_AUTH_RESPONSE_TYPE_AUTH_CODE || $response_type == OAUTH2_AUTH_RESPONSE_TYPE_CODE_AND_TOKEN)
$result["token"] = $this->createAccessToken($account_id, $scope);
if ($response_type == OAUTH2_AUTH_RESPONSE_TYPE_ACCESS_TOKEN)
$result["error"] = OAUTH2_ERROR_UNSUPPORTED_RESPONSE_TYPE;
}
return $result;
}
/**
*
* @param <type> $redirect_uri
* @return <type>
*/
public function isNativeApp($redirect_uri)
{
return $redirect_uri === API_OAuth2_Application::NATIVE_APP_REDIRECT_URI;
}
public function remember_this_ses_id($ses_id)
{
try
{
$token = API_OAuth2_Token::load_by_oauth_token($this->appbox, $this->token);
$token->set_session_id($ses_id);
return true;
}
catch (Exception $e)
{
}
return false;
}
public function verifyAccessToken($scope = NULL, $exit_not_present = TRUE, $exit_invalid = TRUE, $exit_expired = TRUE, $exit_scope = TRUE, $realm = NULL)
{
$token_param = $this->getAccessTokenParams();
if ($token_param === FALSE) // Access token was not provided
return $exit_not_present ? $this->errorWWWAuthenticateResponseHeader(OAUTH2_HTTP_BAD_REQUEST, $realm, OAUTH2_ERROR_INVALID_REQUEST, 'The request is missing a required parameter, includes an unsupported parameter or parameter value, repeats the same parameter, uses more than one method for including an access token, or is otherwise malformed.', NULL, $scope) : FALSE;
// Get the stored token data (from the implementing subclass)
$token = $this->getAccessToken($token_param);
if ($token === NULL)
return $exit_invalid ? $this->errorWWWAuthenticateResponseHeader(OAUTH2_HTTP_UNAUTHORIZED, $realm, OAUTH2_ERROR_INVALID_TOKEN, 'The access token provided is invalid.', NULL, $scope) : FALSE;
if (isset($token['revoked']) && $token['revoked'])
{
return $exit_invalid ? $this->errorWWWAuthenticateResponseHeader(OAUTH2_HTTP_UNAUTHORIZED, $realm, OAUTH2_ERROR_INVALID_TOKEN, 'End user has revoked access to his personal datas for your application.', NULL, $scope) : FALSE;
}
if ($this->enable_expire)
{
// Check token expiration (I'm leaving this check separated, later we'll fill in better error messages)
if (isset($token["expires"]) && time() > $token["expires"])
return $exit_expired ? $this->errorWWWAuthenticateResponseHeader(OAUTH2_HTTP_UNAUTHORIZED, $realm, OAUTH2_ERROR_EXPIRED_TOKEN, 'The access token provided has expired.', NULL, $scope) : FALSE;
}
// Check scope, if provided
// If token doesn't have a scope, it's NULL/empty, or it's insufficient, then throw an error
if ($scope && (!isset($token["scope"]) || !$token["scope"] || !$this->checkScope($scope, $token["scope"])))
return $exit_scope ? $this->errorWWWAuthenticateResponseHeader(OAUTH2_HTTP_FORBIDDEN, $realm, OAUTH2_ERROR_INSUFFICIENT_SCOPE, 'The request requires higher privileges than provided by the access token.', NULL, $scope) : FALSE;
//save token's linked ses_id
$this->session_id = $token['session_id'];
$this->usr_id = $token['usr_id'];
$this->token = $token['oauth_token'];
return TRUE;
}
public function finishClientAuthorization($is_authorized, $params = array())
{
$params += array(
'scope' => NULL,
'state' => NULL,
);
extract($params);
if ($state !== NULL)
$result["query"]["state"] = $state;
if ($is_authorized === FALSE)
$result["query"]["error"] = OAUTH2_ERROR_USER_DENIED;
else
{
if ($response_type == OAUTH2_AUTH_RESPONSE_TYPE_AUTH_CODE || $response_type == OAUTH2_AUTH_RESPONSE_TYPE_CODE_AND_TOKEN)
$result["query"]["code"] = $this->createAuthCode($account_id, $redirect_uri, $scope);
if ($response_type == OAUTH2_AUTH_RESPONSE_TYPE_ACCESS_TOKEN || $response_type == OAUTH2_AUTH_RESPONSE_TYPE_CODE_AND_TOKEN)
$result["fragment"] = $this->createAccessToken($account_id, $scope);
}
$this->doRedirectUriCallback($redirect_uri, $result);
}
/**
*
*/
public function grantAccessToken()
{
$filters = array(
"grant_type" => array("filter" => FILTER_VALIDATE_REGEXP, "options" => array("regexp" => OAUTH2_GRANT_TYPE_REGEXP), "flags" => FILTER_REQUIRE_SCALAR),
"scope" => array("flags" => FILTER_REQUIRE_SCALAR),
"code" => array("flags" => FILTER_REQUIRE_SCALAR),
"redirect_uri" => array("filter" => FILTER_SANITIZE_URL),
"username" => array("flags" => FILTER_REQUIRE_SCALAR),
"password" => array("flags" => FILTER_REQUIRE_SCALAR),
"assertion_type" => array("flags" => FILTER_REQUIRE_SCALAR),
"assertion" => array("flags" => FILTER_REQUIRE_SCALAR),
"refresh_token" => array("flags" => FILTER_REQUIRE_SCALAR),
);
$input = filter_input_array(INPUT_POST, $filters);
// Grant Type must be specified.
if (!$input["grant_type"])
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_INVALID_REQUEST, 'Invalid grant_type parameter or parameter missing');
// Make sure we've implemented the requested grant type
if (!in_array($input["grant_type"], $this->getSupportedGrantTypes()))
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_UNSUPPORTED_GRANT_TYPE);
// Authorize the client
$client = $this->getClientCredentials();
if ($this->checkClientCredentials($client[0], $client[1]) === FALSE)
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_INVALID_CLIENT);
if (!$this->checkRestrictedGrantType($client[0], $input["grant_type"]))
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_UNAUTHORIZED_CLIENT);
// Do the granting
switch ($input["grant_type"])
{
case OAUTH2_GRANT_TYPE_AUTH_CODE:
if (!$input["code"] || !$input["redirect_uri"])
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_INVALID_REQUEST);
$stored = $this->getAuthCode($input["code"]);
// Ensure that the input uri starts with the stored uri
if ($stored === NULL || (strcasecmp(substr($input["redirect_uri"], 0, strlen($stored["redirect_uri"])), $stored["redirect_uri"]) !== 0) || $client[0] != $stored["client_id"])
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_INVALID_GRANT);
if ($stored["expires"] < time())
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_EXPIRED_TOKEN);
break;
case OAUTH2_GRANT_TYPE_USER_CREDENTIALS:
if (!$input["username"] || !$input["password"])
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_INVALID_REQUEST, 'Missing parameters. "username" and "password" required');
$stored = $this->checkUserCredentials($client[0], $input["username"], $input["password"]);
if ($stored === FALSE)
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_INVALID_GRANT);
break;
case OAUTH2_GRANT_TYPE_ASSERTION:
if (!$input["assertion_type"] || !$input["assertion"])
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_INVALID_REQUEST);
$stored = $this->checkAssertion($client[0], $input["assertion_type"], $input["assertion"]);
if ($stored === FALSE)
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_INVALID_GRANT);
break;
case OAUTH2_GRANT_TYPE_REFRESH_TOKEN:
if (!$input["refresh_token"])
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_INVALID_REQUEST, 'No "refresh_token" parameter found');
$stored = $this->getRefreshToken($input["refresh_token"]);
if ($stored === NULL || $client[0] != $stored["client_id"])
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_INVALID_GRANT);
if ($stored["expires"] < time())
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_EXPIRED_TOKEN);
// store the refresh token locally so we can delete it when a new refresh token is generated
$this->setVariable('_old_refresh_token', $stored["token"]);
break;
case OAUTH2_GRANT_TYPE_NONE:
$stored = $this->checkNoneAccess($client[0]);
if ($stored === FALSE)
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_INVALID_REQUEST);
}
// Check scope, if provided
if ($input["scope"] && (!is_array($stored) || !isset($stored["scope"]) || !$this->checkScope($input["scope"], $stored["scope"])))
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_INVALID_SCOPE);
if (!$input["scope"])
$input["scope"] = NULL;
$token = $this->createAccessToken($stored['account_id'], $input["scope"]);
$this->sendJsonHeaders();
echo json_encode($token);
return;
}
protected function createAccessToken($account_id, $scope = NULL)
{
$token = array(
"access_token" => $this->genAccessToken(),
"scope" => $scope
);
if ($this->enable_expire)
$token['expires_in'] = $this->getVariable('access_token_lifetime', OAUTH2_DEFAULT_ACCESS_TOKEN_LIFETIME);
$this->setAccessToken($token["access_token"], $account_id, time() + $this->getVariable('access_token_lifetime', OAUTH2_DEFAULT_ACCESS_TOKEN_LIFETIME), $scope);
// Issue a refresh token also, if we support them
if (in_array(OAUTH2_GRANT_TYPE_REFRESH_TOKEN, $this->getSupportedGrantTypes()))
{
$token["refresh_token"] = $this->genAccessToken();
$this->setRefreshToken($token["refresh_token"], $account_id, time() + $this->getVariable('refresh_token_lifetime', OAUTH2_DEFAULT_REFRESH_TOKEN_LIFETIME), $scope);
// If we've granted a new refresh token, expire the old one
if ($this->getVariable('_old_refresh_token'))
$this->unsetRefreshToken($this->getVariable('_old_refresh_token'));
}
return $token;
}
}

View File

@@ -0,0 +1,649 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Application
{
/**
* constant for desktop application
*/
const DESKTOP_TYPE = 'desktop';
/**
* constant for web application
*/
const WEB_TYPE = 'web';
/**
* Uniform Resource Name
*/
const NATIVE_APP_REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
/**
*
* @var appbox
*/
protected $appbox;
/**
*
* @var int
*/
protected $id;
/**
*
* @var User_Adapter
*/
protected $creator;
/**
*
* @var string
*/
protected $type;
/**
*
* @var string
*/
protected $name;
/**
*
* @var string
*/
protected $nonce;
/**
*
* @var string
*/
protected $description;
/**
*
* @var string
*/
protected $website;
/**
*
* @var DateTime
*/
protected $created_on;
/**
*
* @var DateTime
*/
protected $last_modified;
/**
*
* @var string
*/
protected $client_id;
/**
*
* @var string
*/
protected $client_secret;
/**
*
* @var string
*/
protected $redirect_uri;
/**
*
* @param appbox $appbox
* @param int $application_id
* @return API_OAuth2_Application
*/
public function __construct(appbox &$appbox, $application_id)
{
$this->appbox = $appbox;
$this->id = (int) $application_id;
$sql = 'SELECT application_id, creator, type, name, description, website
, created_on, last_modified, client_id, client_secret, nonce
, redirect_uri
FROM api_applications
WHERE application_id = :application_id';
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute(array(':application_id' => $this->id));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$this->creator = User_Adapter::getInstance($row['creator'], $this->appbox);
$this->type = $row['type'];
$this->name = $row['name'];
$this->description = $row['description'];
$this->website = $row['website'];
$this->created_on = new DateTime($row['created_on']);
$this->last_modified = new DateTime($row['last_modified']);
$this->client_id = $row['client_id'];
$this->client_secret = $row['client_secret'];
$this->redirect_uri = $row['redirect_uri'];
$this->nonce = $row['nonce'];
return $this;
}
/**
*
* @return int
*/
public function get_id()
{
return $this->id;
}
/**
*
* @return User_Adapter
*/
public function get_creator()
{
return $this->creator;
}
/**
*
* @return string
*/
public function get_type()
{
return $this->type;
}
/**
*
* @return string
*/
public function get_nonce()
{
return $this->nonce;
}
/**
*
* @param string $type
* @return API_OAuth2_Application
*/
public function set_type($type)
{
if (!in_array($type, array(self::DESKTOP_TYPE, self::WEB_TYPE)))
throw new Exception_InvalidArgument();
$this->type = $type;
if ($this->type == self::DESKTOP_TYPE)
$this->set_redirect_uri(self::NATIVE_APP_REDIRECT_URI);
$sql = 'UPDATE api_applications SET type = :type, last_modified = NOW()
WHERE application_id = :application_id';
$params = array(
':type' => $this->type
, ':application_id' => $this->id
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
return $this;
}
/**
*
* @return string
*/
public function get_name()
{
return $this->name;
}
/**
*
* @param string $name
* @return API_OAuth2_Application
*/
public function set_name($name)
{
$this->name = $name;
$sql = 'UPDATE api_applications SET name = :name, last_modified = NOW()
WHERE application_id = :application_id';
$params = array(
':name' => $this->name
, ':application_id' => $this->id
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
return $this;
}
/**
*
* @return string
*/
public function get_description()
{
return $this->description;
}
/**
*
* @param string $description
* @return API_OAuth2_Application
*/
public function set_description($description)
{
$this->description = $description;
$sql = 'UPDATE api_applications
SET description = :description, last_modified = NOW()
WHERE application_id = :application_id';
$params = array(
':description' => $this->description
, ':application_id' => $this->id
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
return $this;
}
/**
*
* @return string
*/
public function get_website()
{
return $this->website;
}
/**
*
* @param string $website
* @return API_OAuth2_Application
*/
public function set_website($website)
{
$this->website = $website;
$sql = 'UPDATE api_applications
SET website = :website, last_modified = NOW()
WHERE application_id = :application_id';
$params = array(
':website' => $this->website
, ':application_id' => $this->id
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
return $this;
}
/**
*
* @return DateTime
*/
public function get_created_on()
{
return $this->created_on;
}
/**
*
* @return DateTime
*/
public function get_last_modified()
{
return $this->last_modified;
}
/**
*
* @return int
*/
public function get_client_id()
{
return $this->client_id;
}
/**
*
* @param int $client_id
* @return API_OAuth2_Application
*/
public function set_client_id($client_id)
{
$this->client_id = $client_id;
$sql = 'UPDATE api_applications
SET client_id = :client_id, last_modified = NOW()
WHERE application_id = :application_id';
$params = array(
':client_id' => $this->client_id
, ':application_id' => $this->id
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
return $this;
}
/**
*
* @return string
*/
public function get_client_secret()
{
return $this->client_secret;
}
/**
*
* @param string $client_secret
* @return API_OAuth2_Application
*/
public function set_client_secret($client_secret)
{
$this->client_secret = $client_secret;
$sql = 'UPDATE api_applications
SET client_secret = :client_secret, last_modified = NOW()
WHERE application_id = :application_id';
$params = array(
':client_secret' => $this->client_secret
, ':application_id' => $this->id
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
return $this;
}
/**
*
* @return string
*/
public function get_redirect_uri()
{
return $this->redirect_uri;
}
/**
*
* @param string $redirect_uri
* @return API_OAuth2_Application
*/
public function set_redirect_uri($redirect_uri)
{
$this->redirect_uri = $redirect_uri;
$sql = 'UPDATE api_applications
SET redirect_uri = :redirect_uri, last_modified = NOW()
WHERE application_id = :application_id';
$params = array(
':redirect_uri' => $this->redirect_uri
, ':application_id' => $this->id
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
return $this;
}
/**
*
* @param User_Adapter $user
* @return API_OAuth2_Account
*/
public function get_user_account(user_adapter $user)
{
$sql = 'SELECT api_account_id FROM api_accounts
WHERE usr_id = :usr_id AND application_id = :id';
$params = array(
':usr_id' => $user->get_id()
, ':id' => $this->id
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if (!$row)
throw new Exception_NotFound();
return new API_OAuth2_Account($this->appbox, $row['api_account_id']);
}
/**
*
* @return void
*/
public function delete()
{
foreach ($this->get_related_accounts() as $account)
{
$account->delete();
}
$sql = 'DELETE FROM api_applications
WHERE application_id = :application_id';
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute(array(':application_id' => $this->get_id()));
$stmt->closeCursor();
return;
}
/**
*
* @return array
*/
protected function get_related_accounts()
{
$sql = 'SELECT api_account_id FROM api_accounts
WHERE application_id = :application_id';
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute(array(':application_id' => $this->get_id()));
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$accounts = array();
foreach ($rs as $row)
{
$accounts[] = new API_OAuth2_Account($this->appbox, $row['api_account_id']);
}
return $accounts;
}
/**
*
* @param appbox $appbox
* @param User_Adapter $user
* @param type $name
* @return API_OAuth2_Application
*/
public static function create(appbox &$appbox, User_Adapter $user, $name)
{
$sql = 'INSERT INTO api_applications
(application_id, creator, created_on, name
, last_modified, nonce, client_id, client_secret)
VALUES (null, :usr_id, NOW(), :name, NOW()
, :nonce, :client_id, :client_secret)';
$nonce = random::generatePassword(6);
$client_secret = API_OAuth2_Token::generate_token();
$client_token = API_OAuth2_Token::generate_token();
$params = array(
':usr_id' => $user->get_id(),
':name' => $name,
':client_id' => $client_token,
':client_secret' => $client_secret,
':nonce' => $nonce,
);
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$application_id = $appbox->get_connection()->lastInsertId();
$application = new self($appbox, $application_id);
$account = API_OAuth2_Account::create($appbox, $user, $application);
return $application;
}
/**
*
* @param appbox $appbox
* @param type $client_id
* @return API_OAuth2_Application
*/
public static function load_from_client_id(appbox &$appbox, $client_id)
{
$sql = 'SELECT application_id FROM api_applications
WHERE client_id = :client_id';
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute(array(':client_id' => $client_id));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if (!$row)
throw new Exception_NotFound();
return new self($appbox, $row['application_id']);
}
/**
*
* @param appbox $appbox
* @param User_Adapter $user
* @return array
*/
public static function load_dev_app_by_user(appbox &$appbox, User_Adapter $user)
{
$sql = 'SELECT a.application_id
FROM api_applications a, api_accounts b
WHERE a.creator = :usr_id AND a.application_id = b.application_id';
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute(array(':usr_id' => $user->get_id()));
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$apps = array();
foreach ($rs as $row)
{
$apps[] = new API_OAuth2_Application($appbox, $row['application_id']);
}
return $apps;
}
/**
*
* @param appbox $appbox
* @param user_adapter $user
* @return API_OAuth2_Application
*/
public static function load_app_by_user(appbox $appbox, user_adapter $user)
{
$usr_id = $user->get_id();
$sql = 'SELECT a.application_id
FROM api_accounts a, api_applications c
WHERE usr_id = :usr_id AND c.application_id = a.application_id';
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute(array(':usr_id' => $user->get_id()));
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$apps = array();
foreach ($rs as $row)
{
$apps[] = new API_OAuth2_Application($appbox, $row['application_id']);
}
return $apps;
}
public static function load_authorized_app_by_user(appbox $appbox, user_adapter $user)
{
$usr_id = $user->get_id();
$sql = '
SELECT a.application_id
FROM api_accounts a, api_applications c
WHERE usr_id = :usr_id AND c.application_id = a.application_id
AND revoked = 0';
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute(array(':usr_id' => $user->get_id()));
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$apps = array();
foreach ($rs as $row)
{
$apps[] = new API_OAuth2_Application($appbox, $row['application_id']);
}
return $apps;
}
}

View File

@@ -0,0 +1,190 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_AuthCode
{
protected $appbox;
protected $code;
protected $account;
protected $account_id;
protected $redirect_uri;
protected $expires;
protected $scope;
public function __construct(appbox &$appbox, $code)
{
$this->appbox = $appbox;
$this->code = $code;
$sql = 'SELECT code, api_account_id, redirect_uri, UNIX_TIMESTAMP(expires) AS expires, scope
FROM api_oauth_codes WHERE code = :code';
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute(array(':code' => $this->code));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if (!$row)
throw new Exception_NotFound();
$this->account_id = (int) $row['api_account_id'];
$this->redirect_uri = $row['redirect_uri'];
$this->expires = $row['expires'];
$this->scope = $row['scope'];
return $this;
}
public function get_code()
{
return $this->code;
}
/**
*
* @return API_OAuth2_Account
*/
public function get_account()
{
if (!$this->account)
$this->account = new API_OAuth2_Account($this->appbox, $this->account_id);
return $this->account;
}
public function get_redirect_uri()
{
return $this->redirect_uri;
}
public function set_redirect_uri($redirect_uri)
{
$sql = 'UPDATE api_oauth_codes SET redirect_uri = :redirect_uri
WHERE code = :code';
$params = array(':redirect_uri' => $redirect_uri, ':code' => $this->code);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$this->redirect_uri = $redirect_uri;
return $this;
}
/**
*
* @return int
*/
public function get_expires()
{
return $this->expires;
}
public function get_scope()
{
return $this->scope;
}
public function set_scope($scope)
{
$sql = 'UPDATE api_oauth_codes SET scope = :scope
WHERE code = :code';
$params = array(':scope' => $scope, ':code' => $this->code);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$this->scope = $scope;
return $this;
}
public function delete()
{
$sql = 'DELETE FROM api_oauth_codes WHERE code = :code';
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute(array(':code' => $this->code));
$stmt->closeCursor();
return;
}
/**
*
* @param appbox $appbox
* @param API_OAuth2_Account $account
* @return array
*/
public static function load_codes_by_account(appbox &$appbox, API_OAuth2_Account $account)
{
$sql = 'SELECT code FROM api_oauth_codes
WHERE api_account_id = :account_id';
$stmt = $appbox->get_connection()->prepare($sql);
$params = array(":account_id" => $account->get_id());
$stmt->execute($params);
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$codes = array();
foreach ($rs as $row)
{
$codes[] = new API_OAuth2_AuthCode($appbox, $row['code']);
}
return $codes;
}
/**
*
* @param appbox $appbox
* @param API_OAuth2_Account $account
* @param type $code
* @param int $expires
* @return API_OAuth2_AuthCode
*/
public static function create(appbox &$appbox, API_OAuth2_Account $account, $code, $expires)
{
$sql = 'INSERT INTO api_oauth_codes (code, api_account_id, expires)
VALUES (:code, :account_id, FROM_UNIXTIME(:expires))';
$stmt = $appbox->get_connection()->prepare($sql);
$params = array(
":code" => $code,
":account_id" => $account->get_id(),
":expires" => $expires
);
$stmt->execute($params);
$stmt->closeCursor();
return new self($appbox, $code);
}
}

View File

@@ -0,0 +1,50 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Autoloader
{
/**
* Registers Oauth2_Autoloader as an SPL autoloader.
*/
static public function register()
{
ini_set('unserialize_callback_func', 'spl_autoload_call');
spl_autoload_register(array(new self, 'autoload'));
}
/**
* Handles autoloading of classes.
*
* @param string $class A class name.
*
* @return boolean Returns true if the class has been loaded
*/
static public function autoload($class)
{
if (file_exists($file = dirname(__FILE__) . '/../../../vendor/oauth2/lib/' . str_replace(array('_', "\0"), array('/', ''), $class) . '.inc'))
{
require $file;
}
}
}

View File

@@ -0,0 +1,181 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_Exception extends Exception implements API_OAuth2_Exception_Interface
{
/**
*
* @var int
*/
protected $http_code;
/**
*
* @var string
*/
protected $error;
/**
*
* @var string
*/
protected $error_description;
/**
*
* @var string
*/
protected $error_uri;
/**
*
* @var string
*/
protected $scope;
/**
*
* @param int $http_code
* @param string $error
* @param string $error_description
* @param string $scope
* @param string $error_uri
* @return API_OAuth2_Exception_Exception
*/
public function __construct($http_code, $error, $error_description = null, $scope = null, $error_uri = null)
{
$this->error = $error;
$this->error_description = $error_description;
$this->scope = $scope;
$this->error_uri = $error_uri;
parent::__construct();
return $this;
}
/**
*
* @return int
*/
public function getHttp_code()
{
return $this->http_code;
}
/**
*
* @param int $http_code
* @return API_OAuth2_Exception_Exception
*/
public function setHttp_code($http_code)
{
$this->http_code = $http_code;
return $this;
}
/**
*
* @return string
*/
public function getError()
{
return $this->error;
}
/**
*
* @param string $scope
* @return API_OAuth2_Exception_Exception
*/
public function setError($error)
{
$this->error = $error;
return $this;
}
/**
*
* @return string
*/
public function getError_description()
{
return $this->error_description;
}
/**
*
* @param string $scope
* @return API_OAuth2_Exception_Exception
*/
public function setError_description($error_description)
{
$this->error_description = $error_description;
return $this;
}
/**
*
* @return string
*/
public function getError_uri()
{
return $this->error_uri;
}
/**
*
* @param string $scope
* @return API_OAuth2_Exception_Exception
*/
public function setError_uri($error_uri)
{
$this->error_uri = $error_uri;
return $this;
}
/**
*
* @return string
*/
public function getScope()
{
return $this->scope;
}
/**
*
* @param string $scope
* @return API_OAuth2_Exception_Exception
*/
public function setScope($scope)
{
$this->scope = $scope;
return $this;
}
}

View File

@@ -0,0 +1,33 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
interface API_OAuth2_Exception_Interface
{
public function getError();
public function getHttp_code();
public function getError_description();
public function getError_uri();
}

View File

@@ -0,0 +1,102 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_Redirect extends API_OAuth2_Exception_Exception
{
/**
*
* @var int
*/
protected $http_code = 302;
/**
*
* @var string
*/
protected $state;
/**
*
* @var string
*/
protected $redirect_uri;
/**
*
* @param string $redirect_uri
* @param string $error
* @param string $error_description
* @param string $state
* @param string $error_uri
* @return API_OAuth2_Exception_Redirect
*/
public function __construct($redirect_uri, $error, $error_description = null, $state = null, $error_uri = null)
{
$this->redirect_uri = $redirect_uri;
$this->state = $state;
parent::__construct($this->http_code, $error, $error_description, $error_uri);
return $this;
}
/**
*
* @return string
*/
public function getState()
{
return $this->state;
}
/**
*
* @param string $redirect_uri
* @return API_OAuth2_Exception_Redirect
*/
public function setState($state)
{
$this->state = $state;
return $this;
}
/**
*
* @return string
*/
public function getRedirect_uri()
{
return $this->redirect_uri;
}
/**
*
* @param string $redirect_uri
* @return API_OAuth2_Exception_Redirect
*/
public function setRedirect_uri($redirect_uri)
{
$this->redirect_uri = $redirect_uri;
return $this;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_Redirect_AccessDenied extends API_OAuth2_Exception_Redirect
{
/**
*
* @var string
*/
protected $error = 'access_denied';
/**
*
* @var string
*/
protected $error_description = " The resource owner or authorization server denied the request.";
/**
*
* @param string $redirect_uri
* @param string $state
* @param string $error_uri
* @return API_OAuth2_Exception_Redirect_AccessDenied
*/
public function __construct($redirect_uri, $state = null, $error_uri = null)
{
parent::__construct($redirect_uri, $this->error, $this->error_description, $state, $error_uri);
return $this;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_Redirect_InvalidClient extends API_OAuth2_Exception_Redirect
{
/**
*
* @var string
*/
protected $error = 'invalid_Client';
/**
*
* @var string
*/
protected $error_description = "The Client id is not valid.";
/**
*
* @param string $redirect_uri
* @param string $state
* @param string $error_uri
* @return API_OAuth2_Exception_Redirect_InvalidClient
*/
public function __construct($redirect_uri, $state = null, $error_uri = null)
{
parent::__construct($redirect_uri, $this->error, $this->error_description, $state, $error_uri);
return $this;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_Redirect_InvalidRequest extends API_OAuth2_Exception_Redirect
{
/**
*
* @var string
*/
protected $error = 'invalid_request';
/**
*
* @var string
*/
protected $error_description = "The request is missing a required parameter, includes an unsupported parameter or parameter value, repeats the same parameter, uses more than one method for including an access token, or is otherwise malformed.";
/**
*
* @param string $redirect_uri
* @param string $state
* @param string $error_uri
* @return API_OAuth2_Exception_Redirect_InvalidRequest
*/
public function __construct($redirect_uri, $state = null, $error_uri = null)
{
parent::__construct($redirect_uri, $this->error, $this->error_description, $state, $error_uri);
return $this;
}
}

View File

@@ -0,0 +1,81 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_Redirect_InvalidScope extends API_OAuth2_Exception_Redirect
{
/**
*
* @var string
*/
protected $error = 'invalid_scope';
/**
*
* @var string
*/
protected $error_description = "The requested scope is invalid, unknown, or malformed.";
/**
*
* @var string
*/
protected $scope;
/**
*
* @param string $redirect_uri
* @param string $scope
* @param string $state
* @param string $error_uri
* @return API_OAuth2_Exception_Redirect_InvalidScope
*/
public function __construct($redirect_uri, $scope, $state = null, $error_uri = null)
{
$this->scope = $scope;
parent::__construct($redirect_uri, $this->error, $this->error_description, $state, $error_uri);
return $this;
}
/**
*
* @var string
*/
public function getScope()
{
return $this->scope;
}
/**
*
* @param string $scope
* @return API_OAuth2_Exception_Redirect_InvalidScope
*/
public function setScope($scope)
{
$this->scope = $scope;
return $this;
}
}

View File

@@ -0,0 +1,50 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_Redirect_ServerError extends API_OAuth2_Exception_Redirect
{
/**
*
* @var string
*/
protected $error = 'server_error';
/**
*
* @var string
*/
protected $error_description = "The authorization server encountered an unexpected condition which prevented it from fulfilling the request.";
/**
*
* @param string $redirect_uri
* @param string $state
* @param string $error_uri
* @return API_OAuth2_Exception_Redirect_ServerError
*/
public function __construct($redirect_uri, $state = null, $error_uri = null)
{
parent::__construct($redirect_uri, $this->error, $this->error_description, $state, $error_uri);
return $this;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_Redirect_Unauthorized extends API_OAuth2_Exception_Redirect
{
/**
*
* @var string
*/
protected $error = 'temporarily_unavailable';
/**
*
* @var string
*/
protected $error_description = "The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.";
/**
*
* @param string $redirect_uri
* @param string $state
* @param string $error_uri
* @return API_OAuth2_Exception_Redirect_Unauthorized
*/
public function __construct($redirect_uri, $state = null, $error_uri = null)
{
parent::__construct($redirect_uri, $this->error, $this->error_description, $state, $error_uri);
return $this;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_Redirect_UnauthorizedClient extends API_OAuth2_Exception_Redirect
{
/**
*
* @var string
*/
protected $error = 'unauthorized_client';
/**
*
* @var string
*/
protected $error_description = "The client is not authorized to request an authorization code using this method.";
/**
*
* @param string $redirect_uri
* @param string $state
* @param string $error_uri
* @return API_OAuth2_Exception_Redirect_UnauthorizedClient
*/
public function __construct($redirect_uri, $state = null, $error_uri = null)
{
parent::__construct($redirect_uri, $this->error, $this->error_description, $state, $error_uri);
return $this;
}
}

View File

@@ -0,0 +1,81 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_Redirect_UnsupportedResponseType extends API_OAuth2_Exception_Redirect
{
/**
*
* @var string
*/
protected $error = 'unsupported_response_type';
/**
*
* @var string
*/
protected $error_description = "The authorization server does not support obtaining an authorization code using this method.";
/**
*
* @var string
*/
protected $method;
/**
*
* @param string $redirect_uri
* @param string $method
* @param string $state
* @param string $error_uri
* @return API_OAuth2_Exception_Redirect_UnsupportedResponseType
*/
public function __construct($redirect_uri, $method, $state = null, $error_uri = null)
{
$this->method = $method;
parent::__construct($redirect_uri, $this->error, $this->error_description, $state, $error_uri);
return $this;
}
/**
*
* @var string
*/
public function getMethod()
{
return $this->method;
}
/**
*
* @param string $method
* @return API_OAuth2_Exception_Redirect_UnsupportedResponseType
*/
public function setMethod($method)
{
$this->method = $method;
return $this;
}
}

View File

@@ -0,0 +1,79 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_WWWAuthenticate extends API_OAuth2_Exception_Exception
{
/**
*
* @var string
*/
protected $realm;
/**
*
* @var string
*/
protected $scope;
/**
*
* @param int $http_code
* @param string $realm
* @param string $error
* @param string $error_description
* @param string $error_uri
* @param string $scope
* @return API_OAuth2_Exception_WWWAuthenticate
*/
public function __construct($http_code, $realm, $error, $error_description = null, $error_uri = null, $scope = null)
{
$this->realm = $realm;
$this->scope = $scope;
parent::__construct($http_code, $error, $error_description, $error_uri);
return $this;
}
/**
*
* @return string
*/
public function getRealm()
{
return $this->realm;
}
/**
*
* @param string $realm
* @return API_OAuth2_Exception_WWWAuthenticate
*/
public function setRealm($realm)
{
$this->realm = $realm;
return $this;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_WWWAuthenticate_ExpiredToken extends API_OAuth2_Exception_WWWAuthenticate_Type_Unauthorized
{
/**
*
* @var string
*/
protected $error = 'expired_token';
/**
*
* @var string
*/
protected $error_description = "The access token provided has expired.";
/**
*
* @param string $realm
* @param string $scope
* @param string $error_uri
* @return API_OAuth2_Exception_WWWAuthenticate_ExpiredToken
*/
public function __construct($realm, $scope = null, $error_uri = null)
{
parent::__construct($realm, $this->error, $this->error_description, $error_uri, $scope);
return $this;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_WWWAuthenticate_InsufficientScope extends API_OAuth2_Exception_WWWAuthenticate_Type_Forbidden
{
/**
*
* @var string
*/
protected $error = 'insufficient_scope';
/**
*
* @var string
*/
protected $error_description = "The request requires higher privileges than provided by the access token.";
/**
*
* @param string $realm
* @param string $scope
* @param string $error_uri
* @return API_OAuth2_Exception_WWWAuthenticate_InsufficientScope
*/
public function __construct($realm, $scope = null, $error_uri = null)
{
parent::__construct($realm, $this->error, $this->error_description, $error_uri, $scope);
return $this;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_WWWAuthenticate_InvalidClient extends API_OAuth2_Exception_WWWAuthenticate_Type_BadRequest
{
/**
*
* @var string
*/
protected $error = 'invalid_request';
/**
*
* @var string
*/
protected $error_description = "The request is missing a required parameter, includes an unsupported parameter or parameter value, repeats the same parameter, uses more than one method for including an access token, or is otherwise malformed.";
/**
*
* @param string $realm
* @param string $scope
* @param string $error_uri
* @return API_OAuth2_Exception_WWWAuthenticate_InvalidClient
*/
public function __construct($realm, $scope = null, $error_uri = null)
{
parent::__construct($realm, $this->error, $this->error_description, $error_uri, $scope);
return $this;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_WWWAuthenticate_InvalidRequest extends API_OAuth2_Exception_WWWAuthenticate_Type_BadRequest
{
/**
*
* @var string
*/
protected $error = 'invalid_request';
/**
*
* @var string
*/
protected $error_description = "The request is missing a required parameter, includes an unsupported parameter or parameter value, repeats the same parameter, uses more than one method for including an access token, or is otherwise malformed.";
/**
*
* @param string $realm
* @param string $scope
* @param string $error_uri
* @return API_OAuth2_Exception_WWWAuthenticate_InvalidRequest
*/
public function __construct($realm, $scope = null, $error_uri = null)
{
parent::__construct($realm, $this->error, $this->error_description, $error_uri, $scope);
return $this;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_WWWAuthenticate_InvalidToken extends API_OAuth2_Exception_WWWAuthenticate_Type_Unauthorized
{
/**
*
* @var string
*/
protected $error = 'invalid_token';
/**
*
* @var string
*/
protected $error_description = "The access token provided is invalid.";
/**
*
* @param string $realm
* @param string $scope
* @param string $error_uri
* @return API_OAuth2_Exception_WWWAuthenticate_InvalidToken
*/
public function __construct($realm, $scope = null, $error_uri = null)
{
parent::__construct($realm, $this->error, $this->error_description, $error_uri, $scope);
return $this;
}
}

View File

@@ -0,0 +1,48 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_WWWAuthenticate_Type_BadRequest extends API_OAuth2_Exception_WWWAuthenticate
{
/**
*
* @var int
*/
protected $http_code = 400;
/**
*
* @param string $realm
* @param string $error
* @param string $error_description
* @param string $error_uri
* @param string $scope
* @return API_OAuth2_Exception_WWWAuthenticate_Type_BadRequest
*/
public function __construct($realm, $error, $error_description = null, $error_uri = null, $scope = null)
{
parent::__construct($this->http_code, $realm, $error, $error_description = null, $error_uri, $scope);
return $this;
}
}

View File

@@ -0,0 +1,43 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_WWWAuthenticate_Type_Forbidden extends API_OAuth2_Exception_WWWAuthenticate
{
/**
*
* @param string $realm
* @param string $error
* @param string $error_description
* @param string $error_uri
* @param string $scope
* @return API_OAuth2_Exception_WWWAuthenticate_Type_Forbidden
*/
public function __construct($realm, $error, $error_description = null, $error_uri = null, $scope = null)
{
parent::__construct($realm, $error, $error_description = null, $error_uri, $scope);
$this->setHttp_code(403);
return $this;
}
}

View File

@@ -0,0 +1,48 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Exception_WWWAuthenticate_Type_Unauthorized extends API_OAuth2_Exception_WWWAuthenticate
{
/**
*
* @var string
*/
protected $http_code = 401;
/**
*
* @param string $realm
* @param string $error
* @param string $error_description
* @param string $error_uri
* @param string $scope
* @return API_OAuth2_Exception_WWWAuthenticate_Type_Unauthorized
*/
public function __construct($realm, $error, $error_description = null, $error_uri = null, $scope = null)
{
parent::__construct($this->http_code, $realm, $error, $error_description = null, $error_uri, $scope);
return $this;
}
}

View File

@@ -0,0 +1,173 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Validator\Constraints;
class API_OAuth2_Form_DevApp
{
/**
*
* @var string
*/
public $name;
/**
*
* @var string
*/
public $description;
/**
*
* @var string
*/
public $website;
/**
*
* @var string
*/
public $callback;
/**
*
* @param Request $request
* @return API_OAuth2_Form_DevApp
*/
public function __construct(Request $request)
{
$this->name = $request->get('name', null);
$this->description = $request->get('description', null);
$this->website = $request->get('website', null);
$this->callback = $request->get('callback', null);
return $this;
}
/**
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
*
* @param string $callback
* @return API_OAuth2_Form_DevApp
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
*
* @param string $callback
* @return API_OAuth2_Form_DevApp
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
*
* @return string
*/
public function getWebsite()
{
return $this->website;
}
/**
*
* @param string $callback
* @return API_OAuth2_Form_DevApp
*/
public function setWebsite($website)
{
$this->website = $website;
return $this;
}
/**
*
* @return string
*/
public function getCallback()
{
return $this->callback;
}
/**
*
* @param string $callback
* @return API_OAuth2_Form_DevApp
*/
public function setCallback($callback)
{
$this->callback = $callback;
return $this;
}
/**
*
* @param ClassMetadata $metadata
* @return API_OAuth2_Form_DevApp
*/
static public function loadValidatorMetadata(ClassMetadata $metadata)
{
$blank = array('message' => _('Cette valeur ne peut être vide'));
$url = array('message' => _('Url non valide'));
$metadata->addPropertyConstraint('name', new Constraints\NotBlank($blank));
$metadata->addPropertyConstraint('description', new Constraints\NotBlank($blank));
$metadata->addPropertyConstraint('website', new Constraints\NotBlank($blank));
$metadata->addPropertyConstraint('website', new Constraints\Url($url));
$metadata->addPropertyConstraint('callback', new Constraints\NotBlank($blank));
$metadata->addPropertyConstraint('callback', new Constraints\Url($url));
return;
}
}

View File

@@ -0,0 +1,149 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_RefreshToken
{
protected $appbox;
protected $token;
protected $account_id;
protected $account;
protected $expires;
protected $scope;
public function __construct(appbox &$appbox, $token)
{
$this->appbox = $appbox;
$this->token = $token;
$sql = 'SELECT api_account_id, UNIX_TIMESTAMP(expires) AS expires, scope
FROM api_oauth_refresh_tokens WHERE refresh_token = :token';
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute(array(':token' => $this->token));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$this->account_id = (int) $row['api_account_id'];
$this->expires = $row['expires'];
$this->scope = $row['scope'];
return $this;
}
public function get_value()
{
return $this->token;
}
/**
*
* @return API_OAuth2_Account
*/
public function get_account()
{
if (!$this->account)
$this->account = new API_OAuth2_Account($this->appbox, $this->account_id);
return $this->account;
}
/**
*
* @return int
*/
public function get_expires()
{
return $this->expires;
}
public function get_scope()
{
return $this->scope;
}
public function delete()
{
$sql = 'DELETE FROM api_oauth_refresh_tokens
WHERE refresh_token = :refresh_token';
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute(array(":refresh_token" => $this->token));
$stmt->closeCursor();
return;
}
/**
*
* @param appbox $appbox
* @param API_OAuth2_Account $account
* @return array
*/
public static function load_by_account(appbox &$appbox, API_OAuth2_Account $account)
{
$sql = 'SELECT refresh_token FROM api_oauth_refresh_tokens
WHERE api_account_id = :account_id';
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute(array(':account_id' => $account->get_id()));
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$tokens = array();
foreach ($rs as $row)
{
$tokens[] = new API_OAuth2_RefreshToken($appbox, $row['refresh_token']);
}
return $tokens;
}
/**
*
* @param appbox $appbox
* @param API_OAuth2_Account $account
* @param int $expires
* @param type $refresh_token
* @param type $scope
* @return API_OAuth2_RefreshToken
*/
public static function create(appbox &$appbox, API_OAuth2_Account $account, $expires, $refresh_token, $scope)
{
$sql = 'INSERT INTO api_oauth_refresh_tokens
(refresh_token, api_account_id, expires, scope)
VALUES (:refresh_token, :account_id, :expires, :scope)';
$stmt = $appbox->get_connection()->prepare($sql);
$params = array(
":refresh_token" => $refresh_token,
":account_id" => $account->get_id(),
":expires" => $expires,
":scope" => $scope
);
$stmt->execute($params);
$stmt->closeCursor();
return new self($appbox, $refresh_token);
}
}

View File

@@ -0,0 +1,331 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package OAuth2 Connector
*
* @see http://oauth.net/2/
* @uses http://code.google.com/p/oauth2-php/
*
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_OAuth2_Token
{
/**
*
* @var appbox
*/
protected $appbox;
/**
*
* @var API_OAuth2_Account
*/
protected $account;
/**
*
* @var string
*/
protected $token;
/**
*
* @var int
*/
protected $session_id;
/**
*
* @var int
*/
protected $expires;
/**
*
* @var string
*/
protected $scope;
/**
*
* @param appbox $appbox
* @param API_OAuth2_Account $account
* @return API_OAuth2_Token
*/
public function __construct(appbox &$appbox, API_OAuth2_Account &$account)
{
$this->appbox = $appbox;
$this->account = $account;
$sql = 'SELECT oauth_token, session_id, UNIX_TIMESTAMP(expires) as expires, scope
FROM api_oauth_tokens
WHERE api_account_id = :account_id';
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute(array(':account_id' => $this->account->get_id()));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$row)
throw new Exception_NotFound();
$stmt->closeCursor();
$this->token = $row['oauth_token'];
$this->session_id = is_null($row['session_id']) ? null : (int) $row['session_id'];
$this->expires = $row['expires'];
$this->scope = $row['scope'];
return $this;
}
/**
*
* @return string
*/
public function get_value()
{
return $this->token;
}
/**
*
* @param string $oauth_token
* @return API_OAuth2_Token
*/
public function set_value($oauth_token)
{
$sql = 'UPDATE api_oauth_tokens SET oauth_token = :oauth_token
WHERE oauth_token = :current_token';
$params = array(
':oauth_token' => $oauth_token
, ':current_token' => $this->token
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$this->token = $oauth_token;
return $this;
}
/**
*
* @return int
*/
public function get_session_id()
{
return $this->session_id;
}
/**
*
* @param int $session_id
* @return API_OAuth2_Token
*/
public function set_session_id($session_id)
{
$sql = 'UPDATE api_oauth_tokens SET session_id = :session_id
WHERE oauth_token = :current_token';
$params = array(
':session_id' => $session_id
, ':current_token' => $this->token
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$this->session_id = (int) $session_id;
return $this;
}
/**
*
* @return int
*/
public function get_expires()
{
return $this->expires;
}
/**
*
* @param int $expires
* @return API_OAuth2_Token
*/
public function set_expires($expires)
{
$sql = 'UPDATE api_oauth_tokens SET expires = FROM_UNIXTIME(:expires)
WHERE oauth_token = :oauth_token';
$params = array(
':expires' => $expires
, ':oauth_token' => $this->get_value()
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$this->expires = $expires;
return $this;
}
/**
*
* @return string
*/
public function get_scope()
{
return $this->scope;
}
public function set_scope($scope)
{
$sql = 'UPDATE api_oauth_tokens SET scope = :scope
WHERE oauth_token = :oauth_token';
$params = array(
':scope' => $scope
, ':oauth_token' => $this->get_value()
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$this->scope = $scope;
return $this;
}
/**
*
* @return API_OAuth2_Account
*/
public function get_account()
{
return $this->account;
}
/**
*
* @return API_OAuth2_Token
*/
public function renew()
{
$sql = 'UPDATE api_oauth_tokens SET oauth_token = :new_token
WHERE oauth_token = :old_token';
$new_token = self::generate_token();
$params = array(
':new_token' => $new_token
, ':old_token' => $this->get_value()
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$this->token = $new_token;
return $this;
}
/**
*
* @return void
*/
public function delete()
{
$sql = 'DELETE FROM api_oauth_tokens WHERE oauth_token = :oauth_token';
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute(array(':oauth_token' => $this->get_value()));
$stmt->closeCursor();
return;
}
/**
*
* @param appbox $appbox
* @param type $oauth_token
* @return API_OAuth2_Token
*/
public static function load_by_oauth_token(appbox &$appbox, $oauth_token)
{
$sql = 'SELECT a.api_account_id
FROM api_oauth_tokens a, api_accounts b
WHERE a.oauth_token = :oauth_token
AND a.api_account_id = b.api_account_id';
$stmt = $appbox->get_connection()->prepare($sql);
$params = array(":oauth_token" => $oauth_token);
$stmt->execute($params);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if (!$row)
throw new Exception_NotFound();
$account = new API_OAuth2_Account($appbox, $row['api_account_id']);
return new self($appbox, $account);
}
/**
*
* @param appbox $appbox
* @param API_OAuth2_Account $account
* @param string $scope
* @return API_OAuth2_Token
*/
public static function create(appbox &$appbox, API_OAuth2_Account &$account, $scope = null)
{
$sql = 'INSERT INTO api_oauth_tokens
(oauth_token, session_id, api_account_id, expires, scope)
VALUES (:token, null, :account_id, :expire, :scope)';
$params = array(
':token' => self::generate_token()
, ':account_id' => $account->get_id()
, ':expire' => time() + 3600
, ':scope' => $scope
);
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
return new API_OAuth2_Token($appbox, $account);
}
/**
*
* @return string
*/
public static function generate_token()
{
return md5(base64_encode(pack('N6', mt_rand(), mt_rand(), mt_rand(), mt_rand(), mt_rand(), uniqid())));
}
}

View File

@@ -0,0 +1,21 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package APIv1
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
abstract class API_V1_Abstract implements API_V1_Interface
{
}

View File

@@ -0,0 +1,316 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package APIv1
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
interface API_V1_Interface
{
public function get_version();
/**
* Route : /databoxes/list/FORMAT/
*
* Method : GET
*
* Parameters :
*
*/
public function get_databoxes(\Symfony\Component\HttpFoundation\Request $request);
/**
* Route /databoxes/DATABOX_ID/collections/FORMAT/
*
* Method : GET
*
* Parameters ;
* DATABOX_ID : required INT
*/
public function get_databox_collections(\Symfony\Component\HttpFoundation\Request $request, $databox_id);
/**
* Route /databoxes/DATABOX_ID/status/FORMAT/
*
* Method : GET
*
* Parameters ;
* DATABOX_ID : required INT
*/
public function get_databox_status(\Symfony\Component\HttpFoundation\Request $request, $databox_id);
/**
* Route /databoxes/DATABOX_ID/metadatas/FORMAT/
*
* Method : GET
*
* Parameters ;
* DATABOX_ID : required INT
*/
public function get_databox_metadatas(\Symfony\Component\HttpFoundation\Request $request, $databox_id);
/**
* Route /databoxes/DATABOX_ID/termsOfUse/FORMAT/
*
* Method : GET
*
* Parameters ;
* DATABOX_ID : required INT
*/
public function get_databox_terms(\Symfony\Component\HttpFoundation\Request $request, $databox_id);
/**
* Route : /records/search/FORMAT/
*
* Method : GET or POST
*
* Parameters :
* bases[] : array
* status[] : array
* fields[] : array
* record_type : boolean
* media_type : string
*
* Response :
* Array of record objects
*
*/
public function search_records(\Symfony\Component\HttpFoundation\Request $request);
/**
* Route : /records/DATABOX_ID/RECORD_ID/related/FORMAT/
*
* Method : GET
*
* Parameters :
* DATABOX_ID : required INT
* RECORD_ID : required INT
*
*/
public function get_record_related(\Symfony\Component\HttpFoundation\Request $request, $databox_id, $record_id);
/**
* Route : /records/DATABOX_ID/RECORD_ID/metadatas/FORMAT/
*
* Method : GET
*
* Parameters :
* DATABOX_ID : required INT
* RECORD_ID : required INT
*
*/
public function get_record_metadatas(\Symfony\Component\HttpFoundation\Request $request, $databox_id, $record_id);
/**
* Route : /records/DATABOX_ID/RECORD_ID/status/FORMAT/
*
* Method : GET
*
* Parameters :
* DATABOX_ID : required INT
* RECORD_ID : required INT
*
*/
public function get_record_status(\Symfony\Component\HttpFoundation\Request $request, $databox_id, $record_id);
/**
* Route : /records/DATABOX_ID/RECORD_ID/embed/FORMAT/
*
* Method : GET
*
* Parameters :
* DATABOX_ID : required INT
* RECORD_ID : required INT
*
*/
public function get_record_embed(\Symfony\Component\HttpFoundation\Request $request, $databox_id, $record_id);
/**
* Route : /records/DATABOX_ID/RECORD_ID/setmetadatas/FORMAT/
*
* Method : POST
*
* Parameters :
* DATABOX_ID : required INT
* RECORD_ID : required INT
*
*/
public function set_record_metadatas(\Symfony\Component\HttpFoundation\Request $request, $databox_id, $record_id);
/**
* Route : /records/DATABOX_ID/RECORD_ID/setstatus/FORMAT/
*
* Method : POST
*
* Parameters :
* DATABOX_ID : required INT
* RECORD_ID : required INT
*
*/
public function set_record_status(\Symfony\Component\HttpFoundation\Request $request, $databox_id, $record_id);
/**
* Route : /records/DATABOX_ID/RECORD_ID/setcollection/FORMAT/
*
* Method : POST
*
* Parameters :
* DATABOX_ID : required INT
* RECORD_ID : required INT
*
*/
public function set_record_collection(\Symfony\Component\HttpFoundation\Request $request, $databox_id, $record_id);
/**
* Route : /records/DATABOX_ID/RECORD_ID/addtobasket/FORMAT/
*
* Method : POST
*
* Parameters :
* DATABOX_ID : required INT
* RECORD_ID : required INT
*
*/
public function add_record_tobasket(\Symfony\Component\HttpFoundation\Request $request, $databox_id, $record_id);
/**
* Route : /baskets/list/FORMAT/
*
* Method : POST
*
* Parameters :
*
*/
public function search_baskets(\Symfony\Component\HttpFoundation\Request $request);
/**
* Route : /baskets/add/FORMAT/
*
* Method : POST
*
* Parameters :
*
*/
public function create_basket(\Symfony\Component\HttpFoundation\Request $request);
/**
* Route : /baskets/BASKET_ID/delete/FORMAT/
*
* Method : POST
*
* Parameters :
* BASKET_ID : required INT
*
*/
public function delete_basket(\Symfony\Component\HttpFoundation\Request $request, $basket_id);
/**
* Route : /baskets/BASKET_ID/content/FORMAT/
*
* Method : POST
*
* Parameters :
* BASKET_ID : required INT
*
*/
public function get_basket(\Symfony\Component\HttpFoundation\Request $request, $basket_id);
/**
* Route : /baskets/BASKET_ID/title/FORMAT/
*
* Method : GET
*
* Parameters :
* BASKET_ID : required INT
*
*/
public function set_basket_title(\Symfony\Component\HttpFoundation\Request $request, $basket_id);
/**
* Route : /baskets/BASKET_ID/description/FORMAT/
*
* Method : POST
*
* Parameters :
* BASKET_ID : required INT
*
*/
public function set_basket_description(\Symfony\Component\HttpFoundation\Request $request, $basket_id);
/**
* Route : /publications/list/FORMAT/
*
* Method : POST
*
* Parameters :
*
*/
public function search_publications(\Symfony\Component\HttpFoundation\Request $request, User_Adapter &$user);
/**
* Route : /publications/PUBLICATION_ID/remove/FORMAT/
*
* Method : GET
*
* Parameters :
* PUBLICATION_ID : required INT
*
*/
public function remove_publications(\Symfony\Component\HttpFoundation\Request $request, $publication_id);
/**
* Route : /publications/PUBLICATION_ID/content/FORMAT/
*
* Method : GET
*
* Parameters :
* PUBLICATION_ID : required INT
*
*/
public function get_publication(\Symfony\Component\HttpFoundation\Request $request, $publication_id, User_Adapter &$user);
/**
* Route : /users/search/FORMAT/
*
* Method : POST-GET
*
* Parameters :
*
*/
public function search_users(\Symfony\Component\HttpFoundation\Request $request);
/**
* Route : /users/USER_ID/access/FORMAT/
*
* Method : GET
*
* Parameters :
* USER_ID : required INT
*
*/
public function get_user_acces(\Symfony\Component\HttpFoundation\Request $request, $usr_id);
/**
* Route : /users/add/FORMAT/
*
* Method : POST
*
* Parameters :
*
*/
public function add_user(\Symfony\Component\HttpFoundation\Request $request);
public function get_error_message(\Symfony\Component\HttpFoundation\Request $request, $error);
public function get_error_code(\Symfony\Component\HttpFoundation\Request $request, $code);
}

View File

@@ -0,0 +1,390 @@
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class API_V1_Log
{
const DATABOXES_RESSOURCE = 'databoxes';
const RECORDS_RESSOURCE = 'record';
const BASKETS_RESSOURCE = 'baskets';
const FEEDS_RESSOURCE = 'feeds';
/**
*
* @var int
*/
protected $id;
/**
*
* @var int
*/
protected $account_id;
/**
*
* @var DateTime
*/
protected $date;
/**
*
* @var int
*/
protected $status_code;
/**
*
* @var string
*/
protected $format;
/**
*
* @var string
*/
protected $ressource;
/**
*
* @var string
*/
protected $general;
/**
*
* @var string
*/
protected $aspect;
/**
*
* @var string
*/
protected $action;
/**
*
* @var API_OAuth2_Account
*/
protected $account;
/**
*
* @var appbox
*/
protected $appbox;
/**
*
* @param appbox $appbox
* @param Request $request
* @param API_OAuth2_Account $account
*/
public function __construct(appbox &$appbox, $log_id)
{
$this->appbox = $appbox;
$this->id = (int) $log_id;
$sql = '
SELECT
api_log_id,
api_account_id,
api_log_route,
api_log_date,
api_log_status_code,
api_log_format,
api_log_ressource,
api_log_general,
api_log_aspect,
api_log_action
FROM
api_logs
WHERE
api_log_id = :log_id';
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute(array(':log_id' => $this->id));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$this->account_id = $row['api_account_id'];
$this->account = new API_OAuth2_Account($this->appbox, (int) $row['api_account_id']);
$this->aspect = $row['api_log_aspect'];
$this->date = new DateTime($row['api_log_date']);
$this->format = $row['api_log_format'];
$this->general = $row['api_log_general'];
$this->ressource = $row['api_log_ressource'];
$this->status_code = (int) $row['api_log_status_code'];
return $this;
}
public function get_account_id()
{
return $this->account_id;
}
public function set_account_id($account_id)
{
$this->account_id = $account_id;
$sql = 'UPDATE api_log
SET api_account_id = :account_id
WHERE api_log_id = :log_id';
$params = array(
':api_account_id' => $this->account_id
, ':log_id' => $this->id
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
return $this;
}
public function get_date()
{
return $this->date;
}
public function set_date(DateTime $date)
{
$this->date = $date;
$sql = 'UPDATE api_log
SET api_log_date = :date
WHERE api_log_id = :log_id';
$params = array(
':date' => $this->date->format("Y-m-d H:i:s")
, ':log_id' => $this->id
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
return $this;
}
public function get_status_code()
{
return $this->status_code;
}
public function set_status_code($status_code)
{
$this->status_code = (int) $status_code;
$sql = 'UPDATE api_log
SET api_log_status_code = :code
WHERE api_log_id = :log_id';
$params = array(
':code' => $this->status_code
, ':log_id' => $this->id
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
return $this;
}
public function get_format()
{
return $this->format;
}
public function set_format($format)
{
if (!in_array($format, array('json', 'jsonp', 'yaml', 'unknow')))
throw new Exception_InvalidArgument();
$this->format = $format;
$sql = 'UPDATE api_log
SET api_log_format = :format
WHERE api_log_id = :log_id';
$params = array(
':format' => $this->format
, ':log_id' => $this->id
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
return $this;
}
public function get_ressource()
{
return $this->ressource;
}
public function set_ressource($ressource)
{
if (!in_array($format, array(self::DATABOXES_RESSOURCE,self::BASKETS_RESSOURCE, self::FEEDS_RESSOURCE, self::RECORDS_RESSOURCE)))
throw new Exception_InvalidArgument();
$this->ressource = $ressource;
$sql = 'UPDATE api_log
SET api_log_ressource = :ressource
WHERE api_log_id = :log_id';
$params = array(
':ressource' => $this->ressource
, ':log_id' => $this->id
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
return $this;
}
public function get_general()
{
return $this->general;
}
public function set_general($general)
{
$this->general = $general;
$sql = 'UPDATE api_log
SET api_log_general = :general
WHERE api_log_id = :log_id';
$params = array(
':general' => $this->general
, ':log_id' => $this->id
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
return $this;
}
public function get_aspect()
{
return $this->aspect;
}
public function set_aspect($aspect)
{
$this->aspect = $aspect;
$sql = 'UPDATE api_log
SET api_log_aspect = :aspect
WHERE api_log_id = :log_id';
$params = array(
':aspect' => $this->aspect
, ':log_id' => $this->id
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
return $this;
}
public function get_action()
{
return $this->action;
}
public function set_action($action)
{
$this->action = $action;
$sql = 'UPDATE api_log
SET api_log_action = :action
WHERE api_log_id = :log_id';
$params = array(
':action' => $this->action
, ':log_id' => $this->id
);
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
return $this;
}
public function get_account()
{
return $this->account;
}
public static function create(appbox &$appbox, API_OAuth2_Account $account, $route, $status_code, $format, $ressource, $general = null, $aspect = null, $action = null)
{
$sql = '
INSERT INTO
api_logs (
api_log_id,
api_account_id,
api_log_route,
api_log_date,
api_log_status_code,
api_log_format,
api_log_ressource,
api_log_general,
api_log_aspect,
api_log_action
)
VALUES (
null,
:account_id,
:route,
NOW(),
:status_code,
:format,
:ressource,
:general,
:aspect,
:action
)';
$params = array(
':account_id' => $account->get_id(),
':route' => $route,
':status_code' => $status_code,
':format' => $format,
':ressource' => $ressource,
':general' => $general,
':aspect' => $aspect,
':action' => $action
);
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$log_id = $appbox->get_connection()->lastInsertId();
return new self($appbox, $log_id);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,33 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package APIv1
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
abstract class API_V1_exception_abstract extends Exception
{
protected static $details;
public function __construct()
{
return $this;
}
public static function get_details()
{
return static::$details;
}
}

View File

@@ -0,0 +1,23 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package APIv1
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_V1_exception_badrequest extends API_V1_exception_abstract
{
protected static $details = 'Parameter is invalid or missing';
}

View File

@@ -0,0 +1,23 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package APIv1
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_V1_exception_forbidden extends API_V1_exception_abstract
{
protected static $details = 'Access to the requested ressource is forbidden';
}

View File

@@ -0,0 +1,23 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package APIv1
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_V1_exception_internalservererror extends API_V1_exception_abstract
{
protected static $details = 'Internal Server Error';
}

View File

@@ -0,0 +1,23 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package APIv1
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_V1_exception_methodnotallowed extends API_V1_exception_abstract
{
protected static $details = 'Attempting to use POST with a GET-only endpoint, or vice-versa';
}

View File

@@ -0,0 +1,23 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package APIv1
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_V1_exception_notfound extends API_V1_exception_abstract
{
protected static $details = 'Requested ressource is not found';
}

View File

@@ -0,0 +1,23 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package APIv1
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
class API_V1_exception_unauthorized extends API_V1_exception_abstract
{
protected static $details = 'The OAuth token was provided but was invalid.';
}

View File

@@ -0,0 +1,348 @@
<?php
require_once dirname(__FILE__) . "/../../../../lib/vendor/oauth2/lib/OAuth2.inc";
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
*
*
* @package APIv1
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
* @link www.phraseanet.com
*/
use \Symfony\Component\HttpFoundation\Request;
class API_V1_result
{
/**
*
* @var string
*/
protected $api_version;
/**
*
* @var string
*/
protected $response_time;
/**
*
* @var int
*/
protected $http_code = 200;
/**
*
* @var string
*/
protected $error_message;
/**
*
* @var string
*/
protected $error_details;
/**
*
* @var string
*/
protected $request;
/**
*
* @var mixed
*/
protected $response;
/**
*
* @var string
*/
protected $response_type;
/**
* Constant for responsetype json
*/
const FORMAT_JSON = 'json';
/**
* Constant for responsetype yaml
*/
const FORMAT_YAML = 'yaml';
/**
* Constant for responsetype jsonp
*/
const FORMAT_JSONP = 'jsonp';
const ERROR_BAD_REQUEST = 'Bad Request';
const ERROR_UNAUTHORIZED = 'Unauthorized';
const ERROR_FORBIDDEN = 'Forbidden';
const ERROR_NOTFOUND = 'Not Found';
const ERROR_METHODNOTALLOWED = 'Method Not Allowed';
const ERROR_INTERNALSERVERERROR = 'Internal Server Error';
/**
* API v1 Result constructor
*
* @param Request $request
* @param API_V1_adapter $api
* @param string $response_type One of the API_V1_result 'FORMAT_*' constants
* @return API_V1_result
*/
public function __construct(Request $request, API_V1_adapter $api)
{
$date = new DateTime();
$this->request = $request;
$this->api_version = $api->get_version();
$this->response_time = $date->format(DATE_ATOM);
$this->response = new stdClass();
$this->parse_response_type();
return $this;
}
protected function parse_response_type()
{
if (trim($this->request->get('callback')) !== '')
return $this->response_type = self::FORMAT_JSONP;
$accept = $this->request->getAcceptableContentTypes();
$response_types = array();
foreach ($accept as $key => $app_type)
{
$response_types[strtolower($app_type)] = true;
}
if (array_key_exists('application/json', $response_types))
return $this->response_type = self::FORMAT_JSON;
if (array_key_exists('application/yaml', $response_types))
return $this->response_type = self::FORMAT_YAML;
if (array_key_exists('text/yaml', $response_types))
return $this->response_type = self::FORMAT_YAML;
return $this->response_type = self::FORMAT_JSON;
}
/**
* Set datas to the response
* If no datas provided (aka empty array), a stdClass if set,
* so the serialized datas will be objects
*
* @param array $datas
* @return API_V1_result
*/
public function set_datas(array $datas)
{
if (count($datas) === 0)
$datas = new stdClass ();
$this->response = $datas;
return $this;
}
/**
* Format the data and return serialized string
*
* @return string
*/
public function format()
{
$request_uri = sprintf('%s %s'
, $this->request->getMethod()
, $this->request->getBasePath()
.$this->request->getPathInfo()
);
$ret = array(
'meta' => array(
'api_version' => $this->api_version
, 'request' => $request_uri
, 'response_time' => $this->response_time
, 'http_code' => $this->http_code
, 'error_message' => $this->error_message
, 'error_details' => $this->error_details
, 'charset' => 'UTF-8'
)
, 'response' => $this->response
);
$return_value = false;
switch ($this->response_type)
{
case self::FORMAT_JSON:
default:
$return_value = p4string::jsonencode($ret);
break;
case self::FORMAT_YAML:
if($ret['response'] instanceof stdClass)
$ret['response'] = array();
$dumper = new Symfony\Component\Yaml\Dumper();
$return_value = $dumper->dump($ret, 8);
break;
case self::FORMAT_JSONP:
$callback = trim($this->request->get('callback'));
$return_value = $callback . '(' . p4string::jsonencode($ret) . ')';
break;
}
return $return_value;
}
/**
* Return serailized datas content type
*
* @return string
*/
public function get_content_type()
{
switch ($this->response_type)
{
case self::FORMAT_JSON:
default:
$return_value = 'application/json';
break;
case self::FORMAT_YAML:
$return_value = 'application/yaml';
break;
case self::FORMAT_JSONP:
$return_value = 'text/javascript';
break;
}
return $return_value;
}
/**
* Set the API_V1_result http_code, error_message and error_details
* with the appropriate datas
*
* @param string $const
* @return API_V1_result
*/
public function set_error_message($const)
{
switch ($const)
{
case self::ERROR_BAD_REQUEST:
$this->http_code = 400;
$this->error_message = $const;
$this->error_details = API_V1_exception_badrequest::get_details();
break;
case self::ERROR_UNAUTHORIZED:
$this->http_code = 401;
$this->error_message = $const;
$this->error_details = API_V1_exception_unauthorized::get_details();
break;
case self::ERROR_FORBIDDEN:
$this->http_code = 403;
$this->error_message = $const;
$this->error_details = API_V1_exception_forbidden::get_details();
break;
case self::ERROR_NOTFOUND:
$this->http_code = 404;
$this->error_message = $const;
$this->error_details = API_V1_exception_notfound::get_details();
break;
case self::ERROR_METHODNOTALLOWED:
$this->http_code = 405;
$this->error_message = $const;
$this->error_details = API_V1_exception_methodnotallowed::get_details();
break;
case self::ERROR_INTERNALSERVERERROR:
$this->http_code = 500;
$this->error_message = $const;
$this->error_details = API_V1_exception_internalservererror::get_details();
break;
case OAUTH2_ERROR_INVALID_REQUEST:
$this->error_message = $const;
break;
}
return $this;
}
/**
* Set the API_V1_result http_code, error_message and error_details
* with the appropriate datas
*
* @param string $const
* @return API_V1_result
*/
public function set_error_code($code)
{
switch($code = (int)$code)
{
case 400:
$this->http_code = $code;
$this->error_message = self::ERROR_BAD_REQUEST;
$this->error_details = API_V1_exception_badrequest::get_details();
break;
case 401:
$this->http_code = $code;
$this->error_message = self::ERROR_UNAUTHORIZED;
$this->error_details = API_V1_exception_unauthorized::get_details();
break;
case 403:
$this->http_code = $code;
$this->error_message = self::ERROR_FORBIDDEN;
$this->error_details = API_V1_exception_forbidden::get_details();
break;
case 404:
$this->http_code = $code;
$this->error_message = self::ERROR_NOTFOUND;
$this->error_details = API_V1_exception_notfound::get_details();
break;
case 405:
$this->http_code = $code;
$this->error_message = self::ERROR_METHODNOTALLOWED;
$this->error_details = API_V1_exception_methodnotallowed::get_details();
break;
case 500:
$this->http_code = $code;
$this->error_message = self::ERROR_INTERNALSERVERERROR;
$this->error_details = API_V1_exception_internalservererror::get_details();
break;
}
return $this;
}
/**
* Returns the correct http code depending on the errors
*
* @return int
*/
public function get_http_code()
{
if($this->response_type == self::FORMAT_JSONP && $this->http_code != 500)
return 200;
else
return $this->http_code;
}
/**
*
* @param int $code
*/
public function set_http_code($code)
{
$this->http_code = (int)$code;
}
}