mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-23 18:03:17 +00:00
Merge pull request #1021 from nlegoff/api-doctrine
[READY][3.9] Transform api_* tables to doctrine entities
This commit is contained in:
@@ -71,14 +71,17 @@ use Alchemy\Phrasea\Controller\Utils\ConnectionTest;
|
||||
use Alchemy\Phrasea\Controller\Utils\PathFileTest;
|
||||
use Alchemy\Phrasea\Controller\User\Notifications;
|
||||
use Alchemy\Phrasea\Controller\User\Preferences;
|
||||
use Alchemy\Phrasea\Core\Middleware\TokenMiddlewareProvider;
|
||||
use Alchemy\Phrasea\Core\PhraseaExceptionHandler;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\LogoutSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\PhraseaLocaleSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\MaintenanceSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\CookiesDisablerSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\PhraseaInstallSubscriber;
|
||||
use Alchemy\Phrasea\Core\Middleware\ApiApplicationMiddlewareProvider;
|
||||
use Alchemy\Phrasea\Core\Middleware\BasketMiddlewareProvider;
|
||||
use Alchemy\Phrasea\Core\Middleware\TokenMiddlewareProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\ACLServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\APIServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\BrowserServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\BorderManagerServiceProvider;
|
||||
@@ -213,8 +216,10 @@ class Application extends SilexApplication
|
||||
|
||||
$this->register(new BasketMiddlewareProvider());
|
||||
$this->register(new TokenMiddlewareProvider());
|
||||
$this->register(new ApiApplicationMiddlewareProvider());
|
||||
|
||||
$this->register(new ACLServiceProvider());
|
||||
$this->register(new APIServiceProvider());
|
||||
$this->register(new AuthenticationManagerServiceProvider());
|
||||
$this->register(new BorderManagerServiceProvider());
|
||||
$this->register(new BrowserServiceProvider());
|
||||
@@ -472,6 +477,7 @@ class Application extends SilexApplication
|
||||
$dispatcher->addSubscriber(new PhraseaLocaleSubscriber($app));
|
||||
$dispatcher->addSubscriber(new MaintenanceSubscriber($app));
|
||||
$dispatcher->addSubscriber(new CookiesDisablerSubscriber($app));
|
||||
$dispatcher->addSubscriber(new PhraseaInstallSubscriber($app));
|
||||
|
||||
return $dispatcher;
|
||||
})
|
||||
|
@@ -13,6 +13,7 @@ namespace Alchemy\Phrasea\Command\Developer;
|
||||
|
||||
use Alchemy\Phrasea\Border\Manager;
|
||||
use Alchemy\Phrasea\Command\Command;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
use Alchemy\Phrasea\Model\Entities\AuthFailure;
|
||||
use Alchemy\Phrasea\Model\Entities\AggregateToken;
|
||||
use Alchemy\Phrasea\Model\Entities\Basket;
|
||||
@@ -88,6 +89,8 @@ class RegenerateSqliteDb extends Command
|
||||
|
||||
$this->generateUsers($this->container['EM'], $DI);
|
||||
$this->insertOauthApps($DI);
|
||||
$this->insertOauthAccounts($DI);
|
||||
$this->insertNativeApps();
|
||||
$this->generateCollection($DI);
|
||||
$this->generateRecord($DI);
|
||||
$this->insertTwoTasks($this->container['EM']);
|
||||
@@ -124,8 +127,10 @@ class RegenerateSqliteDb extends Command
|
||||
$fixtures['user']['test_phpunit_alt2'] = $DI['user_alt2']->getId();
|
||||
$fixtures['user']['user_guest'] = $DI['user_guest']->getId();
|
||||
|
||||
$fixtures['oauth']['user'] = $DI['app-user']->get_id();
|
||||
$fixtures['oauth']['user_notAdmin'] = $DI['app-user_notAdmin']->get_id();
|
||||
$fixtures['oauth']['user'] = $DI['api-app-user']->getId();
|
||||
$fixtures['oauth']['acc-user'] = $DI['api-app-acc-user']->getId();
|
||||
$fixtures['oauth']['user-not-admin'] = $DI['api-app-user-not-admin']->getId();
|
||||
$fixtures['oauth']['acc-user-not-admin'] = $DI['api-app-acc-user-not-admin']->getId();
|
||||
|
||||
$fixtures['databox']['records'] = $DI['databox']->get_sbas_id();
|
||||
$fixtures['collection']['coll'] = $DI['coll']->get_base_id();
|
||||
@@ -182,15 +187,64 @@ class RegenerateSqliteDb extends Command
|
||||
|
||||
private function insertOauthApps(\Pimple $DI)
|
||||
{
|
||||
$DI['app-user'] = \API_OAuth2_Application::create($this->container, $DI['user'], 'test application for user');
|
||||
$DI['app-user']->set_redirect_uri('http://callback.com/callback/');
|
||||
$DI['app-user']->set_website('http://website.com/');
|
||||
$DI['app-user']->set_type(\API_OAuth2_Application::WEB_TYPE);
|
||||
$DI['api-app-user'] = $this->container['manipulator.api-application']->create(
|
||||
'test application for user',
|
||||
ApiApplication::WEB_TYPE,
|
||||
'an api application description',
|
||||
'http://website.com/',
|
||||
$DI['user'],
|
||||
'http://callback.com/callback/'
|
||||
);
|
||||
|
||||
$DI['app-user_notAdmin'] = \API_OAuth2_Application::create($this->container, $DI['user_notAdmin'], 'test application for user not admin');
|
||||
$DI['app-user_notAdmin']->set_redirect_uri('http://callback.com/callback/');
|
||||
$DI['app-user_notAdmin']->set_website('http://website.com/');
|
||||
$DI['app-user_notAdmin']->set_type(\API_OAuth2_Application::WEB_TYPE);
|
||||
$DI['api-app-user-not-admin'] = $this->container['manipulator.api-application']->create(
|
||||
'test application for user',
|
||||
ApiApplication::WEB_TYPE,
|
||||
'an api application description',
|
||||
'http://website.com/',
|
||||
$DI['user_notAdmin'],
|
||||
'http://callback.com/callback/'
|
||||
);
|
||||
}
|
||||
|
||||
public function insertOauthAccounts(\Pimple $DI)
|
||||
{
|
||||
$DI['api-app-acc-user'] = $this->container['manipulator.api-account']->create($DI['api-app-user'], $DI['user']);
|
||||
$this->container['manipulator.api-oauth-token']->create($DI['api-app-acc-user']);
|
||||
$DI['api-app-acc-user-not-admin'] = $this->container['manipulator.api-account']->create($DI['api-app-user-not-admin'], $DI['user_notAdmin']);
|
||||
$this->container['manipulator.api-oauth-token']->create($DI['api-app-acc-user-not-admin']);
|
||||
}
|
||||
|
||||
public function insertNativeApps()
|
||||
{
|
||||
$application = $this->container['manipulator.api-application']->create(
|
||||
\API_OAuth2_Application_Navigator::CLIENT_NAME,
|
||||
ApiApplication::DESKTOP_TYPE,
|
||||
'',
|
||||
'http://www.phraseanet.com',
|
||||
null,
|
||||
ApiApplication::NATIVE_APP_REDIRECT_URI
|
||||
);
|
||||
|
||||
$application->setGrantPassword(true);
|
||||
$application->setClientId(\API_OAuth2_Application_Navigator::CLIENT_ID);
|
||||
$application->setClientSecret(\API_OAuth2_Application_Navigator::CLIENT_SECRET);
|
||||
|
||||
$this->container['manipulator.api-application']->update($application);
|
||||
|
||||
$application = $this->container['manipulator.api-application']->create(
|
||||
\API_OAuth2_Application_OfficePlugin::CLIENT_NAME,
|
||||
ApiApplication::DESKTOP_TYPE,
|
||||
'',
|
||||
'http://www.phraseanet.com',
|
||||
null,
|
||||
ApiApplication::NATIVE_APP_REDIRECT_URI
|
||||
);
|
||||
|
||||
$application->setGrantPassword(true);
|
||||
$application->setClientId(\API_OAuth2_Application_OfficePlugin::CLIENT_ID);
|
||||
$application->setClientSecret(\API_OAuth2_Application_OfficePlugin::CLIENT_SECRET);
|
||||
|
||||
$this->container['manipulator.api-application']->update($application);
|
||||
}
|
||||
|
||||
private function insertAuthFailures(EntityManager $em, \Pimple $DI)
|
||||
|
@@ -1,393 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Controller\Api;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
|
||||
class Logger
|
||||
{
|
||||
const DATABOXES_RESOURCE = 'databoxes';
|
||||
const RECORDS_RESOURCE = 'record';
|
||||
const BASKETS_RESOURCE = 'baskets';
|
||||
const FEEDS_RESOURCE = 'feeds';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $account_id;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var DateTime
|
||||
*/
|
||||
private $date;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $status_code;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $format;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $resource;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $general;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $aspect;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $action;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var API_OAuth2_Account
|
||||
*/
|
||||
private $account;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Application
|
||||
*/
|
||||
private $app;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Application $app
|
||||
* @param integer $log_id
|
||||
*/
|
||||
public function __construct(Application $app, $log_id)
|
||||
{
|
||||
$this->app = $app;
|
||||
$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_resource,
|
||||
api_log_general,
|
||||
api_log_aspect,
|
||||
api_log_action
|
||||
FROM
|
||||
api_logs
|
||||
WHERE
|
||||
api_log_id = :log_id';
|
||||
|
||||
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute([':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->app, (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->resource = $row['api_log_resource'];
|
||||
$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 = [
|
||||
':api_account_id' => $this->account_id
|
||||
, ':log_id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.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 = [
|
||||
':date' => $this->date->format("Y-m-d H:i:s")
|
||||
, ':log_id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.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 = [
|
||||
':code' => $this->status_code
|
||||
, ':log_id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.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, ['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 = [
|
||||
':format' => $this->format
|
||||
, ':log_id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$stmt->closeCursor();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function get_resource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
public function set_resource($resource)
|
||||
{
|
||||
if ( ! in_array($resource, [self::DATABOXES_RESOURCE, self::BASKETS_RESOURCE, self::FEEDS_RESOURCE, self::RECORDS_RESOURCE]))
|
||||
throw new \Exception_InvalidArgument();
|
||||
|
||||
$this->resource = $resource;
|
||||
|
||||
$sql = 'UPDATE api_log
|
||||
SET api_log_resource = :resource
|
||||
WHERE api_log_id = :log_id';
|
||||
|
||||
$params = [
|
||||
':resource' => $this->resource,
|
||||
':log_id' => $this->id,
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.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 = [
|
||||
':general' => $this->general
|
||||
, ':log_id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.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 = [
|
||||
':aspect' => $this->aspect
|
||||
, ':log_id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.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 = [
|
||||
':action' => $this->action
|
||||
, ':log_id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$stmt->closeCursor();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function get_account()
|
||||
{
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
public static function create(Application $app, \API_OAuth2_Account $account, $route, $status_code, $format, $resource, $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_resource,
|
||||
api_log_general,
|
||||
api_log_aspect,
|
||||
api_log_action
|
||||
)
|
||||
VALUES (
|
||||
null,
|
||||
:account_id,
|
||||
:route,
|
||||
NOW(),
|
||||
:status_code,
|
||||
:format,
|
||||
:resource,
|
||||
:general,
|
||||
:aspect,
|
||||
:action
|
||||
)';
|
||||
|
||||
$params = [
|
||||
':account_id' => $account->get_id(),
|
||||
':route' => $route,
|
||||
':status_code' => $status_code,
|
||||
':format' => $format,
|
||||
':resource' => $resource,
|
||||
':general' => $general,
|
||||
':aspect' => $aspect,
|
||||
':action' => $action
|
||||
];
|
||||
|
||||
$stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$stmt->closeCursor();
|
||||
|
||||
$log_id = $app['phraseanet.appbox']->get_connection()->lastInsertId();
|
||||
|
||||
return new self($app, $log_id);
|
||||
}
|
||||
}
|
@@ -21,6 +21,7 @@ use Silex\ControllerProviderInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
class Oauth2 implements ControllerProviderInterface
|
||||
{
|
||||
@@ -30,10 +31,6 @@ class Oauth2 implements ControllerProviderInterface
|
||||
|
||||
$controllers = $app['controllers_factory'];
|
||||
|
||||
$app['oauth'] = $app->share(function ($app) {
|
||||
return new \API_OAuth2_Adapter($app);
|
||||
});
|
||||
|
||||
/**
|
||||
* AUTHORIZE ENDPOINT
|
||||
*
|
||||
@@ -42,45 +39,45 @@ class Oauth2 implements ControllerProviderInterface
|
||||
*/
|
||||
$authorize_func = function () use ($app) {
|
||||
$request = $app['request'];
|
||||
$oauth2_adapter = $app['oauth'];
|
||||
$oauth2Adapter = $app['oauth2-server'];
|
||||
|
||||
$context = new Context(Context::CONTEXT_OAUTH2_NATIVE);
|
||||
$app['dispatcher']->dispatch(PhraseaEvents::PRE_AUTHENTICATE, new PreAuthenticate($request, $context));
|
||||
|
||||
//Check for auth params, send error or redirect if not valid
|
||||
$params = $oauth2_adapter->getAuthorizationRequestParameters($request);
|
||||
$params = $oauth2Adapter->getAuthorizationRequestParameters($request);
|
||||
|
||||
$app_authorized = false;
|
||||
$appAuthorized = false;
|
||||
$errorMessage = false;
|
||||
|
||||
$client = \API_OAuth2_Application::load_from_client_id($app, $params['client_id']);
|
||||
if (null === $client = $app['repo.api-applications']->findByClientId($params['client_id'])) {
|
||||
throw new NotFoundHttpException(sprintf('Application with client id %s could not be found', $params['client_id']));
|
||||
}
|
||||
|
||||
$oauth2_adapter->setClient($client);
|
||||
$oauth2Adapter->setClient($client);
|
||||
|
||||
$action_accept = $request->get("action_accept");
|
||||
$action_login = $request->get("action_login");
|
||||
$actionAccept = $request->get("action_accept");
|
||||
$actionLogin = $request->get("action_login");
|
||||
|
||||
$template = "api/auth/end_user_authorization.html.twig";
|
||||
|
||||
$custom_template = sprintf(
|
||||
"%s/config/templates/web/api/auth/end_user_authorization/%s.html.twig"
|
||||
, $app['root.path']
|
||||
, $client->get_id()
|
||||
, $client->getId()
|
||||
);
|
||||
|
||||
if (file_exists($custom_template)) {
|
||||
$template = sprintf(
|
||||
'api/auth/end_user_authorization/%s.html.twig'
|
||||
, $client->get_id()
|
||||
, $client->getId()
|
||||
);
|
||||
}
|
||||
|
||||
if (!$app['authentication']->isAuthenticated()) {
|
||||
if ($action_login !== null) {
|
||||
if ($actionLogin !== null) {
|
||||
try {
|
||||
$usr_id = $app['auth.native']->getUsrId($request->get("login"), $request->get("password"), $request);
|
||||
|
||||
if (null === $usr_id) {
|
||||
if (null === $usrId = $app['auth.native']->getUsrId($request->get("login"), $request->get("password"), $request)) {
|
||||
$app['session']->getFlashBag()->set('error', $app->trans('login::erreur: Erreur d\'authentification'));
|
||||
|
||||
return $app->redirectPath('oauth2_authorize');
|
||||
@@ -91,48 +88,51 @@ class Oauth2 implements ControllerProviderInterface
|
||||
return $app->redirectPath('oauth2_authorize', ['error' => 'account-locked']);
|
||||
}
|
||||
|
||||
$app['authentication']->openAccount($app['repo.users']->find($usr_id));
|
||||
$app['authentication']->openAccount($app['repo.users']->find($usrId));
|
||||
}
|
||||
|
||||
return new Response($app['twig']->render($template, ["auth" => $oauth2_adapter]));
|
||||
return new Response($app['twig']->render($template, ["auth" => $oauth2Adapter]));
|
||||
}
|
||||
|
||||
//check if current client is already authorized by current user
|
||||
$user_auth_clients = \API_OAuth2_Application::load_authorized_app_by_user(
|
||||
$app
|
||||
, $app['authentication']->getUser()
|
||||
);
|
||||
$clients = $app['repo.api-applications']->findAuthorizedAppsByUser($app['authentication']->getUser());
|
||||
|
||||
foreach ($user_auth_clients as $auth_client) {
|
||||
if ($client->get_client_id() == $auth_client->get_client_id()) {
|
||||
$app_authorized = true;
|
||||
foreach ($clients as $authClient) {
|
||||
if ($client->getClientId() == $authClient->getClientId()) {
|
||||
$appAuthorized = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$account = $oauth2_adapter->updateAccount($app['authentication']->getUser());
|
||||
$account = $oauth2Adapter->updateAccount($app['authentication']->getUser());
|
||||
|
||||
$params['account_id'] = $account->get_id();
|
||||
$params['account_id'] = $account->getId();
|
||||
|
||||
if (!$app_authorized && $action_accept === null) {
|
||||
if (!$appAuthorized && $actionAccept === null) {
|
||||
$params = [
|
||||
"auth" => $oauth2_adapter,
|
||||
"auth" => $oauth2Adapter,
|
||||
"errorMessage" => $errorMessage,
|
||||
];
|
||||
|
||||
return new Response($app['twig']->render($template, $params));
|
||||
} elseif (!$app_authorized && $action_accept !== null) {
|
||||
$app_authorized = (Boolean) $action_accept;
|
||||
$account->set_revoked(!$app_authorized);
|
||||
} elseif (!$appAuthorized && $actionAccept !== null) {
|
||||
$appAuthorized = (Boolean) $actionAccept;
|
||||
|
||||
if ($appAuthorized) {
|
||||
$app['manipulator.api-account']->authorizeAccess($account);
|
||||
} else {
|
||||
$app['manipulator.api-account']->revokeAccess($account);
|
||||
}
|
||||
}
|
||||
|
||||
//if native app show template
|
||||
if ($oauth2_adapter->isNativeApp($params['redirect_uri'])) {
|
||||
$params = $oauth2_adapter->finishNativeClientAuthorization($app_authorized, $params);
|
||||
if ($oauth2Adapter->isNativeApp($params['redirect_uri'])) {
|
||||
$params = $oauth2Adapter->finishNativeClientAuthorization($appAuthorized, $params);
|
||||
|
||||
return new Response($app['twig']->render("api/auth/native_app_access_token.html.twig", $params));
|
||||
}
|
||||
|
||||
$oauth2_adapter->finishClientAuthorization($app_authorized, $params);
|
||||
$oauth2Adapter->finishClientAuthorization($appAuthorized, $params);
|
||||
|
||||
// As OAuth2 library already outputs response content, we need to send an empty
|
||||
// response to avoid breaking silex controller
|
||||
@@ -152,7 +152,7 @@ class Oauth2 implements ControllerProviderInterface
|
||||
throw new HttpException(400, 'This route requires the use of the https scheme', null, ['content-type' => 'application/json']);
|
||||
}
|
||||
|
||||
$app['oauth']->grantAccessToken($request);
|
||||
$app['oauth2-server']->grantAccessToken($request);
|
||||
ob_flush();
|
||||
flush();
|
||||
|
||||
|
@@ -62,8 +62,13 @@ class V1 implements ControllerProviderInterface
|
||||
});
|
||||
|
||||
$controllers->after(function (Request $request, Response $response) use ($app) {
|
||||
$this->logQuery($app, $request, $response);
|
||||
$this->logout($app);
|
||||
$token = $app['session']->get('token');
|
||||
$app['manipulator.api-log']->create($token->getAccount(), $request, $response);
|
||||
$app['manipulator.api-oauth-token']->setLastUsed($token, new \DateTime());
|
||||
$app['session']->set('token', null);
|
||||
if (null !== $app['authentication']->getUser()) {
|
||||
$app['authentication']->closeAccount();
|
||||
}
|
||||
});
|
||||
|
||||
$controllers->get('/monitor/scheduler/', 'controller.api.v1:get_scheduler')
|
||||
@@ -1967,119 +1972,39 @@ class V1 implements ControllerProviderInterface
|
||||
$app['dispatcher']->dispatch(PhraseaEvents::PRE_AUTHENTICATE, new PreAuthenticate($request, $context));
|
||||
$app['dispatcher']->dispatch(PhraseaEvents::API_OAUTH2_START, new ApiOAuth2StartEvent());
|
||||
|
||||
$oauth2_adapter = new \API_OAuth2_Adapter($app);
|
||||
$oauth2_adapter->verifyAccessToken();
|
||||
$app['oauth2-server']->verifyAccessToken();
|
||||
|
||||
$token = \API_OAuth2_Token::load_by_oauth_token($app, $oauth2_adapter->getToken());
|
||||
if (null === $token = $app['repo.api-oauth-tokens']->find($app['oauth2-server']->getToken())) {
|
||||
throw new NotFoundHttpException('Provided token is not valid.');
|
||||
}
|
||||
$app['session']->set('token', $token);
|
||||
|
||||
$oAuth2App = $token->get_account()->get_application();
|
||||
/* @var $oAuth2App \API_OAuth2_Application */
|
||||
$oAuth2Account = $token->getAccount();
|
||||
$oAuth2App = $oAuth2Account->getApplication();
|
||||
|
||||
if ($oAuth2App->get_client_id() == \API_OAuth2_Application_Navigator::CLIENT_ID
|
||||
if ($oAuth2App->getClientId() == \API_OAuth2_Application_Navigator::CLIENT_ID
|
||||
&& !$app['conf']->get(['registry', 'api-clients', 'navigator-enabled'])) {
|
||||
return Result::createError($request, 403, 'The use of phraseanet Navigator is not allowed')->createResponse();
|
||||
return Result::createError($request, 403, 'The use of Phraseanet Navigator is not allowed')->createResponse();
|
||||
}
|
||||
|
||||
if ($oAuth2App->get_client_id() == \API_OAuth2_Application_OfficePlugin::CLIENT_ID
|
||||
if ($oAuth2App->getClientId() == \API_OAuth2_Application_OfficePlugin::CLIENT_ID
|
||||
&& ! $app['conf']->get(['registry', 'api-clients', 'office-enabled'])) {
|
||||
return Result::createError($request, 403, 'The use of Office Plugin is not allowed.')->createResponse();
|
||||
}
|
||||
|
||||
$user = $app['repo.users']->find($oauth2_adapter->get_usr_id());
|
||||
$app['authentication']->openAccount($user);
|
||||
$oauth2_adapter->remember_this_ses_id($app['session']->get('session_id'));
|
||||
$app['authentication']->openAccount($oAuth2Account->getUser());
|
||||
$app['oauth2-server']->rememberSession($app['session']);
|
||||
$app['dispatcher']->dispatch(PhraseaEvents::API_OAUTH2_END, new ApiOAuth2EndEvent());
|
||||
}
|
||||
|
||||
public function ensureAdmin(Request $request, Application $app)
|
||||
{
|
||||
$user = $app['session']->get('token')->get_account()->get_user();
|
||||
if (!$app['acl']->get($user)->is_admin()) {
|
||||
$user = $app['session']->get('token')->getAccount()->getUser();
|
||||
if (!$user->isAdmin()) {
|
||||
return Result::createError($request, 401, 'You are not authorized')->createResponse();
|
||||
}
|
||||
}
|
||||
|
||||
private function logQuery(Application $app, Request $request, Response $response)
|
||||
{
|
||||
$infos = $this->parseRoute($request->getPathInfo(), $response);
|
||||
|
||||
Logger::create(
|
||||
$app,
|
||||
$app['session']->get('token')->get_account(),
|
||||
$request->getMethod() . " " . $request->getPathInfo(),
|
||||
$response->getStatusCode(),
|
||||
$response->headers->get('content-type'),
|
||||
$infos['ressource'],
|
||||
$infos['general'],
|
||||
$infos['aspect'],
|
||||
$infos['action']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the requested route to fetch
|
||||
* - the ressource (databox, basket, record etc ..)
|
||||
* - general action (list, add, search)
|
||||
* - the action (setstatus, setname etc..)
|
||||
* - the aspect (collections, related, content etc..)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseRoute($route, Response $response)
|
||||
{
|
||||
$ressource = $general = $aspect = $action = null;
|
||||
$exploded_route = explode('/', trim($route, '/'));
|
||||
|
||||
if ($response->isOk() && sizeof($exploded_route) > 0) {
|
||||
$ressource = $exploded_route[0];
|
||||
|
||||
if (count($exploded_route) == 2 && (int) $exploded_route[1] == 0) {
|
||||
$general = $exploded_route[1];
|
||||
} else {
|
||||
switch ($ressource) {
|
||||
case Logger::DATABOXES_RESOURCE :
|
||||
if ((int) $exploded_route[1] > 0 && count($exploded_route) == 3) {
|
||||
$aspect = $exploded_route[2];
|
||||
}
|
||||
break;
|
||||
case Logger::RECORDS_RESOURCE :
|
||||
if ((int) $exploded_route[1] > 0 && count($exploded_route) == 4) {
|
||||
if (!isset($exploded_route[3])) {
|
||||
$aspect = "record";
|
||||
} elseif (preg_match("/^set/", $exploded_route[3])) {
|
||||
$action = $exploded_route[3];
|
||||
} else {
|
||||
$aspect = $exploded_route[3];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Logger::BASKETS_RESOURCE :
|
||||
if ((int) $exploded_route[1] > 0 && count($exploded_route) == 3) {
|
||||
if (preg_match("/^set/", $exploded_route[2]) || preg_match("/^delete/", $exploded_route[2])) {
|
||||
$action = $exploded_route[2];
|
||||
} else {
|
||||
$aspect = $exploded_route[2];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Logger::FEEDS_RESOURCE :
|
||||
if ((int) $exploded_route[1] > 0 && count($exploded_route) == 3) {
|
||||
$aspect = $exploded_route[2];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'ressource' => $ressource,
|
||||
'general' => $general,
|
||||
'aspect' => $aspect,
|
||||
'action' => $action
|
||||
];
|
||||
}
|
||||
|
||||
private function list_user(User $user)
|
||||
{
|
||||
switch ($user->getGender()) {
|
||||
@@ -2119,11 +2044,4 @@ class V1 implements ControllerProviderInterface
|
||||
'locale' => $user->getLocale() ?: null,
|
||||
];
|
||||
}
|
||||
|
||||
private function logout(Application $app)
|
||||
{
|
||||
if (null !== $app['authentication']->getUser()) {
|
||||
$app['authentication']->closeAccount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@ use Alchemy\Geonames\Exception\ExceptionInterface as GeonamesExceptionInterface;
|
||||
use Alchemy\Phrasea\Application as PhraseaApplication;
|
||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
||||
use Alchemy\Phrasea\Model\Entities\FtpCredential;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
use Alchemy\Phrasea\Notification\Receiver;
|
||||
use Alchemy\Phrasea\Notification\Mail\MailRequestEmailUpdate;
|
||||
use Alchemy\Phrasea\Form\Login\PhraseaRenewPasswordForm;
|
||||
@@ -69,7 +70,8 @@ class Account implements ControllerProviderInterface
|
||||
->bind('account_auth_apps');
|
||||
|
||||
// Displays a an authorized app grant
|
||||
$controllers->get('/security/application/{application_id}/grant/', 'account.controller:grantAccess')
|
||||
$controllers->get('/security/application/{application}/grant/', 'account.controller:grantAccess')
|
||||
->before($app['middleware.api-application.converter'])
|
||||
->assert('application_id', '\d+')
|
||||
->bind('grant_app_access');
|
||||
|
||||
@@ -191,33 +193,29 @@ class Account implements ControllerProviderInterface
|
||||
/**
|
||||
* Display authorized applications that can access user informations
|
||||
*
|
||||
* @param Application $app A Silex application where the controller is mounted on
|
||||
* @param Request $request The current request
|
||||
* @param Integer $application_id The application id
|
||||
* @param Application $app
|
||||
* @param Request $request
|
||||
* @param ApiApplication $application
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function grantAccess(Application $app, Request $request, $application_id)
|
||||
public function grantAccess(Application $app, Request $request, ApiApplication $application)
|
||||
{
|
||||
if (!$request->isXmlHttpRequest() || !array_key_exists($request->getMimeType('json'), array_flip($request->getAcceptableContentTypes()))) {
|
||||
$app->abort(400, $app->trans('Bad request format, only JSON is allowed'));
|
||||
}
|
||||
|
||||
$error = false;
|
||||
|
||||
try {
|
||||
$account = \API_OAuth2_Account::load_with_user(
|
||||
$app
|
||||
, new \API_OAuth2_Application($app, $application_id)
|
||||
, $app['authentication']->getUser()
|
||||
);
|
||||
|
||||
$account->set_revoked((bool) $request->query->get('revoke'), false);
|
||||
} catch (NotFoundHttpException $e) {
|
||||
$error = true;
|
||||
if (null === $account = $app['repo.api-accounts']->findByUserAndApplication($app['authentication']->getUser(), $application)) {
|
||||
return $app->json(['success' => false]);
|
||||
}
|
||||
|
||||
return $app->json(['success' => !$error]);
|
||||
if (false === (Boolean) $request->query->get('revoke')) {
|
||||
$app['manipulator.api-account']->authorizeAccess($account);
|
||||
} else {
|
||||
$app['manipulator.api-account']->revokeAccess($account);
|
||||
}
|
||||
|
||||
return $app->json(['success' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -243,8 +241,17 @@ class Account implements ControllerProviderInterface
|
||||
*/
|
||||
public function accountAuthorizedApps(Application $app, Request $request)
|
||||
{
|
||||
$data = [];
|
||||
|
||||
foreach ($app['repo.api-applications']->findByUser($app['authentication']->getUser()) as $application) {
|
||||
$account = $app['repo.api-accounts']->findByUserAndApplication($app['authentication']->getUser(), $application);
|
||||
|
||||
$data[$application->getId()]['application'] = $application;
|
||||
$data[$application->getId()]['user-account'] = $account;
|
||||
}
|
||||
|
||||
return $app['twig']->render('account/authorized_apps.html.twig', [
|
||||
"applications" => \API_OAuth2_Application::load_app_by_user($app, $app['authentication']->getUser()),
|
||||
"applications" => $data,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@@ -11,6 +11,8 @@
|
||||
|
||||
namespace Alchemy\Phrasea\Controller\Root;
|
||||
|
||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
use Silex\Application;
|
||||
use Silex\ControllerProviderInterface;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
@@ -37,147 +39,126 @@ class Developers implements ControllerProviderInterface
|
||||
$controllers->post('/application/', 'controller.account.developers:newApp')
|
||||
->bind('submit_developers_application');
|
||||
|
||||
$controllers->get('/application/{id}/', 'controller.account.developers:getApp')
|
||||
->assert('id', '\d+')
|
||||
$controllers->get('/application/{application}/', 'controller.account.developers:getApp')
|
||||
->before($app['middleware.api-application.converter'])
|
||||
->assert('application', '\d+')
|
||||
->bind('developers_application');
|
||||
|
||||
$controllers->delete('/application/{id}/', 'controller.account.developers:deleteApp')
|
||||
->assert('id', '\d+')
|
||||
$controllers->delete('/application/{application}/', 'controller.account.developers:deleteApp')
|
||||
->before($app['middleware.api-application.converter'])
|
||||
->assert('application', '\d+')
|
||||
->bind('delete_developers_application');
|
||||
|
||||
$controllers->post('/application/{id}/authorize_grant_password/', 'controller.account.developers:authorizeGrantpassword')
|
||||
->assert('id', '\d+')
|
||||
$controllers->post('/application/{application}/authorize_grant_password/', 'controller.account.developers:authorizeGrantPassword')
|
||||
->before($app['middleware.api-application.converter'])
|
||||
->assert('application', '\d+')
|
||||
->bind('submit_developers_application_authorize_grant_password');
|
||||
|
||||
$controllers->post('/application/{id}/access_token/', 'controller.account.developers:renewAccessToken')
|
||||
->assert('id', '\d+')
|
||||
$controllers->post('/application/{application}/access_token/', 'controller.account.developers:renewAccessToken')
|
||||
->before($app['middleware.api-application.converter'])
|
||||
->assert('application', '\d+')
|
||||
->bind('submit_developers_application_token');
|
||||
|
||||
$controllers->post('/application/{id}/callback/', 'controller.account.developers:renewAppCallback')
|
||||
->assert('id', '\d+')
|
||||
$controllers->post('/application/{application}/callback/', 'controller.account.developers:renewAppCallback')
|
||||
->before($app['middleware.api-application.converter'])
|
||||
->assert('application', '\d+')
|
||||
->bind('submit_application_callback');
|
||||
|
||||
return $controllers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete application
|
||||
* Delete application.
|
||||
*
|
||||
* @param Application $app
|
||||
* @param Request $request
|
||||
* @param ApiApplication $application
|
||||
*
|
||||
* @param Application $app A Silex application where the controller is mounted on
|
||||
* @param Request $request The current request
|
||||
* @param integer $id The application id
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function deleteApp(Application $app, Request $request, $id)
|
||||
public function deleteApp(Application $app, Request $request, ApiApplication $application)
|
||||
{
|
||||
if (!$request->isXmlHttpRequest() || !array_key_exists($request->getMimeType('json'), array_flip($request->getAcceptableContentTypes()))) {
|
||||
$app->abort(400, 'Bad request format, only JSON is allowed');
|
||||
}
|
||||
|
||||
$error = false;
|
||||
$app['manipulator.api-application']->delete($application);
|
||||
|
||||
try {
|
||||
$clientApp = new \API_OAuth2_Application($app, $id);
|
||||
$clientApp->delete();
|
||||
} catch (NotFoundHttpException $e) {
|
||||
$error = true;
|
||||
}
|
||||
|
||||
return $app->json(['success' => !$error]);
|
||||
return $app->json(['success' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change application callback
|
||||
* Change application callback.
|
||||
*
|
||||
* @param Application $app
|
||||
* @param Request $request
|
||||
* @param ApiApplication $application
|
||||
*
|
||||
* @param Application $app A Silex application where the controller is mounted on
|
||||
* @param Request $request The current request
|
||||
* @param integer $id The application id
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function renewAppCallback(Application $app, Request $request, $id)
|
||||
public function renewAppCallback(Application $app, Request $request, ApiApplication $application)
|
||||
{
|
||||
if (!$request->isXmlHttpRequest() || !array_key_exists($request->getMimeType('json'), array_flip($request->getAcceptableContentTypes()))) {
|
||||
$app->abort(400, 'Bad request format, only JSON is allowed');
|
||||
}
|
||||
|
||||
$error = false;
|
||||
|
||||
try {
|
||||
$clientApp = new \API_OAuth2_Application($app, $id);
|
||||
|
||||
if (null !== $request->request->get("callback")) {
|
||||
$clientApp->set_redirect_uri($request->request->get("callback"));
|
||||
} else {
|
||||
$error = true;
|
||||
}
|
||||
} catch (NotFoundHttpException $e) {
|
||||
$error = true;
|
||||
$app['manipulator.api-application']->setRedirectUri($application, $request->request->get("callback"));
|
||||
} catch (InvalidArgumentException $e) {
|
||||
return $app->json(['success' => false]);
|
||||
}
|
||||
|
||||
return $app->json(['success' => !$error]);
|
||||
return $app->json(['success' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorize application to use a grant password type
|
||||
* Authorize application to use a grant password type.
|
||||
*
|
||||
* @param Application $app
|
||||
* @param Request $request
|
||||
* @param ApiApplication $application
|
||||
*
|
||||
* @param Application $app A Silex application where the controller is mounted on
|
||||
* @param Request $request The current request
|
||||
* @param integer $id The application id
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function renewAccessToken(Application $app, Request $request, $id)
|
||||
public function renewAccessToken(Application $app, Request $request, ApiApplication $application)
|
||||
{
|
||||
if (!$request->isXmlHttpRequest() || !array_key_exists($request->getMimeType('json'), array_flip($request->getAcceptableContentTypes()))) {
|
||||
$app->abort(400, 'Bad request format, only JSON is allowed');
|
||||
}
|
||||
|
||||
$error = false;
|
||||
$accessToken = null;
|
||||
|
||||
try {
|
||||
$clientApp = new \API_OAuth2_Application($app, $id);
|
||||
$account = $clientApp->get_user_account($app['authentication']->getUser());
|
||||
|
||||
$token = $account->get_token();
|
||||
|
||||
if ($token instanceof \API_OAuth2_Token) {
|
||||
$token->renew();
|
||||
} else {
|
||||
$token = \API_OAuth2_Token::create($app['phraseanet.appbox'], $account, $app['random.medium']);
|
||||
}
|
||||
|
||||
$accessToken = $token->get_value();
|
||||
} catch (\Exception $e) {
|
||||
$error = true;
|
||||
if (null === $account = $app['repo.api-accounts']->findByUserAndApplication($app['authentication']->getUser(), $application)) {
|
||||
$app->abort(404, sprintf('Account not found for application %s', $application->getName()));
|
||||
}
|
||||
|
||||
return $app->json(['success' => !$error, 'token' => $accessToken]);
|
||||
if(null !== $devToken = $app['repo.api-oauth-tokens']->findDeveloperToken($account)) {
|
||||
$app['manipulator.api-oauth-token']->renew($devToken);
|
||||
} else {
|
||||
// dev tokens do not expires
|
||||
$devToken = $app['manipulator.api-oauth-token']->create($account);
|
||||
}
|
||||
|
||||
return $app->json(['success' => true, 'token' => $devToken->getOauthToken()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorize application to use a grant password type
|
||||
* Authorize application to use a grant password type.
|
||||
*
|
||||
* @param Application $app
|
||||
* @param Request $request
|
||||
* @param ApiApplication $application
|
||||
*
|
||||
* @param Application $app A Silex application where the controller is mounted on
|
||||
* @param Request $request The current request
|
||||
* @param integer $id The application id
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function authorizeGrantpassword(Application $app, Request $request, $id)
|
||||
public function authorizeGrantPassword(Application $app, Request $request, ApiApplication $application)
|
||||
{
|
||||
if (!$request->isXmlHttpRequest() || !array_key_exists($request->getMimeType('json'), array_flip($request->getAcceptableContentTypes()))) {
|
||||
$app->abort(400, 'Bad request format, only JSON is allowed');
|
||||
}
|
||||
|
||||
$error = false;
|
||||
$application->setGrantPassword((Boolean) $request->request->get('grant'));
|
||||
$app['manipulator.api-application']->update($application);
|
||||
|
||||
try {
|
||||
$clientApp = new \API_OAuth2_Application($app, $id);
|
||||
$clientApp->set_grant_password((bool) $request->request->get('grant', false));
|
||||
} catch (NotFoundHttpException $e) {
|
||||
$error = true;
|
||||
}
|
||||
|
||||
return $app->json(['success' => !$error]);
|
||||
return $app->json(['success' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,7 +170,7 @@ class Developers implements ControllerProviderInterface
|
||||
*/
|
||||
public function newApp(Application $app, Request $request)
|
||||
{
|
||||
if ($request->request->get('type') === \API_OAuth2_Application::DESKTOP_TYPE) {
|
||||
if ($request->request->get('type') === ApiApplication::DESKTOP_TYPE) {
|
||||
$form = new \API_OAuth2_Form_DevAppDesktop($app['request']);
|
||||
} else {
|
||||
$form = new \API_OAuth2_Form_DevAppInternet($app['request']);
|
||||
@@ -198,22 +179,25 @@ class Developers implements ControllerProviderInterface
|
||||
$violations = $app['validator']->validate($form);
|
||||
|
||||
if ($violations->count() === 0) {
|
||||
$application = \API_OAuth2_Application::create($app, $app['authentication']->getUser(), $form->getName());
|
||||
$application
|
||||
->set_description($form->getDescription())
|
||||
->set_redirect_uri($form->getSchemeCallback() . $form->getCallback())
|
||||
->set_type($form->getType())
|
||||
->set_website($form->getSchemeWebsite() . $form->getWebsite());
|
||||
$application = $app['manipulator.api-application']->create(
|
||||
$form->getName(),
|
||||
$form->getType(),
|
||||
$form->getDescription(),
|
||||
sprintf('%s%s', $form->getSchemeWebsite(), $form->getWebsite()),
|
||||
$app['authentication']->getUser(),
|
||||
sprintf('%s%s', $form->getSchemeCallback(), $form->getCallback())
|
||||
);
|
||||
|
||||
return $app->redirectPath('developers_application', ['id' => $application->get_id()]);
|
||||
// create an account as well
|
||||
$app['manipulator.api-account']->create($application, $app['authentication']->getUser());
|
||||
|
||||
return $app->redirectPath('developers_application', ['application' => $application->getId()]);
|
||||
}
|
||||
|
||||
$var = [
|
||||
return $app['twig']->render('/developers/application_form.html.twig', [
|
||||
"violations" => $violations,
|
||||
"form" => $form
|
||||
];
|
||||
|
||||
return $app['twig']->render('/developers/application_form.html.twig', $var);
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,7 +210,7 @@ class Developers implements ControllerProviderInterface
|
||||
public function listApps(Application $app, Request $request)
|
||||
{
|
||||
return $app['twig']->render('developers/applications.html.twig', [
|
||||
"applications" => \API_OAuth2_Application::load_dev_app_by_user($app, $app['authentication']->getUser())
|
||||
"applications" => $app['repo.api-applications']->findByCreator($app['authentication']->getUser())
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -247,25 +231,24 @@ class Developers implements ControllerProviderInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Get application information
|
||||
* Gets application information.
|
||||
*
|
||||
* @param Application $app A Silex application where the controller is mounted on
|
||||
* @param Request $request The current request
|
||||
* @param integer $id The application id
|
||||
* @return Response
|
||||
* @param Application $app
|
||||
* @param Request $request
|
||||
* @param ApiApplication $application
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getApp(Application $app, Request $request, $id)
|
||||
public function getApp(Application $app, Request $request, ApiApplication $application)
|
||||
{
|
||||
try {
|
||||
$client = new \API_OAuth2_Application($app, $id);
|
||||
} catch (NotFoundHttpException $e) {
|
||||
$app->abort(404);
|
||||
$token = null;
|
||||
|
||||
if (null !== $account = $app['repo.api-accounts']->findByUserAndApplication($app['authentication']->getUser(), $application)) {
|
||||
$token = $app['repo.api-oauth-tokens']->findDeveloperToken($account);
|
||||
}
|
||||
|
||||
$token = $client->get_user_account($app['authentication']->getUser())->get_token()->get_value();
|
||||
|
||||
return $app['twig']->render('developers/application.html.twig', [
|
||||
"application" => $client,
|
||||
"application" => $application,
|
||||
"user" => $app['authentication']->getUser(),
|
||||
"token" => $token
|
||||
]);
|
||||
|
31
lib/Alchemy/Phrasea/Core/Event/InstallFinishEvent.php
Normal file
31
lib/Alchemy/Phrasea/Core/Event/InstallFinishEvent.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Event;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Symfony\Component\EventDispatcher\Event as SfEvent;
|
||||
|
||||
class InstallFinishEvent extends SfEvent
|
||||
{
|
||||
private $user;
|
||||
|
||||
public function __construct(User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
public function getUser()
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
}
|
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Event\Subscriber;
|
||||
|
||||
use Alchemy\Phrasea\Core\Event\InstallFinishEvent;
|
||||
use Alchemy\Phrasea\Core\PhraseaEvents;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
use Silex\Application;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class PhraseaInstallSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
private $app;
|
||||
|
||||
public function __construct(Application $app)
|
||||
{
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
PhraseaEvents::INSTALL_FINISH => 'onInstallFinished'
|
||||
];
|
||||
}
|
||||
|
||||
public function onInstallFinished(InstallFinishEvent $event)
|
||||
{
|
||||
$this->createNavigatorApplication();
|
||||
$this->createOfficePluginApplication();
|
||||
}
|
||||
|
||||
private function createNavigatorApplication()
|
||||
{
|
||||
$application = $this->app['manipulator.api-application']->create(
|
||||
\API_OAuth2_Application_Navigator::CLIENT_NAME,
|
||||
ApiApplication::DESKTOP_TYPE,
|
||||
'',
|
||||
'http://www.phraseanet.com',
|
||||
null,
|
||||
ApiApplication::NATIVE_APP_REDIRECT_URI
|
||||
);
|
||||
|
||||
$application->setGrantPassword(true);
|
||||
$application->setClientId(\API_OAuth2_Application_Navigator::CLIENT_ID);
|
||||
$application->setClientSecret(\API_OAuth2_Application_Navigator::CLIENT_SECRET);
|
||||
|
||||
$this->app['manipulator.api-application']->update($application);
|
||||
}
|
||||
|
||||
private function createOfficePluginApplication()
|
||||
{
|
||||
$application = $this->app['manipulator.api-application']->create(
|
||||
\API_OAuth2_Application_OfficePlugin::CLIENT_NAME,
|
||||
ApiApplication::DESKTOP_TYPE,
|
||||
'',
|
||||
'http://www.phraseanet.com',
|
||||
null,
|
||||
ApiApplication::NATIVE_APP_REDIRECT_URI
|
||||
);
|
||||
|
||||
$application->setGrantPassword(true);
|
||||
$application->setClientId(\API_OAuth2_Application_OfficePlugin::CLIENT_ID);
|
||||
$application->setClientSecret(\API_OAuth2_Application_OfficePlugin::CLIENT_SECRET);
|
||||
|
||||
$this->app['manipulator.api-application']->update($application);
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Middleware;
|
||||
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class ApiApplicationMiddlewareProvider implements ServiceProviderInterface
|
||||
{
|
||||
public function register(Application $app)
|
||||
{
|
||||
$app['middleware.api-application.converter'] = $app->protect(function (Request $request, Application $app) {
|
||||
if ($request->attributes->has('application')) {
|
||||
$request->attributes->set('application', $app['converter.api-application']->convert($request->attributes->get('application')));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
{
|
||||
}
|
||||
}
|
@@ -18,6 +18,8 @@ final class PhraseaEvents
|
||||
const PRE_AUTHENTICATE = 'phrasea.pre-authenticate';
|
||||
const POST_AUTHENTICATE = 'phrasea.post-authenticate';
|
||||
|
||||
const INSTALL_FINISH = "phrasea.install-finish";
|
||||
|
||||
const API_OAUTH2_START = 'api.oauth2.start';
|
||||
const API_OAUTH2_END = 'api.oauth2.end';
|
||||
const API_LOAD_START = 'api.load.start';
|
||||
|
29
lib/Alchemy/Phrasea/Core/Provider/APIServiceProvider.php
Normal file
29
lib/Alchemy/Phrasea/Core/Provider/APIServiceProvider.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Provider;
|
||||
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
|
||||
class APIServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
public function register(Application $app)
|
||||
{
|
||||
$app['oauth2-server'] = $app->share(function ($app) {
|
||||
return new \API_OAuth2_Adapter($app);
|
||||
});
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
{
|
||||
}
|
||||
}
|
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Provider;
|
||||
|
||||
use Alchemy\Phrasea\Model\Converter\ApiApplicationConverter;
|
||||
use Alchemy\Phrasea\Model\Converter\BasketConverter;
|
||||
use Alchemy\Phrasea\Model\Converter\TaskConverter;
|
||||
use Alchemy\Phrasea\Model\Converter\TokenConverter;
|
||||
@@ -32,6 +33,10 @@ class ConvertersServiceProvider implements ServiceProviderInterface
|
||||
$app['converter.token'] = $app->share(function ($app) {
|
||||
return new TokenConverter($app['repo.tokens']);
|
||||
});
|
||||
|
||||
$app['converter.api-application'] = $app->share(function ($app) {
|
||||
return new ApiApplicationConverter($app['repo.api-applications']);
|
||||
});
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
|
@@ -13,6 +13,12 @@ namespace Alchemy\Phrasea\Core\Provider;
|
||||
|
||||
use Alchemy\Phrasea\Model\Manipulator\ACLManipulator;
|
||||
use Alchemy\Phrasea\Model\Manipulator\PresetManipulator;
|
||||
use Alchemy\Phrasea\Model\Manipulator\ApiAccountManipulator;
|
||||
use Alchemy\Phrasea\Model\Manipulator\ApiApplicationManipulator;
|
||||
use Alchemy\Phrasea\Model\Manipulator\ApiLogManipulator;
|
||||
use Alchemy\Phrasea\Model\Manipulator\ApiOauthCodeManipulator;
|
||||
use Alchemy\Phrasea\Model\Manipulator\ApiOauthRefreshTokenManipulator;
|
||||
use Alchemy\Phrasea\Model\Manipulator\ApiOauthTokenManipulator;
|
||||
use Alchemy\Phrasea\Model\Manipulator\RegistrationManipulator;
|
||||
use Alchemy\Phrasea\Model\Manipulator\TaskManipulator;
|
||||
use Alchemy\Phrasea\Model\Manipulator\TokenManipulator;
|
||||
@@ -52,6 +58,30 @@ class ManipulatorServiceProvider implements ServiceProviderInterface
|
||||
$app['manipulator.registration'] = $app->share(function ($app) {
|
||||
return new RegistrationManipulator($app, $app['EM'], $app['acl'], $app['phraseanet.appbox'], $app['repo.registrations']);
|
||||
});
|
||||
|
||||
$app['manipulator.api-application'] = $app->share(function ($app) {
|
||||
return new ApiApplicationManipulator($app['EM'], $app['repo.api-applications'], $app['random.medium']);
|
||||
});
|
||||
|
||||
$app['manipulator.api-account'] = $app->share(function ($app) {
|
||||
return new ApiAccountManipulator($app['EM'], $app['repo.api-accounts']);
|
||||
});
|
||||
|
||||
$app['manipulator.api-oauth-code'] = $app->share(function ($app) {
|
||||
return new ApiOauthCodeManipulator($app['EM'], $app['repo.api-oauth-codes'], $app['random.medium']);
|
||||
});
|
||||
|
||||
$app['manipulator.api-oauth-token'] = $app->share(function ($app) {
|
||||
return new ApiOauthTokenManipulator($app['EM'], $app['repo.api-oauth-tokens'], $app['random.medium']);
|
||||
});
|
||||
|
||||
$app['manipulator.api-oauth-refresh-token'] = $app->share(function ($app) {
|
||||
return new ApiOauthRefreshTokenManipulator($app['EM'], $app['repo.api-oauth-refresh-tokens'], $app['random.medium']);
|
||||
});
|
||||
|
||||
$app['manipulator.api-log'] = $app->share(function ($app) {
|
||||
return new ApiLogManipulator($app['EM'], $app['repo.api-logs']);
|
||||
});
|
||||
}
|
||||
|
||||
public function boot(SilexApplication $app)
|
||||
|
@@ -97,6 +97,24 @@ class RepositoriesServiceProvider implements ServiceProviderInterface
|
||||
$app['repo.presets'] = $app->share(function (PhraseaApplication $app) {
|
||||
return $app['EM']->getRepository('Phraseanet:Preset');
|
||||
});
|
||||
$app['repo.api-accounts'] = $app->share(function (PhraseaApplication $app) {
|
||||
return $app['EM']->getRepository('Phraseanet:ApiAccount');
|
||||
});
|
||||
$app['repo.api-logs'] = $app->share(function (PhraseaApplication $app) {
|
||||
return $app['EM']->getRepository('Phraseanet:ApiLog');
|
||||
});
|
||||
$app['repo.api-applications'] = $app->share(function (PhraseaApplication $app) {
|
||||
return $app['EM']->getRepository('Phraseanet:ApiApplication');
|
||||
});
|
||||
$app['repo.api-oauth-codes'] = $app->share(function (PhraseaApplication $app) {
|
||||
return $app['EM']->getRepository('Phraseanet:ApiOauthCode');
|
||||
});
|
||||
$app['repo.api-oauth-tokens'] = $app->share(function (PhraseaApplication $app) {
|
||||
return $app['EM']->getRepository('Phraseanet:ApiOauthToken');
|
||||
});
|
||||
$app['repo.api-oauth-refresh-tokens'] = $app->share(function (PhraseaApplication $app) {
|
||||
return $app['EM']->getRepository('Phraseanet:ApiOauthRefreshToken');
|
||||
});
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
|
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Converter;
|
||||
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
use Alchemy\Phrasea\Model\Repositories\ApiApplicationRepository;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
class ApiApplicationConverter implements ConverterInterface
|
||||
{
|
||||
private $repository;
|
||||
|
||||
public function __construct(ApiApplicationRepository $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return ApiApplication
|
||||
*/
|
||||
public function convert($id)
|
||||
{
|
||||
if (null === $application = $this->repository->find((int) $id)) {
|
||||
throw new NotFoundHttpException(sprintf('Application %s not found.', $id));
|
||||
}
|
||||
|
||||
return $application;
|
||||
}
|
||||
}
|
192
lib/Alchemy/Phrasea/Model/Entities/ApiAccount.php
Normal file
192
lib/Alchemy/Phrasea/Model/Entities/ApiAccount.php
Normal file
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Entities;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Gedmo\Mapping\Annotation as Gedmo;
|
||||
|
||||
/**
|
||||
* @ORM\Table(name="ApiAccounts", indexes={
|
||||
* @ORM\Index(name="user_id", columns={"user_id"}),
|
||||
* @ORM\Index(name="application_id", columns={"application_id"})
|
||||
* })
|
||||
* @ORM\Entity(repositoryClass="Alchemy\Phrasea\Model\Repositories\ApiAccountRepository")
|
||||
*/
|
||||
class ApiAccount
|
||||
{
|
||||
/**
|
||||
* @ORM\Column(type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="User")
|
||||
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false)
|
||||
*
|
||||
* @return User
|
||||
**/
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(type="boolean")
|
||||
*/
|
||||
private $revoked = false;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="api_version", type="string", length=16, nullable=false)
|
||||
*/
|
||||
private $apiVersion;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="ApiApplication", inversedBy="accounts")
|
||||
* @ORM\JoinColumn(name="application_id", referencedColumnName="id", nullable=false)
|
||||
*
|
||||
* @return ApiApplication
|
||||
**/
|
||||
private $application;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="ApiOauthToken", mappedBy="account", cascade={"remove"})
|
||||
**/
|
||||
private $tokens;
|
||||
|
||||
/**
|
||||
* @Gedmo\Timestampable(on="create")
|
||||
* @ORM\Column(type="datetime")
|
||||
*/
|
||||
private $created;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->tokens = new ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $apiVersion
|
||||
*
|
||||
* @return ApiAccount
|
||||
*/
|
||||
public function setApiVersion($apiVersion)
|
||||
{
|
||||
$this->apiVersion = $apiVersion;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getApiVersion()
|
||||
{
|
||||
return $this->apiVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ApiApplication $application
|
||||
*
|
||||
* @return ApiAccount
|
||||
*/
|
||||
public function setApplication(ApiApplication $application)
|
||||
{
|
||||
$application->addAccount($this);
|
||||
|
||||
$this->application = $application;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ApiApplication
|
||||
*/
|
||||
public function getApplication()
|
||||
{
|
||||
return $this->application;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $created
|
||||
*
|
||||
* @return ApiAccount
|
||||
*/
|
||||
public function setCreated(\DateTime $created)
|
||||
{
|
||||
$this->created = $created;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getCreated()
|
||||
{
|
||||
return $this->created;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $revoked
|
||||
*
|
||||
* @return ApiAccount
|
||||
*/
|
||||
public function setRevoked($revoked)
|
||||
{
|
||||
$this->revoked = (Boolean) $revoked;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function isRevoked()
|
||||
{
|
||||
return $this->revoked;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*
|
||||
* @return ApiAccount
|
||||
*/
|
||||
public function setUser(User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ApiOauthToken $token
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addTokens(ApiOauthToken $token)
|
||||
{
|
||||
$this->tokens->add($token);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
412
lib/Alchemy/Phrasea/Model/Entities/ApiApplication.php
Normal file
412
lib/Alchemy/Phrasea/Model/Entities/ApiApplication.php
Normal file
@@ -0,0 +1,412 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Entities;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Gedmo\Mapping\Annotation as Gedmo;
|
||||
|
||||
/**
|
||||
* @ORM\Table(name="ApiApplications", uniqueConstraints={
|
||||
* @ORM\UniqueConstraint(name="client_id", columns={"client_id"})}, indexes={
|
||||
* @ORM\Index(name="creator_id", columns={"creator_id"})
|
||||
* })
|
||||
* @ORM\Entity(repositoryClass="Alchemy\Phrasea\Model\Repositories\ApiApplicationRepository")
|
||||
*/
|
||||
class ApiApplication
|
||||
{
|
||||
/** desktop application */
|
||||
const DESKTOP_TYPE = 'desktop';
|
||||
/** web application */
|
||||
const WEB_TYPE = 'web';
|
||||
/** Uniform Resource Name */
|
||||
const NATIVE_APP_REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="User")
|
||||
* @ORM\JoinColumn(name="creator_id", referencedColumnName="id", nullable=true)
|
||||
*
|
||||
* @return User|null
|
||||
**/
|
||||
private $creator;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=128, nullable=false)
|
||||
*/
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=128, nullable=false)
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="text", nullable=false)
|
||||
*/
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=128, nullable=false)
|
||||
*/
|
||||
private $website;
|
||||
|
||||
/**
|
||||
* @Gedmo\Timestampable(on="create")
|
||||
* @ORM\Column(type="datetime")
|
||||
*/
|
||||
private $created;
|
||||
|
||||
/**
|
||||
* @Gedmo\Timestampable(on="update")
|
||||
* @ORM\Column(type="datetime")
|
||||
*/
|
||||
private $updated;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="client_id", type="string", length=32, nullable=false)
|
||||
*/
|
||||
private $clientId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="client_secret", type="string", length=32, nullable=false)
|
||||
*/
|
||||
private $clientSecret;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=64, nullable=false)
|
||||
*/
|
||||
private $nonce;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="redirect_uri", type="string", length=128, nullable=false)
|
||||
*/
|
||||
private $redirectUri;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(type="boolean", nullable=false)
|
||||
*/
|
||||
private $activated = true;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="grant_password", type="boolean", nullable=false)
|
||||
*/
|
||||
private $grantPassword = false;
|
||||
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="ApiAccount", mappedBy="application", cascade={"remove"})
|
||||
**/
|
||||
private $accounts;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->accounts = new ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $activated
|
||||
*
|
||||
* @return ApiApplication
|
||||
*/
|
||||
public function setActivated($activated)
|
||||
{
|
||||
$this->activated = (Boolean) $activated;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function isActivated()
|
||||
{
|
||||
return $this->activated;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $clientId
|
||||
*
|
||||
* @return ApiApplication
|
||||
*/
|
||||
public function setClientId($clientId)
|
||||
{
|
||||
$this->clientId = $clientId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getClientId()
|
||||
{
|
||||
return $this->clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $clientSecret
|
||||
*
|
||||
* @return ApiApplication
|
||||
*/
|
||||
public function setClientSecret($clientSecret)
|
||||
{
|
||||
$this->clientSecret = $clientSecret;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getClientSecret()
|
||||
{
|
||||
return $this->clientSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $created
|
||||
*
|
||||
* @return ApiApplication
|
||||
*/
|
||||
public function setCreated(\DateTime $created)
|
||||
{
|
||||
$this->created = $created;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getCreated()
|
||||
{
|
||||
return $this->created;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $creator
|
||||
*
|
||||
* @return ApiApplication
|
||||
*/
|
||||
public function setCreator(User $creator = null)
|
||||
{
|
||||
$this->creator = $creator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User|null
|
||||
*/
|
||||
public function getCreator()
|
||||
{
|
||||
return $this->creator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $description
|
||||
*
|
||||
* @return ApiApplication
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $grantPassword
|
||||
*
|
||||
* @return ApiApplication
|
||||
*/
|
||||
public function setGrantPassword($grantPassword)
|
||||
{
|
||||
$this->grantPassword = (Boolean) $grantPassword;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function isPasswordGranted()
|
||||
{
|
||||
return $this->grantPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return ApiApplication
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $nonce
|
||||
*
|
||||
* @return ApiApplication
|
||||
*/
|
||||
public function setNonce($nonce)
|
||||
{
|
||||
$this->nonce = $nonce;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getNonce()
|
||||
{
|
||||
return $this->nonce;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $redirectUri
|
||||
*
|
||||
* @return ApiApplication
|
||||
*/
|
||||
public function setRedirectUri($redirectUri)
|
||||
{
|
||||
$this->redirectUri = $redirectUri;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRedirectUri()
|
||||
{
|
||||
return $this->redirectUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
*
|
||||
* @return ApiApplication
|
||||
*/
|
||||
public function setType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $updated
|
||||
*
|
||||
* @return ApiApplication
|
||||
*/
|
||||
public function setUpdated(\DateTime $updated)
|
||||
{
|
||||
$this->updated = $updated;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getUpdated()
|
||||
{
|
||||
return $this->updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $website
|
||||
*
|
||||
* @return ApiApplication
|
||||
*/
|
||||
public function setWebsite($website)
|
||||
{
|
||||
$this->website = $website;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getWebsite()
|
||||
{
|
||||
return $this->website;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ApiAccount $account
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addAccount(ApiAccount $account)
|
||||
{
|
||||
$this->accounts->add($account);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
360
lib/Alchemy/Phrasea/Model/Entities/ApiLog.php
Normal file
360
lib/Alchemy/Phrasea/Model/Entities/ApiLog.php
Normal file
@@ -0,0 +1,360 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Entities;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Gedmo\Mapping\Annotation as Gedmo;
|
||||
|
||||
/**
|
||||
* @ORM\Table(name="ApiLogs", indexes={@ORM\Index(name="account_id", columns={"account_id"})})
|
||||
* @ORM\Entity(repositoryClass="Alchemy\Phrasea\Model\Repositories\ApiLogRepository")
|
||||
*/
|
||||
class ApiLog
|
||||
{
|
||||
const DATABOXES_RESOURCE = 'databoxes';
|
||||
const RECORDS_RESOURCE = 'records';
|
||||
const BASKETS_RESOURCE = 'baskets';
|
||||
const FEEDS_RESOURCE = 'feeds';
|
||||
const QUARANTINE_RESOURCE = 'quarantine';
|
||||
const STORIES_RESOURCE = 'stories';
|
||||
const MONITOR_RESOURCE = 'monitor';
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="ApiAccount")
|
||||
* @ORM\JoinColumn(name="account_id", referencedColumnName="id", nullable=false)
|
||||
*
|
||||
* @return ApiAccount
|
||||
**/
|
||||
private $account;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=128, nullable=true)
|
||||
*/
|
||||
private $route;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=16, nullable=true)
|
||||
*/
|
||||
private $method;
|
||||
|
||||
/**
|
||||
* @Gedmo\Timestampable(on="create")
|
||||
* @ORM\Column(type="datetime")
|
||||
*/
|
||||
private $created;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="status_code", type="integer", nullable=true)
|
||||
*/
|
||||
private $statusCode;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=64, nullable=true)
|
||||
*/
|
||||
private $format;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=64, nullable=true)
|
||||
*/
|
||||
private $resource;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=64, nullable=true)
|
||||
*/
|
||||
private $general;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=64, nullable=true)
|
||||
*/
|
||||
private $aspect;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=64, nullable=true)
|
||||
*/
|
||||
private $action;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="error_code", type="integer", nullable=true)
|
||||
*/
|
||||
private $errorCode;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="error_message", type="text", nullable=true)
|
||||
*/
|
||||
private $errorMessage;
|
||||
|
||||
/**
|
||||
* @param ApiAccount $account
|
||||
*
|
||||
* @return ApiLog
|
||||
*/
|
||||
public function setAccount(ApiAccount $account)
|
||||
{
|
||||
$this->account = $account;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ApiAccount
|
||||
*/
|
||||
public function getAccount()
|
||||
{
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $action
|
||||
*
|
||||
* @return ApiLog
|
||||
*/
|
||||
public function setAction($action)
|
||||
{
|
||||
$this->action = $action;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAction()
|
||||
{
|
||||
return $this->action;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $aspect
|
||||
*
|
||||
* @return ApiLog
|
||||
*/
|
||||
public function setAspect($aspect)
|
||||
{
|
||||
$this->aspect = $aspect;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAspect()
|
||||
{
|
||||
return $this->aspect;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $errorCode
|
||||
*
|
||||
* @return ApiLog
|
||||
*/
|
||||
public function setErrorCode($errorCode)
|
||||
{
|
||||
$this->errorCode = $errorCode;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer
|
||||
*/
|
||||
public function getErrorCode()
|
||||
{
|
||||
return $this->errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $errorMessage
|
||||
*
|
||||
* @return ApiLog
|
||||
*/
|
||||
public function setErrorMessage($errorMessage)
|
||||
{
|
||||
$this->errorMessage = $errorMessage;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getErrorMessage()
|
||||
{
|
||||
return $this->errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $format
|
||||
*
|
||||
* @return ApiLog
|
||||
*/
|
||||
public function setFormat($format)
|
||||
{
|
||||
$this->format = $format;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFormat()
|
||||
{
|
||||
return $this->format;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $general
|
||||
*
|
||||
* @return ApiLog
|
||||
*/
|
||||
public function setGeneral($general)
|
||||
{
|
||||
$this->general = $general;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getGeneral()
|
||||
{
|
||||
return $this->general;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $resource
|
||||
*
|
||||
* @return ApiLog
|
||||
*/
|
||||
public function setResource($resource)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $route
|
||||
*
|
||||
* @return ApiLog
|
||||
*/
|
||||
public function setRoute($route)
|
||||
{
|
||||
$this->route = $route;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRoute()
|
||||
{
|
||||
return $this->route;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $statusCode
|
||||
*
|
||||
* @return ApiLog
|
||||
*/
|
||||
public function setStatusCode($statusCode)
|
||||
{
|
||||
$this->statusCode = $statusCode;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer
|
||||
*/
|
||||
public function getStatusCode()
|
||||
{
|
||||
return $this->statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $created
|
||||
*
|
||||
* @return ApiLog
|
||||
*/
|
||||
public function setCreated(\DateTime $created)
|
||||
{
|
||||
$this->created = $created;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getCreated()
|
||||
{
|
||||
return $this->created;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
*
|
||||
* @return ApiLog
|
||||
*/
|
||||
public function setMethod($method)
|
||||
{
|
||||
$this->method = $method;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod()
|
||||
{
|
||||
return $this->method;
|
||||
}
|
||||
}
|
200
lib/Alchemy/Phrasea/Model/Entities/ApiOauthCode.php
Normal file
200
lib/Alchemy/Phrasea/Model/Entities/ApiOauthCode.php
Normal file
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Entities;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Gedmo\Mapping\Annotation as Gedmo;
|
||||
|
||||
/**
|
||||
* @ORM\Table(name="ApiOauthCodes", indexes={@ORM\Index(name="account_id", columns={"account_id"})})
|
||||
* @ORM\Entity(repositoryClass="Alchemy\Phrasea\Model\Repositories\ApiOauthCodeRepository")
|
||||
*/
|
||||
class ApiOauthCode
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="code", type="string", length=128, nullable=false)
|
||||
* @ORM\Id
|
||||
*/
|
||||
private $code;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="ApiAccount")
|
||||
* @ORM\JoinColumn(name="account_id", referencedColumnName="id", nullable=false)
|
||||
*
|
||||
* @return ApiAccount
|
||||
**/
|
||||
private $account;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="redirect_uri", type="string", length=128, nullable=false)
|
||||
*/
|
||||
private $redirectUri;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $expires;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=128, nullable=true)
|
||||
*/
|
||||
private $scope;
|
||||
|
||||
/**
|
||||
* @Gedmo\Timestampable(on="create")
|
||||
* @ORM\Column(type="datetime")
|
||||
*/
|
||||
private $created;
|
||||
|
||||
/**
|
||||
* @Gedmo\Timestampable(on="update")
|
||||
* @ORM\Column(type="datetime")
|
||||
*/
|
||||
private $updated;
|
||||
|
||||
/**
|
||||
* @param ApiAccount $account
|
||||
*
|
||||
* @return ApiOauthCode
|
||||
*/
|
||||
public function setAccount(ApiAccount $account)
|
||||
{
|
||||
$this->account = $account;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ApiAccount
|
||||
*/
|
||||
public function getAccount()
|
||||
{
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $code
|
||||
*
|
||||
* @return ApiOauthCode
|
||||
*/
|
||||
public function setCode($code)
|
||||
{
|
||||
$this->code = $code;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $created
|
||||
*
|
||||
* @return ApiOauthCode
|
||||
*/
|
||||
public function setCreated(\DateTime $created)
|
||||
{
|
||||
$this->created = $created;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getCreated()
|
||||
{
|
||||
return $this->created;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $timestamp
|
||||
*
|
||||
* @return ApiOauthCode
|
||||
*/
|
||||
public function setExpires($timestamp)
|
||||
{
|
||||
$this->expires = $timestamp;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $timestamp
|
||||
*/
|
||||
public function getExpires()
|
||||
{
|
||||
return $this->expires;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $redirectUri
|
||||
*
|
||||
* @return ApiOauthCode
|
||||
*/
|
||||
public function setRedirectUri($redirectUri)
|
||||
{
|
||||
$this->redirectUri = $redirectUri;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRedirectUri()
|
||||
{
|
||||
return $this->redirectUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $scope
|
||||
*
|
||||
* @return ApiOauthCode
|
||||
*/
|
||||
public function setScope($scope)
|
||||
{
|
||||
$this->scope = $scope;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getScope()
|
||||
{
|
||||
return $this->scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $updated
|
||||
*
|
||||
* @return ApiOauthCode
|
||||
*/
|
||||
public function setUpdated(\DateTime $updated)
|
||||
{
|
||||
$this->updated = $updated;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getUpdated()
|
||||
{
|
||||
return $this->updated;
|
||||
}
|
||||
}
|
173
lib/Alchemy/Phrasea/Model/Entities/ApiOauthRefreshToken.php
Normal file
173
lib/Alchemy/Phrasea/Model/Entities/ApiOauthRefreshToken.php
Normal file
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Entities;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Gedmo\Mapping\Annotation as Gedmo;
|
||||
|
||||
/**
|
||||
* @ORM\Table(name="ApiOauthRefreshTokens", indexes={@ORM\Index(name="account_id", columns={"account_id"})})
|
||||
* @ORM\Entity(repositoryClass="Alchemy\Phrasea\Model\Repositories\ApiOauthRefreshTokenRepository")
|
||||
*/
|
||||
class ApiOauthRefreshToken
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="refresh_token", type="string", length=128, nullable=false)
|
||||
* @ORM\Id
|
||||
*/
|
||||
private $refreshToken;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="ApiAccount")
|
||||
* @ORM\JoinColumn(name="account_id", referencedColumnName="id", nullable=false)
|
||||
*
|
||||
* @return ApiAccount
|
||||
**/
|
||||
private $account;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="integer", nullable=false)
|
||||
*/
|
||||
private $expires;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=128, nullable=true)
|
||||
*/
|
||||
private $scope;
|
||||
|
||||
/**
|
||||
* @Gedmo\Timestampable(on="create")
|
||||
* @ORM\Column(type="datetime")
|
||||
*/
|
||||
private $created;
|
||||
|
||||
/**
|
||||
* @Gedmo\Timestampable(on="update")
|
||||
* @ORM\Column(type="datetime")
|
||||
*/
|
||||
private $updated;
|
||||
|
||||
/**
|
||||
* @param ApiAccount $account
|
||||
*
|
||||
* @return ApiOauthRefreshToken
|
||||
*/
|
||||
public function setAccount(ApiAccount $account)
|
||||
{
|
||||
$this->account = $account;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ApiAccount
|
||||
*/
|
||||
public function getAccount()
|
||||
{
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $created
|
||||
*
|
||||
* @return ApiOauthRefreshToken
|
||||
*/
|
||||
public function setCreated(\DateTime $created)
|
||||
{
|
||||
$this->created = $created;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getCreated()
|
||||
{
|
||||
return $this->created;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $expires
|
||||
*
|
||||
* @return ApiOauthRefreshToken
|
||||
*/
|
||||
public function setExpires($expires)
|
||||
{
|
||||
$this->expires = $expires;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer
|
||||
*/
|
||||
public function getExpires()
|
||||
{
|
||||
return $this->expires;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $refreshToken
|
||||
*
|
||||
* @return ApiOauthRefreshToken
|
||||
*/
|
||||
public function setRefreshToken($refreshToken)
|
||||
{
|
||||
$this->refreshToken = $refreshToken;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRefreshToken()
|
||||
{
|
||||
return $this->refreshToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $scope
|
||||
*
|
||||
* @return ApiOauthRefreshToken
|
||||
*/
|
||||
public function setScope($scope)
|
||||
{
|
||||
$this->scope = $scope;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getScope()
|
||||
{
|
||||
return $this->scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $updated
|
||||
*
|
||||
* @return ApiOauthRefreshToken
|
||||
*/
|
||||
public function setUpdated(\DateTime $updated)
|
||||
{
|
||||
$this->updated = $updated;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getUpdated()
|
||||
{
|
||||
return $this->updated;
|
||||
}
|
||||
}
|
229
lib/Alchemy/Phrasea/Model/Entities/ApiOauthToken.php
Normal file
229
lib/Alchemy/Phrasea/Model/Entities/ApiOauthToken.php
Normal file
@@ -0,0 +1,229 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Entities;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Gedmo\Mapping\Annotation as Gedmo;
|
||||
|
||||
/**
|
||||
* @ORM\Table(name="ApiOauthTokens", indexes={
|
||||
* @ORM\Index(name="account_id", columns={"account_id"}),
|
||||
* @ORM\Index(name="session_id", columns={"session_id"})
|
||||
* })
|
||||
* @ORM\Entity(repositoryClass="Alchemy\Phrasea\Model\Repositories\ApiOauthTokenRepository")
|
||||
*/
|
||||
class ApiOauthToken
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="oauth_token", type="string", length=128, nullable=false)
|
||||
* @ORM\Id
|
||||
*/
|
||||
private $oauthToken;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="session_id", type="integer", nullable=true)
|
||||
*/
|
||||
private $sessionId;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="ApiAccount", inversedBy="tokens")
|
||||
* @ORM\JoinColumn(name="account_id", referencedColumnName="id", nullable=false)
|
||||
*
|
||||
* @return ApiAccount
|
||||
**/
|
||||
private $account;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="integer", nullable=true)
|
||||
*/
|
||||
private $expires;
|
||||
|
||||
/**
|
||||
* @Gedmo\Timestampable(on="create")
|
||||
* @ORM\Column(type="datetime", name="last_used")
|
||||
*/
|
||||
private $lastUsed;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=128, nullable=true)
|
||||
*/
|
||||
private $scope;
|
||||
|
||||
/**
|
||||
* @Gedmo\Timestampable(on="create")
|
||||
* @ORM\Column(type="datetime")
|
||||
*/
|
||||
private $created;
|
||||
|
||||
/**
|
||||
* @Gedmo\Timestampable(on="update")
|
||||
* @ORM\Column(type="datetime")
|
||||
*/
|
||||
private $updated;
|
||||
|
||||
/**
|
||||
* @param ApiAccount $account
|
||||
*
|
||||
* @return ApiOauthTokens
|
||||
*/
|
||||
public function setAccount(ApiAccount $account)
|
||||
{
|
||||
$account->addTokens($this);
|
||||
|
||||
$this->account = $account;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ApiAccount
|
||||
*/
|
||||
public function getAccount()
|
||||
{
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $created
|
||||
*
|
||||
* @return ApiOauthTokens
|
||||
*/
|
||||
public function setCreated(\DateTime $created)
|
||||
{
|
||||
$this->created = $created;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getCreated()
|
||||
{
|
||||
return $this->created;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $expires
|
||||
*
|
||||
* @return ApiOauthTokens
|
||||
*/
|
||||
public function setExpires($expires = null)
|
||||
{
|
||||
$this->expires = $expires;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer
|
||||
*/
|
||||
public function getExpires()
|
||||
{
|
||||
return $this->expires;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $oauthToken
|
||||
*
|
||||
* @return ApiOauthTokens
|
||||
*/
|
||||
public function setOauthToken($oauthToken)
|
||||
{
|
||||
$this->oauthToken = $oauthToken;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getOauthToken()
|
||||
{
|
||||
return $this->oauthToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $scope
|
||||
*
|
||||
* @return ApiOauthTokens
|
||||
*/
|
||||
public function setScope($scope)
|
||||
{
|
||||
$this->scope = $scope;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getScope()
|
||||
{
|
||||
return $this->scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $sessionId
|
||||
*
|
||||
* @return ApiOauthTokens
|
||||
*/
|
||||
public function setSessionId($sessionId)
|
||||
{
|
||||
$this->sessionId = $sessionId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Session
|
||||
*/
|
||||
public function getSessionId()
|
||||
{
|
||||
return $this->sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $updated
|
||||
*
|
||||
* @return ApiOauthTokens
|
||||
*/
|
||||
public function setUpdated(\DateTime $updated)
|
||||
{
|
||||
$this->updated = $updated;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getUpdated()
|
||||
{
|
||||
return $this->updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $lastUsed
|
||||
*
|
||||
* @return ApiOauthToken
|
||||
*/
|
||||
public function setLastUsed(\DateTime $lastUsed)
|
||||
{
|
||||
$this->lastUsed = $lastUsed;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getLastUsed()
|
||||
{
|
||||
return $this->lastUsed;
|
||||
}
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Manipulator;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Authentication\ACLProvider;
|
||||
use Alchemy\Phrasea\Controller\Api\V1;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiAccount;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
|
||||
class ApiAccountManipulator implements ManipulatorInterface
|
||||
{
|
||||
private $om;
|
||||
private $repository;
|
||||
|
||||
public function __construct(ObjectManager $om, EntityRepository $repo)
|
||||
{
|
||||
$this->om = $om;
|
||||
$this->repository = $repo;
|
||||
}
|
||||
|
||||
public function create(ApiApplication $application, User $user)
|
||||
{
|
||||
$account = new ApiAccount();
|
||||
$account->setUser($user);
|
||||
$account->setApplication($application);
|
||||
$account->setApiVersion(V1::VERSION);
|
||||
|
||||
$this->update($account);
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
public function delete(ApiAccount $account)
|
||||
{
|
||||
$this->om->remove($account);
|
||||
$this->om->flush();
|
||||
}
|
||||
|
||||
public function update(ApiAccount $account)
|
||||
{
|
||||
$this->om->persist($account);
|
||||
$this->om->flush();
|
||||
}
|
||||
|
||||
public function authorizeAccess(ApiAccount $account)
|
||||
{
|
||||
$account->setRevoked(false);
|
||||
|
||||
$this->update($account);
|
||||
}
|
||||
|
||||
public function revokeAccess(ApiAccount $account)
|
||||
{
|
||||
$account->setRevoked(true);
|
||||
|
||||
$this->update($account);
|
||||
}
|
||||
}
|
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Manipulator;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Authentication\ACLProvider;
|
||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Alchemy\Phrasea\Model\Manipulator\TokenManipulator;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use RandomLib\Generator;
|
||||
|
||||
class ApiApplicationManipulator implements ManipulatorInterface
|
||||
{
|
||||
private $om;
|
||||
private $repository;
|
||||
private $randomGenerator;
|
||||
|
||||
public function __construct(ObjectManager $om, EntityRepository $repo, Generator $random)
|
||||
{
|
||||
$this->om = $om;
|
||||
$this->repository = $repo;
|
||||
$this->randomGenerator = $random;
|
||||
}
|
||||
|
||||
public function create($name, $type, $description, $applicationWebsite, User $creator = null, $redirectUri = null)
|
||||
{
|
||||
$application = new ApiApplication();
|
||||
$application->setCreator($creator);
|
||||
$application->setName($name);
|
||||
$application->setDescription($description);
|
||||
$this->doSetType($application, $type);
|
||||
$this->doSetWebsiteUrl($application, $applicationWebsite);
|
||||
$this->doSetRedirectUri($application, $redirectUri);
|
||||
$application->setNonce($this->randomGenerator->generateString(64));
|
||||
$application->setClientId($this->randomGenerator->generateString(32, TokenManipulator::LETTERS_AND_NUMBERS));
|
||||
$application->setClientSecret($this->randomGenerator->generateString(32, TokenManipulator::LETTERS_AND_NUMBERS));
|
||||
|
||||
$this->om->persist($application);
|
||||
$this->om->flush();
|
||||
|
||||
return $application;
|
||||
}
|
||||
|
||||
public function delete(ApiApplication $application)
|
||||
{
|
||||
$this->om->remove($application);
|
||||
$this->om->flush();
|
||||
}
|
||||
|
||||
public function update(ApiApplication $application)
|
||||
{
|
||||
$this->om->persist($application);
|
||||
$this->om->flush();
|
||||
}
|
||||
|
||||
public function setType(ApiApplication $application, $type)
|
||||
{
|
||||
$this->doSetType($application, $type);
|
||||
$this->update($application);
|
||||
}
|
||||
|
||||
public function setRedirectUri(ApiApplication $application, $uri)
|
||||
{
|
||||
$this->doSetRedirectUri($application, $uri);
|
||||
$this->update($application);
|
||||
}
|
||||
|
||||
public function setWebsiteUrl(ApiApplication $application, $url)
|
||||
{
|
||||
$this->doSetWebsiteUrl($application, $url);
|
||||
$this->update($application);
|
||||
}
|
||||
|
||||
private function doSetType(ApiApplication $application, $type)
|
||||
{
|
||||
if (!in_array($type, [ApiApplication::DESKTOP_TYPE, ApiApplication::WEB_TYPE])) {
|
||||
throw new InvalidArgumentException(sprintf('%s api application type is not supported, it should be one of the following %s', $type, implode(', ', [ApiApplication::DESKTOP_TYPE, ApiApplication::WEB_TYPE])));
|
||||
}
|
||||
$application->setType($type);
|
||||
}
|
||||
|
||||
private function doSetRedirectUri(ApiApplication $application, $uri)
|
||||
{
|
||||
if ($application->getType() === ApiApplication::DESKTOP_TYPE) {
|
||||
$application->setRedirectUri(ApiApplication::NATIVE_APP_REDIRECT_URI);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (false === filter_var($uri, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED)) {
|
||||
throw new InvalidArgumentException(sprintf('Redirect Uri Url %s is not legal.', $uri));
|
||||
}
|
||||
|
||||
$application->setRedirectUri($uri);
|
||||
}
|
||||
|
||||
private function doSetWebsiteUrl(ApiApplication $application, $url)
|
||||
{
|
||||
if (false === filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED)) {
|
||||
throw new InvalidArgumentException(sprintf('Website Url %s is not legal.', $url));
|
||||
}
|
||||
|
||||
$application->setWebsite($url);
|
||||
}
|
||||
}
|
215
lib/Alchemy/Phrasea/Model/Manipulator/ApiLogManipulator.php
Normal file
215
lib/Alchemy/Phrasea/Model/Manipulator/ApiLogManipulator.php
Normal file
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Manipulator;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Authentication\ACLProvider;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiAccount;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiLog;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class ApiLogManipulator implements ManipulatorInterface
|
||||
{
|
||||
private $om;
|
||||
private $repository;
|
||||
|
||||
public function __construct(ObjectManager $om, EntityRepository $repo)
|
||||
{
|
||||
$this->om = $om;
|
||||
$this->repository = $repo;
|
||||
}
|
||||
|
||||
public function create(ApiAccount $account, Request $request, Response $response)
|
||||
{
|
||||
$log = new ApiLog();
|
||||
$log->setAccount($account);
|
||||
$this->doSetFromHttpContext($log, $request, $response);
|
||||
|
||||
$this->update($log);
|
||||
|
||||
return $log;
|
||||
}
|
||||
|
||||
public function delete(ApiLog $log)
|
||||
{
|
||||
$this->om->remove($log);
|
||||
$this->om->flush();
|
||||
}
|
||||
|
||||
public function update(ApiLog $log)
|
||||
{
|
||||
$this->om->persist($log);
|
||||
$this->om->flush();
|
||||
}
|
||||
|
||||
private function doSetFromHttpContext(ApiLog $log, Request $request, Response $response)
|
||||
{
|
||||
$log->setRoute($request->getPathInfo());
|
||||
$log->setMethod($request->getMethod());
|
||||
$log->setStatusCode($response->getStatusCode());
|
||||
$log->setFormat($response->headers->get('content-type'));
|
||||
$this->setDetails($log, $request, $response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the requested route to fetch
|
||||
* - the resource (databox, basket, record etc ..)
|
||||
* - general action (list, add, search)
|
||||
* - the action (setstatus, setname etc..)
|
||||
* - the aspect (collections, related, content etc..)
|
||||
*
|
||||
* @param ApiLog $log
|
||||
* @param Request $request
|
||||
* @param Response $response
|
||||
*/
|
||||
private function setDetails(ApiLog $log, Request $request, Response $response)
|
||||
{
|
||||
$chunks = explode('/', trim($request->getPathInfo(), '/'));
|
||||
|
||||
if (false === $response->isOk() || sizeof($chunks) === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch ($chunks[0]) {
|
||||
case ApiLog::DATABOXES_RESOURCE :
|
||||
$this->hydrateDataboxes($log, $chunks);
|
||||
break;
|
||||
case ApiLog::RECORDS_RESOURCE :
|
||||
$this->hydrateRecords($log, $chunks);
|
||||
break;
|
||||
case ApiLog::BASKETS_RESOURCE :
|
||||
$this->hydrateBaskets($log, $chunks);
|
||||
break;
|
||||
case ApiLog::FEEDS_RESOURCE :
|
||||
$this->hydrateFeeds($log, $chunks);
|
||||
break;
|
||||
case ApiLog::QUARANTINE_RESOURCE :
|
||||
$this->hydrateQuarantine($log, $chunks);
|
||||
break;
|
||||
case ApiLog::STORIES_RESOURCE :
|
||||
$this->hydrateStories($log, $chunks);
|
||||
break;
|
||||
case ApiLog::MONITOR_RESOURCE :
|
||||
$this->hydrateMonitor($log, $chunks);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function hydrateDataboxes(ApiLog $log, $chunks)
|
||||
{
|
||||
$log->setResource($chunks[0]);
|
||||
$log->setGeneral($chunks[0]);
|
||||
if (count($chunks) === 2) {
|
||||
$log->setAction($chunks[1]);
|
||||
}
|
||||
if ((int) $chunks[1] > 0 && count($chunks) === 3) {
|
||||
$log->setAspect($chunks[2]);
|
||||
}
|
||||
}
|
||||
|
||||
private function hydrateRecords(ApiLog $log, $chunks)
|
||||
{
|
||||
$log->setResource($chunks[0]);
|
||||
$log->setGeneral($chunks[0]);
|
||||
if (count($chunks) === 2) {
|
||||
$log->setAction($chunks[1]);
|
||||
}
|
||||
if (count($chunks) === 3 && (int) $chunks[1] > 0 && (int) $chunks[2] > 0) {
|
||||
$log->setAction('get');
|
||||
}
|
||||
if ((int) $chunks[1] > 0 && (int) $chunks[2] > 0 && count($chunks) == 4) {
|
||||
if (preg_match("/^set/", $chunks[3])) {
|
||||
$log->setAction($chunks[3]);
|
||||
} else {
|
||||
$log->setAspect($chunks[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function hydrateBaskets(ApiLog $log, $chunks)
|
||||
{
|
||||
$log->setResource($chunks[0]);
|
||||
$log->setGeneral($chunks[0]);
|
||||
if (count($chunks) === 2) {
|
||||
$log->setAction($chunks[1]);
|
||||
}
|
||||
if ((int) $chunks[1] > 0 && count($chunks) == 3) {
|
||||
if (preg_match("/^set/", $chunks[2]) || preg_match("/^delete/", $chunks[2])) {
|
||||
$log->setAction($chunks[2]);
|
||||
} else {
|
||||
$log->setAspect($chunks[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function hydrateFeeds(ApiLog $log, $chunks)
|
||||
{
|
||||
$log->setResource($chunks[0]);
|
||||
$log->setGeneral($chunks[0]);
|
||||
if (count($chunks) === 2) {
|
||||
if (preg_match("/^content$/", $chunks[1])) {
|
||||
$log->setAspect($chunks[1]);
|
||||
} else {
|
||||
$log->setAction($chunks[1]);
|
||||
}
|
||||
}
|
||||
if (count($chunks) === 3) {
|
||||
if ((int) $chunks[1] > 0) {
|
||||
$log->setAspect($chunks[2]);
|
||||
}
|
||||
if (preg_match("/^entry$/", $chunks[1]) && (int) $chunks[2] > 0) {
|
||||
$log->setAspect($chunks[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function hydrateQuarantine(ApiLog $log, $chunks)
|
||||
{
|
||||
$log->setResource($chunks[0]);
|
||||
$log->setGeneral($chunks[0]);
|
||||
if (count($chunks) === 2) {
|
||||
$log->setAction($chunks[1]);
|
||||
}
|
||||
}
|
||||
|
||||
private function hydrateStories(ApiLog $log, $chunks)
|
||||
{
|
||||
$log->setGeneral($chunks[0]);
|
||||
$log->setResource($chunks[0]);
|
||||
if ((int) $chunks[1] > 0 && (int) $chunks[2] > 0 && count($chunks) == 4) {
|
||||
$log->setAspect($chunks[3]);
|
||||
}
|
||||
if (count($chunks) === 3 && (int) $chunks[1] > 0 && (int) $chunks[2] > 0) {
|
||||
$log->setAction('get');
|
||||
}
|
||||
}
|
||||
|
||||
private function hydrateMonitor(ApiLog $log, $chunks)
|
||||
{
|
||||
$log->setGeneral($chunks[0]);
|
||||
if (count($chunks) === 2) {
|
||||
$log->setAspect($chunks[1]);
|
||||
}
|
||||
if (count($chunks) === 3 && (int) $chunks[2] > 0) {
|
||||
$log->setAspect($chunks[1]);
|
||||
$log->setAction('get');
|
||||
}
|
||||
if (count($chunks) === 4) {
|
||||
$log->setAspect($chunks[1]);
|
||||
$log->setAction($chunks[3]);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Manipulator;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Authentication\ACLProvider;
|
||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiAccount;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiOauthCode;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Alchemy\Phrasea\Model\Manipulator\TokenManipulator;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use RandomLib\Generator;
|
||||
|
||||
class ApiOauthCodeManipulator implements ManipulatorInterface
|
||||
{
|
||||
private $om;
|
||||
private $repository;
|
||||
private $randomGenerator;
|
||||
|
||||
public function __construct(ObjectManager $om, EntityRepository $repo, Generator $random)
|
||||
{
|
||||
$this->om = $om;
|
||||
$this->repository = $repo;
|
||||
$this->randomGenerator = $random;
|
||||
}
|
||||
|
||||
public function create(ApiAccount $account, $redirectUri, $expire, $scope = null)
|
||||
{
|
||||
$code = new ApiOauthCode();
|
||||
|
||||
$code->setCode($this->getNewCode());
|
||||
$this->doSetRedirectUri($code, $redirectUri);
|
||||
$code->setAccount($account);
|
||||
$code->setExpires($expire);
|
||||
$code->setScope($scope);
|
||||
|
||||
$this->update($code);
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
public function delete(ApiOauthCode $code)
|
||||
{
|
||||
$this->om->remove($code);
|
||||
$this->om->flush();
|
||||
}
|
||||
|
||||
public function update(ApiOauthCode $code)
|
||||
{
|
||||
$this->om->persist($code);
|
||||
$this->om->flush();
|
||||
}
|
||||
|
||||
public function setCode(ApiOauthCode $code, $oauthCode)
|
||||
{
|
||||
$code->setCode($oauthCode);
|
||||
$this->update($code);
|
||||
}
|
||||
|
||||
public function setRedirectUri(ApiOauthCode $code, $uri)
|
||||
{
|
||||
$this->doSetRedirectUri($code, $uri);
|
||||
$this->update($code);
|
||||
}
|
||||
|
||||
private function doSetRedirectUri(ApiOauthCode $code, $uri)
|
||||
{
|
||||
if (false === filter_var($uri, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED)
|
||||
&& $uri !== ApiApplication::NATIVE_APP_REDIRECT_URI
|
||||
) {
|
||||
throw new InvalidArgumentException(sprintf('Redirect Uri Url %s is not legal.', $uri));
|
||||
}
|
||||
|
||||
$code->setRedirectUri($uri);
|
||||
}
|
||||
|
||||
private function getNewCode()
|
||||
{
|
||||
do {
|
||||
$code = $this->randomGenerator->generateString(16, TokenManipulator::LETTERS_AND_NUMBERS);
|
||||
} while (null !== $this->repository->find($code));
|
||||
|
||||
return $code;
|
||||
}
|
||||
}
|
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Manipulator;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Authentication\ACLProvider;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiAccount;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiOauthRefreshtoken;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Alchemy\Phrasea\Model\Manipulator\TokenManipulator;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use RandomLib\Generator;
|
||||
|
||||
class ApiOauthRefreshTokenManipulator implements ManipulatorInterface
|
||||
{
|
||||
private $om;
|
||||
private $repository;
|
||||
private $randomGenerator;
|
||||
|
||||
public function __construct(ObjectManager $om, EntityRepository $repo, Generator $random)
|
||||
{
|
||||
$this->om = $om;
|
||||
$this->repository = $repo;
|
||||
$this->randomGenerator = $random;
|
||||
}
|
||||
|
||||
public function create(ApiAccount $account, $expire, $scope = null)
|
||||
{
|
||||
$refreshToken = new ApiOauthRefreshtoken();
|
||||
|
||||
$refreshToken->setCode($this->getNewToken());
|
||||
$refreshToken->setAccount($account);
|
||||
$refreshToken->setExpires($expire);
|
||||
$refreshToken->setScope($scope);
|
||||
|
||||
$this->update($refreshToken);
|
||||
|
||||
return $refreshToken;
|
||||
}
|
||||
|
||||
public function delete(ApiOauthRefreshtoken $refreshToken)
|
||||
{
|
||||
$this->om->remove($refreshToken);
|
||||
$this->om->flush();
|
||||
}
|
||||
|
||||
public function update(ApiOauthRefreshtoken $refreshToken)
|
||||
{
|
||||
$this->om->persist($refreshToken);
|
||||
$this->om->flush();
|
||||
}
|
||||
|
||||
public function setRefreshToken(ApiOauthRefreshtoken $refreshToken, $token)
|
||||
{
|
||||
$refreshToken->setRefreshToken($token);
|
||||
$this->update($refreshToken);
|
||||
}
|
||||
|
||||
private function getNewToken()
|
||||
{
|
||||
do {
|
||||
$refreshToken = $this->randomGenerator->generateString(32, TokenManipulator::LETTERS_AND_NUMBERS);
|
||||
} while (null !== $this->repository->find($refreshToken));
|
||||
|
||||
return $refreshToken;
|
||||
}
|
||||
}
|
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Manipulator;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Authentication\ACLProvider;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiAccount;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiOauthToken;
|
||||
use Alchemy\Phrasea\Model\Entities\Session;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Alchemy\Phrasea\Model\Manipulator\TokenManipulator;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use RandomLib\Generator;
|
||||
|
||||
class ApiOauthTokenManipulator implements ManipulatorInterface
|
||||
{
|
||||
private $om;
|
||||
private $repository;
|
||||
private $randomGenerator;
|
||||
|
||||
public function __construct(ObjectManager $om, EntityRepository $repo, Generator $random)
|
||||
{
|
||||
$this->om = $om;
|
||||
$this->repository = $repo;
|
||||
$this->randomGenerator = $random;
|
||||
}
|
||||
|
||||
public function create(ApiAccount $account, $expire = null, $scope = null)
|
||||
{
|
||||
$token = new ApiOauthToken();
|
||||
$token->setOauthToken($this->getNewToken());
|
||||
$token->setExpires($expire);
|
||||
$token->setScope($scope);
|
||||
$token->setAccount($account);
|
||||
|
||||
$this->om->persist($account);
|
||||
$this->update($token);
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
public function delete(ApiOauthToken $token)
|
||||
{
|
||||
$this->om->remove($token);
|
||||
$this->om->flush();
|
||||
}
|
||||
|
||||
public function update(ApiOauthToken $token)
|
||||
{
|
||||
$this->om->persist($token);
|
||||
$this->om->flush();
|
||||
}
|
||||
|
||||
public function setLastUsed(ApiOauthToken $token, \DateTime $date)
|
||||
{
|
||||
$token->setLastUsed($date);
|
||||
$this->update($token);
|
||||
}
|
||||
|
||||
public function rememberSessionId(ApiOauthToken $token, $sessionId)
|
||||
{
|
||||
$token->setSessionId($sessionId);
|
||||
$this->update($token);
|
||||
}
|
||||
|
||||
public function renew(ApiOauthToken $token, $expire = null)
|
||||
{
|
||||
$token->setOauthToken($this->getNewToken());
|
||||
$token->setExpires($expire);
|
||||
|
||||
$this->update($token);
|
||||
}
|
||||
|
||||
public function setOauthToken(ApiOauthToken $token, $oauthToken)
|
||||
{
|
||||
$token->setOauthToken($oauthToken);
|
||||
$this->update($token);
|
||||
}
|
||||
|
||||
private function getNewToken()
|
||||
{
|
||||
do {
|
||||
$token = $this->randomGenerator->generateString(32, TokenManipulator::LETTERS_AND_NUMBERS);
|
||||
} while (null !== $this->repository->find($token));
|
||||
|
||||
return $token;
|
||||
}
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Repositories;
|
||||
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
|
||||
/**
|
||||
* ApiAccountRepository
|
||||
*
|
||||
* This class was generated by the Doctrine ORM. Add your own custom
|
||||
* repository methods below.
|
||||
*/
|
||||
class ApiAccountRepository extends EntityRepository
|
||||
{
|
||||
public function findByUserAndApplication(User $user, ApiApplication $application)
|
||||
{
|
||||
$qb = $this->createQueryBuilder('acc');
|
||||
$qb->where($qb->expr()->eq('acc.user', ':user'));
|
||||
$qb->andWhere($qb->expr()->eq('acc.application', ':app'));
|
||||
$qb->setParameter(':user', $user);
|
||||
$qb->setParameter(':app', $application);
|
||||
|
||||
return $qb->getQuery()->getOneOrNullResult();
|
||||
}
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Repositories;
|
||||
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\Query\Expr;
|
||||
|
||||
/**
|
||||
* ApiApplicationRepository
|
||||
*
|
||||
* This class was generated by the Doctrine ORM. Add your own custom
|
||||
* repository methods below.
|
||||
*/
|
||||
class ApiApplicationRepository extends EntityRepository
|
||||
{
|
||||
public function findByClientId($clientId)
|
||||
{
|
||||
$qb = $this->createQueryBuilder('app');
|
||||
$qb->where($qb->expr()->eq('app.clientId', ':clientId'));
|
||||
$qb->setParameter(':clientId', $clientId);
|
||||
|
||||
return $qb->getQuery()->getOneOrNullResult();
|
||||
}
|
||||
|
||||
public function findByCreator(User $user)
|
||||
{
|
||||
$qb = $this->createQueryBuilder('app');
|
||||
$qb->where($qb->expr()->eq('app.creator', ':creator'));
|
||||
$qb->setParameter(':creator', $user);
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
|
||||
public function findByUser(User $user)
|
||||
{
|
||||
$qb = $this->createQueryBuilder('app');
|
||||
$qb->innerJoin('app.accounts', 'acc', Expr\Join::WITH, $qb->expr()->eq('acc.user', ':user'));
|
||||
$qb->setParameter(':user', $user);
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
|
||||
public function findAuthorizedAppsByUser(User $user)
|
||||
{
|
||||
$qb = $this->createQueryBuilder('app');
|
||||
$qb->innerJoin('app.accounts', 'acc', Expr\Join::WITH, $qb->expr()->eq('acc.user', ':user'));
|
||||
$qb->where($qb->expr()->eq('acc.revoked', $qb->expr()->literal(false)));
|
||||
$qb->setParameter(':user', $user);
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
}
|
15
lib/Alchemy/Phrasea/Model/Repositories/ApiLogRepository.php
Normal file
15
lib/Alchemy/Phrasea/Model/Repositories/ApiLogRepository.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Repositories;
|
||||
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
|
||||
/**
|
||||
* ApiLogRepository
|
||||
*
|
||||
* This class was generated by the Doctrine ORM. Add your own custom
|
||||
* repository methods below.
|
||||
*/
|
||||
class ApiLogRepository extends EntityRepository
|
||||
{
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Repositories;
|
||||
|
||||
use Alchemy\Phrasea\Model\Entities\ApiAccount;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
|
||||
/**
|
||||
* ApiOauthCodeRepository
|
||||
*
|
||||
* This class was generated by the Doctrine ORM. Add your own custom
|
||||
* repository methods below.
|
||||
*/
|
||||
class ApiOauthCodeRepository extends EntityRepository
|
||||
{
|
||||
public function findByAccount(ApiAccount $account)
|
||||
{
|
||||
$qb = $this->createQueryBuilder('c');
|
||||
$qb->where($qb->expr()->eq('c.account', ':account'));
|
||||
$qb->setParameter(':account', $account);
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Repositories;
|
||||
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
|
||||
/**
|
||||
* ApiOauthRefreshTokenRepository
|
||||
*
|
||||
* This class was generated by the Doctrine ORM. Add your own custom
|
||||
* repository methods below.
|
||||
*/
|
||||
class ApiOauthRefreshTokenRepository extends EntityRepository
|
||||
{
|
||||
public function findByAccount(ApiAccount $account)
|
||||
{
|
||||
$qb = $this->createQueryBuilder('rt');
|
||||
$qb->where($qb->expr()->eq('rt.account', ':account'));
|
||||
$qb->setParameter(':account', $account);
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Model\Repositories;
|
||||
|
||||
use Alchemy\Phrasea\Model\Entities\ApiAccount;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\Query\Expr;
|
||||
|
||||
/**
|
||||
* ApiOauthTokenRepository
|
||||
*
|
||||
* This class was generated by the Doctrine ORM. Add your own custom
|
||||
* repository methods below.
|
||||
*/
|
||||
class ApiOauthTokenRepository extends EntityRepository
|
||||
{
|
||||
public function findDeveloperToken(ApiAccount $account)
|
||||
{
|
||||
$qb = $this->createQueryBuilder('tok');
|
||||
$qb->innerJoin('tok.account', 'acc', Expr\Join::WITH, $qb->expr()->eq('acc.id', ':acc_id'));
|
||||
$qb->innerJoin('acc.application', 'app', Expr\Join::WITH, $qb->expr()->orx(
|
||||
$qb->expr()->eq('app.creator', 'acc.user'),
|
||||
$qb->expr()->isNull('app.creator')
|
||||
));
|
||||
$qb->where($qb->expr()->isNull('tok.expires'));
|
||||
$qb->orderBy('tok.created', 'DESC');
|
||||
$qb->setParameter(':acc_id', $account->getId());
|
||||
|
||||
/*
|
||||
* @note until we add expiration token, there is no way to distinguish a developer issued token from
|
||||
* a connection process issued token.
|
||||
*/
|
||||
$tokens = $qb->getQuery()->getResult();
|
||||
|
||||
if (0 === count($tokens)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return current($tokens);
|
||||
}
|
||||
|
||||
public function findOauthTokens(ApiAccount $account)
|
||||
{
|
||||
$qb = $this->createQueryBuilder('tok');
|
||||
$qb->where($qb->expr()->eq('tok.account', ':acc'));
|
||||
$qb->setParameter(':acc', $account);
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
}
|
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Setup\DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
class ApiMigration extends AbstractMigration
|
||||
{
|
||||
public function isAlreadyApplied()
|
||||
{
|
||||
return $this->tableExists('ApiApplication');
|
||||
}
|
||||
|
||||
public function doUpSql(Schema $schema)
|
||||
{
|
||||
$this->addSql("CREATE TABLE ApiLogs (id INT AUTO_INCREMENT NOT NULL, account_id INT NOT NULL, route VARCHAR(128) DEFAULT NULL, method VARCHAR(16) DEFAULT NULL, created DATETIME NOT NULL, status_code INT DEFAULT NULL, format VARCHAR(64) DEFAULT NULL, resource VARCHAR(64) DEFAULT NULL, general VARCHAR(64) DEFAULT NULL, aspect VARCHAR(64) DEFAULT NULL, action VARCHAR(64) DEFAULT NULL, error_code INT DEFAULT NULL, error_message LONGTEXT DEFAULT NULL, INDEX IDX_91E90F309B6B5FBA (account_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB");
|
||||
$this->addSql("CREATE TABLE ApiApplications (id INT AUTO_INCREMENT NOT NULL, creator_id INT DEFAULT NULL, type VARCHAR(128) NOT NULL, name VARCHAR(128) NOT NULL, description LONGTEXT NOT NULL, website VARCHAR(128) NOT NULL, created DATETIME NOT NULL, updated DATETIME NOT NULL, client_id VARCHAR(32) NOT NULL, client_secret VARCHAR(32) NOT NULL, nonce VARCHAR(64) NOT NULL, redirect_uri VARCHAR(128) NOT NULL, activated TINYINT(1) NOT NULL, grant_password TINYINT(1) NOT NULL, INDEX IDX_53F7BBE661220EA6 (creator_id), UNIQUE INDEX client_id (client_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB");
|
||||
$this->addSql("CREATE TABLE ApiOauthCodes (code VARCHAR(128) NOT NULL, account_id INT NOT NULL, redirect_uri VARCHAR(128) NOT NULL, expires DATETIME DEFAULT NULL, scope VARCHAR(128) DEFAULT NULL, created DATETIME NOT NULL, updated DATETIME NOT NULL, INDEX IDX_BE6B11809B6B5FBA (account_id), PRIMARY KEY(code)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB");
|
||||
$this->addSql("CREATE TABLE ApiOauthRefreshTokens (refresh_token VARCHAR(128) NOT NULL, account_id INT NOT NULL, expires DATETIME NOT NULL, scope VARCHAR(128) DEFAULT NULL, created DATETIME NOT NULL, updated DATETIME NOT NULL, INDEX IDX_7DA42A5A9B6B5FBA (account_id), PRIMARY KEY(refresh_token)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB");
|
||||
$this->addSql("CREATE TABLE ApiOauthTokens (oauth_token VARCHAR(128) NOT NULL, account_id INT NOT NULL, session_id INT DEFAULT NULL, expires DATETIME DEFAULT NULL, last_used DATETIME NOT NULL, scope VARCHAR(128) DEFAULT NULL, created DATETIME NOT NULL, updated DATETIME NOT NULL, INDEX IDX_4FD469539B6B5FBA (account_id), INDEX session_id (session_id), PRIMARY KEY(oauth_token)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB");
|
||||
$this->addSql("CREATE TABLE ApiAccounts (id INT AUTO_INCREMENT NOT NULL, user_id INT NOT NULL, application_id INT NOT NULL, revoked TINYINT(1) NOT NULL, api_version VARCHAR(16) NOT NULL, created DATETIME NOT NULL, INDEX IDX_2C54E637A76ED395 (user_id), INDEX IDX_2C54E6373E030ACD (application_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB");
|
||||
$this->addSql("ALTER TABLE ApiLogs ADD CONSTRAINT FK_91E90F309B6B5FBA FOREIGN KEY (account_id) REFERENCES ApiAccounts (id)");
|
||||
$this->addSql("ALTER TABLE ApiApplications ADD CONSTRAINT FK_53F7BBE661220EA6 FOREIGN KEY (creator_id) REFERENCES Users (id)");
|
||||
$this->addSql("ALTER TABLE ApiOauthCodes ADD CONSTRAINT FK_BE6B11809B6B5FBA FOREIGN KEY (account_id) REFERENCES ApiAccounts (id)");
|
||||
$this->addSql("ALTER TABLE ApiOauthRefreshTokens ADD CONSTRAINT FK_7DA42A5A9B6B5FBA FOREIGN KEY (account_id) REFERENCES ApiAccounts (id)");
|
||||
$this->addSql("ALTER TABLE ApiOauthTokens ADD CONSTRAINT FK_4FD469539B6B5FBA FOREIGN KEY (account_id) REFERENCES ApiAccounts (id)");
|
||||
$this->addSql("ALTER TABLE ApiAccounts ADD CONSTRAINT FK_2C54E637A76ED395 FOREIGN KEY (user_id) REFERENCES Users (id)");
|
||||
$this->addSql("ALTER TABLE ApiAccounts ADD CONSTRAINT FK_2C54E6373E030ACD FOREIGN KEY (application_id) REFERENCES ApiApplications (id)");
|
||||
}
|
||||
|
||||
public function doDownSql(Schema $schema)
|
||||
{
|
||||
$this->addSql("ALTER TABLE ApiAccounts DROP FOREIGN KEY FK_2C54E6373E030ACD");
|
||||
$this->addSql("ALTER TABLE ApiLogs DROP FOREIGN KEY FK_91E90F309B6B5FBA");
|
||||
$this->addSql("ALTER TABLE ApiOauthCodes DROP FOREIGN KEY FK_BE6B11809B6B5FBA");
|
||||
$this->addSql("ALTER TABLE ApiOauthRefreshTokens DROP FOREIGN KEY FK_7DA42A5A9B6B5FBA");
|
||||
$this->addSql("ALTER TABLE ApiOauthTokens DROP FOREIGN KEY FK_4FD469539B6B5FBA");
|
||||
$this->addSql("DROP TABLE ApiLogs");
|
||||
$this->addSql("DROP TABLE ApiApplications");
|
||||
$this->addSql("DROP TABLE ApiOauthCodes");
|
||||
$this->addSql("DROP TABLE ApiOauthRefreshTokens");
|
||||
$this->addSql("DROP TABLE ApiOauthTokens");
|
||||
$this->addSql("DROP TABLE ApiAccounts");
|
||||
}
|
||||
}
|
@@ -12,10 +12,12 @@
|
||||
namespace Alchemy\Phrasea\Setup;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Core\PhraseaEvents;
|
||||
use Alchemy\Phrasea\Core\Event\InstallFinishEvent;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\ORM\Tools\SchemaTool;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
|
||||
class Installer
|
||||
{
|
||||
@@ -46,6 +48,8 @@ class Installer
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->app['dispatcher']->dispatch(PhraseaEvents::INSTALL_FINISH, new InstallFinishEvent($user));
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
|
@@ -1,263 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
|
||||
class API_OAuth2_Account
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var Application
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var User
|
||||
*/
|
||||
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;
|
||||
|
||||
public function __construct(Application $app, $account_id)
|
||||
{
|
||||
$this->app = $app;
|
||||
$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->app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute([':api_account_id' => $this->id]);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
$this->application_id = (int) $row['application_id'];
|
||||
$this->user = $app['repo.users']->find($row['usr_id']);
|
||||
|
||||
$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
|
||||
*/
|
||||
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 = [
|
||||
':revoked' => ($boolean ? '1' : '0')
|
||||
, 'account_id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.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->app['phraseanet.appbox'], $this, $this->app['random.medium']);
|
||||
} catch (NotFoundHttpException $e) {
|
||||
$this->token = API_OAuth2_Token::create($this->app['phraseanet.appbox'], $this, $this->app['random.medium']);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return API_OAuth2_Application
|
||||
*/
|
||||
public function get_application()
|
||||
{
|
||||
if ( ! $this->application)
|
||||
$this->application = new API_OAuth2_Application($this->app, $this->application_id);
|
||||
|
||||
return $this->application;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$this->get_token()->delete();
|
||||
|
||||
foreach (API_OAuth2_AuthCode::load_codes_by_account($this->app, $this) as $code) {
|
||||
$code->delete();
|
||||
}
|
||||
foreach (API_OAuth2_RefreshToken::load_by_account($this->app, $this) as $token) {
|
||||
$token->delete();
|
||||
}
|
||||
|
||||
$sql = 'DELETE FROM api_accounts WHERE api_account_id = :account_id';
|
||||
|
||||
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute(['account_id' => $this->id]);
|
||||
$stmt->closeCursor();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public static function create(Application $app, User $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 = [
|
||||
':usr_id' => $user->getId()
|
||||
, ':application_id' => $application->get_id()
|
||||
, ':api_version' => API_OAuth2_Adapter::API_VERSION
|
||||
, ':revoked' => 0
|
||||
, ':created' => $datetime->format("Y-m-d H:i:s")
|
||||
];
|
||||
|
||||
$stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$stmt->closeCursor();
|
||||
|
||||
$account_id = $app['phraseanet.appbox']->get_connection()->lastInsertId();
|
||||
|
||||
return new self($app, $account_id);
|
||||
}
|
||||
|
||||
public static function load_with_user(Application $app, API_OAuth2_Application $application, User $user)
|
||||
{
|
||||
$sql = 'SELECT api_account_id FROM api_accounts
|
||||
WHERE usr_id = :usr_id AND application_id = :application_id';
|
||||
|
||||
$params = [
|
||||
":usr_id" => $user->getId(),
|
||||
":application_id" => $application->get_id()
|
||||
];
|
||||
|
||||
$stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
if (! $row) {
|
||||
throw new NotFoundHttpException('Account nof found.');
|
||||
}
|
||||
|
||||
return new self($app, $row['api_account_id']);
|
||||
}
|
||||
}
|
@@ -13,7 +13,12 @@ use Alchemy\Phrasea\Application;
|
||||
|
||||
use Alchemy\Phrasea\Authentication\Exception\AccountLockedException;
|
||||
use Alchemy\Phrasea\Authentication\Exception\RequireCaptchaException;
|
||||
use Alchemy\Phrasea\Exception\RuntimeException;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
|
||||
class API_OAuth2_Adapter extends OAuth2
|
||||
{
|
||||
@@ -24,7 +29,7 @@ class API_OAuth2_Adapter extends OAuth2
|
||||
|
||||
/**
|
||||
*
|
||||
* @var API_OAuth2_Application
|
||||
* @var ApiApplication
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
@@ -64,12 +69,6 @@ class API_OAuth2_Adapter extends OAuth2
|
||||
*/
|
||||
protected $session_id;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $usr_id_requested;
|
||||
|
||||
/**
|
||||
* access token of current request
|
||||
* @var string
|
||||
@@ -81,13 +80,11 @@ class API_OAuth2_Adapter extends OAuth2
|
||||
* @param Application $app
|
||||
* @return API_OAuth2_Adapter
|
||||
*/
|
||||
public function __construct(Application $app)
|
||||
public function __construct(Application $app, array $conf = [])
|
||||
{
|
||||
parent::__construct();
|
||||
$this->params = [];
|
||||
parent::__construct($conf);
|
||||
$this->app = $app;
|
||||
|
||||
return $this;
|
||||
$this->params = [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,7 +98,7 @@ class API_OAuth2_Adapter extends OAuth2
|
||||
|
||||
/**
|
||||
*
|
||||
* @return API_OAuth2_Application
|
||||
* @return ApiApplication
|
||||
*/
|
||||
public function getClient()
|
||||
{
|
||||
@@ -125,11 +122,7 @@ class API_OAuth2_Adapter extends OAuth2
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param API_OAuth2_Application $client
|
||||
*/
|
||||
public function setClient(API_OAuth2_Application $client)
|
||||
public function setClient(ApiApplication $client)
|
||||
{
|
||||
$this->client = $client;
|
||||
|
||||
@@ -155,100 +148,84 @@ class API_OAuth2_Adapter extends OAuth2
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_usr_id()
|
||||
{
|
||||
return $this->usr_id;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Implements OAuth2::checkClientCredentials().
|
||||
*
|
||||
* @param string $client_id
|
||||
* @param string $client_secret
|
||||
* @param string $clientId
|
||||
* @param string $clientSecret
|
||||
* @return boolean
|
||||
*/
|
||||
protected function checkClientCredentials($client_id, $client_secret = NULL)
|
||||
protected function checkClientCredentials($clientId, $clientSecret = null)
|
||||
{
|
||||
try {
|
||||
$application = API_OAuth2_Application::load_from_client_id($this->app, $client_id);
|
||||
|
||||
if ($client_secret === NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ($application->get_client_secret() === $client_secret);
|
||||
} catch (\Exception $e) {
|
||||
|
||||
if (null === $application = $this->app['repo.api-applications']->findByClientId($clientId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (null === $clientSecret) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $application->getClientSecret() === $clientSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Implements OAuth2::getRedirectUri().
|
||||
*
|
||||
* @param string $client_id
|
||||
* @return string
|
||||
* @param $clientId
|
||||
*
|
||||
* @return mixed
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function getRedirectUri($client_id)
|
||||
protected function getRedirectUri($clientId)
|
||||
{
|
||||
$application = API_OAuth2_Application::load_from_client_id($this->app, $client_id);
|
||||
if (null === $application = $this->app['repo.api-applications']->findByClientId($clientId)) {
|
||||
throw new BadRequestHttpException(sprintf('Application with client id %s could not be found', $clientId));
|
||||
}
|
||||
|
||||
return $application->get_redirect_uri();
|
||||
return $application->getRedirectUri();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Implements OAuth2::getAccessToken().
|
||||
*
|
||||
* @param string $oauth_token
|
||||
* @param string $oauthToken
|
||||
* @return array
|
||||
*/
|
||||
protected function getAccessToken($oauth_token)
|
||||
protected function getAccessToken($oauthToken)
|
||||
{
|
||||
$result = null;
|
||||
|
||||
try {
|
||||
$token = API_OAuth2_Token::load_by_oauth_token($this->app, $oauth_token);
|
||||
|
||||
$result = [
|
||||
'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()->getId()
|
||||
, 'oauth_token' => $token->get_value()
|
||||
];
|
||||
|
||||
} catch (\Exception $e) {
|
||||
|
||||
if (null === $token = $this->app['repo.api-oauth-tokens']->find($oauthToken)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $result;
|
||||
return [
|
||||
'scope' => $token->getScope(),
|
||||
'expires' => $token->getExpires(),
|
||||
'client_id' => $token->getAccount()->getApplication()->getClientId(),
|
||||
'session_id' => $token->getSessionId(),
|
||||
'revoked' => (int) $token->getAccount()->isRevoked(),
|
||||
'usr_id' => $token->getAccount()->getUser()->getId(),
|
||||
'oauth_token' => $token->getOauthToken(),
|
||||
];
|
||||
}
|
||||
/**
|
||||
* Implements OAuth2::setAccessToken().
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type $oauth_token
|
||||
* @param type $account_id
|
||||
* @param type $expires
|
||||
* @param string $scope
|
||||
* @return API_OAuth2_Adapter
|
||||
* @param $oauthToken
|
||||
* @param $accountId
|
||||
* @param $expires
|
||||
* @param null $scope
|
||||
*
|
||||
* @return $this
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function setAccessToken($oauth_token, $account_id, $expires, $scope = NULL)
|
||||
protected function setAccessToken($oauthToken, $accountId, $expires = null, $scope = null)
|
||||
{
|
||||
$account = new API_OAuth2_Account($this->app, $account_id);
|
||||
$token = API_OAuth2_Token::create($this->app['phraseanet.appbox'], $account, $this->app['random.medium'], $scope);
|
||||
$token->set_value($oauth_token)->set_expires($expires);
|
||||
if (null === $account = $this->app['repo.api-accounts']->find($accountId)) {
|
||||
throw new RuntimeException(sprintf('Account with id %s is not valid', $accountId));
|
||||
}
|
||||
$token = $this->app['manipulator.api-oauth-token']->create($account, $expires, $scope);
|
||||
$this->app['manipulator.api-oauth-token']->setOauthToken($token, $oauthToken);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -279,87 +256,104 @@ class API_OAuth2_Adapter extends OAuth2
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Overrides OAuth2::getAuthCode().
|
||||
*
|
||||
* @return array
|
||||
* @param $code
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
protected function getAuthCode($code)
|
||||
{
|
||||
try {
|
||||
$code = new API_OAuth2_AuthCode($this->app, $code);
|
||||
|
||||
return [
|
||||
'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) {
|
||||
|
||||
if (null === $code = $this->app['repo.api-oauth-codes']->find($code)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
return [
|
||||
'redirect_uri' => $code->getRedirectUri(),
|
||||
'client_id' => $code->getAccount()->getApplication()->getClientId(),
|
||||
'expires' => $code->getExpires(),
|
||||
'account_id' => $code->getAccount()->getId(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Overrides OAuth2::setAuthCode().
|
||||
*
|
||||
* @param string $code
|
||||
* @param int $account_id
|
||||
* @param string $redirect_uri
|
||||
* @param string $expires
|
||||
* @param string $scope
|
||||
* @return API_OAuth2_Adapter
|
||||
* @param $oauthCode
|
||||
* @param $accountId
|
||||
* @param $redirectUri
|
||||
* @param $expires
|
||||
* @param null $scope
|
||||
*
|
||||
* @return $this|void
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function setAuthCode($code, $account_id, $redirect_uri, $expires, $scope = NULL)
|
||||
protected function setAuthCode($oauthCode, $accountId, $redirectUri, $expires = null, $scope = null)
|
||||
{
|
||||
$account = new API_OAuth2_Account($this->app, $account_id);
|
||||
$code = API_OAuth2_AuthCode::create($this->app, $account, $code, $expires);
|
||||
$code->set_redirect_uri($redirect_uri)->set_scope($scope);
|
||||
if (null === $account = $this->app['repo.api-accounts']->find($accountId)) {
|
||||
throw new RuntimeException(sprintf('Account with id %s is not valid', $accountId));
|
||||
}
|
||||
$code = $this->app['manipulator.api-oauth-code']->create($account, $redirectUri, $expires, $scope);
|
||||
$this->app['manipulator.api-oauth-code']->setCode($code, $oauthCode);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides OAuth2::setRefreshToken().
|
||||
*
|
||||
* @param $refreshToken
|
||||
* @param $accountId
|
||||
* @param $expires
|
||||
* @param null $scope
|
||||
*
|
||||
* @return $this|void
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function setRefreshToken($refresh_token, $account_id, $expires, $scope = NULL)
|
||||
protected function setRefreshToken($refreshToken, $accountId, $expires, $scope = null)
|
||||
{
|
||||
$account = new API_OAuth2_Account($this->app, $account_id);
|
||||
API_OAuth2_RefreshToken::create($this->app, $account, $expires, $refresh_token, $scope);
|
||||
if (null === $account = $this->app['repo.api-accounts']->find($accountId)) {
|
||||
throw new RuntimeException(sprintf('Account with id %s is not valid', $accountId));
|
||||
}
|
||||
$token = $this->app['manipulator.api-oauth-refresh-token']->create($account, $expires, $scope);
|
||||
$this->app['manipulator.api-oauth-refresh-token']->setRefreshToken($token, $refreshToken);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides OAuth2::getRefreshToken().
|
||||
*
|
||||
* @param $refreshToken
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
protected function getRefreshToken($refresh_token)
|
||||
protected function getRefreshToken($refreshToken)
|
||||
{
|
||||
try {
|
||||
$token = new API_OAuth2_RefreshToken($this->app, $refresh_token);
|
||||
|
||||
return [
|
||||
'token' => $token->get_value()
|
||||
, 'expires' => $token->get_expires()->format('U')
|
||||
, 'client_id' => $token->get_account()->get_application()->get_client_id()
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
|
||||
if (null === $token = $this->app['repo.api-oauth-refresh-token']->find($refreshToken)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
return [
|
||||
'token' => $token->getRefreshToken(),
|
||||
'expires' => $token->getExpires(),
|
||||
'client_id' => $token->getAccount()->getApplication()->getClientId()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides OAuth2::unsetRefreshToken().
|
||||
*
|
||||
* @param $refreshToken
|
||||
*
|
||||
* @return $this|void
|
||||
*/
|
||||
protected function unsetRefreshToken($refresh_token)
|
||||
protected function unsetRefreshToken($refreshToken)
|
||||
{
|
||||
$token = new API_OAuth2_RefreshToken($this->app, $refresh_token);
|
||||
$token->delete();
|
||||
if (null !== $token = $this->app['repo.api-oauth-refresh-token']->find($refreshToken)) {
|
||||
$this->app['manipulator.api-oauth-refresh-token']->delete($token);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -371,22 +365,21 @@ class API_OAuth2_Adapter extends OAuth2
|
||||
*/
|
||||
public function getAuthorizationRequestParameters(Request $request)
|
||||
{
|
||||
|
||||
$datas = [
|
||||
'response_type' => $request->get('response_type', false)
|
||||
, 'client_id' => $request->get('client_id', false)
|
||||
, 'redirect_uri' => $request->get('redirect_uri', false)
|
||||
$data = [
|
||||
'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);
|
||||
|
||||
if ($state) {
|
||||
$datas["state"] = $state;
|
||||
$data["state"] = $state;
|
||||
}
|
||||
|
||||
if ($scope) {
|
||||
$datas["scope"] = $scope;
|
||||
$data["scope"] = $scope;
|
||||
}
|
||||
|
||||
$filters = [
|
||||
@@ -405,17 +398,16 @@ class API_OAuth2_Adapter extends OAuth2
|
||||
, "scope" => ["flags" => FILTER_REQUIRE_SCALAR]
|
||||
];
|
||||
|
||||
$input = filter_var_array($datas, $filters);
|
||||
$input = filter_var_array($data, $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"]
|
||||
);
|
||||
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);
|
||||
}
|
||||
@@ -424,68 +416,71 @@ class API_OAuth2_Adapter extends OAuth2
|
||||
* 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"]);
|
||||
$redirectUri = $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);
|
||||
|
||||
if ( ! $redirectUri && ! $input["redirect_uri"]) {
|
||||
$this->errorJsonResponse(OAUTH2_HTTP_FOUND, OAUTH2_ERROR_INVALID_REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* getRedirectUri() should return FALSE if the given client ID is invalid
|
||||
* 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 ($redirectUri === 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"]) {
|
||||
if ($redirectUri && $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) {
|
||||
$input["redirect_uri"], 0, strlen($redirectUri)
|
||||
), $redirectUri);
|
||||
if ($compare !== 0) {
|
||||
$this->errorDoRedirectUriCallback($input["redirect_uri"], OAUTH2_ERROR_REDIRECT_URI_MISMATCH, null, null, $input["state"]);
|
||||
}
|
||||
} elseif ($redirectUri) {
|
||||
/**
|
||||
* They did not provide a uri from input, so use the stored one
|
||||
*/
|
||||
$input["redirect_uri"] = $redirect_uri;
|
||||
$input["redirect_uri"] = $redirectUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check response_type
|
||||
*/
|
||||
if (! $input["response_type"]) {
|
||||
$this->errorDoRedirectUriCallback($input["redirect_uri"], OAUTH2_ERROR_INVALID_REQUEST, 'Invalid response type.', NULL, $input["state"]);
|
||||
$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"]);
|
||||
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"]);
|
||||
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"]);
|
||||
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
|
||||
@@ -496,150 +491,131 @@ class API_OAuth2_Adapter extends OAuth2
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*
|
||||
* @param User $user
|
||||
* @return API_OAuth2_Account
|
||||
* @return mixed
|
||||
* @throws logicalException
|
||||
*/
|
||||
public function updateAccount(User $user)
|
||||
{
|
||||
if ($this->client === null)
|
||||
if ($this->client === null) {
|
||||
throw new logicalException("Client property must be set before update an account");
|
||||
}
|
||||
|
||||
try {
|
||||
$account = API_OAuth2_Account::load_with_user($this->app, $this->client, $user);
|
||||
} catch (\Exception $e) {
|
||||
$account = $this->createAccount($user->getId());
|
||||
if (null === $account = $this->app['repo.api-accounts']->findByUserAndApplication($user, $this->client)) {
|
||||
$account = $this->app['manipulator.api-account']->create($this->client, $user);
|
||||
}
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $is_authorized
|
||||
* @param array $params
|
||||
*
|
||||
* @param int $usr_id
|
||||
* @return API_OAuth2_Account
|
||||
*/
|
||||
private function createAccount($usr_id)
|
||||
{
|
||||
$user = $this->app['repo.users']->find($usr_id);
|
||||
|
||||
return API_OAuth2_Account::create($this->app, $user, $this->client);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param <type> $is_authorized
|
||||
* @param array $params
|
||||
* @return string
|
||||
* @return array
|
||||
*/
|
||||
public function finishNativeClientAuthorization($is_authorized, $params = [])
|
||||
{
|
||||
$result = [];
|
||||
$params += [
|
||||
'scope' => NULL,
|
||||
'state' => NULL,
|
||||
];
|
||||
extract($params);
|
||||
$params += ['scope' => null, 'state' => null,];
|
||||
|
||||
if ($state !== NULL)
|
||||
$result["query"]["state"] = $state;
|
||||
if ($params['state'] !== null) {
|
||||
$result["query"]["state"] = $params['state'] ;
|
||||
}
|
||||
|
||||
if ($is_authorized === FALSE) {
|
||||
if ($is_authorized === false) {
|
||||
$result["error"] = OAUTH2_ERROR_USER_DENIED;
|
||||
} else {
|
||||
if ($response_type == OAUTH2_AUTH_RESPONSE_TYPE_AUTH_CODE)
|
||||
$result["code"] = $this->createAuthCode($account_id, $redirect_uri, $scope);
|
||||
if ($params['response_type'] === OAUTH2_AUTH_RESPONSE_TYPE_AUTH_CODE) {
|
||||
$result["code"] = $this->createAuthCode($params['account_id'], $params['redirect_uri'], $params['scope']);
|
||||
}
|
||||
|
||||
if ($response_type == OAUTH2_AUTH_RESPONSE_TYPE_ACCESS_TOKEN)
|
||||
if ($params['response_type'] === OAUTH2_AUTH_RESPONSE_TYPE_ACCESS_TOKEN) {
|
||||
$result["error"] = OAUTH2_ERROR_UNSUPPORTED_RESPONSE_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $redirectUri
|
||||
*
|
||||
* @param <type> $redirect_uri
|
||||
* @return <type>
|
||||
* @return bool
|
||||
*/
|
||||
public function isNativeApp($redirect_uri)
|
||||
public function isNativeApp($redirectUri)
|
||||
{
|
||||
return $redirect_uri === API_OAuth2_Application::NATIVE_APP_REDIRECT_URI;
|
||||
return $redirectUri === ApiApplication::NATIVE_APP_REDIRECT_URI;
|
||||
}
|
||||
|
||||
public function remember_this_ses_id($ses_id)
|
||||
public function rememberSession(Session $session)
|
||||
{
|
||||
try {
|
||||
$token = API_OAuth2_Token::load_by_oauth_token($this->app, $this->token);
|
||||
$token->set_session_id($ses_id);
|
||||
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
|
||||
if (null !== $token = $this->app['repo.api-oauth-tokens']->find($this->token)) {
|
||||
$this->app['manipulator.api-oauth-token']->rememberSessionId($token, $session->getId());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function verifyAccessToken($scope = NULL, $exit_not_present = TRUE, $exit_invalid = TRUE, $exit_expired = TRUE, $exit_scope = TRUE, $realm = NULL)
|
||||
public function verifyAccessToken($scope = null, $exit_not_present = true, $exit_invalid = true, $exit_expired = true, $exit_scope = true, $realm = null)
|
||||
{
|
||||
$token_param = $this->getAccessTokenParams();
|
||||
|
||||
// Access token was not provided
|
||||
if ($token_param === false) {
|
||||
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;
|
||||
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 ($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;
|
||||
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;
|
||||
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 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;
|
||||
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;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function finishClientAuthorization($is_authorized, $params = [])
|
||||
{
|
||||
$params += [
|
||||
'scope' => NULL,
|
||||
'state' => NULL,
|
||||
'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);
|
||||
if ($params['state'] !== null) {
|
||||
$result["query"]["state"] = $params['state'];
|
||||
}
|
||||
$this->doRedirectUriCallback($redirect_uri, $result);
|
||||
if ($is_authorized === false) {
|
||||
$result["query"]["error"] = OAUTH2_ERROR_USER_DENIED;
|
||||
} else {
|
||||
if ($params['response_type'] == OAUTH2_AUTH_RESPONSE_TYPE_AUTH_CODE || $params['response_type'] == OAUTH2_AUTH_RESPONSE_TYPE_CODE_AND_TOKEN) {
|
||||
$result["query"]["code"] = $this->createAuthCode($params['account_id'], $params['redirect_uri'], $params['scope']);
|
||||
}
|
||||
|
||||
if ($params['response_type'] == OAUTH2_AUTH_RESPONSE_TYPE_ACCESS_TOKEN || $params['response_type'] == OAUTH2_AUTH_RESPONSE_TYPE_CODE_AND_TOKEN) {
|
||||
$result["fragment"] = $this->createAccessToken($params['account_id'], $params['scope']);
|
||||
}
|
||||
}
|
||||
$this->doRedirectUriCallback($params['redirect_uri'], $result);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -648,62 +624,75 @@ class API_OAuth2_Adapter extends OAuth2
|
||||
public function grantAccessToken()
|
||||
{
|
||||
$filters = [
|
||||
"grant_type" => ["filter" => FILTER_VALIDATE_REGEXP, "options" => ["regexp" => OAUTH2_GRANT_TYPE_REGEXP], "flags" => FILTER_REQUIRE_SCALAR],
|
||||
"scope" => ["flags" => FILTER_REQUIRE_SCALAR],
|
||||
"code" => ["flags" => FILTER_REQUIRE_SCALAR],
|
||||
"redirect_uri" => ["filter" => FILTER_SANITIZE_URL],
|
||||
"username" => ["flags" => FILTER_REQUIRE_SCALAR],
|
||||
"password" => ["flags" => FILTER_REQUIRE_SCALAR],
|
||||
"assertion_type" => ["flags" => FILTER_REQUIRE_SCALAR],
|
||||
"assertion" => ["flags" => FILTER_REQUIRE_SCALAR],
|
||||
"grant_type" => [
|
||||
"filter" => FILTER_VALIDATE_REGEXP,
|
||||
"options" => ["regexp" => OAUTH2_GRANT_TYPE_REGEXP],
|
||||
"flags" => FILTER_REQUIRE_SCALAR
|
||||
],
|
||||
"scope" => ["flags" => FILTER_REQUIRE_SCALAR],
|
||||
"code" => ["flags" => FILTER_REQUIRE_SCALAR],
|
||||
"redirect_uri" => ["filter" => FILTER_SANITIZE_URL],
|
||||
"username" => ["flags" => FILTER_REQUIRE_SCALAR],
|
||||
"password" => ["flags" => FILTER_REQUIRE_SCALAR],
|
||||
"assertion_type" => ["flags" => FILTER_REQUIRE_SCALAR],
|
||||
"assertion" => ["flags" => FILTER_REQUIRE_SCALAR],
|
||||
"refresh_token" => ["flags" => FILTER_REQUIRE_SCALAR],
|
||||
];
|
||||
|
||||
$input = filter_input_array(INPUT_POST, $filters);
|
||||
|
||||
// Grant Type must be specified.
|
||||
if ( ! $input["grant_type"])
|
||||
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()))
|
||||
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)
|
||||
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"]))
|
||||
if ( ! $this->checkRestrictedGrantType($client[0], $input["grant_type"])) {
|
||||
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_UNAUTHORIZED_CLIENT);
|
||||
}
|
||||
|
||||
if ( ! $this->checkRestrictedGrantType($client[0], $input["grant_type"]))
|
||||
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"])
|
||||
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"])
|
||||
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())
|
||||
if ($stored["expires"] < time()) {
|
||||
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_EXPIRED_TOKEN);
|
||||
}
|
||||
break;
|
||||
case OAUTH2_GRANT_TYPE_USER_CREDENTIALS:
|
||||
$application = API_OAuth2_Application::load_from_client_id($this->app, $client[0]);
|
||||
$application = ApiApplication::load_from_client_id($this->app, $client[0]);
|
||||
|
||||
if ( ! $application->is_password_granted()) {
|
||||
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_UNSUPPORTED_GRANT_TYPE, 'Password grant type is not enable for your client');
|
||||
}
|
||||
|
||||
if ( ! $input["username"] || ! $input["password"])
|
||||
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"]);
|
||||
|
||||
@@ -712,26 +701,31 @@ class API_OAuth2_Adapter extends OAuth2
|
||||
}
|
||||
break;
|
||||
case OAUTH2_GRANT_TYPE_ASSERTION:
|
||||
if ( ! $input["assertion_type"] || ! $input["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)
|
||||
if ($stored === false) {
|
||||
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_INVALID_GRANT);
|
||||
}
|
||||
|
||||
break;
|
||||
case OAUTH2_GRANT_TYPE_REFRESH_TOKEN:
|
||||
if ( ! $input["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"])
|
||||
if ($stored === null || $client[0] != $stored["client_id"]) {
|
||||
$this->errorJsonResponse(OAUTH2_HTTP_BAD_REQUEST, OAUTH2_ERROR_INVALID_GRANT);
|
||||
}
|
||||
|
||||
if ($stored["expires"] < time())
|
||||
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"]);
|
||||
@@ -740,16 +734,19 @@ class API_OAuth2_Adapter extends OAuth2
|
||||
case OAUTH2_GRANT_TYPE_NONE:
|
||||
$stored = $this->checkNoneAccess($client[0]);
|
||||
|
||||
if ($stored === FALSE)
|
||||
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"])))
|
||||
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;
|
||||
if ( ! $input["scope"]) {
|
||||
$input["scope"] = null;
|
||||
}
|
||||
|
||||
$token = $this->createAccessToken($stored['account_id'], $input["scope"]);
|
||||
$this->sendJsonHeaders();
|
||||
@@ -759,51 +756,64 @@ class API_OAuth2_Adapter extends OAuth2
|
||||
return;
|
||||
}
|
||||
|
||||
protected function createAccessToken($account_id, $scope = NULL)
|
||||
protected function createAccessToken($accountId, $scope = null)
|
||||
{
|
||||
$token = [
|
||||
"access_token" => $this->genAccessToken(),
|
||||
"scope" => $scope
|
||||
];
|
||||
|
||||
if ($this->enable_expire)
|
||||
$expires = null;
|
||||
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);
|
||||
$this->setAccessToken($token["access_token"], $accountId, 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);
|
||||
$this->setRefreshToken($token["refresh_token"], $accountId, 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'))
|
||||
if ($this->getVariable('_old_refresh_token')) {
|
||||
$this->unsetRefreshToken($this->getVariable('_old_refresh_token'));
|
||||
}
|
||||
}
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
protected function checkUserCredentials($client_id, $username, $password)
|
||||
/**
|
||||
* @param $clientId
|
||||
* @param $username
|
||||
* @param $password
|
||||
*
|
||||
* @return array|boolean
|
||||
*/
|
||||
protected function checkUserCredentials($clientId, $username, $password)
|
||||
{
|
||||
try {
|
||||
$this->setClient(API_OAuth2_Application::load_from_client_id($this->app, $client_id));
|
||||
if (null === $client = $this->app['repo.api-applications']->findByClientId($clientId)) {
|
||||
return false;
|
||||
}
|
||||
$this->setClient($client);
|
||||
|
||||
$usr_id = $this->app['auth.native']->getUsrId($username, $password, Request::createFromGlobals());
|
||||
$usrId = $this->app['auth.native']->getUsrId($username, $password, Request::createFromGlobals());
|
||||
|
||||
if (!$usr_id) {
|
||||
if (!$usrId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null === $user = $this->app['repo.users']->find($usr_id)) {
|
||||
if (null === $user = $this->app['repo.users']->find($usrId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$account = $this->updateAccount($user);
|
||||
|
||||
return [
|
||||
'redirect_uri' => $this->client->get_redirect_uri()
|
||||
, 'client_id' => $this->client->get_client_id()
|
||||
, 'account_id' => $account->get_id()
|
||||
'redirect_uri' => $this->client->getRedirectUri(),
|
||||
'client_id' => $this->client->getClient(),
|
||||
'account_id' => $account->getId(),
|
||||
];
|
||||
} catch (AccountLockedException $e) {
|
||||
return false;
|
||||
|
@@ -1,718 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Alchemy\Phrasea\Model\Manipulator\TokenManipulator;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
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 Application
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var User
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $activated;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $grant_password;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Application $app
|
||||
* @param int $application_id
|
||||
* @return API_OAuth2_Application
|
||||
*/
|
||||
public function __construct(Application $app, $application_id)
|
||||
{
|
||||
$this->app = $app;
|
||||
$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, activated, grant_password
|
||||
FROM api_applications
|
||||
WHERE application_id = :application_id';
|
||||
|
||||
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute([':application_id' => $this->id]);
|
||||
|
||||
if (0 === $stmt->rowCount()) {
|
||||
throw new NotFoundHttpException(sprintf('Application with id %d not found', $this->id));
|
||||
}
|
||||
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
$this->creator = ! $row['creator'] ? null : $this->app['repo.users']->find($row['creator']);
|
||||
$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'];
|
||||
$this->activated = ! ! $row['activated'];
|
||||
$this->grant_password = ! ! $row['grant_password'];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_id()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
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, [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 = [
|
||||
':type' => $this->type
|
||||
, ':application_id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.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 = [
|
||||
':name' => $this->name
|
||||
, ':application_id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.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 = [
|
||||
':description' => $this->description
|
||||
, ':application_id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.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 = [
|
||||
':website' => $this->website
|
||||
, ':application_id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$stmt->closeCursor();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell wether application is activated
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_activated()
|
||||
{
|
||||
return $this->activated;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param boolean $activated
|
||||
* @return API_OAuth2_Application
|
||||
*/
|
||||
public function set_activated($activated)
|
||||
{
|
||||
$this->activated = $activated;
|
||||
|
||||
$sql = 'UPDATE api_applications
|
||||
SET activated = :activated, last_modified = NOW()
|
||||
WHERE application_id = :application_id';
|
||||
|
||||
$params = [
|
||||
':activated' => $this->activated
|
||||
, ':application_id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$stmt->closeCursor();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell wether application authorize password grant type
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_password_granted()
|
||||
{
|
||||
return $this->grant_password;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param boolean $grant
|
||||
* @return API_OAuth2_Application
|
||||
*/
|
||||
public function set_grant_password($grant)
|
||||
{
|
||||
$this->grant_password = ! ! $grant;
|
||||
|
||||
$sql = 'UPDATE api_applications
|
||||
SET grant_password = :grant_password, last_modified = NOW()
|
||||
WHERE application_id = :application_id';
|
||||
|
||||
$params = [
|
||||
':grant_password' => $this->grant_password
|
||||
, ':application_id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.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 = [
|
||||
':client_id' => $this->client_id
|
||||
, ':application_id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.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 = [
|
||||
':client_secret' => $this->client_secret
|
||||
, ':application_id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.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 = [
|
||||
':redirect_uri' => $this->redirect_uri
|
||||
, ':application_id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$stmt->closeCursor();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param User $user
|
||||
* @return API_OAuth2_Account
|
||||
*/
|
||||
public function get_user_account(User $user)
|
||||
{
|
||||
$sql = 'SELECT api_account_id FROM api_accounts
|
||||
WHERE usr_id = :usr_id AND application_id = :id';
|
||||
|
||||
$params = [
|
||||
':usr_id' => $user->getId()
|
||||
, ':id' => $this->id
|
||||
];
|
||||
|
||||
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
if ( ! $row)
|
||||
throw new NotFoundHttpException('Application not found.');
|
||||
|
||||
return new API_OAuth2_Account($this->app, $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->app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute([':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->app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute([':application_id' => $this->get_id()]);
|
||||
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
$accounts = [];
|
||||
|
||||
foreach ($rs as $row) {
|
||||
$accounts[] = new API_OAuth2_Account($this->app, $row['api_account_id']);
|
||||
}
|
||||
|
||||
return $accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Application $app
|
||||
* @param User $user
|
||||
* @param type $name
|
||||
* @return API_OAuth2_Application
|
||||
*/
|
||||
public static function create(Application $app, User $user = null, $name)
|
||||
{
|
||||
$sql = '
|
||||
INSERT INTO api_applications (
|
||||
application_id, creator, created_on, name, last_modified,
|
||||
nonce, client_id, client_secret, activated, grant_password
|
||||
)
|
||||
VALUES (
|
||||
null, :usr_id, NOW(), :name, NOW(), :nonce, :client_id,
|
||||
:client_secret, :activated, :grant_password
|
||||
)';
|
||||
|
||||
$nonce = $app['random.medium']->generateString(64);
|
||||
$client_secret = $app['random.medium']->generateString(32, TokenManipulator::LETTERS_AND_NUMBERS);
|
||||
$client_token = $app['random.medium']->generateString(32, TokenManipulator::LETTERS_AND_NUMBERS);
|
||||
|
||||
$params = [
|
||||
':usr_id' => $user ? $user->getId() : null,
|
||||
':name' => $name,
|
||||
':client_id' => $client_token,
|
||||
':client_secret' => $client_secret,
|
||||
':nonce' => $nonce,
|
||||
':activated' => 1,
|
||||
':grant_password' => 0
|
||||
];
|
||||
|
||||
$stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$stmt->closeCursor();
|
||||
|
||||
$application_id = $app['phraseanet.appbox']->get_connection()->lastInsertId();
|
||||
|
||||
$application = new self($app, $application_id);
|
||||
|
||||
if ($user) {
|
||||
API_OAuth2_Account::create($app, $user, $application);
|
||||
}
|
||||
|
||||
return $application;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Application $app
|
||||
* @param type $client_id
|
||||
* @return API_OAuth2_Application
|
||||
*/
|
||||
public static function load_from_client_id(Application $app, $client_id)
|
||||
{
|
||||
$sql = 'SELECT application_id FROM api_applications
|
||||
WHERE client_id = :client_id';
|
||||
|
||||
$stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute([':client_id' => $client_id]);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
if ( ! $row)
|
||||
throw new NotFoundHttpException('Client not found.');
|
||||
|
||||
return new self($app, $row['application_id']);
|
||||
}
|
||||
|
||||
public static function load_dev_app_by_user(Application $app, User $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 = $app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute([':usr_id' => $user->getId()]);
|
||||
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
$apps = [];
|
||||
foreach ($rs as $row) {
|
||||
$apps[] = new API_OAuth2_Application($app, $row['application_id']);
|
||||
}
|
||||
|
||||
return $apps;
|
||||
}
|
||||
|
||||
public static function load_app_by_user(Application $app, User $user)
|
||||
{
|
||||
$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 = $app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute([':usr_id' => $user->getId()]);
|
||||
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
$apps = [];
|
||||
foreach ($rs as $row) {
|
||||
$apps[] = new API_OAuth2_Application($app, $row['application_id']);
|
||||
}
|
||||
|
||||
return $apps;
|
||||
}
|
||||
|
||||
public static function load_authorized_app_by_user(Application $app, User $user)
|
||||
{
|
||||
$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 = $app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute([':usr_id' => $user->getId()]);
|
||||
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
$apps = [];
|
||||
foreach ($rs as $row) {
|
||||
$apps[] = new API_OAuth2_Application($app, $row['application_id']);
|
||||
}
|
||||
|
||||
return $apps;
|
||||
}
|
||||
}
|
@@ -1,180 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
class API_OAuth2_AuthCode
|
||||
{
|
||||
protected $app;
|
||||
protected $code;
|
||||
protected $account;
|
||||
protected $account_id;
|
||||
protected $redirect_uri;
|
||||
protected $expires;
|
||||
protected $scope;
|
||||
|
||||
public function __construct(Application $app, $code)
|
||||
{
|
||||
$this->app = $app;
|
||||
$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->app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute([':code' => $this->code]);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
if ( ! $row)
|
||||
throw new NotFoundHttpException('Code not found');
|
||||
|
||||
$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->app, $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 = [':redirect_uri' => $redirect_uri, ':code' => $this->code];
|
||||
|
||||
$stmt = $this->app['phraseanet.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 = [':scope' => $scope, ':code' => $this->code];
|
||||
|
||||
$stmt = $this->app['phraseanet.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->app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute([':code' => $this->code]);
|
||||
$stmt->closeCursor();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Application $app
|
||||
* @param API_OAuth2_Account $account
|
||||
* @return array
|
||||
*/
|
||||
public static function load_codes_by_account(Application $app, API_OAuth2_Account $account)
|
||||
{
|
||||
$sql = 'SELECT code FROM api_oauth_codes
|
||||
WHERE api_account_id = :account_id';
|
||||
|
||||
$stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
|
||||
$params = [":account_id" => $account->get_id()];
|
||||
$stmt->execute($params);
|
||||
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
$codes = [];
|
||||
|
||||
foreach ($rs as $row) {
|
||||
$codes[] = new API_OAuth2_AuthCode($app, $row['code']);
|
||||
}
|
||||
|
||||
return $codes;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Application $app
|
||||
* @param API_OAuth2_Account $account
|
||||
* @param type $code
|
||||
* @param int $expires
|
||||
* @return API_OAuth2_AuthCode
|
||||
*/
|
||||
public static function create(Application $app, 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 = $app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
|
||||
$params = [
|
||||
":code" => $code,
|
||||
":account_id" => $account->get_id(),
|
||||
":expires" => $expires
|
||||
];
|
||||
$stmt->execute($params);
|
||||
$stmt->closeCursor();
|
||||
|
||||
return new self($app, $code);
|
||||
}
|
||||
}
|
@@ -9,6 +9,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Validator\Constraints;
|
||||
@@ -48,9 +49,7 @@ class API_OAuth2_Form_DevAppDesktop
|
||||
public $urlwebsite;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Request $request
|
||||
* @return API_OAuth2_Form_DevApp
|
||||
* @param Request $request
|
||||
*/
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
@@ -58,8 +57,8 @@ class API_OAuth2_Form_DevAppDesktop
|
||||
$this->description = $request->get('description', '');
|
||||
$this->scheme_website = $request->get('scheme-website', 'http://');
|
||||
$this->website = $request->get('website', '');
|
||||
$this->callback = API_OAuth2_Application::NATIVE_APP_REDIRECT_URI;
|
||||
$this->type = API_OAuth2_Application::DESKTOP_TYPE;
|
||||
$this->callback = ApiApplication::NATIVE_APP_REDIRECT_URI;
|
||||
$this->type = ApiApplication::DESKTOP_TYPE;
|
||||
|
||||
$this->urlwebsite = $this->scheme_website . $this->website;
|
||||
|
||||
|
@@ -9,6 +9,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Validator\Constraints;
|
||||
@@ -44,9 +45,7 @@ class API_OAuth2_Form_DevAppInternet
|
||||
public $urlcallback;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Request $request
|
||||
* @return API_OAuth2_Form_DevApp
|
||||
* @param Request $request
|
||||
*/
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
@@ -56,10 +55,10 @@ class API_OAuth2_Form_DevAppInternet
|
||||
$this->callback = $request->get('callback', '');
|
||||
$this->scheme_website = $request->get('scheme-website', 'http://');
|
||||
$this->scheme_callback = $request->get('scheme-callback', 'http://');
|
||||
$this->type = API_OAuth2_Application::WEB_TYPE;
|
||||
$this->type = ApiApplication::WEB_TYPE;
|
||||
|
||||
$this->urlwebsite = $this->scheme_website . $this->website;
|
||||
$this->urlcallback = $this->scheme_callback . $this->callback;
|
||||
$this->urlwebsite = sprintf('%s%s', $this->scheme_website, $this->website);
|
||||
$this->urlcallback = sprintf('%s%s', $this->scheme_callback, $this->callback);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@@ -1,139 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
|
||||
class API_OAuth2_RefreshToken
|
||||
{
|
||||
protected $app;
|
||||
protected $token;
|
||||
protected $account_id;
|
||||
protected $account;
|
||||
protected $expires;
|
||||
protected $scope;
|
||||
|
||||
public function __construct(Application $app, $token)
|
||||
{
|
||||
$this->app = $app;
|
||||
$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->app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute([':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->app, $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->app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute([":refresh_token" => $this->token]);
|
||||
$stmt->closeCursor();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Application $app
|
||||
* @param API_OAuth2_Account $account
|
||||
* @return array
|
||||
*/
|
||||
public static function load_by_account(Application $app, API_OAuth2_Account $account)
|
||||
{
|
||||
$sql = 'SELECT refresh_token FROM api_oauth_refresh_tokens
|
||||
WHERE api_account_id = :account_id';
|
||||
|
||||
$stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$stmt->execute([':account_id' => $account->get_id()]);
|
||||
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
$tokens = [];
|
||||
|
||||
foreach ($rs as $row) {
|
||||
$tokens[] = new API_OAuth2_RefreshToken($app, $row['refresh_token']);
|
||||
}
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Application $app
|
||||
* @param API_OAuth2_Account $account
|
||||
* @param int $expires
|
||||
* @param type $refresh_token
|
||||
* @param type $scope
|
||||
* @return API_OAuth2_RefreshToken
|
||||
*/
|
||||
public static function create(Application $app, 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 = $app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$params = [
|
||||
":refresh_token" => $refresh_token,
|
||||
":account_id" => $account->get_id(),
|
||||
":expires" => $expires,
|
||||
":scope" => $scope
|
||||
];
|
||||
$stmt->execute($params);
|
||||
$stmt->closeCursor();
|
||||
|
||||
return new self($app, $refresh_token);
|
||||
}
|
||||
}
|
@@ -1,319 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Model\Manipulator\TokenManipulator;
|
||||
use RandomLib\Generator;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
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;
|
||||
|
||||
private $generator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param appbox $appbox
|
||||
* @param API_OAuth2_Account $account
|
||||
* @return API_OAuth2_Token
|
||||
*/
|
||||
public function __construct(appbox $appbox, API_OAuth2_Account $account, Generator $generator)
|
||||
{
|
||||
$this->appbox = $appbox;
|
||||
$this->account = $account;
|
||||
$this->generator = $generator;
|
||||
|
||||
$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([':account_id' => $this->account->get_id()]);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ( ! $row)
|
||||
throw new NotFoundHttpException('Account not found');
|
||||
|
||||
$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 = [
|
||||
':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 = [
|
||||
':session_id' => $session_id
|
||||
, ':current_token' => $this->token
|
||||
];
|
||||
|
||||
$stmt = $this->appbox->get_connection()->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$stmt->closeCursor();
|
||||
|
||||
$this->session_id = $session_id !== null ? (int) $session_id : $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 = [
|
||||
':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 = [
|
||||
':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 = $this->generator->generateString(32, TokenManipulator::LETTERS_AND_NUMBERS);
|
||||
|
||||
$params = [
|
||||
':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([':oauth_token' => $this->get_value()]);
|
||||
$stmt->closeCursor();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Application $app
|
||||
* @param string $oauth_token
|
||||
* @return API_OAuth2_Token
|
||||
*/
|
||||
public static function load_by_oauth_token(Application $app, $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 = $app['phraseanet.appbox']->get_connection()->prepare($sql);
|
||||
$params = [":oauth_token" => $oauth_token];
|
||||
$stmt->execute($params);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
if (!$row) {
|
||||
throw new NotFoundHttpException('Account not found');
|
||||
}
|
||||
|
||||
return new self($app['phraseanet.appbox'], new API_OAuth2_Account($app, $row['api_account_id']), $app['random.medium']);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @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, Generator $generator, $scope = null)
|
||||
{
|
||||
$sql = 'INSERT INTO api_oauth_tokens
|
||||
(oauth_token, session_id, api_account_id, expires, scope)
|
||||
VALUES (:token, null, :account_id, :expire, :scope)';
|
||||
|
||||
$expires = new \DateTime('+1 hour');
|
||||
|
||||
$params = [
|
||||
':token' => $generator->generateString(32, TokenManipulator::LETTERS_AND_NUMBERS)
|
||||
, ':account_id' => $account->get_id()
|
||||
, ':expire' => $expires->format(DATE_ISO8601)
|
||||
, ':scope' => $scope
|
||||
];
|
||||
|
||||
$stmt = $appbox->get_connection()->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$stmt->closeCursor();
|
||||
|
||||
return new API_OAuth2_Token($appbox, $account, $generator);
|
||||
}
|
||||
}
|
@@ -251,6 +251,12 @@ abstract class base implements cache_cacheableInterface
|
||||
|
||||
$ORMTables = [
|
||||
'AuthFailures',
|
||||
'ApiApplications',
|
||||
'ApiAccounts',
|
||||
'ApiLogs',
|
||||
'ApiOauthCodes',
|
||||
'ApiOauthRefreshTokens',
|
||||
'ApiOauthTokens',
|
||||
'AggregateTokens',
|
||||
'BasketElements',
|
||||
'Baskets',
|
||||
|
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
class patch_370alpha3a extends patchAbstract
|
||||
@@ -42,7 +43,7 @@ class patch_370alpha3a extends patchAbstract
|
||||
*/
|
||||
public function getDoctrineMigrations()
|
||||
{
|
||||
return [];
|
||||
return ['api'];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,18 +59,21 @@ class patch_370alpha3a extends patchAbstract
|
||||
*/
|
||||
public function apply(base $appbox, Application $app)
|
||||
{
|
||||
try {
|
||||
\API_OAuth2_Application::load_from_client_id($app, \API_OAuth2_Application_Navigator::CLIENT_ID);
|
||||
} catch (NotFoundHttpException $e) {
|
||||
$client = \API_OAuth2_Application::create($app, null, \API_OAuth2_Application_Navigator::CLIENT_NAME);
|
||||
if (null === $app['repo.api-applications']->findByClientId(\API_OAuth2_Application_Navigator::CLIENT_ID)) {
|
||||
$application = $app['manipulator.api-application']->create(
|
||||
\API_OAuth2_Application_Navigator::CLIENT_NAME,
|
||||
ApiApplication::DESKTOP_TYPE,
|
||||
'',
|
||||
'http://www.phraseanet.com',
|
||||
null,
|
||||
ApiApplication::NATIVE_APP_REDIRECT_URI
|
||||
);
|
||||
|
||||
$client->set_activated(true);
|
||||
$client->set_grant_password(true);
|
||||
$client->set_website("http://www.phraseanet.com");
|
||||
$client->set_client_id(\API_OAuth2_Application_Navigator::CLIENT_ID);
|
||||
$client->set_client_secret(\API_OAuth2_Application_Navigator::CLIENT_SECRET);
|
||||
$client->set_type(\API_OAuth2_Application::DESKTOP_TYPE);
|
||||
$client->set_redirect_uri(\API_OAuth2_Application::NATIVE_APP_REDIRECT_URI);
|
||||
$application->setGrantPassword(true);
|
||||
$application->setClientId(\API_OAuth2_Application_Navigator::CLIENT_ID);
|
||||
$application->setClientSecret(\API_OAuth2_Application_Navigator::CLIENT_SECRET);
|
||||
|
||||
$app['manipulator.api-application']->update($application);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
class patch_3715alpha1a extends patchAbstract
|
||||
@@ -59,18 +60,21 @@ class patch_3715alpha1a extends patchAbstract
|
||||
*/
|
||||
public function apply(base $appbox, Application $app)
|
||||
{
|
||||
try {
|
||||
\API_OAuth2_Application::load_from_client_id($app, \API_OAuth2_Application_OfficePlugin::CLIENT_ID);
|
||||
} catch (NotFoundHttpException $e) {
|
||||
$client = \API_OAuth2_Application::create($app, null, \API_OAuth2_Application_OfficePlugin::CLIENT_NAME);
|
||||
if (null === $app['repo.api-applications']->findByClientId(\API_OAuth2_Application_OfficePlugin::CLIENT_ID)) {
|
||||
$application = $app['manipulator.api-application']->create(
|
||||
\API_OAuth2_Application_OfficePlugin::CLIENT_NAME,
|
||||
ApiApplication::DESKTOP_TYPE,
|
||||
'',
|
||||
'http://www.phraseanet.com',
|
||||
null,
|
||||
ApiApplication::NATIVE_APP_REDIRECT_URI
|
||||
);
|
||||
|
||||
$client->set_activated(true);
|
||||
$client->set_grant_password(true);
|
||||
$client->set_website("http://www.phraseanet.com");
|
||||
$client->set_client_id(\API_OAuth2_Application_OfficePlugin::CLIENT_ID);
|
||||
$client->set_client_secret(\API_OAuth2_Application_OfficePlugin::CLIENT_SECRET);
|
||||
$client->set_type(\API_OAuth2_Application::DESKTOP_TYPE);
|
||||
$client->set_redirect_uri(\API_OAuth2_Application::NATIVE_APP_REDIRECT_URI);
|
||||
$application->setGrantPassword(true);
|
||||
$application->setClientId(\API_OAuth2_Application_OfficePlugin::CLIENT_ID);
|
||||
$application->setClientSecret(\API_OAuth2_Application_OfficePlugin::CLIENT_SECRET);
|
||||
|
||||
$app['manipulator.api-application']->update($application);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
246
lib/classes/patch/390alpha17a.php
Normal file
246
lib/classes/patch/390alpha17a.php
Normal file
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
class patch_390alpha17a extends patchAbstract
|
||||
{
|
||||
/** @var string */
|
||||
private $release = '3.9.0-alpha.17';
|
||||
|
||||
/** @var array */
|
||||
private $concern = [base::APPLICATION_BOX];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_release()
|
||||
{
|
||||
return $this->release;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function require_all_upgrades()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function concern()
|
||||
{
|
||||
return $this->concern;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDoctrineMigrations()
|
||||
{
|
||||
return ['api'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function apply(base $appbox, Application $app)
|
||||
{
|
||||
$this->fillApplicationTable($app['EM']);
|
||||
$this->fillAccountTable($app['EM']);
|
||||
$this->fillLogTable($app['EM']);
|
||||
$this->fillCodeTable($app['EM']);
|
||||
$this->fillRefreshTokenTable($app['EM']);
|
||||
$this->fillOauthTokenTable($app['EM']);
|
||||
$this->setOauthTokenExpiresToNull($app['EM']);
|
||||
$this->updateLogsTable($app['EM']);
|
||||
}
|
||||
|
||||
private function fillApplicationTable(EntityManager $em)
|
||||
{
|
||||
if (false === $this->tableExists($em, 'api_applications')) {
|
||||
return true;
|
||||
}
|
||||
$em->getConnection()->executeUpdate(
|
||||
'INSERT INTO ApiApplications
|
||||
(
|
||||
id, `type`, `name`, description, website,
|
||||
created, updated, client_id, client_secret, nonce,
|
||||
redirect_uri, activated, grant_password, creator_id
|
||||
|
||||
)
|
||||
(
|
||||
SELECT
|
||||
a.application_id, a.`type`, a.`name`, a.description, a.website,
|
||||
a.created_on, a.last_modified, a.client_id, a.client_secret, a.nonce,
|
||||
a.redirect_uri, a.activated, a.grant_password, creator
|
||||
FROM api_applications a
|
||||
LEFT JOIN Users u ON (u.id = a.creator)
|
||||
WHERE u.id IS NOT NULL
|
||||
OR a.`name` = "'. \API_OAuth2_Application_Navigator::CLIENT_NAME .'"
|
||||
OR a.`name` = "'. \API_OAuth2_Application_OfficePlugin::CLIENT_NAME .'"
|
||||
)'
|
||||
);
|
||||
}
|
||||
|
||||
private function fillAccountTable(EntityManager $em)
|
||||
{
|
||||
if (false === $this->tableExists($em, 'api_accounts')) {
|
||||
return true;
|
||||
}
|
||||
$em->getConnection()->executeUpdate(
|
||||
'INSERT INTO ApiAccounts
|
||||
(
|
||||
id, user_id, revoked,
|
||||
api_version, created, application_id
|
||||
|
||||
)
|
||||
(
|
||||
SELECT
|
||||
a.api_account_id, a.usr_id, a.revoked,
|
||||
a.api_version, a.created, a.application_id
|
||||
FROM api_accounts a
|
||||
INNER JOIN Users ON (Users.id = a.usr_id)
|
||||
INNER JOIN api_applications b ON (a.application_id = b.application_id)
|
||||
)'
|
||||
);
|
||||
}
|
||||
|
||||
private function fillLogTable(EntityManager $em)
|
||||
{
|
||||
if (false === $this->tableExists($em, 'api_accounts')) {
|
||||
return true;
|
||||
}
|
||||
$em->getConnection()->executeUpdate(
|
||||
'INSERT INTO ApiLogs
|
||||
(
|
||||
id, account_id, route, error_message,
|
||||
created, status_code, format, resource,
|
||||
general, aspect, `action`, error_code
|
||||
|
||||
)
|
||||
(
|
||||
SELECT
|
||||
a.api_log_id, a.api_account_id, a.api_log_route, a.api_log_error_message,
|
||||
a.api_log_date, a.api_log_status_code, a.api_log_format, a.api_log_ressource,
|
||||
a.api_log_general, a.api_log_aspect, a.api_log_action, a.api_log_error_code
|
||||
FROM api_logs a
|
||||
INNER JOIN api_accounts b ON (b.api_account_id = a.api_account_id)
|
||||
)'
|
||||
);
|
||||
}
|
||||
|
||||
private function fillCodeTable(EntityManager $em)
|
||||
{
|
||||
if (false === $this->tableExists($em, 'api_oauth_codes')) {
|
||||
return true;
|
||||
}
|
||||
$em->getConnection()->executeUpdate(
|
||||
'INSERT INTO ApiOauthCodes
|
||||
(
|
||||
code, account_id, redirect_uri, expires,
|
||||
scope, created, updated
|
||||
|
||||
)
|
||||
(
|
||||
SELECT
|
||||
a.code, a.api_account_id, a.redirect_uri, a.expires,
|
||||
a.scope, NOW(), NOW()
|
||||
FROM api_oauth_codes a
|
||||
INNER JOIN api_accounts b ON (b.api_account_id = a.api_account_id)
|
||||
)'
|
||||
);
|
||||
}
|
||||
|
||||
private function fillRefreshTokenTable(EntityManager $em)
|
||||
{
|
||||
if (false === $this->tableExists($em, 'api_oauth_refresh_tokens')) {
|
||||
return true;
|
||||
}
|
||||
$em->getConnection()->executeUpdate(
|
||||
'INSERT INTO ApiOauthRefreshTokens
|
||||
(
|
||||
refresh_token, account_id, expires,
|
||||
scope, created, updated
|
||||
|
||||
)
|
||||
(
|
||||
SELECT
|
||||
a.refresh_token, a.api_account_id, a.expires,
|
||||
a.scope, NOW(), NOW()
|
||||
FROM api_oauth_refresh_tokens a
|
||||
INNER JOIN api_accounts b ON (b.api_account_id = a.api_account_id)
|
||||
)'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private function fillOauthTokenTable(EntityManager $em)
|
||||
{
|
||||
if (false === $this->tableExists($em, 'api_oauth_tokens')) {
|
||||
return true;
|
||||
}
|
||||
$em->getConnection()->executeUpdate(
|
||||
'INSERT INTO ApiOauthTokens
|
||||
(
|
||||
oauth_token, account_id, session_id, expires,
|
||||
scope, created, updated, last_used
|
||||
|
||||
)
|
||||
(
|
||||
SELECT
|
||||
a.oauth_token, a.api_account_id, a.session_id, expires,
|
||||
a.scope, NOW(), NOW(), NOW()
|
||||
FROM api_oauth_tokens a
|
||||
INNER JOIN api_accounts b ON (b.api_account_id = a.api_account_id)
|
||||
)'
|
||||
);
|
||||
}
|
||||
|
||||
private function setOauthTokenExpiresToNull(EntityManager $em)
|
||||
{
|
||||
$qb = $em->createQueryBuilder();
|
||||
$q = $qb->update('Phraseanet:ApiOauthToken', 'a')
|
||||
->set('a.expires', $qb->expr()->literal(null))
|
||||
->getQuery();
|
||||
$q->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update ApiLogs Table
|
||||
*
|
||||
* before :
|
||||
* +--------------------+
|
||||
* | route |
|
||||
* +--------------------+
|
||||
* | GET /databox/list/ |
|
||||
* +--------------------+
|
||||
*
|
||||
* after :
|
||||
* +----------------+--------+
|
||||
* | route | method |
|
||||
* +----------------+--------+
|
||||
* | /databox/list/ | GET |
|
||||
* +----------------+--------+
|
||||
*
|
||||
*/
|
||||
private function updateLogsTable(EntityManager $em)
|
||||
{
|
||||
$em->getConnection()->executeUpdate("
|
||||
UPDATE `ApiLogs`
|
||||
SET method = SUBSTRING_INDEX(SUBSTRING_INDEX(route, ' ', 1), ' ', -1),
|
||||
route = SUBSTRING_INDEX(SUBSTRING_INDEX(route, ' ', 2), ' ', -1)
|
||||
");
|
||||
}
|
||||
}
|
@@ -77,567 +77,6 @@
|
||||
<engine>InnoDB</engine>
|
||||
</table>
|
||||
|
||||
<!-- API -->
|
||||
<table name="api_accounts">
|
||||
<fields>
|
||||
<field>
|
||||
<name>api_account_id</name>
|
||||
<type>int(11) unsigned</type>
|
||||
<null></null>
|
||||
<extra>auto_increment</extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>usr_id</name>
|
||||
<type>int(11) unsigned</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>revoked</name>
|
||||
<type>int(1)</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>api_version</name>
|
||||
<type>char(16)</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>application_id</name>
|
||||
<type>int(11)</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>created</name>
|
||||
<type>datetime</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
</fields>
|
||||
<indexes>
|
||||
<index>
|
||||
<name>PRIMARY</name>
|
||||
<type>PRIMARY</type>
|
||||
<fields>
|
||||
<field>api_account_id</field>
|
||||
</fields>
|
||||
</index>
|
||||
<index>
|
||||
<name>usr_id</name>
|
||||
<type>INDEX</type>
|
||||
<fields>
|
||||
<field>usr_id</field>
|
||||
</fields>
|
||||
</index>
|
||||
<index>
|
||||
<name>application_id</name>
|
||||
<type>INDEX</type>
|
||||
<fields>
|
||||
<field>application_id</field>
|
||||
</fields>
|
||||
</index>
|
||||
</indexes>
|
||||
<engine>InnoDB</engine>
|
||||
</table>
|
||||
|
||||
|
||||
<table name="api_applications">
|
||||
<fields>
|
||||
<field>
|
||||
<name>application_id</name>
|
||||
<type>int(11) unsigned</type>
|
||||
<null></null>
|
||||
<extra>auto_increment</extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>creator</name>
|
||||
<type>int(11) unsigned</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>type</name>
|
||||
<type>enum('web','desktop')</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>name</name>
|
||||
<type>varchar(64)</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>description</name>
|
||||
<type>text</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>website</name>
|
||||
<type>varchar(120)</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>created_on</name>
|
||||
<type>datetime</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>last_modified</name>
|
||||
<type>datetime</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>client_id</name>
|
||||
<type>char(128)</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>client_secret</name>
|
||||
<type>char(128)</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>nonce</name>
|
||||
<type>char(64)</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>redirect_uri</name>
|
||||
<type>varchar(128)</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>activated</name>
|
||||
<type>int(1)</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>grant_password</name>
|
||||
<type>int(1)</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
</fields>
|
||||
<indexes>
|
||||
<index>
|
||||
<name>PRIMARY</name>
|
||||
<type>PRIMARY</type>
|
||||
<fields>
|
||||
<field>application_id</field>
|
||||
</fields>
|
||||
</index>
|
||||
<index>
|
||||
<name>creator</name>
|
||||
<type>INDEX</type>
|
||||
<fields>
|
||||
<field>creator</field>
|
||||
</fields>
|
||||
</index>
|
||||
<index>
|
||||
<name>client_id</name>
|
||||
<type>UNIQUE</type>
|
||||
<fields>
|
||||
<field>client_id</field>
|
||||
</fields>
|
||||
</index>
|
||||
</indexes>
|
||||
<defaults>
|
||||
<default>
|
||||
<data key="application_id">null</data>
|
||||
<data key="creator">null</data>
|
||||
<data key="type">desktop</data>
|
||||
<data key="name">phraseanet-navigator</data>
|
||||
<data key="description"></data>
|
||||
<data key="website">http://www.phraseanet.com</data>
|
||||
<data key="created_on">NOW()</data>
|
||||
<data key="last_modified">NOW()</data>
|
||||
<data key="client_id">\alchemy\phraseanet\id\4f981093aebb66.06844599</data>
|
||||
<data key="client_secret">\alchemy\phraseanet\secret\4f9810d4b09799.51622662</data>
|
||||
<data key="nonce">5b6lIf</data>
|
||||
<data key="redirect_uri">urn:ietf:wg:oauth:2.0:oob</data>
|
||||
<data key="activated">1</data>
|
||||
<data key="grant_password">1</data>
|
||||
</default>
|
||||
<default>
|
||||
<data key="application_id">null</data>
|
||||
<data key="creator">null</data>
|
||||
<data key="type">desktop</data>
|
||||
<data key="name">office-plugin</data>
|
||||
<data key="description"></data>
|
||||
<data key="website">http://www.phraseanet.com</data>
|
||||
<data key="created_on">NOW()</data>
|
||||
<data key="last_modified">NOW()</data>
|
||||
<data key="client_id">\alchemy\phraseanet\id\999585175b5fbb6e140efbdfea86c561</data>
|
||||
<data key="client_secret">\alchemy\phraseanet\secret\6d53d0bc74e6c8c1a325541f71da1ea5</data>
|
||||
<data key="nonce">AfCF61</data>
|
||||
<data key="redirect_uri">urn:ietf:wg:oauth:2.0:oob</data>
|
||||
<data key="activated">1</data>
|
||||
<data key="grant_password">1</data>
|
||||
</default>
|
||||
</defaults>
|
||||
<engine>InnoDB</engine>
|
||||
</table>
|
||||
|
||||
|
||||
<table name="api_logs">
|
||||
<fields>
|
||||
<field>
|
||||
<name>api_log_id</name>
|
||||
<type>int(11) unsigned</type>
|
||||
<null></null>
|
||||
<extra>auto_increment</extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>api_account_id</name>
|
||||
<type>int(11) unsigned</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>api_log_route</name>
|
||||
<type>varchar(256)</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>api_log_date</name>
|
||||
<type>datetime</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>api_log_status_code</name>
|
||||
<type>int(11) unsigned</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>api_log_format</name>
|
||||
<type>varchar(64)</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>api_log_resource</name>
|
||||
<type>varchar(64)</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>api_log_general</name>
|
||||
<type>varchar(64)</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>api_log_aspect</name>
|
||||
<type>varchar(64)</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>api_log_action</name>
|
||||
<type>varchar(64)</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>api_log_error_code</name>
|
||||
<type>int(11) unsigned</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>api_log_error_message</name>
|
||||
<type>varchar(256)</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
</fields>
|
||||
<indexes>
|
||||
<index>
|
||||
<name>PRIMARY</name>
|
||||
<type>PRIMARY</type>
|
||||
<fields>
|
||||
<field>api_log_id</field>
|
||||
</fields>
|
||||
</index>
|
||||
<index>
|
||||
<name>api_account_id</name>
|
||||
<type>INDEX</type>
|
||||
<fields>
|
||||
<field>api_account_id</field>
|
||||
</fields>
|
||||
</index>
|
||||
</indexes>
|
||||
<engine>InnoDB</engine>
|
||||
</table>
|
||||
|
||||
|
||||
<table name="api_oauth_codes">
|
||||
<fields>
|
||||
<field>
|
||||
<name>code</name>
|
||||
<type>char(128)</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>api_account_id</name>
|
||||
<type>int(11) unsigned</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>redirect_uri</name>
|
||||
<type>varchar(256)</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>expires</name>
|
||||
<type>DATETIME</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>scope</name>
|
||||
<type>varchar(200)</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
</fields>
|
||||
<indexes>
|
||||
<index>
|
||||
<name>PRIMARY</name>
|
||||
<type>PRIMARY</type>
|
||||
<fields>
|
||||
<field>code</field>
|
||||
</fields>
|
||||
</index>
|
||||
<index>
|
||||
<name>api_account_id</name>
|
||||
<type>INDEX</type>
|
||||
<fields>
|
||||
<field>api_account_id</field>
|
||||
</fields>
|
||||
</index>
|
||||
</indexes>
|
||||
<engine>InnoDB</engine>
|
||||
</table>
|
||||
|
||||
|
||||
<table name="api_oauth_tokens">
|
||||
<fields>
|
||||
<field>
|
||||
<name>oauth_token</name>
|
||||
<type>char(128)</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>session_id</name>
|
||||
<type>int(6)</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>api_account_id</name>
|
||||
<type>int(11)</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>expires</name>
|
||||
<type>DATETIME</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>scope</name>
|
||||
<type>varchar(200)</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
</fields>
|
||||
<indexes>
|
||||
<index>
|
||||
<name>PRIMARY</name>
|
||||
<type>PRIMARY</type>
|
||||
<fields>
|
||||
<field>oauth_token</field>
|
||||
</fields>
|
||||
</index>
|
||||
<index>
|
||||
<name>api_account_id</name>
|
||||
<type>INDEX</type>
|
||||
<fields>
|
||||
<field>api_account_id</field>
|
||||
</fields>
|
||||
</index>
|
||||
<index>
|
||||
<name>session_id</name>
|
||||
<type>INDEX</type>
|
||||
<fields>
|
||||
<field>session_id</field>
|
||||
</fields>
|
||||
</index>
|
||||
</indexes>
|
||||
<engine>InnoDB</engine>
|
||||
</table>
|
||||
|
||||
|
||||
<table name="api_oauth_refresh_tokens">
|
||||
<fields>
|
||||
<field>
|
||||
<name>refresh_token</name>
|
||||
<type>char(128)</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>api_account_id</name>
|
||||
<type>int(11)</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>expires</name>
|
||||
<type>DATETIME</type>
|
||||
<null></null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
<field>
|
||||
<name>scope</name>
|
||||
<type>varchar(200)</type>
|
||||
<null>YES</null>
|
||||
<extra></extra>
|
||||
<default></default>
|
||||
<comment></comment>
|
||||
</field>
|
||||
</fields>
|
||||
<indexes>
|
||||
<index>
|
||||
<name>PRIMARY</name>
|
||||
<type>PRIMARY</type>
|
||||
<fields>
|
||||
<field>refresh_token</field>
|
||||
</fields>
|
||||
</index>
|
||||
<index>
|
||||
<name>api_account_id</name>
|
||||
<type>INDEX</type>
|
||||
<fields>
|
||||
<field>api_account_id</field>
|
||||
</fields>
|
||||
</index>
|
||||
</indexes>
|
||||
<engine>InnoDB</engine>
|
||||
</table>
|
||||
|
||||
<table name="bridge_accounts">
|
||||
<fields>
|
||||
<field>
|
||||
|
@@ -60,6 +60,9 @@ migrations:
|
||||
migration19:
|
||||
version: token
|
||||
class: Alchemy\Phrasea\Setup\DoctrineMigrations\TokenMigration
|
||||
migration20:
|
||||
version: api
|
||||
class: Alchemy\Phrasea\Setup\DoctrineMigrations\ApiMigration
|
||||
migration21:
|
||||
version: aggregate-token
|
||||
class: Alchemy\Phrasea\Setup\DoctrineMigrations\AggregateTokenMigration
|
||||
|
@@ -13,28 +13,30 @@
|
||||
<h3>{{ "Vous avez autorise ces applications a acceder a votre compte" | trans }}</h3>
|
||||
{% if applications|length > 0 %}
|
||||
<ul class="unstyled app-list">
|
||||
{% for application in applications %}
|
||||
<li id="app_{{ application.get_id() }}">
|
||||
{% for data in applications if data["user-account"] is not none %}
|
||||
{% set application = data["application"] %}
|
||||
{% set account = data["user-account"] %}
|
||||
<li id="app_{{ application.getId() }}">
|
||||
<div>
|
||||
{% set account = application.get_user_account(app["authentication"].getUser()) %}
|
||||
<a href="{{ path("grant_app_access", {"application_id" : application.get_id()}) }}" class="revoke app-btn btn btn-small pull-right {% if account.is_revoked() %}hidden{% endif %}" value="{{application.get_id()}}">{{ "Revoquer l\'access" | trans }}</a>
|
||||
<a href="{{ path("grant_app_access", {"application_id" : application.get_id()}) }}" class="authorize app-btn btn btn-small pull-right {% if not account.is_revoked() %}hidden{% endif %}" value="{{application.get_id()}}">{{ "Authoriser l\'access" | trans }}</a>
|
||||
|
||||
<a href="{{ path("grant_app_access", {"application" : application.getId()}) }}" class="revoke app-btn btn btn-small pull-right {% if account.isRevoked() %}hidden{% endif %}" value="{{application.getId()}}">{{ "Revoquer l\'access" | trans }}</a>
|
||||
<a href="{{ path("grant_app_access", {"application" : application.getId()}) }}" class="authorize app-btn btn btn-small pull-right {% if not account.isRevoked() %}hidden{% endif %}" value="{{application.getId()}}">{{ "Authoriser l\'access" | trans }}</a>
|
||||
<p class="app-row">
|
||||
<a href="{{ application.get_website() }}" target="_blank">
|
||||
<strong>{{ application.get_name() }}</strong>
|
||||
<a href="{{ application.getWebsite() }}" target="_blank">
|
||||
<strong>{{ application.getName() }}</strong>
|
||||
</a>
|
||||
{% if application.get_creator() is not none %}
|
||||
{% if application.getCreator() is not none %}
|
||||
<small>
|
||||
{% set user_name = application.get_creator().getDisplayName() %}
|
||||
{% set user_name = application.getCreator().getDisplayName() %}
|
||||
{% trans with {'%user_name%' : user_name} %}par %user_name%{% endtrans %}
|
||||
</small>
|
||||
{% endif%}
|
||||
</p>
|
||||
<p class="app-row">
|
||||
<span class="status text-error {% if account.is_revoked() == false %}hidden{% endif %}">{{ "Not Allowed" | trans }}</span>
|
||||
<span class="status text-success {% if account.is_revoked() == true %}hidden{% endif %}">{{ "Allowed" | trans }}</span>
|
||||
<span class="status text-error {% if account.isRevoked() == false %}hidden{% endif %}">{{ "Not Allowed" | trans }}</span>
|
||||
<span class="status text-success {% if account.isRevoked() == true %}hidden{% endif %}">{{ "Allowed" | trans }}</span>
|
||||
</p>
|
||||
<p class="app-row">{{ application.get_description()|truncate(120, true, "...") }}</p>
|
||||
<p class="app-row">{{ application.getDescription()|truncate(120, true, "...") }}</p>
|
||||
</div>
|
||||
</li>
|
||||
{%endfor%}
|
||||
|
@@ -37,7 +37,7 @@
|
||||
<h1 id="namePhr">{{ app['conf'].get(['registry', 'general', 'title']) }}</h1>
|
||||
</div>
|
||||
|
||||
{% if user is not none %}
|
||||
{% if app['authentication'].getUser() is not none %}
|
||||
{% set username = '<b>' ~ app['authentication'].getUser().getDisplayName() ~ '</b>' %}
|
||||
<div id="hello-box" class="span6 offset3">
|
||||
<p class="login_hello">
|
||||
|
@@ -10,11 +10,11 @@
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<h1>{{ "Application" | trans }}</h1>
|
||||
<input type="hidden" value="{{ application.get_id() }}" name="app_id"/>
|
||||
<input type="hidden" value="{{ application.getId() }}" name="app_id"/>
|
||||
|
||||
<div>
|
||||
<div><strong><a class="link" href="{{ path("developers_application", {"id" : application.get_id()}) }}">{{ application.get_name() }}</a></strong></div>
|
||||
<div>{{ application.get_description() }}</div>
|
||||
<div><strong><a class="link" href="{{ path("developers_application", {"application" : application.getId()}) }}">{{ application.getName() }}</a></strong></div>
|
||||
<div>{{ application.getDescription() }}</div>
|
||||
</div>
|
||||
|
||||
<h1>{{ "settings OAuth" | trans }}</h1>
|
||||
@@ -24,22 +24,22 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Client ID</td>
|
||||
<td>{{ application.get_client_id() }}</td>
|
||||
<td>{{ application.getClientId() }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Client Secret</td>
|
||||
<td>{{ application.get_client_secret() }}</td>
|
||||
<td>{{ application.getClientSecret() }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ "URL de callback" | trans }}</td>
|
||||
{% if application.get_type() == constant("API_OAuth2_Application::DESKTOP_TYPE") %}
|
||||
{% if application.getType() == constant("DESKTOP_TYPE", application) %}
|
||||
<td>
|
||||
<span>{{ application.get_redirect_uri() }}</span>
|
||||
<span>{{ application.getRedirectUri() }}</span>
|
||||
</td>
|
||||
{% else %}
|
||||
<td class="url_callback">
|
||||
<span class="url_callback_input">{{ application.get_redirect_uri() }}</span>
|
||||
<a href="{{ path("submit_application_callback", {"id" : application.get_id()}) }}" class="save_callback btn btn-small btn-info" style="display:none;">
|
||||
<span class="url_callback_input">{{ application.getRedirectUri() }}</span>
|
||||
<a href="{{ path("submit_application_callback", {"application" : application.getId()}) }}" class="save_callback btn btn-small btn-info" style="display:none;">
|
||||
{{ "Save" | trans }}
|
||||
</a>
|
||||
<button type="button" class="modifier_callback btn btn-small">
|
||||
@@ -61,9 +61,9 @@
|
||||
<td>
|
||||
<input class="grant-type"
|
||||
type="checkbox"
|
||||
{{ application.is_password_granted() ? "checked='checked'" : "" }}
|
||||
{{ application.isPasswordGranted() ? "checked='checked'" : "" }}
|
||||
name="grant"
|
||||
value="{{ path("submit_developers_application_authorize_grant_password", {"id" : application.get_id()}) }}"
|
||||
value="{{ path("submit_developers_application_authorize_grant_password", {"application" : application.getId()}) }}"
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -81,18 +81,18 @@
|
||||
</td>
|
||||
<td>
|
||||
<span id="my_access_token">
|
||||
{% if not token is none %}
|
||||
{{ token|default("") }}
|
||||
{% if not token is none %}
|
||||
{{ token.getOauthToken()|default("") }}
|
||||
{% else %}
|
||||
{{ "Le token n\'a pas encore ete genere" | trans }}
|
||||
{% endif %}
|
||||
</span>
|
||||
<a id="generate_access" href="{{ path("submit_developers_application_token",{ "id" : application.get_id()}) }}" class="btn btn-small btn-info">{{ "boutton::generer" | trans }}</a>
|
||||
</td>
|
||||
<a id="generate_access" href="{{ path("submit_developers_application_token",{ "application" : application.getId()}) }}" class="btn btn-small btn-info">{{ "boutton::generer" | trans }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div>
|
||||
<div class="form-actions">
|
||||
<a class="btn btn-primary" href="{{ path("developers_applications") }}">{{ "boutton::retour" | trans }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -15,7 +15,7 @@
|
||||
{% if applications|length > 0 %}
|
||||
<ul class="app-list unstyled">
|
||||
{% for application in applications %}
|
||||
<li id="app_{{ application.get_id() }}">
|
||||
<li id="app_{{ application.getId() }}">
|
||||
<a href="#appModal-{{ loop.index }}" role="button" data-toggle="modal" class="pull-right btn btn-danger btn-small" type="button">
|
||||
{{ "button::supprimer" | trans }}
|
||||
</a>
|
||||
@@ -23,24 +23,24 @@
|
||||
<div id="appModal-{{ loop.index }}" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">{{ application.get_name() }}</h3>
|
||||
<h3 id="myModalLabel">{{ application.getName() }}</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>{{ "Are you sure you want to delete this application?" | trans }} </p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">{{ "No" | trans }}</button>
|
||||
<a href="{{ path("delete_developers_application", {"id" : application.get_id()}) }}" class="delete-app btn btn-info">{{ "Yes" | trans }}</a>
|
||||
<a href="{{ path("delete_developers_application", {"application" : application.getId()}) }}" class="delete-app btn btn-info">{{ "Yes" | trans }}</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="app-row">
|
||||
<strong>
|
||||
<a class="link" href="{{ path("developers_application", {"id" : application.get_id}) }}">
|
||||
{{ application.get_name() }}
|
||||
<a class="link" href="{{ path("developers_application", {"application" : application.getId}) }}">
|
||||
{{ application.getName() }}
|
||||
</a>
|
||||
</strong>
|
||||
</p>
|
||||
<p class="app-row">{{ application.get_description()|truncate(120, true, "...") }}</p>
|
||||
<p class="app-row">{{ application.getDescription()|truncate(120, true, "...") }}</p>
|
||||
</li>
|
||||
{%endfor%}
|
||||
</ul>
|
||||
|
@@ -7,6 +7,7 @@ use Alchemy\Phrasea\Border\File;
|
||||
use Alchemy\Phrasea\Controller\Api\V1;
|
||||
use Alchemy\Phrasea\Core\PhraseaEvents;
|
||||
use Alchemy\Phrasea\Authentication\Context;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
use Alchemy\Phrasea\Model\Entities\Task;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
@@ -17,37 +18,13 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
{
|
||||
/**
|
||||
* @var \API_OAuth2_Token
|
||||
*/
|
||||
private static $token;
|
||||
|
||||
/**
|
||||
* @var \API_OAuth2_Account
|
||||
*/
|
||||
private static $account;
|
||||
/**
|
||||
* @var \API_OAuth2_Application
|
||||
*/
|
||||
private static $oauthApplication;
|
||||
/**
|
||||
* @var \API_OAuth2_Token
|
||||
*/
|
||||
private static $adminToken;
|
||||
/**
|
||||
* @var \API_OAuth2_Account
|
||||
*/
|
||||
private static $adminAccount;
|
||||
/**
|
||||
* @var \API_OAuth2_Application
|
||||
*/
|
||||
private static $adminApplication;
|
||||
private static $apiInitialized = false;
|
||||
|
||||
abstract protected function getParameters(array $parameters = []);
|
||||
abstract protected function unserialize($data);
|
||||
abstract protected function getAcceptMimeType();
|
||||
|
||||
private $adminAccessToken;
|
||||
private $userAccessToken;
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->unsetToken();
|
||||
@@ -62,26 +39,30 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
return $this->loadApp('lib/Alchemy/Phrasea/Application/Api.php');
|
||||
});
|
||||
|
||||
if (!self::$apiInitialized) {
|
||||
self::$account = \API_OAuth2_Account::load_with_user(self::$DI['app'], self::$DI['oauth2-app-user_notAdmin'], self::$DI['user_notAdmin']);
|
||||
self::$account->set_revoked(false);
|
||||
self::$token = self::$account->get_token()->get_value();
|
||||
if (null === $this->adminAccessToken) {
|
||||
$tokens = self::$DI['app']['repo.api-oauth-tokens']->findOauthTokens(self::$DI['oauth2-app-acc-user']);
|
||||
if (count($tokens) === 0) {
|
||||
$this->fail(sprintf('No access token generated between user %s & application %s',
|
||||
self::$DI['oauth2-app-acc-user']->getUser()->getLogin(),
|
||||
self::$DI['oauth2-app-acc-user']->getApplication()->getName()
|
||||
));
|
||||
}
|
||||
|
||||
self::$adminAccount = \API_OAuth2_Account::load_with_user(self::$DI['app'], self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
self::$adminAccount->set_revoked(false);
|
||||
self::$adminToken = self::$adminAccount->get_token()->get_value();
|
||||
|
||||
self::$apiInitialized = true;
|
||||
$this->adminAccessToken = current($tokens);
|
||||
}
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass()
|
||||
{
|
||||
self::$apiInitialized = false;
|
||||
self::$token = self::$account = self::$oauthApplication = self::$adminToken
|
||||
= self::$adminAccount = self::$adminApplication = null;
|
||||
|
||||
parent::tearDownAfterClass();
|
||||
if (null === $this->userAccessToken) {
|
||||
$tokens = self::$DI['app']['repo.api-oauth-tokens']->findOauthTokens(self::$DI['oauth2-app-acc-user-not-admin']);
|
||||
if (count($tokens) === 0) {
|
||||
$this->fail(sprintf('No access token generated between user %s & application %s',
|
||||
self::$DI['oauth2-app-acc-user-not-admin']->getUser()->getLogin(),
|
||||
self::$DI['oauth2-app-acc-user-not-admin']->getApplication()->getName()
|
||||
));
|
||||
}
|
||||
|
||||
$this->userAccessToken = current($tokens);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,7 +79,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
}
|
||||
});
|
||||
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
self::$DI['client']->request('GET', $route, $this->getParameters(), [], ['HTTP_Accept' => $this->getAcceptMimeType()]);
|
||||
|
||||
$this->assertEquals(1, $preEvent);
|
||||
@@ -107,7 +88,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
public function testThatSessionIsClosedAfterRequest()
|
||||
{
|
||||
$this->assertCount(0, self::$DI['app']['EM']->getRepository('Phraseanet:Session')->findAll());
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
self::$DI['client']->request('GET', '/api/v1/databoxes/list/', $this->getParameters(), [], ['HTTP_Accept' => $this->getAcceptMimeType()]);
|
||||
$this->assertCount(0, self::$DI['app']['EM']->getRepository('Phraseanet:Session')->findAll());
|
||||
}
|
||||
@@ -126,7 +107,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
public function testRouteNotFound()
|
||||
{
|
||||
$route = '/api/v1/nothinghere';
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
self::$DI['client']->request('GET', $route, $this->getParameters(), [], ['HTTP_Accept' => $this->getAcceptMimeType()]);
|
||||
$content = $this->unserialize(self::$DI['client']->getResponse()->getContent());
|
||||
|
||||
@@ -136,7 +117,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testDataboxListRoute()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
self::$DI['client']->request('GET', '/api/v1/databoxes/list/', $this->getParameters(), [], ['HTTP_Accept' => $this->getAcceptMimeType()]);
|
||||
$content = $this->unserialize(self::$DI['client']->getResponse()->getContent());
|
||||
|
||||
@@ -167,12 +148,14 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
$fail = null;
|
||||
|
||||
try {
|
||||
$nativeApp = self::$DI['app']['repo.api-applications']->findByClientId(\API_OAuth2_Application_Navigator::CLIENT_ID);
|
||||
if (null === $nativeApp) {
|
||||
throw new \Exception(sprintf('%s not found', \API_OAuth2_Application_Navigator::CLIENT_ID));
|
||||
}
|
||||
$account = self::$DI['app']['manipulator.api-account']->create($nativeApp, self::$DI['user']);
|
||||
$token = self::$DI['app']['manipulator.api-oauth-token']->create($account);
|
||||
|
||||
$nativeApp = \API_OAuth2_Application::load_from_client_id(self::$DI['app'], \API_OAuth2_Application_Navigator::CLIENT_ID);
|
||||
|
||||
$account = \API_OAuth2_Account::create(self::$DI['app'], self::$DI['user'], $nativeApp);
|
||||
$token = $account->get_token()->get_value();
|
||||
$this->setToken($token);
|
||||
$this->setToken($token->getOauthToken());
|
||||
self::$DI['client']->request('GET', '/api/v1/databoxes/list/', $this->getParameters(), [], ['HTTP_Accept' => $this->getAcceptMimeType()]);
|
||||
$content = $this->unserialize(self::$DI['client']->getResponse()->getContent());
|
||||
|
||||
@@ -183,7 +166,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
$fail = $e;
|
||||
}
|
||||
|
||||
self::$DI['app']['conf']->set(['registry', 'api-clients', 'navigator-enabled'], false);
|
||||
self::$DI['app']['conf']->set(['registry', 'api-clients', 'navigator-enabled'], $value);
|
||||
|
||||
if ($fail) {
|
||||
throw $fail;
|
||||
@@ -195,7 +178,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
*/
|
||||
public function testAdminOnlyShedulerState()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
|
||||
self::$DI['client']->request('GET', '/api/v1/monitor/tasks/', $this->getParameters(), [], ['HTTP_Accept' => $this->getAcceptMimeType()]);
|
||||
$content = $this->unserialize(self::$DI['client']->getResponse()->getContent());
|
||||
@@ -231,10 +214,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
*/
|
||||
public function testGetMonitorTasks()
|
||||
{
|
||||
if (null === self::$adminToken) {
|
||||
$this->markTestSkipped('there is no user with admin rights');
|
||||
}
|
||||
$this->setToken(self::$adminToken);
|
||||
$this->setToken($this->adminAccessToken);
|
||||
|
||||
$route = '/api/v1/monitor/tasks/';
|
||||
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
|
||||
@@ -259,10 +239,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
*/
|
||||
public function testGetScheduler()
|
||||
{
|
||||
if (null === self::$adminToken) {
|
||||
$this->markTestSkipped('there is no user with admin rights');
|
||||
}
|
||||
$this->setToken(self::$adminToken);
|
||||
$this->setToken($this->adminAccessToken);
|
||||
|
||||
$route = '/api/v1/monitor/scheduler/';
|
||||
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
|
||||
@@ -338,15 +315,11 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
{
|
||||
$tasks = self::$DI['app']['repo.tasks']->findAll();
|
||||
|
||||
if (null === self::$adminToken) {
|
||||
$this->markTestSkipped('there is no user with admin rights');
|
||||
}
|
||||
|
||||
if (!count($tasks)) {
|
||||
$this->markTestSkipped('no tasks created for the current instance');
|
||||
}
|
||||
|
||||
$this->setToken(self::$adminToken);
|
||||
$this->setToken($this->adminAccessToken);
|
||||
$idTask = $tasks[0]->getId();
|
||||
|
||||
$route = '/api/v1/monitor/task/' . $idTask . '/';
|
||||
@@ -365,15 +338,11 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
{
|
||||
$tasks = self::$DI['app']['repo.tasks']->findAll();
|
||||
|
||||
if (null === self::$adminToken) {
|
||||
$this->markTestSkipped('there is no user with admin rights');
|
||||
}
|
||||
|
||||
if (!count($tasks)) {
|
||||
$this->markTestSkipped('no tasks created for the current instance');
|
||||
}
|
||||
|
||||
$this->setToken(self::$adminToken);
|
||||
$this->setToken($this->adminAccessToken);
|
||||
$idTask = $tasks[0]->getId();
|
||||
|
||||
$route = '/api/v1/monitor/task/' . $idTask . '/';
|
||||
@@ -393,10 +362,10 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testUnknowGetMonitorTaskById()
|
||||
{
|
||||
if (null === self::$adminToken) {
|
||||
if (null === $this->adminAccessToken) {
|
||||
$this->markTestSkipped('no tasks created for the current instance');
|
||||
}
|
||||
$this->setToken(self::$adminToken);
|
||||
$this->setToken($this->adminAccessToken);
|
||||
self::$DI['client']->followRedirects();
|
||||
self::$DI['client']->request('GET', '/api/v1/monitor/task/0/', $this->getParameters(), [], ['HTTP_Accept' => $this->getAcceptMimeType()]);
|
||||
$content = $this->unserialize(self::$DI['client']->getResponse()->getContent());
|
||||
@@ -405,17 +374,13 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testPostMonitorStartTask()
|
||||
{
|
||||
if (null === self::$adminToken) {
|
||||
$this->markTestSkipped('there is no user with admin rights');
|
||||
}
|
||||
|
||||
$tasks = self::$DI['app']['repo.tasks']->findAll();
|
||||
|
||||
if (!count($tasks)) {
|
||||
$this->markTestSkipped('no tasks created for the current instance');
|
||||
}
|
||||
|
||||
$this->setToken(self::$adminToken);
|
||||
$this->setToken($this->adminAccessToken);
|
||||
$idTask = $tasks[0]->getId();
|
||||
|
||||
$route = '/api/v1/monitor/task/' . $idTask . '/start/';
|
||||
@@ -437,15 +402,11 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
{
|
||||
$tasks = self::$DI['app']['repo.tasks']->findAll();
|
||||
|
||||
if (null === self::$adminToken) {
|
||||
$this->markTestSkipped('there is no user with admin rights');
|
||||
}
|
||||
|
||||
if (!count($tasks)) {
|
||||
$this->markTestSkipped('no tasks created for the current instance');
|
||||
}
|
||||
|
||||
$this->setToken(self::$adminToken);
|
||||
$this->setToken($this->adminAccessToken);
|
||||
$idTask = $tasks[0]->getId();
|
||||
|
||||
$route = '/api/v1/monitor/task/' . $idTask . '/stop/';
|
||||
@@ -465,12 +426,9 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testgetMonitorPhraseanet()
|
||||
{
|
||||
if (null === self::$adminToken) {
|
||||
$this->markTestSkipped('there is no user with admin rights');
|
||||
}
|
||||
self::$DI['app']['phraseanet.SE'] = $this->createSearchEngineMock();
|
||||
|
||||
$this->setToken(self::$adminToken);
|
||||
$this->setToken($this->adminAccessToken);
|
||||
|
||||
self::$DI['client']->request('GET', '/api/v1/monitor/phraseanet/', $this->getParameters(), [], ['HTTP_Accept' => $this->getAcceptMimeType()]);
|
||||
$content = $this->unserialize(self::$DI['client']->getResponse()->getContent());
|
||||
@@ -488,7 +446,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testRecordRoute()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
|
||||
$route = '/api/v1/records/' . self::$DI['record_1']->get_sbas_id() . '/' . self::$DI['record_1']->get_record_id() . '/';
|
||||
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
|
||||
@@ -510,7 +468,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testStoryRoute()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
self::$DI['app']['session']->set('usr_id', self::$DI['user']->getId());
|
||||
if (false === self::$DI['record_story_1']->hasChild(self::$DI['record_1'])) {
|
||||
self::$DI['record_story_1']->appendChild(self::$DI['record_1']);
|
||||
@@ -541,7 +499,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testDataboxCollectionRoute()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$databox_id = self::$DI['record_1']->get_sbas_id();
|
||||
$route = '/api/v1/databoxes/' . $databox_id . '/collections/';
|
||||
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
|
||||
@@ -581,7 +539,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testDataboxStatusRoute()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$databox_id = self::$DI['record_1']->get_sbas_id();
|
||||
$databox = self::$DI['app']['phraseanet.appbox']->get_databox($databox_id);
|
||||
$ref_status = $databox->get_statusbits();
|
||||
@@ -630,7 +588,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testDataboxMetadatasRoute()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$databox_id = self::$DI['record_1']->get_sbas_id();
|
||||
$databox = self::$DI['app']['phraseanet.appbox']->get_databox($databox_id);
|
||||
$ref_structure = $databox->get_meta_structure();
|
||||
@@ -713,7 +671,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testDataboxTermsOfUseRoute()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$databox_id = self::$DI['record_1']->get_sbas_id();
|
||||
$route = '/api/v1/databoxes/' . $databox_id . '/termsOfUse/';
|
||||
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
|
||||
@@ -752,7 +710,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
self::$DI['app']['manipulator.user']->expects($this->once())->method('logQuery');
|
||||
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
self::$DI['client']->request('POST', '/api/v1/search/', $this->getParameters(), [], ['HTTP_Accept' => $this->getAcceptMimeType()]);
|
||||
$content = $this->unserialize(self::$DI['client']->getResponse()->getContent());
|
||||
|
||||
@@ -785,7 +743,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
$this->markTestSkipped('Phrasea2 extension is required for this test');
|
||||
}
|
||||
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
|
||||
self::$DI['record_story_1'];
|
||||
|
||||
@@ -821,7 +779,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
$this->markTestSkipped('Phrasea2 extension is required for this test');
|
||||
}
|
||||
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
self::$DI['client']->request('POST', '/api/v1/records/search/', $this->getParameters(), [], ['HTTP_Accept' => $this->getAcceptMimeType()]);
|
||||
$content = $this->unserialize(self::$DI['client']->getResponse()->getContent());
|
||||
|
||||
@@ -843,7 +801,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
*/
|
||||
public function testRecordsSearchRouteWithQuery($method)
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$searchEngine = $this->getMockBuilder('Alchemy\Phrasea\SearchEngine\SearchEngineResult')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
@@ -872,7 +830,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testRecordsCaptionRoute()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
|
||||
self::$DI['app']['phraseanet.SE'] = $this->createSearchEngineMock();
|
||||
$this->injectMetadatas(self::$DI['record_1']);
|
||||
@@ -898,7 +856,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testRecordsMetadatasRoute()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
|
||||
$route = '/api/v1/records/' . self::$DI['record_1']->get_sbas_id() . '/' . self::$DI['record_1']->get_record_id() . '/metadatas/';
|
||||
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
|
||||
@@ -921,7 +879,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testRecordsStatusRoute()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
|
||||
$route = '/api/v1/records/' . self::$DI['record_1']->get_sbas_id() . '/' . self::$DI['record_1']->get_record_id() . '/status/';
|
||||
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
|
||||
@@ -944,7 +902,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testRecordsEmbedRoute()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
|
||||
$route = '/api/v1/records/' . self::$DI['record_1']->get_sbas_id() . '/' . self::$DI['record_1']->get_record_id() . '/embed/';
|
||||
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
|
||||
@@ -970,7 +928,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testStoriesEmbedRoute()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$story = self::$DI['record_story_1'];
|
||||
|
||||
$route = '/api/v1/stories/' . $story->get_sbas_id() . '/' . $story->get_record_id() . '/embed/';
|
||||
@@ -997,7 +955,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testRecordsEmbedRouteMimeType()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
|
||||
$route = '/api/v1/records/' . self::$DI['record_1']->get_sbas_id() . '/' . self::$DI['record_1']->get_record_id() . '/embed/';
|
||||
|
||||
@@ -1011,7 +969,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testRecordsEmbedRouteDevices()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
|
||||
$route = '/api/v1/records/' . self::$DI['record_1']->get_sbas_id() . '/' . self::$DI['record_1']->get_record_id() . '/embed/';
|
||||
|
||||
@@ -1023,7 +981,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testRecordsRelatedRoute()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
|
||||
$route = '/api/v1/records/' . self::$DI['record_1']->get_sbas_id() . '/' . self::$DI['record_1']->get_record_id() . '/related/';
|
||||
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
|
||||
@@ -1050,7 +1008,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
public function testRecordsSetMetadatas()
|
||||
{
|
||||
self::$DI['app']['phraseanet.SE'] = $this->createSearchEngineMock();
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
|
||||
$record = self::$DI['record_1'];
|
||||
|
||||
@@ -1108,7 +1066,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
public function testRecordsSetStatus()
|
||||
{
|
||||
self::$DI['app']['phraseanet.SE'] = $this->createSearchEngineMock();
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
|
||||
$route = '/api/v1/records/' . self::$DI['record_1']->get_sbas_id() . '/' . self::$DI['record_1']->get_record_id() . '/setstatus/';
|
||||
|
||||
@@ -1170,7 +1128,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
$file = new File(self::$DI['app'], self::$DI['app']['mediavorus']->guess(__DIR__ . '/../../../../../files/test001.jpg'), self::$DI['collection']);
|
||||
$record = \record_adapter::createFromFile($file, self::$DI['app']);
|
||||
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
|
||||
$route = '/api/v1/records/' . $record->get_sbas_id() . '/' . $record->get_record_id() . '/setcollection/';
|
||||
|
||||
@@ -1198,7 +1156,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testSearchBaskets()
|
||||
{
|
||||
$this->setToken(self::$adminToken);
|
||||
$this->setToken($this->adminAccessToken);
|
||||
$route = '/api/v1/baskets/list/';
|
||||
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
|
||||
|
||||
@@ -1216,7 +1174,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testAddBasket()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
|
||||
$route = '/api/v1/baskets/add/';
|
||||
|
||||
@@ -1236,7 +1194,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testBasketContent()
|
||||
{
|
||||
$this->setToken(self::$adminToken);
|
||||
$this->setToken($this->adminAccessToken);
|
||||
|
||||
$basketElement = self::$DI['app']['EM']->find('Phraseanet:BasketElement', 1);
|
||||
$basket = $basketElement->getBasket();
|
||||
@@ -1271,7 +1229,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testSetBasketTitle()
|
||||
{
|
||||
$this->setToken(self::$adminToken);
|
||||
$this->setToken($this->adminAccessToken);
|
||||
|
||||
$basket = self::$DI['app']['EM']->find('Phraseanet:Basket', 1);
|
||||
|
||||
@@ -1319,7 +1277,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testSetBasketDescription()
|
||||
{
|
||||
$this->setToken(self::$adminToken);
|
||||
$this->setToken($this->adminAccessToken);
|
||||
|
||||
$basket = self::$DI['app']['EM']->find('Phraseanet:Basket', 1);
|
||||
|
||||
@@ -1342,7 +1300,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testDeleteBasket()
|
||||
{
|
||||
$this->setToken(self::$adminToken);
|
||||
$this->setToken($this->adminAccessToken);
|
||||
$route = '/api/v1/baskets/1/delete/';
|
||||
$this->evaluateMethodNotAllowedRoute($route, ['GET', 'PUT', 'DELETE']);
|
||||
|
||||
@@ -1368,7 +1326,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
public function testAddRecord()
|
||||
{
|
||||
self::$DI['app']['phraseanet.SE'] = $this->createSearchEngineMock();
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$route = '/api/v1/records/add/';
|
||||
|
||||
$params = $this->getAddRecordParameters();
|
||||
@@ -1388,7 +1346,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
public function testAddRecordForceRecord()
|
||||
{
|
||||
self::$DI['app']['phraseanet.SE'] = $this->createSearchEngineMock();
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$route = '/api/v1/records/add/';
|
||||
|
||||
$params = $this->getAddRecordParameters();
|
||||
@@ -1413,7 +1371,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testAddRecordForceLazaret()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$route = '/api/v1/records/add/';
|
||||
|
||||
$params = $this->getAddRecordParameters();
|
||||
@@ -1437,7 +1395,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testAddRecordWrongBehavior()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$route = '/api/v1/records/add/';
|
||||
|
||||
$params = $this->getAddRecordParameters();
|
||||
@@ -1452,7 +1410,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testAddRecordWrongBaseId()
|
||||
{
|
||||
$this->setToken(self::$adminToken);
|
||||
$this->setToken($this->adminAccessToken);
|
||||
$route = '/api/v1/records/add/';
|
||||
|
||||
$params = $this->getAddRecordParameters();
|
||||
@@ -1467,7 +1425,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testAddRecordNoBaseId()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$route = '/api/v1/records/add/';
|
||||
|
||||
$params = $this->getAddRecordParameters();
|
||||
@@ -1482,7 +1440,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testAddRecordMultipleFiles()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$route = '/api/v1/records/add/';
|
||||
|
||||
$file = [
|
||||
@@ -1499,7 +1457,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testAddRecordNofile()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$route = '/api/v1/records/add/';
|
||||
|
||||
self::$DI['client']->request('POST', $route, $this->getParameters($this->getAddRecordParameters()), [], ['HTTP_Accept' => $this->getAcceptMimeType()]);
|
||||
@@ -1513,7 +1471,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
{
|
||||
$created_feed = self::$DI['app']['EM']->find('Phraseanet:Feed', 1);
|
||||
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$route = '/api/v1/feeds/list/';
|
||||
|
||||
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
|
||||
@@ -1564,7 +1522,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
self::$DI['app']['EM']->persist($created_entry);
|
||||
self::$DI['app']['EM']->flush();
|
||||
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$route = '/api/v1/feeds/content/';
|
||||
|
||||
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
|
||||
@@ -1609,7 +1567,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
$feed = self::$DI['app']['EM']->find('Phraseanet:Feed', 1);
|
||||
$created_entry = $feed->getEntries()->first();
|
||||
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$route = '/api/v1/feeds/entry/' . $created_entry->getId() . '/';
|
||||
|
||||
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
|
||||
@@ -1638,7 +1596,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
$created_feed->setCollection(self::$DI['collection_no_access']);
|
||||
|
||||
$this->setToken(self::$adminToken);
|
||||
$this->setToken($this->adminAccessToken);
|
||||
$route = '/api/v1/feeds/entry/' . $created_entry->getId() . '/';
|
||||
|
||||
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
|
||||
@@ -1666,7 +1624,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
self::$DI['app']['EM']->persist($created_entry);
|
||||
self::$DI['app']['EM']->flush();
|
||||
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$route = '/api/v1/feeds/' . $created_feed->getId() . '/content/';
|
||||
|
||||
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
|
||||
@@ -1702,7 +1660,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testQuarantineList()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
$route = '/api/v1/quarantine/list/';
|
||||
|
||||
$quarantineItemId = self::$DI['lazaret_1']->getId();
|
||||
@@ -1733,7 +1691,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testQuarantineContent()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
|
||||
$quarantineItemId = self::$DI['lazaret_1']->getId();
|
||||
$route = '/api/v1/quarantine/item/' . $quarantineItemId . '/';
|
||||
@@ -1778,7 +1736,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
|
||||
|
||||
public function testRouteMe()
|
||||
{
|
||||
$this->setToken(self::$token);
|
||||
$this->setToken($this->userAccessToken);
|
||||
|
||||
$route = '/api/v1/me/';
|
||||
|
||||
|
@@ -4,21 +4,10 @@ namespace Alchemy\Tests\Phrasea\Controller\Api;
|
||||
|
||||
use Alchemy\Phrasea\Core\PhraseaEvents;
|
||||
use Alchemy\Phrasea\Authentication\Context;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
|
||||
/**
|
||||
* Test oauthv2 flow based on ietf authv2 spec
|
||||
* @link http://tools.ietf.org/html/draft-ietf-oauth-v2-18
|
||||
*/
|
||||
class OAuth2Test extends \PhraseanetAuthenticatedWebTestCase
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var API_OAuth2_Application
|
||||
*/
|
||||
public static $account_id;
|
||||
public static $account;
|
||||
public $oauth;
|
||||
protected $client;
|
||||
protected $queryParameters;
|
||||
|
||||
public function setUp()
|
||||
@@ -31,48 +20,23 @@ class OAuth2Test extends \PhraseanetAuthenticatedWebTestCase
|
||||
|
||||
$this->queryParameters = [
|
||||
"response_type" => "code",
|
||||
"client_id" => self::$DI['oauth2-app-user']->get_client_id(),
|
||||
"redirect_uri" => self::$DI['oauth2-app-user']->get_redirect_uri(),
|
||||
"client_id" => self::$DI['oauth2-app-user']->getClientId(),
|
||||
"redirect_uri" => self::$DI['oauth2-app-user']->getRedirectUri(),
|
||||
"scope" => "",
|
||||
"state" => "valueTest"
|
||||
];
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass()
|
||||
{
|
||||
self::$account_id = self::$account = null;
|
||||
parent::tearDownAfterClass();
|
||||
}
|
||||
|
||||
public static function deleteInsertedRow(\appbox $appbox, \API_OAuth2_Application $app)
|
||||
{
|
||||
$conn = $appbox->get_connection();
|
||||
$sql = '
|
||||
DELETE FROM api_applications
|
||||
WHERE application_id = :id
|
||||
';
|
||||
$t = [':id' => $app->get_id()];
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->execute($t);
|
||||
$stmt->closeCursor();
|
||||
$sql = '
|
||||
DELETE FROM api_accounts
|
||||
WHERE api_account_id = :id
|
||||
';
|
||||
$acc = self::getAccount();
|
||||
$t = [':id' => $acc->get_id()];
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->execute($t);
|
||||
$stmt->closeCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideEventNames
|
||||
*/
|
||||
public function testThatEventsAreTriggered($revoked, $method, $eventName, $className)
|
||||
{
|
||||
$acc = self::getAccount();
|
||||
$acc->set_revoked($revoked); // revoked to show form
|
||||
if ($revoked) {
|
||||
self::$DI['app']['manipulator.api-account']->revokeAccess(self::$DI['oauth2-app-acc-user']);
|
||||
} else {
|
||||
self::$DI['app']['manipulator.api-account']->authorizeAccess(self::$DI['oauth2-app-acc-user']);
|
||||
}
|
||||
|
||||
$preEvent = 0;
|
||||
self::$DI['app']['dispatcher']->addListener($eventName, function ($event) use (&$preEvent, $className) {
|
||||
@@ -96,32 +60,6 @@ class OAuth2Test extends \PhraseanetAuthenticatedWebTestCase
|
||||
];
|
||||
}
|
||||
|
||||
public static function getApp($rowId)
|
||||
{
|
||||
$sql = "SELECT * FROM api_applications WHERE application_id = :app_id";
|
||||
$t = [":app_id" => $rowId];
|
||||
$conn = self::$DI['app']['phraseanet.appbox']->get_connection();
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->execute($t);
|
||||
$result = $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function getAccount()
|
||||
{
|
||||
$sql = "SELECT api_account_id FROM api_accounts WHERE application_id = :app_id AND usr_id = :usr_id";
|
||||
$t = [":app_id" => self::$DI['oauth2-app-user']->get_id(), ":usr_id" => self::$DI['user']->getId()];
|
||||
$conn = self::$DI['app']['phraseanet.appbox']->get_connection();
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->execute($t);
|
||||
$row = $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
return new \API_OAuth2_Account(self::$DI['app'], $row["api_account_id"]);
|
||||
}
|
||||
|
||||
public function setQueryParameters($parameter, $value)
|
||||
{
|
||||
$this->queryParameters[$parameter] = $value;
|
||||
@@ -129,18 +67,17 @@ class OAuth2Test extends \PhraseanetAuthenticatedWebTestCase
|
||||
|
||||
public function unsetQueryParameter($parameter)
|
||||
{
|
||||
if (isset($this->queryParameters[$parameter]))
|
||||
if (isset($this->queryParameters[$parameter])) {
|
||||
unset($this->queryParameters[$parameter]);
|
||||
}
|
||||
}
|
||||
|
||||
public function testAuthorizeRedirect()
|
||||
{
|
||||
//session off
|
||||
$apps = \API_OAuth2_Application::load_authorized_app_by_user(self::$DI['app'], self::$DI['user']);
|
||||
$apps = self::$DI['app']['repo.api-applications']->findAuthorizedAppsByUser(self::$DI['user']);
|
||||
foreach ($apps as $app) {
|
||||
if ($app->get_client_id() == self::$DI['oauth2-app-user']->get_client_id()) {
|
||||
$authorize = true;
|
||||
|
||||
if ($app->getClientId() === self::$DI['oauth2-app-user']->getClientId()) {
|
||||
self::$DI['client']->followRedirects();
|
||||
}
|
||||
}
|
||||
@@ -148,13 +85,11 @@ class OAuth2Test extends \PhraseanetAuthenticatedWebTestCase
|
||||
|
||||
public function testAuthorize()
|
||||
{
|
||||
$acc = self::getAccount();
|
||||
$acc->set_revoked(true); // revoked to show form
|
||||
|
||||
self::$DI['app']['manipulator.api-account']->revokeAccess(self::$DI['oauth2-app-acc-user']);
|
||||
self::$DI['client']->request('GET', '/api/oauthv2/authorize', $this->queryParameters);
|
||||
$this->assertTrue(self::$DI['client']->getResponse()->isSuccessful());
|
||||
$this->assertRegExp("/" . self::$DI['oauth2-app-user']->get_client_id() . "/", self::$DI['client']->getResponse()->getContent());
|
||||
$this->assertRegExp("/" . str_replace("/", '\/', self::$DI['oauth2-app-user']->get_redirect_uri()) . "/", self::$DI['client']->getResponse()->getContent());
|
||||
$this->assertRegExp("/" . self::$DI['oauth2-app-user']->getCLientId() . "/", self::$DI['client']->getResponse()->getContent());
|
||||
$this->assertRegExp("/" . str_replace("/", '\/', self::$DI['oauth2-app-user']->getRedirectUri()) . "/", self::$DI['client']->getResponse()->getContent());
|
||||
$this->assertRegExp("/" . $this->queryParameters["response_type"] . "/", self::$DI['client']->getResponse()->getContent());
|
||||
$this->assertRegExp("/" . $this->queryParameters["scope"] . "/", self::$DI['client']->getResponse()->getContent());
|
||||
$this->assertRegExp("/" . $this->queryParameters["state"] . "/", self::$DI['client']->getResponse()->getContent());
|
||||
@@ -165,7 +100,6 @@ class OAuth2Test extends \PhraseanetAuthenticatedWebTestCase
|
||||
$this->setQueryParameters('grant_type', 'authorization_code');
|
||||
$this->setQueryParameters('code', '12345678918');
|
||||
self::$DI['client']->request('POST', '/api/oauthv2/token', $this->queryParameters);
|
||||
|
||||
$this->assertEquals(400, self::$DI['client']->getResponse()->getStatusCode());
|
||||
}
|
||||
}
|
||||
|
@@ -355,7 +355,6 @@ class AccountTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
public function testAUthorizedAppGrantAccessBadRequest()
|
||||
{
|
||||
self::$DI['client']->request('GET', '/account/security/application/3/grant/');
|
||||
|
||||
$this->assertBadResponse(self::$DI['client']->getResponse());
|
||||
}
|
||||
|
||||
@@ -376,7 +375,7 @@ class AccountTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
*/
|
||||
public function testAUthorizedAppGrantAccessSuccessfull($revoke, $expected)
|
||||
{
|
||||
self::$DI['client']->request('GET', '/account/security/application/' . self::$DI['oauth2-app-user']->get_id() . '/grant/', [
|
||||
self::$DI['client']->request('GET', '/account/security/application/' . self::$DI['oauth2-app-user']->getId() . '/grant/', [
|
||||
'revoke' => $revoke
|
||||
], [], [
|
||||
'HTTP_ACCEPT' => 'application/json',
|
||||
@@ -384,20 +383,15 @@ class AccountTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
]);
|
||||
|
||||
$response = self::$DI['client']->getResponse();
|
||||
|
||||
$this->assertTrue($response->isOk());
|
||||
$json = json_decode($response->getContent());
|
||||
$this->assertInstanceOf('StdClass', $json);
|
||||
$this->assertObjectHasAttribute('success', $json);
|
||||
$this->assertTrue($json->success);
|
||||
|
||||
$account = \API_OAuth2_Account::load_with_user(
|
||||
self::$DI['app']
|
||||
, self::$DI['oauth2-app-user']
|
||||
, self::$DI['user']
|
||||
);
|
||||
$account = self::$DI['app']['repo.api-accounts']->findByUserAndApplication(self::$DI['user'], self::$DI['oauth2-app-user']);
|
||||
|
||||
$this->assertEquals($expected, $account->is_revoked());
|
||||
$this->assertEquals($expected, $account->isRevoked());
|
||||
}
|
||||
|
||||
public function revokeProvider()
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Alchemy\Tests\Phrasea\Controller\Root;
|
||||
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
class DevelopersTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
@@ -34,7 +35,7 @@ class DevelopersTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
public function testPostNewAppInvalidArguments()
|
||||
{
|
||||
$crawler = self::$DI['client']->request('POST', '/developers/application/', [
|
||||
'type' => \API_OAuth2_Application::WEB_TYPE,
|
||||
'type' => ApiApplication::WEB_TYPE,
|
||||
'name' => '',
|
||||
'description' => 'okok',
|
||||
'website' => 'my.website.com',
|
||||
@@ -55,11 +56,11 @@ class DevelopersTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
*/
|
||||
public function testPostNewApp()
|
||||
{
|
||||
$apps = \API_OAuth2_Application::load_dev_app_by_user(self::$DI['app'], self::$DI['user']);
|
||||
$apps = self::$DI['app']['repo.api-applications']->findByCreator(self::$DI['user']);
|
||||
$nbApp = count($apps);
|
||||
|
||||
self::$DI['client']->request('POST', '/developers/application/', [
|
||||
'type' => \API_OAuth2_Application::WEB_TYPE,
|
||||
'type' => ApiApplication::WEB_TYPE,
|
||||
'name' => 'hello',
|
||||
'description' => 'okok',
|
||||
'website' => 'my.website.com',
|
||||
@@ -68,7 +69,7 @@ class DevelopersTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
'scheme-callback' => 'http://'
|
||||
]);
|
||||
|
||||
$apps = \API_OAuth2_Application::load_dev_app_by_user(self::$DI['app'], self::$DI['user']);
|
||||
$apps = self::$DI['app']['repo.api-applications']->findByCreator(self::$DI['user']);
|
||||
|
||||
$this->assertTrue(self::$DI['client']->getResponse()->isRedirect());
|
||||
$this->assertGreaterThan($nbApp, count($apps));
|
||||
@@ -77,7 +78,7 @@ class DevelopersTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
/**
|
||||
* @cover \Alchemy\Phrasea\Controller\Root\Developers::getApp
|
||||
*/
|
||||
public function testGetUnknowApp()
|
||||
public function testGetUnknownApp()
|
||||
{
|
||||
self::$DI['client']->request('GET', '/developers/application/0/');
|
||||
|
||||
@@ -90,7 +91,7 @@ class DevelopersTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
public function testGetApp()
|
||||
{
|
||||
$oauthApp = self::$DI['oauth2-app-user'];
|
||||
self::$DI['client']->request('GET', '/developers/application/' . $oauthApp->get_id() . '/');
|
||||
self::$DI['client']->request('GET', '/developers/application/' . $oauthApp->getId() . '/');
|
||||
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
|
||||
}
|
||||
|
||||
@@ -121,16 +122,17 @@ class DevelopersTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
*/
|
||||
public function testDeleteApp()
|
||||
{
|
||||
$oauthApp = \API_OAuth2_Application::create(self::$DI['app'], self::$DI['user'], 'test app');
|
||||
$this->XMLHTTPRequest('DELETE', '/developers/application/' . $oauthApp->get_id() . '/');
|
||||
$oauthApp = self::$DI['app']['manipulator.api-application']->create(
|
||||
'test app',
|
||||
ApiApplication::DESKTOP_TYPE,
|
||||
'',
|
||||
'http://phraseanet.com/'
|
||||
);
|
||||
$id = $oauthApp->getId();
|
||||
$this->XMLHTTPRequest('DELETE', '/developers/application/' . $id . '/');
|
||||
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
|
||||
|
||||
try {
|
||||
new \API_OAuth2_Application(self::$DI['app'], $oauthApp->get_id());
|
||||
$this->fail('Application not deleted');
|
||||
} catch (NotFoundHttpException $e) {
|
||||
|
||||
}
|
||||
$this->assertNull(self::$DI['app']['repo.api-applications']->find($id));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,7 +165,7 @@ class DevelopersTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
public function testRenewAppCallbackError2()
|
||||
{
|
||||
$oauthApp = self::$DI['oauth2-app-user'];
|
||||
$this->XMLHTTPRequest('POST', '/developers/application/'.$oauthApp->get_id().'/callback/');
|
||||
$this->XMLHTTPRequest('POST', '/developers/application/'.$oauthApp->getId().'/callback/');
|
||||
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
|
||||
$content = json_decode(self::$DI['client']->getResponse()->getContent());
|
||||
$this->assertFalse($content->success);
|
||||
@@ -176,15 +178,15 @@ class DevelopersTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
{
|
||||
$oauthApp = self::$DI['oauth2-app-user'];
|
||||
|
||||
$this->XMLHTTPRequest('POST', '/developers/application/' . $oauthApp->get_id() . '/callback/', [
|
||||
'callback' => 'my.callback.com'
|
||||
]);
|
||||
$this->XMLHTTPRequest('POST', '/developers/application/' . $oauthApp->getId() . '/callback/', [
|
||||
'callback' => 'http://my.callback.com'
|
||||
]);
|
||||
|
||||
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
|
||||
$content = json_decode(self::$DI['client']->getResponse()->getContent());
|
||||
$this->assertTrue($content->success);
|
||||
$oauthApp = new \API_OAuth2_Application(self::$DI['app'], $oauthApp->get_id());
|
||||
$this->assertEquals('my.callback.com', $oauthApp->get_redirect_uri());
|
||||
$oauthApp = self::$DI['app']['repo.api-applications']->find($oauthApp->getId());
|
||||
$this->assertEquals('http://my.callback.com', $oauthApp->getRedirectUri());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,12 +206,11 @@ class DevelopersTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
{
|
||||
$this->XMLHTTPRequest('POST', '/developers/application/0/access_token/', [
|
||||
'callback' => 'my.callback.com'
|
||||
]);
|
||||
]);
|
||||
|
||||
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
|
||||
$content = json_decode(self::$DI['client']->getResponse()->getContent());
|
||||
$this->assertFalse($content->success);
|
||||
$this->assertNull($content->token);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -219,7 +220,7 @@ class DevelopersTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
{
|
||||
$oauthApp = self::$DI['oauth2-app-user'];
|
||||
|
||||
$this->XMLHTTPRequest('POST', '/developers/application/' . $oauthApp->get_id() . '/access_token/');
|
||||
$this->XMLHTTPRequest('POST', '/developers/application/' . $oauthApp->getId() . '/access_token/');
|
||||
|
||||
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
|
||||
$content = json_decode(self::$DI['client']->getResponse()->getContent());
|
||||
@@ -258,14 +259,14 @@ class DevelopersTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
{
|
||||
$oauthApp = self::$DI['oauth2-app-user'];
|
||||
|
||||
$this->XMLHTTPRequest('POST', '/developers/application/' . $oauthApp->get_id() . '/authorize_grant_password/', [
|
||||
$this->XMLHTTPRequest('POST', '/developers/application/' . $oauthApp->getId() . '/authorize_grant_password/', [
|
||||
'grant' => '1'
|
||||
]);
|
||||
|
||||
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
|
||||
$content = json_decode(self::$DI['client']->getResponse()->getContent());
|
||||
$this->assertTrue($content->success);
|
||||
$oauthApp = new \API_OAuth2_Application(self::$DI['app'], $oauthApp->get_id());
|
||||
$this->assertTrue($oauthApp->is_password_granted());
|
||||
$oauthApp = self::$DI['app']['repo.api-applications']->find($oauthApp->getId());
|
||||
$this->assertTrue($oauthApp->isPasswordGranted());
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Alchemy\Tests\Phrasea\Core\Provider;
|
||||
|
||||
class ConvertersServiceProvider extends ServiceProviderTestCase
|
||||
class ConvertersServiceProviderTest extends ServiceProviderTestCase
|
||||
{
|
||||
public function provideServiceDescription()
|
||||
{
|
||||
@@ -10,17 +10,22 @@ class ConvertersServiceProvider extends ServiceProviderTestCase
|
||||
[
|
||||
'Alchemy\Phrasea\Core\Provider\ConvertersServiceProvider',
|
||||
'converter.task',
|
||||
'Alchemy\Phrasea\Controller\Converter\TaskConverter'
|
||||
'Alchemy\Phrasea\Model\Converter\TaskConverter'
|
||||
],
|
||||
[
|
||||
'Alchemy\Phrasea\Core\Provider\ConvertersServiceProvider',
|
||||
'converter.basket',
|
||||
'Alchemy\Phrasea\Controller\Converter\BasketConverter'
|
||||
'Alchemy\Phrasea\Model\Converter\BasketConverter'
|
||||
],
|
||||
[
|
||||
'Alchemy\Phrasea\Core\Provider\ConvertersServiceProvider',
|
||||
'converter.token',
|
||||
'Alchemy\Phrasea\Controller\Converter\TokenConverter'
|
||||
'Alchemy\Phrasea\Model\Converter\TokenConverter'
|
||||
],
|
||||
[
|
||||
'Alchemy\Phrasea\Core\Provider\ConvertersServiceProvider',
|
||||
'converter.api-application',
|
||||
'Alchemy\Phrasea\Model\Converter\ApiApplicationConverter'
|
||||
],
|
||||
];
|
||||
}
|
@@ -27,6 +27,36 @@ class ManipulatorServiceProviderTest extends ServiceProviderTestCase
|
||||
'manipulator.token',
|
||||
'Alchemy\Phrasea\Model\Manipulator\TokenManipulator'
|
||||
],
|
||||
[
|
||||
'Alchemy\Phrasea\Core\Provider\ManipulatorServiceProvider',
|
||||
'manipulator.api-application',
|
||||
'Alchemy\Phrasea\Model\Manipulator\ApiApplicationManipulator'
|
||||
],
|
||||
[
|
||||
'Alchemy\Phrasea\Core\Provider\ManipulatorServiceProvider',
|
||||
'manipulator.api-account',
|
||||
'Alchemy\Phrasea\Model\Manipulator\ApiAccountManipulator'
|
||||
],
|
||||
[
|
||||
'Alchemy\Phrasea\Core\Provider\ManipulatorServiceProvider',
|
||||
'manipulator.api-log',
|
||||
'Alchemy\Phrasea\Model\Manipulator\ApiLogManipulator'
|
||||
],
|
||||
[
|
||||
'Alchemy\Phrasea\Core\Provider\ManipulatorServiceProvider',
|
||||
'manipulator.api-oauth-token',
|
||||
'Alchemy\Phrasea\Model\Manipulator\ApiOauthTokenManipulator'
|
||||
],
|
||||
[
|
||||
'Alchemy\Phrasea\Core\Provider\ManipulatorServiceProvider',
|
||||
'manipulator.api-oauth-code',
|
||||
'Alchemy\Phrasea\Model\Manipulator\ApiOauthCodeManipulator'
|
||||
],
|
||||
[
|
||||
'Alchemy\Phrasea\Core\Provider\ManipulatorServiceProvider',
|
||||
'manipulator.api-oauth-refresh-token',
|
||||
'Alchemy\Phrasea\Model\Manipulator\ApiOauthRefreshTokenManipulator'
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -33,6 +33,12 @@ class RepositoriesServiceProviderTest extends ServiceProviderTestCase
|
||||
['Alchemy\Phrasea\Core\Provider\RepositoriesServiceProvider', 'repo.user-queries', 'Alchemy\Phrasea\Model\Repositories\UserQueryRepository'],
|
||||
['Alchemy\Phrasea\Core\Provider\RepositoriesServiceProvider', 'repo.tokens', 'Alchemy\Phrasea\Model\Repositories\TokenRepository'],
|
||||
['Alchemy\Phrasea\Core\Provider\RepositoriesServiceProvider', 'repo.presets', 'Alchemy\Phrasea\Model\Repositories\PresetRepository'],
|
||||
['Alchemy\Phrasea\Core\Provider\RepositoriesServiceProvider', 'repo.api-applications', 'Alchemy\Phrasea\Model\Repositories\ApiApplicationRepository'],
|
||||
['Alchemy\Phrasea\Core\Provider\RepositoriesServiceProvider', 'repo.api-accounts', 'Alchemy\Phrasea\Model\Repositories\ApiAccountRepository'],
|
||||
['Alchemy\Phrasea\Core\Provider\RepositoriesServiceProvider', 'repo.api-logs', 'Alchemy\Phrasea\Model\Repositories\ApiLogRepository'],
|
||||
['Alchemy\Phrasea\Core\Provider\RepositoriesServiceProvider', 'repo.api-oauth-tokens', 'Alchemy\Phrasea\Model\Repositories\ApiOauthTokenRepository'],
|
||||
['Alchemy\Phrasea\Core\Provider\RepositoriesServiceProvider', 'repo.api-oauth-codes', 'Alchemy\Phrasea\Model\Repositories\ApiOauthCodeRepository'],
|
||||
['Alchemy\Phrasea\Core\Provider\RepositoriesServiceProvider', 'repo.api-oauth-refresh-tokens', 'Alchemy\Phrasea\Model\Repositories\ApiOauthRefreshTokenRepository'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Tests\Phrasea\Model\Manipulator;
|
||||
|
||||
use Alchemy\Phrasea\Controller\Api\V1;
|
||||
use Alchemy\Phrasea\Model\Manipulator\ApiAccountManipulator;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
|
||||
class ApiAccountManipulatorTest extends \PhraseanetTestCase
|
||||
{
|
||||
public function testCreate()
|
||||
{
|
||||
$manipulator = new ApiAccountManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-accounts']);
|
||||
$nbApps = count(self::$DI['app']['repo.api-accounts']->findAll());
|
||||
$account = $manipulator->create(self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$this->assertGreaterThan($nbApps, count(self::$DI['app']['repo.api-accounts']->findAll()));
|
||||
$this->assertFalse($account->isRevoked());
|
||||
$this->assertEquals(V1::VERSION, $account->getApiVersion());
|
||||
$this->assertGreaterThan($nbApps, count(self::$DI['app']['repo.api-accounts']->findAll()));
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$manipulator = new ApiAccountManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-accounts']);
|
||||
$account = $manipulator->create(self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$accountMem = clone $account;
|
||||
$countBefore = count(self::$DI['app']['repo.api-accounts']->findAll());
|
||||
self::$DI['app']['manipulator.api-oauth-token']->create($account);
|
||||
$manipulator->delete($account);
|
||||
$this->assertGreaterThan(count(self::$DI['app']['repo.api-accounts']->findAll()), $countBefore);
|
||||
$tokens = self::$DI['app']['repo.api-oauth-tokens']->findOauthTokens($accountMem);
|
||||
$this->assertEquals(0, count($tokens));
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
$manipulator = new ApiAccountManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-accounts']);
|
||||
$account = $manipulator->create(self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$account->setApiVersion(24);
|
||||
$manipulator->update($account);
|
||||
$account = self::$DI['app']['repo.api-accounts']->find($account->getId());
|
||||
$this->assertEquals(24, $account->getApiVersion());
|
||||
}
|
||||
|
||||
public function testAuthorizeAccess()
|
||||
{
|
||||
$manipulator = new ApiAccountManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-accounts']);
|
||||
$account = $manipulator->create(self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$manipulator->authorizeAccess($account);
|
||||
$this->assertFalse($account->isRevoked());
|
||||
}
|
||||
|
||||
public function testRevokeAccess()
|
||||
{
|
||||
$manipulator = new ApiAccountManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-accounts']);
|
||||
$account = $manipulator->create(self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$manipulator->revokeAccess($account);
|
||||
$this->assertTrue($account->isRevoked());
|
||||
}
|
||||
}
|
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Tests\Phrasea\Model\Manipulator;
|
||||
|
||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
||||
use Alchemy\Phrasea\Model\Manipulator\ApiApplicationManipulator;
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
|
||||
class ApiApplicationManipulatorTest extends \PhraseanetTestCase
|
||||
{
|
||||
public function testCreateDesktopApplication()
|
||||
{
|
||||
$manipulator = new ApiApplicationManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-applications'], self::$DI['app']['random.medium']);
|
||||
$nbApps = count(self::$DI['app']['repo.api-applications']->findAll());
|
||||
$application = $manipulator->create(
|
||||
'desktop-app',
|
||||
ApiApplication::DESKTOP_TYPE,
|
||||
'Desktop application description',
|
||||
'http://desktop-app-url.net'
|
||||
);
|
||||
$this->assertGreaterThan($nbApps, count(self::$DI['app']['repo.api-applications']->findAll()));
|
||||
$this->assertNotNull($application->getClientId());
|
||||
$this->assertNotNull($application->getClientSecret());
|
||||
$this->assertNotNull($application->getNonce());
|
||||
$this->assertEquals('desktop-app', $application->getName());
|
||||
$this->assertEquals(ApiApplication::DESKTOP_TYPE, $application->getType());
|
||||
$this->assertEquals('http://desktop-app-url.net', $application->getWebsite());
|
||||
$this->assertEquals(ApiApplication::NATIVE_APP_REDIRECT_URI, $application->getRedirectUri());
|
||||
}
|
||||
|
||||
public function testCreateWebApplication()
|
||||
{
|
||||
$manipulator = new ApiApplicationManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-applications'], self::$DI['app']['random.medium']);
|
||||
$nbApps = count(self::$DI['app']['repo.api-applications']->findAll());
|
||||
$application = $manipulator->create(
|
||||
'web-app',
|
||||
ApiApplication::WEB_TYPE,
|
||||
'Desktop application description',
|
||||
'http://web-app-url.net',
|
||||
self::$DI['user'],
|
||||
'http://web-app-url.net/callback'
|
||||
);
|
||||
|
||||
$this->assertGreaterThan($nbApps, count(self::$DI['app']['repo.api-applications']->findAll()));
|
||||
$this->assertNotNull($application->getClientId());
|
||||
$this->assertNotNull($application->getClientSecret());
|
||||
$this->assertNotNull($application->getNonce());
|
||||
$this->assertEquals('web-app', $application->getName());
|
||||
$this->assertEquals(ApiApplication::WEB_TYPE, $application->getType());
|
||||
$this->assertEquals('http://web-app-url.net', $application->getWebsite());
|
||||
$this->assertEquals('http://web-app-url.net/callback', $application->getRedirectUri());
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$manipulator = new ApiApplicationManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-applications'], self::$DI['app']['random.medium']);
|
||||
$application = $manipulator->create(
|
||||
'desktop-app',
|
||||
ApiApplication::DESKTOP_TYPE,
|
||||
'Desktop application description',
|
||||
'http://desktop-app-url.net'
|
||||
);
|
||||
$applicationSave = clone $application;
|
||||
$countBefore = count(self::$DI['app']['repo.api-applications']->findAll());
|
||||
$account = self::$DI['app']['manipulator.api-account']->create($application, self::$DI['user']);
|
||||
$accountMem = clone $account;
|
||||
self::$DI['app']['manipulator.api-oauth-token']->create($account);
|
||||
$manipulator->delete($application);
|
||||
$this->assertGreaterThan(count(self::$DI['app']['repo.api-applications']->findAll()), $countBefore);
|
||||
$accounts = self::$DI['app']['repo.api-accounts']->findByUserAndApplication(self::$DI['user'], $applicationSave);
|
||||
$this->assertEquals(0, count($accounts));
|
||||
$tokens = self::$DI['app']['repo.api-oauth-tokens']->findOauthTokens($accountMem);
|
||||
$this->assertEquals(0, count($tokens));
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
$manipulator = new ApiApplicationManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-applications'], self::$DI['app']['random.medium']);
|
||||
$application = $manipulator->create(
|
||||
'desktop-app',
|
||||
ApiApplication::DESKTOP_TYPE,
|
||||
'Desktop application description',
|
||||
'http://desktop-app-url.net'
|
||||
);
|
||||
$application->setName('new-desktop-app');
|
||||
$manipulator->update($application);
|
||||
$application = self::$DI['app']['repo.api-applications']->find($application->getId());
|
||||
$this->assertEquals('new-desktop-app', $application->getName());
|
||||
}
|
||||
|
||||
public function testSetType()
|
||||
{
|
||||
$manipulator = new ApiApplicationManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-applications'], self::$DI['app']['random.medium']);
|
||||
$application = $manipulator->create(
|
||||
'desktop-app',
|
||||
ApiApplication::DESKTOP_TYPE,
|
||||
'Desktop application description',
|
||||
'http://desktop-app-url.net'
|
||||
);
|
||||
try {
|
||||
$manipulator->setType($application, 'invalid-type');
|
||||
$this->fail('Invalid argument exception should be raised');
|
||||
} catch (InvalidArgumentException $e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function testSetRedirectUri()
|
||||
{
|
||||
$manipulator = new ApiApplicationManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-applications'], self::$DI['app']['random.medium']);
|
||||
$application = $manipulator->create(
|
||||
'desktop-app',
|
||||
ApiApplication::DESKTOP_TYPE,
|
||||
'Desktop application description',
|
||||
'http://desktop-app-url.net'
|
||||
);
|
||||
|
||||
$manipulator->setRedirectUri($application, 'invalid-url.com');
|
||||
$this->assertEquals(ApiApplication::NATIVE_APP_REDIRECT_URI, $application->getRedirectUri());
|
||||
|
||||
$application = $manipulator->create(
|
||||
'web-app',
|
||||
ApiApplication::WEB_TYPE,
|
||||
'Desktop application description',
|
||||
'http://web-app-url.net',
|
||||
self::$DI['user'],
|
||||
'http://web-app-url.net/callback'
|
||||
);
|
||||
try {
|
||||
$manipulator->setWebsiteUrl($application, 'invalid-url.com');
|
||||
$this->fail('Invalid argument exception should be raised');
|
||||
} catch (InvalidArgumentException $e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function testSetWebsiteUrl()
|
||||
{
|
||||
$manipulator = new ApiApplicationManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-applications'], self::$DI['app']['random.medium']);
|
||||
$application = $manipulator->create(
|
||||
'desktop-app',
|
||||
ApiApplication::DESKTOP_TYPE,
|
||||
'Desktop application description',
|
||||
'http://desktop-app-url.net'
|
||||
);
|
||||
try {
|
||||
$manipulator->setWebsiteUrl($application, 'invalid-url.com');
|
||||
$this->fail('Invalid argument exception should be raised');
|
||||
} catch (InvalidArgumentException $e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Tests\Phrasea\Model\Manipulator;
|
||||
|
||||
use Alchemy\Phrasea\Model\Manipulator\ApiLogManipulator;
|
||||
use Alchemy\Phrasea\Model\Manipulator\ApiAccountManipulator;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class ApiLogManipulatorTest extends \PhraseanetTestCase
|
||||
{
|
||||
public function testCreate()
|
||||
{
|
||||
$manipulator = new ApiAccountManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-accounts']);
|
||||
$account = $manipulator->create(self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$nbLogs = count(self::$DI['app']['repo.api-logs']->findAll());
|
||||
$manipulator = new ApiLogManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-logs']);
|
||||
$manipulator->create($account, Request::create('/databoxes/list/', 'POST'), new Response());
|
||||
$this->assertGreaterThan($nbLogs, count(self::$DI['app']['repo.api-accounts']->findAll()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider apiRouteProvider
|
||||
*/
|
||||
public function testsLogHydration($path, $expected)
|
||||
{
|
||||
$emMock = $this->getMock('\Doctrine\ORM\EntityManager', array('persist', 'flush'), array(), '', false);
|
||||
$account = $this->getMock('\Alchemy\Phrasea\Model\Entities\ApiAccount');
|
||||
$manipulator = new ApiLogManipulator($emMock, self::$DI['app']['repo.api-logs']);
|
||||
$log = $manipulator->create($account, Request::create($path, 'POST'), new Response());
|
||||
$this->assertEquals($expected['resource'], $log->getResource());
|
||||
$this->assertEquals($expected['general'], $log->getGeneral());
|
||||
$this->assertEquals($expected['aspect'], $log->getAspect());
|
||||
$this->assertEquals($expected['action'], $log->getAction());
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$manipulator = new ApiAccountManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-accounts']);
|
||||
$account = $manipulator->create(self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$manipulator = new ApiLogManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-logs']);
|
||||
$log = $manipulator->create($account, Request::create('/databoxes/list/', 'POST'), new Response());
|
||||
$countBefore = count(self::$DI['app']['repo.api-logs']->findAll());
|
||||
$manipulator->delete($log);
|
||||
$this->assertGreaterThan(count(self::$DI['app']['repo.api-logs']->findAll()), $countBefore);
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
$manipulator = new ApiAccountManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-accounts']);
|
||||
$account = $manipulator->create(self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$manipulator = new ApiLogManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-logs']);
|
||||
$log = $manipulator->create($account, Request::create('/databoxes/list/', 'POST'), new Response());
|
||||
$log->setAspect('a-new-aspect');
|
||||
$manipulator->update($log);
|
||||
$log = self::$DI['app']['repo.api-logs']->find($log->getId());
|
||||
$this->assertEquals('a-new-aspect', $log->getAspect());
|
||||
}
|
||||
|
||||
public function apiRouteProvider()
|
||||
{
|
||||
return [
|
||||
['/databoxes/list/', ['resource' => 'databoxes', 'aspect' => null, 'action' => 'list', 'general' => 'databoxes']],
|
||||
['/databoxes/1/collections/', ['resource' => 'databoxes', 'aspect' => 'collections', 'action' => null, 'general' => 'databoxes']],
|
||||
['/databoxes/1/status/', ['resource' => 'databoxes', 'aspect' => 'status', 'action' => null, 'general' => 'databoxes']],
|
||||
['/databoxes/1/metadatas/', ['resource' => 'databoxes', 'aspect' => 'metadatas', 'action' => null, 'general' => 'databoxes']],
|
||||
['/databoxes/1/termsOfUse/', ['resource' => 'databoxes', 'aspect' => 'termsOfUse', 'action' => null, 'general' => 'databoxes']],
|
||||
['/quarantine/list/', ['resource' => 'quarantine', 'aspect' => null, 'action' => 'list', 'general' => 'quarantine']],
|
||||
['/records/add/', ['resource' => 'records', 'aspect' => null, 'action' => 'add', 'general' => 'records']],
|
||||
['/records/search/', ['resource' => 'records', 'aspect' => null, 'action' => 'search', 'general' => 'records']],
|
||||
['/records/1/1/caption/', ['resource' => 'records', 'aspect' => 'caption', 'action' => null, 'general' => 'records']],
|
||||
['/records/1/1/metadatas/', ['resource' => 'records', 'aspect' => 'metadatas', 'action' => null, 'general' => 'records']],
|
||||
['/records/1/1/status/', ['resource' => 'records', 'aspect' => 'status', 'action' => null, 'general' => 'records']],
|
||||
['/records/1/1/embed/', ['resource' => 'records', 'aspect' => 'embed', 'action' => null, 'general' => 'records']],
|
||||
['/records/1/1/related/', ['resource' => 'records', 'aspect' => 'related', 'action' => null, 'general' => 'records']],
|
||||
['/records/1/1/', ['resource' => 'records', 'aspect' => null, 'action' => 'get', 'general' => 'records']],
|
||||
['/records/1/1/setstatus/', ['resource' => 'records', 'aspect' => null, 'action' => 'setstatus', 'general' => 'records']],
|
||||
['/records/1/1/setmetadatas/', ['resource' => 'records', 'aspect' => null, 'action' => 'setmetadatas', 'general' => 'records']],
|
||||
['/records/1/1/setcollection/', ['resource' => 'records', 'aspect' => null, 'action' => 'setcollection', 'general' => 'records']],
|
||||
['/stories/1/1/embed/', ['resource' => 'stories', 'aspect' => 'embed', 'action' => null, 'general' => 'stories']],
|
||||
['/stories/1/1/', ['resource' => 'stories', 'aspect' => null, 'action' => 'get', 'general' => 'stories']],
|
||||
['/baskets/add/', ['resource' => 'baskets', 'aspect' => null, 'action' => 'add', 'general' => 'baskets']],
|
||||
['/baskets/1/content/', ['resource' => 'baskets', 'aspect' => 'content', 'action' => '', 'general' => 'baskets']],
|
||||
['/baskets/1/delete/', ['resource' => 'baskets', 'aspect' => null, 'action' => 'delete', 'general' => 'baskets']],
|
||||
['/baskets/1/setdescription/', ['resource' => 'baskets', 'aspect' => null, 'action' => 'setdescription', 'general' => 'baskets']],
|
||||
['/baskets/1/setname/', ['resource' => 'baskets', 'aspect' => null, 'action' => 'setname', 'general' => 'baskets']],
|
||||
['/feeds/list/', ['resource' => 'feeds', 'aspect' => null, 'action' => 'list', 'general' => 'feeds']],
|
||||
['/feeds/1/content/', ['resource' => 'feeds', 'aspect' => 'content', 'action' => null, 'general' => 'feeds']],
|
||||
['/feeds/content/', ['resource' => 'feeds', 'aspect' => 'content', 'action' => null, 'general' => 'feeds']],
|
||||
['/feeds/entry/1/', ['resource' => 'feeds', 'aspect' => 'entry', 'action' => null, 'general' => 'feeds']],
|
||||
['/monitor/phraseanet/', ['resource' => null, 'aspect' => 'phraseanet', 'action' => null, 'general' => 'monitor']],
|
||||
['/monitor/scheduler/', ['resource' => null, 'aspect' => 'scheduler', 'action' => null, 'general' => 'monitor']],
|
||||
['/monitor/task/1/', ['resource' => null, 'aspect' => 'task', 'action' => 'get', 'general' => 'monitor']],
|
||||
['/monitor/task/1/stop/', ['resource' => null, 'aspect' => 'task', 'action' => 'stop', 'general' => 'monitor']],
|
||||
['/monitor/task/1/start/', ['resource' => null, 'aspect' => 'task', 'action' => 'start', 'general' => 'monitor']],
|
||||
['/monitor/tasks/', ['resource' => null, 'aspect' => 'tasks', 'action' => null, 'general' => 'monitor']],
|
||||
];
|
||||
}
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Tests\Phrasea\Model\Manipulator;
|
||||
|
||||
|
||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
||||
use Alchemy\Phrasea\Model\Manipulator\ApiOauthCodeManipulator;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class ApiOauthCodeManipulatorTest extends \PhraseanetTestCase
|
||||
{
|
||||
public function testCreate()
|
||||
{
|
||||
$manipulator = new ApiOauthCodeManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-oauth-codes'], self::$DI['app']['random.medium']);
|
||||
$nbCodes = count(self::$DI['app']['repo.api-oauth-codes']->findAll());
|
||||
$account = self::$DI['app']['manipulator.api-account']->create(self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$manipulator->create($account, 'http://www.redirect.url', time() + 30);
|
||||
$this->assertGreaterThan($nbCodes, count(self::$DI['app']['repo.api-oauth-codes']->findAll()));
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$manipulator = new ApiOauthCodeManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-oauth-codes'], self::$DI['app']['random.medium']);
|
||||
$account = self::$DI['app']['manipulator.api-account']->create(self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$code = $manipulator->create($account, 'http://www.redirect.url', time() + 30);
|
||||
$countBefore = count(self::$DI['app']['repo.api-oauth-codes']->findAll());
|
||||
$manipulator->delete($code);
|
||||
$this->assertGreaterThan(count(self::$DI['app']['repo.api-oauth-codes']->findAll()), $countBefore);
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
|
||||
$manipulator = new ApiOauthCodeManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-oauth-codes'], self::$DI['app']['random.medium']);
|
||||
$account = self::$DI['app']['manipulator.api-account']->create(self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$code = $manipulator->create($account, 'http://www.redirect.url', $t = time() + 30);
|
||||
$code->setExpires(time() + 40);
|
||||
$manipulator->update($code);
|
||||
$code = self::$DI['app']['repo.api-oauth-codes']->find($code->getCode());
|
||||
$this->assertGreaterThan($t, $code->getExpires());
|
||||
}
|
||||
|
||||
/**
|
||||
* @setExpectedException Alchemy\Phrasea\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function testSetRedirectUriBadArgumentException()
|
||||
{
|
||||
$manipulator = new ApiOauthCodeManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-oauth-codes'], self::$DI['app']['random.medium']);
|
||||
$account = self::$DI['app']['manipulator.api-account']->create(self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$code = $manipulator->create($account, 'http://www.redirect.url', time() + 30);
|
||||
try {
|
||||
$manipulator->setRedirectUri($code, 'bad-url');
|
||||
$this->fail('Invalid argument exception should be raised');
|
||||
} catch (InvalidArgumentException $e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Tests\Phrasea\Model\Manipulator;
|
||||
|
||||
use Alchemy\Phrasea\Model\Manipulator\ApiLogManipulator;
|
||||
use Alchemy\Phrasea\Model\Manipulator\ApiOauthTokenManipulator;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class ApiOauthTokenManipulatorTest extends \PhraseanetTestCase
|
||||
{
|
||||
public function testCreate()
|
||||
{
|
||||
$manipulator = new ApiOauthTokenManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-oauth-tokens'], self::$DI['app']['random.medium']);
|
||||
$nbTokens = count(self::$DI['app']['repo.api-oauth-tokens']->findAll());
|
||||
$account = self::$DI['app']['manipulator.api-account']->create(self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$manipulator->create($account);
|
||||
$this->assertGreaterThan($nbTokens, count(self::$DI['app']['repo.api-oauth-tokens']->findAll()));
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$manipulator = new ApiOauthTokenManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-oauth-tokens'], self::$DI['app']['random.medium']);
|
||||
$account = self::$DI['app']['manipulator.api-account']->create(self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$token = $manipulator->create($account);
|
||||
$countBefore = count(self::$DI['app']['repo.api-oauth-tokens']->findAll());
|
||||
$manipulator->delete($token);
|
||||
$this->assertGreaterThan(count(self::$DI['app']['repo.api-oauth-tokens']->findAll()), $countBefore);
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
|
||||
$manipulator = new ApiOauthTokenManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-oauth-tokens'], self::$DI['app']['random.medium']);
|
||||
$account = self::$DI['app']['manipulator.api-account']->create(self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$token = $manipulator->create($account);
|
||||
$token->setSessionId(123456);
|
||||
$manipulator->update($token);
|
||||
$token = self::$DI['app']['repo.api-oauth-tokens']->find($token->getOauthToken());
|
||||
$this->assertEquals(123456, $token->getSessionId());
|
||||
}
|
||||
|
||||
public function testRenew()
|
||||
{
|
||||
$manipulator = new ApiOauthTokenManipulator(self::$DI['app']['EM'], self::$DI['app']['repo.api-oauth-tokens'], self::$DI['app']['random.medium']);
|
||||
$account = self::$DI['app']['manipulator.api-account']->create(self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$token = $manipulator->create($account);
|
||||
$oauthTokenBefore = $token->getOauthToken();
|
||||
$manipulator->renew($token);
|
||||
$this->assertNotEquals($oauthTokenBefore, $token->getOauthToken());
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Tests\Phrasea\Model\Repositories;
|
||||
|
||||
class ApiAccountRepositoryTest extends \PhraseanetTestCase
|
||||
{
|
||||
public function testFindByUserAndApplication()
|
||||
{
|
||||
$acc = self::$DI['app']['EM']->getRepository('Phraseanet:ApiAccount')->findByUserAndApplication(self::$DI['user_notAdmin'], self::$DI['oauth2-app-user-not-admin']);
|
||||
$this->assertEquals(1, count($acc));
|
||||
}
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Tests\Phrasea\Model\Repositories;
|
||||
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
|
||||
class ApiApplicationRepositoryTest extends \PhraseanetTestCase
|
||||
{
|
||||
public function testFindByCreator()
|
||||
{
|
||||
$app = self::$DI['app']['EM']->getRepository('Phraseanet:ApiApplication')->findByCreator(self::$DI['user']);
|
||||
$this->assertCount(1, $app);
|
||||
}
|
||||
|
||||
public function testFindByUser()
|
||||
{
|
||||
$app = self::$DI['app']['EM']->getRepository('Phraseanet:ApiApplication')->findByUser(self::$DI['user']);
|
||||
$this->assertCount(1, $app);
|
||||
}
|
||||
|
||||
public function testFindAuthorizedAppsByUser()
|
||||
{
|
||||
$app = self::$DI['app']['EM']->getRepository('Phraseanet:ApiApplication')->findAuthorizedAppsByUser(self::$DI['user']);
|
||||
$this->assertCount(1, $app);
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Tests\Phrasea\Model\Repositories;
|
||||
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
|
||||
class ApiOauthCodeRepositoryTest extends \PhraseanetTestCase
|
||||
{
|
||||
public function testFindByAccount()
|
||||
{
|
||||
self::$DI['app']['manipulator.api-oauth-code']->create(self::$DI['oauth2-app-acc-user'], 'http://www.callback.fr', time() + 40);
|
||||
$codes = self::$DI['app']['EM']->getRepository('Phraseanet:ApiOauthCode')->findByAccount(self::$DI['oauth2-app-acc-user']);
|
||||
$this->assertGreaterThan(0, count($codes));
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Tests\Phrasea\Model\Repositories;
|
||||
|
||||
use Alchemy\Phrasea\Model\Entities\ApiApplication;
|
||||
|
||||
class ApiOauthTokenRepositoryTest extends \PhraseanetTestCase
|
||||
{
|
||||
public function testFindDeveloperToken()
|
||||
{
|
||||
$tok = self::$DI['app']['EM']->getRepository('Phraseanet:ApiOauthToken')->findByAccount(self::$DI['oauth2-app-acc-user']);
|
||||
$this->assertNotNull($tok);
|
||||
}
|
||||
|
||||
public function testFindOauthTokens()
|
||||
{
|
||||
$tokens = self::$DI['app']['EM']->getRepository('Phraseanet:ApiOauthToken')->findOauthTokens(self::$DI['oauth2-app-acc-user']);
|
||||
$this->assertGreaterThan(0, count($tokens));
|
||||
}
|
||||
}
|
@@ -199,11 +199,19 @@ abstract class PhraseanetTestCase extends WebTestCase
|
||||
});
|
||||
|
||||
self::$DI['oauth2-app-user'] = self::$DI->share(function ($DI) {
|
||||
return new \API_OAuth2_Application($DI['app'], self::$fixtureIds['oauth']['user']);
|
||||
return $DI['app']['repo.api-applications']->find(self::$fixtureIds['oauth']['user']);
|
||||
});
|
||||
|
||||
self::$DI['oauth2-app-user_notAdmin'] = self::$DI->share(function ($DI) {
|
||||
return new \API_OAuth2_Application($DI['app'], self::$fixtureIds['oauth']['user_notAdmin']);
|
||||
self::$DI['oauth2-app-user-not-admin'] = self::$DI->share(function ($DI) {
|
||||
return $DI['app']['repo.api-applications']->find(self::$fixtureIds['oauth']['user-not-admin']);
|
||||
});
|
||||
|
||||
self::$DI['oauth2-app-acc-user'] = self::$DI->share(function ($DI) {
|
||||
return $DI['app']['repo.api-accounts']->find(self::$fixtureIds['oauth']['acc-user']);
|
||||
});
|
||||
|
||||
self::$DI['oauth2-app-acc-user-not-admin'] = self::$DI->share(function ($DI) {
|
||||
return $DI['app']['repo.api-accounts']->find(self::$fixtureIds['oauth']['acc-user-not-admin']);
|
||||
});
|
||||
|
||||
self::$DI['logger'] = self::$DI->share(function () {
|
||||
|
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
|
||||
class api_oauthv2_AccountTest extends \PhraseanetTestCase
|
||||
{
|
||||
/**
|
||||
* @var API_OAuth2_Account
|
||||
*/
|
||||
protected $object;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->object = API_OAuth2_Account::load_with_user(self::$DI['app'], self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
}
|
||||
|
||||
public function testGettersAndSetters()
|
||||
{
|
||||
$this->assertTrue(is_int($this->object->get_id()));
|
||||
$this->assertInstanceOf('Alchemy\Phrasea\Model\Entities\User', $this->object->get_user());
|
||||
$this->assertEquals(self::$DI['user']->getId(), $this->object->get_user()->getId());
|
||||
|
||||
$this->assertEquals('1.0', $this->object->get_api_version());
|
||||
|
||||
$this->assertTrue(is_bool($this->object->is_revoked()));
|
||||
|
||||
$this->object->set_revoked(true);
|
||||
$this->assertTrue($this->object->is_revoked());
|
||||
$this->object->set_revoked(false);
|
||||
$this->assertFalse($this->object->is_revoked());
|
||||
|
||||
$this->assertInstanceOf('DateTime', $this->object->get_created_on());
|
||||
|
||||
$this->assertInstanceOf('API_OAuth2_Token', $this->object->get_token());
|
||||
|
||||
$this->assertInstanceOf('API_OAuth2_Application', $this->object->get_application());
|
||||
$this->assertEquals(self::$DI['oauth2-app-user'], $this->object->get_application());
|
||||
}
|
||||
|
||||
public function testLoad_with_user()
|
||||
{
|
||||
$loaded = API_OAuth2_Account::load_with_user(self::$DI['app'], self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$this->assertInstanceOf('API_OAuth2_Account', $loaded);
|
||||
$this->assertEquals($this->object, $loaded);
|
||||
}
|
||||
}
|
@@ -1,117 +0,0 @@
|
||||
<?php
|
||||
|
||||
class api_oauthv2_ApplicationTest extends \PhraseanetTestCase
|
||||
{
|
||||
public function testLoad_from_client_id()
|
||||
{
|
||||
$client_id = self::$DI['oauth2-app-user']->get_client_id();
|
||||
$loaded = API_OAuth2_Application::load_from_client_id(self::$DI['app'], $client_id);
|
||||
$this->assertInstanceOf('API_OAuth2_Application', $loaded);
|
||||
$this->assertEquals(self::$DI['oauth2-app-user'], $loaded);
|
||||
}
|
||||
|
||||
public function testLoad_dev_app_by_user()
|
||||
{
|
||||
$apps = API_OAuth2_Application::load_dev_app_by_user(self::$DI['app'], self::$DI['user']);
|
||||
$this->assertTrue(is_array($apps));
|
||||
$this->assertTrue(count($apps) > 0);
|
||||
$found = false;
|
||||
foreach ($apps as $app) {
|
||||
if ($app->get_id() === self::$DI['oauth2-app-user']->get_id())
|
||||
$found = true;
|
||||
$this->assertInstanceOf('API_OAuth2_Application', $app);
|
||||
}
|
||||
|
||||
if ( ! $found)
|
||||
$this->fail();
|
||||
}
|
||||
|
||||
public function testLoad_app_by_user()
|
||||
{
|
||||
$apps = API_OAuth2_Application::load_app_by_user(self::$DI['app'], self::$DI['user']);
|
||||
$this->assertTrue(is_array($apps));
|
||||
$this->assertTrue(count($apps) > 0);
|
||||
$found = false;
|
||||
|
||||
foreach ($apps as $app) {
|
||||
if ($app->get_id() === self::$DI['oauth2-app-user']->get_id())
|
||||
$found = true;
|
||||
$this->assertInstanceOf('API_OAuth2_Application', $app);
|
||||
}
|
||||
|
||||
if ( ! $found)
|
||||
$this->fail();
|
||||
}
|
||||
|
||||
public function testGettersAndSetters()
|
||||
{
|
||||
$this->assertTrue(is_int(self::$DI['oauth2-app-user']->get_id()));
|
||||
$this->assertInstanceOf('Alchemy\Phrasea\Model\Entities\User', self::$DI['oauth2-app-user']->get_creator());
|
||||
$this->assertEquals(self::$DI['user']->getId(), self::$DI['oauth2-app-user']->get_creator()->getId());
|
||||
|
||||
$this->assertTrue(in_array(self::$DI['oauth2-app-user']->get_type(), [API_OAuth2_Application::DESKTOP_TYPE, API_OAuth2_Application::WEB_TYPE]));
|
||||
|
||||
$this->assertTrue(is_string(self::$DI['oauth2-app-user']->get_nonce()));
|
||||
$this->assertEquals(64, strlen(self::$DI['oauth2-app-user']->get_nonce()));
|
||||
|
||||
try {
|
||||
self::$DI['oauth2-app-user']->set_type('prout');
|
||||
$this->fail();
|
||||
} catch (Exception_InvalidArgument $e) {
|
||||
|
||||
}
|
||||
|
||||
self::$DI['oauth2-app-user']->set_type(API_OAuth2_Application::WEB_TYPE);
|
||||
$this->assertEquals(API_OAuth2_Application::WEB_TYPE, self::$DI['oauth2-app-user']->get_type());
|
||||
self::$DI['oauth2-app-user']->set_type(API_OAuth2_Application::DESKTOP_TYPE);
|
||||
$this->assertEquals(API_OAuth2_Application::DESKTOP_TYPE, self::$DI['oauth2-app-user']->get_type());
|
||||
$this->assertEquals(API_OAuth2_Application::NATIVE_APP_REDIRECT_URI, self::$DI['oauth2-app-user']->get_redirect_uri());
|
||||
self::$DI['oauth2-app-user']->set_type(API_OAuth2_Application::WEB_TYPE);
|
||||
|
||||
self::$DI['oauth2-app-user']->set_name('prout');
|
||||
$this->assertEquals('prout', self::$DI['oauth2-app-user']->get_name());
|
||||
self::$DI['oauth2-app-user']->set_name('test application for user');
|
||||
$this->assertEquals('test application for user', self::$DI['oauth2-app-user']->get_name());
|
||||
|
||||
$desc = 'prouti prouto prout prout';
|
||||
self::$DI['oauth2-app-user']->set_description($desc);
|
||||
$this->assertEquals($desc, self::$DI['oauth2-app-user']->get_description());
|
||||
self::$DI['oauth2-app-user']->set_description('');
|
||||
$this->assertEquals('', self::$DI['oauth2-app-user']->get_description());
|
||||
|
||||
$site = 'http://www.example.com/';
|
||||
self::$DI['oauth2-app-user']->set_website($site);
|
||||
$this->assertEquals($site, self::$DI['oauth2-app-user']->get_website());
|
||||
self::$DI['oauth2-app-user']->set_website('');
|
||||
$this->assertEquals('', self::$DI['oauth2-app-user']->get_website());
|
||||
|
||||
$this->assertInstanceOf('DateTime', self::$DI['oauth2-app-user']->get_created_on());
|
||||
|
||||
$this->assertInstanceOf('DateTime', self::$DI['oauth2-app-user']->get_last_modified());
|
||||
|
||||
$this->assertMd5(self::$DI['oauth2-app-user']->get_client_id());
|
||||
|
||||
$client_id = md5('prouto');
|
||||
self::$DI['oauth2-app-user']->set_client_id($client_id);
|
||||
$this->assertEquals($client_id, self::$DI['oauth2-app-user']->get_client_id());
|
||||
$this->assertMd5(self::$DI['oauth2-app-user']->get_client_id());
|
||||
|
||||
$this->assertMd5(self::$DI['oauth2-app-user']->get_client_secret());
|
||||
|
||||
$client_secret = md5('prouto');
|
||||
self::$DI['oauth2-app-user']->set_client_secret($client_secret);
|
||||
$this->assertEquals($client_secret, self::$DI['oauth2-app-user']->get_client_secret());
|
||||
$this->assertMd5(self::$DI['oauth2-app-user']->get_client_secret());
|
||||
|
||||
$uri = 'http://www.example.com/callback/';
|
||||
self::$DI['oauth2-app-user']->set_redirect_uri($uri);
|
||||
$this->assertEquals($uri, self::$DI['oauth2-app-user']->get_redirect_uri());
|
||||
|
||||
$this->assertInstanceOf('API_OAuth2_Account', self::$DI['oauth2-app-user']->get_user_account(self::$DI['user']));
|
||||
}
|
||||
|
||||
private function assertmd5($md5)
|
||||
{
|
||||
$this->assertTrue((count(preg_match('/[a-z0-9]{32}/', $md5)) === 1));
|
||||
}
|
||||
}
|
@@ -1,70 +0,0 @@
|
||||
|
||||
<?php
|
||||
|
||||
class api_oauthv2_AuthCodeTest extends \PhraseanetTestCase
|
||||
{
|
||||
/**
|
||||
* @var API_OAuth2_AuthCode
|
||||
*/
|
||||
protected $object;
|
||||
protected $code;
|
||||
|
||||
protected $account;
|
||||
protected $application;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->account = API_OAuth2_Account::load_with_user(self::$DI['app'], self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
$expires = time() + 100;
|
||||
$this->code = self::$DI['app']['random.low']->generateString(8);
|
||||
$this->object = API_OAuth2_AuthCode::create(self::$DI['app'], $this->account, $this->code, $expires);
|
||||
}
|
||||
|
||||
public function testGet_code()
|
||||
{
|
||||
$this->assertEquals($this->code, $this->object->get_code());
|
||||
}
|
||||
|
||||
public function testGet_account()
|
||||
{
|
||||
$this->assertInstanceOf('API_OAuth2_Account', $this->object->get_account());
|
||||
}
|
||||
|
||||
public function testGet_redirect_uri()
|
||||
{
|
||||
$this->assertEquals('', $this->object->get_redirect_uri());
|
||||
}
|
||||
|
||||
public function testSet_redirect_uri()
|
||||
{
|
||||
$redirect_uri = 'https://www.google.com';
|
||||
$this->assertEquals('', $this->object->get_redirect_uri());
|
||||
$this->object->set_redirect_uri($redirect_uri);
|
||||
$this->assertEquals($redirect_uri, $this->object->get_redirect_uri());
|
||||
}
|
||||
|
||||
public function testGet_expires()
|
||||
{
|
||||
$this->assertInternalType('string', $this->object->get_expires());
|
||||
}
|
||||
|
||||
public function testGet_scope()
|
||||
{
|
||||
$this->assertEquals('', $this->object->get_scope());
|
||||
}
|
||||
|
||||
public function testSet_scope()
|
||||
{
|
||||
$scope = 'prout';
|
||||
$this->assertEquals('', $this->object->get_scope());
|
||||
$this->object->set_scope($scope);
|
||||
$this->assertEquals($scope, $this->object->get_scope());
|
||||
}
|
||||
|
||||
public function testLoad_codes_by_account()
|
||||
{
|
||||
$this->assertTrue(is_array(API_OAuth2_AuthCode::load_codes_by_account(self::$DI['app'], $this->account)));
|
||||
$this->assertTrue(count(API_OAuth2_AuthCode::load_codes_by_account(self::$DI['app'], $this->account)) > 0);
|
||||
}
|
||||
}
|
@@ -1,96 +0,0 @@
|
||||
<?php
|
||||
|
||||
class api_oauthv2_RefreshTokenTest extends \PhraseanetTestCase
|
||||
{
|
||||
/**
|
||||
* @var API_OAuth2_RefreshToken
|
||||
*/
|
||||
protected $object;
|
||||
protected $token;
|
||||
protected $scope;
|
||||
|
||||
protected $account;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->account = API_OAuth2_Account::load_with_user(self::$DI['app'], self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
|
||||
$expires = time() + 100;
|
||||
$this->token = self::$DI['app']['random.low']->generateString(8);
|
||||
$this->scope = 'scopidou';
|
||||
|
||||
$this->object = API_OAuth2_RefreshToken::create(self::$DI['app'], $this->account, $expires, $this->token, $this->scope);
|
||||
}
|
||||
|
||||
public function testGet_value()
|
||||
{
|
||||
$this->assertEquals($this->token, $this->object->get_value());
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Implement testGet_account().
|
||||
*/
|
||||
public function testGet_account()
|
||||
{
|
||||
// Remove the following lines when you implement this test.
|
||||
$this->markTestIncomplete(
|
||||
'This test has not been implemented yet.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Implement testGet_expires().
|
||||
*/
|
||||
public function testGet_expires()
|
||||
{
|
||||
// Remove the following lines when you implement this test.
|
||||
$this->markTestIncomplete(
|
||||
'This test has not been implemented yet.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Implement testGet_scope().
|
||||
*/
|
||||
public function testGet_scope()
|
||||
{
|
||||
// Remove the following lines when you implement this test.
|
||||
$this->markTestIncomplete(
|
||||
'This test has not been implemented yet.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Implement testDelete().
|
||||
*/
|
||||
public function testDelete()
|
||||
{
|
||||
// Remove the following lines when you implement this test.
|
||||
$this->markTestIncomplete(
|
||||
'This test has not been implemented yet.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Implement testLoad_by_account().
|
||||
*/
|
||||
public function testLoad_by_account()
|
||||
{
|
||||
// Remove the following lines when you implement this test.
|
||||
$this->markTestIncomplete(
|
||||
'This test has not been implemented yet.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Implement testCreate().
|
||||
*/
|
||||
public function testCreate()
|
||||
{
|
||||
// Remove the following lines when you implement this test.
|
||||
$this->markTestIncomplete(
|
||||
'This test has not been implemented yet.'
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,88 +0,0 @@
|
||||
<?php
|
||||
|
||||
class api_oauthv2_TokenTest extends \PhraseanetTestCase
|
||||
{
|
||||
/**
|
||||
* @var API_OAuth2_Token
|
||||
*/
|
||||
protected $object;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$account = API_OAuth2_Account::load_with_user(self::$DI['app'], self::$DI['oauth2-app-user'], self::$DI['user']);
|
||||
|
||||
try {
|
||||
new API_OAuth2_Token(self::$DI['app']['phraseanet.appbox'], $account, self::$DI['app']['random.medium']);
|
||||
$this->fail();
|
||||
} catch (Exception $e) {
|
||||
|
||||
}
|
||||
|
||||
$this->object = API_OAuth2_Token::create(self::$DI['app']['phraseanet.appbox'], $account, self::$DI['app']['random.medium']);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->object->delete();
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
private function assertmd5($md5)
|
||||
{
|
||||
$this->assertTrue((count(preg_match('/[a-z0-9]{32}/', $md5)) === 1));
|
||||
}
|
||||
|
||||
public function testGettersAndSetters()
|
||||
{
|
||||
$this->assertmd5($this->object->get_value());
|
||||
|
||||
$value = md5('prout');
|
||||
$this->object->set_value($value);
|
||||
$this->assertEquals($value, $this->object->get_value());
|
||||
|
||||
$this->object->set_session_id(null);
|
||||
$this->assertNull($this->object->get_session_id());
|
||||
|
||||
$this->object->set_session_id(458);
|
||||
$this->assertEquals(458, $this->object->get_session_id());
|
||||
|
||||
$expire = time() + 3600;
|
||||
$this->object->set_expires($expire);
|
||||
$diff = (int) $this->object->get_expires() - time();
|
||||
$this->assertSame($expire, $this->object->get_expires(), "expiration timestamp is string : " . $this->object->get_expires());
|
||||
$this->assertTrue($diff > 3500, "expire value $diff should be more than 3500 seconds ");
|
||||
$this->assertTrue($diff < 3700, "expire value $diff should be less than 3700 seconds ");
|
||||
|
||||
$date = time() + 7200;
|
||||
$this->object->set_expires($date);
|
||||
$this->assertEquals($date, $this->object->get_expires());
|
||||
|
||||
$this->assertNull($this->object->get_scope());
|
||||
|
||||
$this->assertNull($this->object->get_scope());
|
||||
$scope = "prout";
|
||||
$this->object->set_scope($scope);
|
||||
$this->assertEquals($scope, $this->object->get_scope());
|
||||
|
||||
$this->assertInstanceOf('API_OAuth2_Account', $this->object->get_account());
|
||||
}
|
||||
|
||||
public function testRenew()
|
||||
{
|
||||
$first = $this->object->get_value();
|
||||
$this->assertMd5($first);
|
||||
$this->object->renew();
|
||||
$second = $this->object->get_value();
|
||||
$this->assertMd5($second);
|
||||
$this->assertNotEquals($second, $first);
|
||||
}
|
||||
|
||||
public function testLoad_by_oauth_token()
|
||||
{
|
||||
$token = $this->object->get_value();
|
||||
$loaded = API_OAuth2_Token::load_by_oauth_token(self::$DI['app'], $token);
|
||||
$this->assertInstanceOf('API_OAuth2_Token', $loaded);
|
||||
$this->assertEquals($this->object, $loaded);
|
||||
}
|
||||
}
|
@@ -7,7 +7,7 @@ $(document).ready(function () {
|
||||
type: "GET",
|
||||
url: $this.attr("href"),
|
||||
dataType: 'json',
|
||||
data: {revoke: $this.hasClass("authorize") ? 1 : 0},
|
||||
data: {revoke: $this.hasClass("authorize") ? 0 : 1},
|
||||
success: function (data) {
|
||||
if (data.success) {
|
||||
var li = $this.closest('li');
|
||||
|
Reference in New Issue
Block a user