/** * * @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 = random::generatePassword(6); $client_secret = API_OAuth2_Token::generate_token(); $client_token = API_OAuth2_Token::generate_token(); $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; }
public function testGenerate_token() { for ($i = 0; $i < 100; $i++) { $this->assertMd5(API_OAuth2_Token::generate_token()); } }
public function connect(SilexApplication $app) { $app['controller.api.v1'] = $this; $controllers = $app['controllers_factory']; /** * @var API_OAuth2_Token */ $app['token'] = null; /** * Api Service * @var Closure */ $app['api'] = function () use($app) { return new \API_V1_adapter($app); }; /** * oAuth token verification process * - Check if oauth_token exists && is valid * - Check if request comes from phraseanet Navigator && phraseanet Navigator * is enbale on current instance * - restore user session * * @ throws \API_V1_exception_unauthorized * @ throws \API_V1_exception_forbidden */ $controllers->before(function ($request) use($app) { $context = new Context(Context::CONTEXT_OAUTH2_TOKEN); $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['token'] = \API_OAuth2_Token::load_by_oauth_token($app, $oauth2_adapter->getToken()); $oAuth2App = $app['token']->get_account()->get_application(); /* @var $oAuth2App \API_OAuth2_Application */ if ($oAuth2App->get_client_id() == \API_OAuth2_Application_Navigator::CLIENT_ID && !$app['conf']->get(['registry', 'api-clients', 'navigator-enabled'])) { throw new \API_V1_exception_forbidden('The use of phraseanet Navigator is not allowed'); } if ($oAuth2App->get_client_id() == \API_OAuth2_Application_OfficePlugin::CLIENT_ID && !$app['conf']->get(['registry', 'api-clients', 'office-enabled'])) { throw new \API_V1_exception_forbidden('The use of Office Plugin is not allowed.'); } if ($app['authentication']->isAuthenticated()) { $app['dispatcher']->dispatch(PhraseaEvents::API_OAUTH2_END, new ApiOAuth2EndEvent()); return; } $user = $app['manipulator.user']->getRepository()->find($oauth2_adapter->get_usr_id()); $app['authentication']->openAccount($user); $oauth2_adapter->remember_this_ses_id($app['session']->get('session_id')); $app['dispatcher']->dispatch(PhraseaEvents::API_OAUTH2_END, new ApiOAuth2EndEvent()); return; }); /** * OAuth log process * * Parse 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 */ $parseRoute = function ($route, Response $response) { $ressource = $general = $aspect = $action = null; $exploded_route = explode('/', \p4string::delFirstSlash(\p4string::delEndSlash($route))); if (sizeof($exploded_route) > 0 && $response->isOk()) { $ressource = $exploded_route[0]; if (sizeof($exploded_route) == 2 && (int) $exploded_route[1] == 0) { $general = $exploded_route[1]; } else { switch ($ressource) { case \API_V1_Log::DATABOXES_RESSOURCE: if ((int) $exploded_route[1] > 0 && sizeof($exploded_route) == 3) { $aspect = $exploded_route[2]; } break; case \API_V1_Log::RECORDS_RESSOURCE: if ((int) $exploded_route[1] > 0 && sizeof($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 \API_V1_Log::BASKETS_RESSOURCE: if ((int) $exploded_route[1] > 0 && sizeof($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 \API_V1_Log::FEEDS_RESSOURCE: if ((int) $exploded_route[1] > 0 && sizeof($exploded_route) == 3) { $aspect = $exploded_route[2]; } break; } } } return ['ressource' => $ressource, 'general' => $general, 'aspect' => $aspect, 'action' => $action]; }; /** * Log occurs in after filter */ $controllers->after(function (Request $request, Response $response) use($app, $parseRoute) { $account = $app['token']->get_account(); $pathInfo = $request->getPathInfo(); $route = $parseRoute($pathInfo, $response); \API_V1_Log::create($app, $account, $request->getMethod() . " " . $pathInfo, $response->getStatusCode(), $response->headers->get('content-type'), $route['ressource'], $route['general'], $route['aspect'], $route['action']); }); $controllers->after(function () use($app) { $app['authentication']->closeAccount(); }); /** * Method Not Allowed Closure */ $bad_request_exception = function () { throw new \API_V1_exception_badrequest(); }; /** * Check wether the current user is Admin or not */ $mustBeAdmin = function (Request $request) use($app) { $user = $app['token']->get_account()->get_user(); if (!$app['acl']->get($user)->is_admin()) { throw new \API_V1_exception_unauthorized('You are not authorized'); } }; /** * Get scheduler informations * * Route : /monitor/scheduler/ * * Method : GET * * Parameters : * */ $controllers->get('/monitor/scheduler/', function (SilexApplication $app, Request $request) { return $app['api']->get_scheduler($app)->get_response(); })->before($mustBeAdmin); /** * Get all tasks information * * Route : /monitor/tasks/ * * Method : GET * * Parameters : * */ $controllers->get('/monitor/tasks/', function (SilexApplication $app, Request $request) { return $app['api']->get_task_list($app)->get_response(); })->before($mustBeAdmin); /** * Get task informations * * Route : /monitor/task/{task}/ * * Method : GET * * Parameters : * */ $controllers->get('/monitor/task/{task}/', function (SilexApplication $app, Request $request, $task) { return $app['api']->get_task($app, $task)->get_response(); })->convert('task', [$app['converter.task'], 'convert'])->before($mustBeAdmin)->assert('task', '\\d+'); /** * Start task * * Route : /monitor/task/{task}/ * * Method : POST * * Parameters : * - name (string) change the name of the task * - autostart (boolean) start task when scheduler starts */ $controllers->post('/monitor/task/{task}/', function (SilexApplication $app, Request $request, $task) { return $app['api']->set_task_property($app, $task)->get_response(); })->convert('task', [$app['converter.task'], 'convert'])->before($mustBeAdmin)->assert('task', '\\d+'); /** * Start task * * Route : /monitor/task/{task}/start/ * * Method : POST * * Parameters : * */ $controllers->post('/monitor/task/{task}/start/', function (SilexApplication $app, Request $request, $task) { return $app['api']->start_task($app, $task)->get_response(); })->convert('task', [$app['converter.task'], 'convert'])->before($mustBeAdmin); /** * Stop task * * Route : /monitor/task/{task}/stop/ * * Method : POST * * Parameters : * */ $controllers->post('/monitor/task/{task}/stop/', function (SilexApplication $app, Request $request, $task) { return $app['api']->stop_task($app, $task)->get_response(); })->convert('task', [$app['converter.task'], 'convert'])->before($mustBeAdmin); /** * Get some information about phraseanet * * Route : /monitor/phraseanet/ * * Method : GET * * Parameters : * */ $controllers->get('/monitor/phraseanet/', function (SilexApplication $app, Request $request) { return $app['api']->get_phraseanet_monitor($app)->get_response(); })->before($mustBeAdmin); /** * Route : /databoxes/list/ * * Method : GET * * Parameters : * */ $controllers->get('/databoxes/list/', function (SilexApplication $app, Request $request) { return $app['api']->get_databoxes($request)->get_response(); }); /** * Route /databoxes/DATABOX_ID/collections/ * * Method : GET * * Parameters ; * DATABOX_ID : required INT */ $controllers->get('/databoxes/{databox_id}/collections/', function (SilexApplication $app, $databox_id) { return $app['api']->get_databox_collections($app['request'], $databox_id)->get_response(); })->assert('databox_id', '\\d+'); $controllers->get('/databoxes/{any_id}/collections/', $bad_request_exception); /** * Route /databoxes/DATABOX_ID/status/ * * Method : GET * * Parameters ; * DATABOX_ID : required INT * */ $controllers->get('/databoxes/{databox_id}/status/', function (SilexApplication $app, $databox_id) { return $app['api']->get_databox_status($app['request'], $databox_id)->get_response(); })->assert('databox_id', '\\d+'); $controllers->get('/databoxes/{any_id}/status/', $bad_request_exception); /** * Route /databoxes/DATABOX_ID/metadatas/ * * Method : GET * * Parameters ; * DATABOX_ID : required INT */ $controllers->get('/databoxes/{databox_id}/metadatas/', function (SilexApplication $app, $databox_id) { return $app['api']->get_databox_metadatas($app['request'], $databox_id)->get_response(); })->assert('databox_id', '\\d+'); $controllers->get('/databoxes/{any_id}/metadatas/', $bad_request_exception); /** * Route /databoxes/DATABOX_ID/termsOfUse/ * * Method : GET * * Parameters ; * DATABOX_ID : required INT */ $controllers->get('/databoxes/{databox_id}/termsOfUse/', function (SilexApplication $app, $databox_id) { return $app['api']->get_databox_terms($app['request'], $databox_id)->get_response(); })->assert('databox_id', '\\d+'); $controllers->get('/databoxes/{any_id}/termsOfUse/', $bad_request_exception); $controllers->get('/quarantine/list/', function (SilexApplication $app, Request $request) { return $app['api']->list_quarantine($app, $request)->get_response(); }); $controllers->get('/quarantine/item/{lazaret_id}/', function ($lazaret_id, SilexApplication $app, Request $request) { return $app['api']->list_quarantine_item($lazaret_id, $app, $request)->get_response(); }); /** * Route : /records/add/ * * Method : POST * * Parameters : * */ $controllers->post('/records/add/', function (SilexApplication $app, Request $request) { return $app['api']->add_record($app, $request)->get_response(); }); /** * Route : /search/ * * Method : GET or POST * * Parameters : * bases[] : array * status[] : array * fields[] : array * record_type : boolean * media_type : string * * Response : * Array containing an array of records and stories collection * */ $controllers->match('/search/', function () use($app) { return $app['api']->search($app['request'])->get_response(); }); /** * Route : /records/search/ * * Method : GET or POST * * Parameters : * bases[] : array * status[] : array * fields[] : array * record_type : boolean * media_type : string * * Response : * Array of record objects * */ $controllers->match('/records/search/', function (SilexApplication $app) { return $app['api']->search_records($app['request'])->get_response(); }); $controllers->get('/records/{databox_id}/{record_id}/caption/', function (SilexApplication $app, $databox_id, $record_id) { return $app['api']->caption_records($app['request'], $databox_id, $record_id)->get_response(); })->assert('databox_id', '\\d+')->assert('record_id', '\\d+'); $controllers->get('/records/{any_id}/{anyother_id}/caption/', $bad_request_exception); /** * Route : /records/DATABOX_ID/RECORD_ID/metadatas/ * * Method : GET * * Parameters : * DATABOX_ID : required INT * RECORD_ID : required INT * */ $controllers->get('/records/{databox_id}/{record_id}/metadatas/', function (SilexApplication $app, $databox_id, $record_id) { return $app['api']->get_record_metadatas($app['request'], $databox_id, $record_id)->get_response(); })->assert('databox_id', '\\d+')->assert('record_id', '\\d+'); $controllers->get('/records/{any_id}/{anyother_id}/metadatas/', $bad_request_exception); /** * Route : /records/DATABOX_ID/RECORD_ID/status/ * * Method : GET * * Parameters : * DATABOX_ID : required INT * RECORD_ID : required INT * */ $controllers->get('/records/{databox_id}/{record_id}/status/', function (SilexApplication $app, $databox_id, $record_id) { return $app['api']->get_record_status($app['request'], $databox_id, $record_id)->get_response(); })->assert('databox_id', '\\d+')->assert('record_id', '\\d+'); $controllers->get('/records/{any_id}/{anyother_id}/status/', $bad_request_exception); /** * Route : /records/DATABOX_ID/RECORD_ID/related/ * * Method : GET * * Parameters : * DATABOX_ID : required INT * RECORD_ID : required INT * */ $controllers->get('/records/{databox_id}/{record_id}/related/', function (SilexApplication $app, $databox_id, $record_id) { return $app['api']->get_record_related($app['request'], $databox_id, $record_id)->get_response(); })->assert('databox_id', '\\d+')->assert('record_id', '\\d+'); $controllers->get('/records/{any_id}/{anyother_id}/related/', $bad_request_exception); /** * Route : /records/DATABOX_ID/RECORD_ID/embed/ * * Method : GET * * Parameters : * DATABOX_ID : required INT * RECORD_ID : required INT * */ $controllers->get('/records/{databox_id}/{record_id}/embed/', function (SilexApplication $app, $databox_id, $record_id) { return $app['api']->get_record_embed($app['request'], $databox_id, $record_id)->get_response(); })->assert('databox_id', '\\d+')->assert('record_id', '\\d+'); $controllers->get('/records/{any_id}/{anyother_id}/embed/', $bad_request_exception); /** * Route : /records/DATABOX_ID/RECORD_ID/setmetadatas/ * * Method : POST * * Parameters : * DATABOX_ID : required INT * RECORD_ID : required INT * */ $controllers->post('/records/{databox_id}/{record_id}/setmetadatas/', function (SilexApplication $app, $databox_id, $record_id) { return $app['api']->set_record_metadatas($app['request'], $databox_id, $record_id)->get_response(); })->assert('databox_id', '\\d+')->assert('record_id', '\\d+'); $controllers->post('/records/{any_id}/{anyother_id}/setmetadatas/', $bad_request_exception); /** * Route : /records/DATABOX_ID/RECORD_ID/setstatus/ * * Method : POST * * Parameters : * DATABOX_ID : required INT * RECORD_ID : required INT * */ $controllers->post('/records/{databox_id}/{record_id}/setstatus/', function (SilexApplication $app, $databox_id, $record_id) { return $app['api']->set_record_status($app['request'], $databox_id, $record_id)->get_response(); })->assert('databox_id', '\\d+')->assert('record_id', '\\d+'); $controllers->post('/records/{any_id}/{anyother_id}/setstatus/', $bad_request_exception); /** * Route : /records/DATABOX_ID/RECORD_ID/setcollection/ * * Method : POST * * Parameters : * DATABOX_ID : required INT * RECORD_ID : required INT * */ $controllers->post('/records/{databox_id}/{record_id}/setcollection/', function (SilexApplication $app, $databox_id, $record_id) { return $app['api']->set_record_collection($app['request'], $databox_id, $record_id)->get_response(); })->assert('databox_id', '\\d+')->assert('record_id', '\\d+'); $controllers->post('/records/{wrong_databox_id}/{wrong_record_id}/setcollection/', $bad_request_exception); $controllers->get('/records/{databox_id}/{record_id}/', function (SilexApplication $app, $databox_id, $record_id) { return $app['api']->get_record($app['request'], $databox_id, $record_id)->get_response(); })->assert('databox_id', '\\d+')->assert('record_id', '\\d+'); $controllers->get('/records/{any_id}/{anyother_id}/', $bad_request_exception); /** * Route : /baskets/list/ * * Method : POST * * Parameters : * */ $controllers->get('/baskets/list/', function (SilexApplication $app) { return $app['api']->search_baskets($app['request'])->get_response(); }); /** * Route : /baskets/add/ * * Method : POST * * Parameters : * */ $controllers->post('/baskets/add/', function (SilexApplication $app) { return $app['api']->create_basket($app['request'])->get_response(); }); /** * Route : /baskets/BASKET_ID/content/ * * Method : GET * * Parameters : * BASKET_ID : required INT * */ $controllers->get('/baskets/{basket}/content/', function (SilexApplication $app, Basket $basket) { return $app['api']->get_basket($app['request'], $basket)->get_response(); })->before($app['middleware.basket.converter'])->before($app['middleware.basket.user-access'])->assert('basket', '\\d+'); $controllers->get('/baskets/{wrong_basket}/content/', $bad_request_exception); /** * Route : /baskets/BASKET_ID/settitle/ * * Method : GET * * Parameters : * BASKET_ID : required INT * */ $controllers->post('/baskets/{basket}/setname/', function (SilexApplication $app, Basket $basket) { return $app['api']->set_basket_title($app['request'], $basket)->get_response(); })->before($app['middleware.basket.converter'])->before($app['middleware.basket.user-is-owner'])->assert('basket', '\\d+'); $controllers->post('/baskets/{wrong_basket}/setname/', $bad_request_exception); /** * Route : /baskets/BASKET_ID/setdescription/ * * Method : POST * * Parameters : * BASKET_ID : required INT * */ $controllers->post('/baskets/{basket}/setdescription/', function (SilexApplication $app, Basket $basket) { return $app['api']->set_basket_description($app['request'], $basket)->get_response(); })->before($app['middleware.basket.converter'])->before($app['middleware.basket.user-is-owner'])->assert('basket', '\\d+'); $controllers->post('/baskets/{wrong_basket}/setdescription/', $bad_request_exception); /** * Route : /baskets/BASKET_ID/delete/ * * Method : POST * * Parameters : * BASKET_ID : required INT * */ $controllers->post('/baskets/{basket}/delete/', function (SilexApplication $app, Basket $basket) { return $app['api']->delete_basket($app['request'], $basket)->get_response(); })->before($app['middleware.basket.converter'])->before($app['middleware.basket.user-is-owner'])->assert('basket', '\\d+'); $controllers->post('/baskets/{wrong_basket}/delete/', $bad_request_exception); /** * Route : /feeds/list/ * * Method : POST * * Parameters : * */ $controllers->get('/feeds/list/', function (SilexApplication $app) { return $app['api']->search_publications($app['request'], $app['authentication']->getUser())->get_response(); }); $controllers->get('/feeds/content/', function (SilexApplication $app) { return $app['api']->get_publications($app['request'], $app['authentication']->getUser())->get_response(); }); $controllers->get('/feeds/entry/{entry_id}/', function (SilexApplication $app, $entry_id) { return $app['api']->get_feed_entry($app['request'], $entry_id, $app['authentication']->getUser())->get_response(); })->assert('entry_id', '\\d+'); $controllers->get('/feeds/entry/{entry_id}/', $bad_request_exception); /** * Route : /feeds/PUBLICATION_ID/content/ * * Method : GET * * Parameters : * PUBLICATION_ID : required INT * */ $controllers->get('/feeds/{feed_id}/content/', function (SilexApplication $app, $feed_id) { return $app['api']->get_publication($app['request'], $feed_id, $app['authentication']->getUser())->get_response(); })->assert('feed_id', '\\d+'); $controllers->get('/feeds/{wrong_feed_id}/content/', $bad_request_exception); /** * Route : /stories/DATABOX_ID/RECORD_ID/embed/ * * Method : GET * * Parameters : * DATABOX_ID : required INT * RECORD_ID : required INT * */ $controllers->get('/stories/{databox_id}/{story_id}/embed/', function ($databox_id, $story_id) use($app) { $result = $app['api']->get_story_embed($app['request'], $databox_id, $story_id); return $result->get_response(); })->assert('databox_id', '\\d+')->assert('story_id', '\\d+'); $controllers->get('/stories/{any_id}/{anyother_id}/embed/', $bad_request_exception); $controllers->get('/stories/{databox_id}/{story_id}/', function ($databox_id, $story_id) use($app) { $result = $app['api']->get_story($app['request'], $databox_id, $story_id); return $result->get_response(); })->assert('databox_id', '\\d+')->assert('story_id', '\\d+'); $controllers->get('/stories/{any_id}/{anyother_id}/', $bad_request_exception); $controllers->get('/stories/{databox_id}/{story_id}/', function ($databox_id, $story_id) use($app) { $result = $app['api']->get_story($app['request'], $databox_id, $story_id); return $result->get_response(); })->assert('databox_id', '\\d+')->assert('story_id', '\\d+'); $controllers->get('/stories/{any_id}/{anyother_id}/', $bad_request_exception); return $controllers; }
public function remember_this_ses_id($ses_id) { try { $token = API_OAuth2_Token::load_by_oauth_token($this->app, $this->token); $token->set_session_id($ses_id); return true; } catch (\Exception $e) { } return false; }
/** * * @return API_OAuth2_Token */ public function get_token() { if (!$this->token) { try { $this->token = new API_OAuth2_Token($this->app['phraseanet.appbox'], $this); } catch (NotFoundHttpException $e) { $this->token = API_OAuth2_Token::create($this->app['phraseanet.appbox'], $this); } } return $this->token; }
/** * Authorize application to use a grant password type * * @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) { 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); } $accessToken = $token->get_value(); } catch (\Exception $e) { $error = true; } return $app->json(['success' => !$error, 'token' => $accessToken]); }