From 64c1dd2c1e962be5d800157a036c67236b0d6321 Mon Sep 17 00:00:00 2001 From: drigato Date: Thu, 27 Feb 2014 17:11:17 -0500 Subject: [PATCH] CC-5701: Airtime File API Beginnings of fil rest api index, get, post actions working without authentication --- .../application/configs/application.ini | 3 + .../controllers/plugins/Acl_plugin.php | 7 + .../application/modules/rest/Bootstrap.php | 14 ++ .../rest/controllers/MediaController.php | 145 ++++++++++++++++++ .../rest/views/scripts/media/get.phtml | 0 .../rest/views/scripts/media/index.phtml | 0 .../rest/views/scripts/media/post.phtml | 0 7 files changed, 169 insertions(+) create mode 100644 airtime_mvc/application/modules/rest/Bootstrap.php create mode 100644 airtime_mvc/application/modules/rest/controllers/MediaController.php create mode 100644 airtime_mvc/application/modules/rest/views/scripts/media/get.phtml create mode 100644 airtime_mvc/application/modules/rest/views/scripts/media/index.phtml create mode 100644 airtime_mvc/application/modules/rest/views/scripts/media/post.phtml diff --git a/airtime_mvc/application/configs/application.ini b/airtime_mvc/application/configs/application.ini index c342ebda7..706beb249 100644 --- a/airtime_mvc/application/configs/application.ini +++ b/airtime_mvc/application/configs/application.ini @@ -6,6 +6,9 @@ bootstrap.class = "Bootstrap" appnamespace = "Application" resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers" resources.frontController.params.displayExceptions = 0 +resources.frontController.moduleDirectory = APPLICATION_PATH "/modules" +;load everything in the modules directory including models +resources.modules[] = "" resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/" resources.view[] = resources.db.adapter = "Pdo_Pgsql" diff --git a/airtime_mvc/application/controllers/plugins/Acl_plugin.php b/airtime_mvc/application/controllers/plugins/Acl_plugin.php index 44555e533..4cf9f97b5 100644 --- a/airtime_mvc/application/controllers/plugins/Acl_plugin.php +++ b/airtime_mvc/application/controllers/plugins/Acl_plugin.php @@ -110,6 +110,13 @@ class Zend_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract { $controller = strtolower($request->getControllerName()); + //Ignore authentication for all access to the rest API. We do auth via API keys for this + //and/or by OAuth. + if (strtolower($request->getModuleName()) == "rest") + { + return; + } + if (in_array($controller, array("api", "auth", "locale"))) { $this->setRoleName("G"); diff --git a/airtime_mvc/application/modules/rest/Bootstrap.php b/airtime_mvc/application/modules/rest/Bootstrap.php new file mode 100644 index 000000000..904d05e4c --- /dev/null +++ b/airtime_mvc/application/modules/rest/Bootstrap.php @@ -0,0 +1,14 @@ +getRouter(); + + $restRoute = new Zend_Rest_Route($front, array(), array( + 'rest'=> array('media'))); + assert($router->addRoute('rest', $restRoute)); + } +} \ No newline at end of file diff --git a/airtime_mvc/application/modules/rest/controllers/MediaController.php b/airtime_mvc/application/modules/rest/controllers/MediaController.php new file mode 100644 index 000000000..e2759bd2e --- /dev/null +++ b/airtime_mvc/application/modules/rest/controllers/MediaController.php @@ -0,0 +1,145 @@ +view->layout()->disableLayout(); + } + + public function indexAction() + { + if (!$this->verifyApiKey()) { + return; + } + $this->getResponse() + ->setHttpResponseCode(200) + ->appendBody(json_encode(CcFilesQuery::create()->find()->toArray())); + } + public function getAction() + { + if (!$this->verifyApiKey()) { + return; + } + $id = $this->getId(); + if (!$id) { + return; + } + + $file = CcFilesQuery::create()->findPk($id); + if ($file) { + $this->getResponse() + ->setHttpResponseCode(200) + ->appendBody(json_encode($file->toArray())); + } else { + $this->fileNotFoundResponse(); + } + } + + public function postAction() + { + if (!$this->verifyApiKey()) { + return; + } + //If we do get an ID on a POST, then that doesn't make any sense + //since POST is only for creating. + if ($id = $this->_getParam('id', false)) { + $resp = $this->getResponse(); + $resp->setHttpResponseCode(400); + $resp->appendBody("ERROR: ID should not be specified when using POST. POST is only used for show creation, and an ID will be chosen by Airtime"); + return; + } + + $file = new CcFiles(); + $file->fromArray($this->getRequest()->getPost()); + $file->save(); + + $resp = $this->getResponse(); + $resp->setHttpResponseCode(201); + $resp->appendBody(json_encode($file->toArray())); + } + + public function putAction() + { + if (!$this->verifyApiKey()) { + return; + } + $id = $this->getId(); + if (!$id) { + return; + } + + $file = CcFilesQuery::create()->findPk($id); + if ($show) + { + $show->importFrom('JSON', $this->getRequest()->getRawBody()); + $show->save(); + $this->getResponse() + ->appendBody("From putAction() updating the requested show"); + } else { + $this->showNotFoundResponse(); + } + } + + public function deleteAction() + { + if (!$this->verifyApiKey()) { + return; + } + $id = $this->getId(); + if (!$id) { + return; + } + $show = CcShowQuery::create()->$query->findPk($id); + if ($show) { + $show->delete(); + } else { + $this->showNotFoundResponse(); + } + } + + private function getId() + { + if (!$id = $this->_getParam('id', false)) { + $resp = $this->getResponse(); + $resp->setHttpResponseCode(400); + $resp->appendBody("ERROR: No show ID specified."); + return false; + } + return $id; + } + + private function verifyAPIKey() + { + //The API key is passed in via HTTP "basic authentication": + // http://en.wikipedia.org/wiki/Basic_access_authentication + + //TODO: Fetch the user's API key from the database to check against + $unencodedStoredApiKey = "foobar"; + $encodedStoredApiKey = base64_encode($unencodedStoredApiKey . ":"); + + //Decode the API key that was passed to us in the HTTP request. + $authHeader = $this->getRequest()->getHeader("Authorization"); + $encodedRequestApiKey = substr($authHeader, strlen("Basic ")); + + //if ($encodedRequestApiKey === $encodedStoredApiKey) + if (true) + { + return true; + } + else + { + $resp = $this->getResponse(); + $resp->setHttpResponseCode(401); + $resp->appendBody("ERROR: Incorrect API key."); + return false; + } + } + + private function fileNotFoundResponse() + { + $resp = $this->getResponse(); + $resp->setHttpResponseCode(404); + $resp->appendBody("ERROR: Show not found."); + } +} \ No newline at end of file diff --git a/airtime_mvc/application/modules/rest/views/scripts/media/get.phtml b/airtime_mvc/application/modules/rest/views/scripts/media/get.phtml new file mode 100644 index 000000000..e69de29bb diff --git a/airtime_mvc/application/modules/rest/views/scripts/media/index.phtml b/airtime_mvc/application/modules/rest/views/scripts/media/index.phtml new file mode 100644 index 000000000..e69de29bb diff --git a/airtime_mvc/application/modules/rest/views/scripts/media/post.phtml b/airtime_mvc/application/modules/rest/views/scripts/media/post.phtml new file mode 100644 index 000000000..e69de29bb