fix docblocks
[grauphel.git] / controller / apicontroller.php
index 8ce8997..aa21429 100644 (file)
@@ -16,8 +16,10 @@ namespace OCA\Grauphel\Controller;
 use \OCP\AppFramework\Controller;
 use \OCP\AppFramework\Http\JSONResponse;
 
+use \OCA\Grauphel\Lib\NoteStorage;
 use \OCA\Grauphel\Lib\OAuth;
 use \OCA\Grauphel\Lib\Dependencies;
+use \OCA\Grauphel\Lib\Response\ErrorResponse;
 
 /**
  * Tomboy's REST API
@@ -33,13 +35,30 @@ use \OCA\Grauphel\Lib\Dependencies;
 class ApiController extends Controller
 {
     /**
+     * constructor of the controller
+     *
+     * @param string   $appName Name of the app
+     * @param IRequest $request Instance of the request
+     */
+    public function __construct($appName, \OCP\IRequest $request, $user)
+    {
+        parent::__construct($appName, $request);
+        $this->user  = $user;
+        $this->deps  = Dependencies::get();
+        $this->notes = new NoteStorage($this->deps->urlGen);
+
+        //default http header: we assume something is broken
+        header('HTTP/1.0 500 Internal Server Error');
+    }
+
+    /**
      * /api/1.0
      *
      * @NoAdminRequired
      * @NoCSRFRequired
      * @PublicPage
      */
-    public function index()
+    public function index($route = 'grauphel.api.index')
     {
         $deps = Dependencies::get();
         $authenticated = false;
@@ -48,12 +67,12 @@ class ApiController extends Controller
         $urlGen = $deps->urlGen;
 
         try {
-            $provider = new \OAuthProvider();
+            $provider = OAuth::getProvider();
             $oauth->registerHandler($provider)
                 ->registerAccessTokenHandler($provider);
             $provider->checkOAuthRequest(
                 $urlGen->getAbsoluteURL(
-                    $urlGen->linkToRoute('grauphel.api.index')
+                    $urlGen->linkToRoute($route)
                 )
             );
             $authenticated = true;
@@ -61,11 +80,15 @@ class ApiController extends Controller
             $username = $token->user;
 
         } catch (\OAuth_Exception $e) {
-            $deps->renderer->errorOut($e->getMessage());
+            return new ErrorResponse($e->getMessage());
         } catch (\OAuthException $e) {
             if ($e->getCode() != OAUTH_PARAMETER_ABSENT) {
                 $oauth->error($e);
             }
+            if ($this->user !== null) {
+                $username = $this->user->getUID();
+                $authenticated = true;
+            }
         }
 
         $data = array(
@@ -85,7 +108,7 @@ class ApiController extends Controller
             $data['user-ref'] = array(
                 'api-ref' => $urlGen->getAbsoluteURL(
                     $urlGen->linkToRoute(
-                        'grauphel.api.user', array('user' => $username)
+                        'grauphel.api.user', array('username' => $username)
                     )
                 ),
                 'href' => null,//FIXME
@@ -93,65 +116,116 @@ class ApiController extends Controller
         }
 
         return new JSONResponse($data);
-        $deps->renderer->sendJson($data);
     }
 
     /**
-     * GET /api/1.0/$user/notes/$noteguid
+     * /api/1.0/
      *
      * @NoAdminRequired
      * @NoCSRFRequired
      * @PublicPage
      */
-    public function note()
+    public function indexSlash()
     {
-        $deps = Dependencies::get();
-        $username = $deps->urlGen->loadUsername();
-        $guid     = $deps->urlGen->loadGuid();
-        $oauth = new \OAuth();
-        $oauth->setDeps($deps);
-        $oauth->verifyOAuthUser($username, $deps->urlGen->note($username, $guid));
+        return $this->index('grauphel.api.indexSlash');
+    }
 
-        $note = $deps->notes->load($username, $guid, false);
-        if ($note === null) {
-            header('HTTP/1.0 404 Not Found');
-            header('Content-type: text/plain');
-            echo "Note does not exist\n";
-            exit(1);
-        }
+    /**
+     * GET /api/1.0/$user
+     *
+     * @NoAdminRequired
+     * @NoCSRFRequired
+     * @PublicPage
+     */
+    public function user($username)
+    {
+        $this->verifyUser(
+            $username,
+            $this->deps->urlGen->getAbsoluteURL(
+                $this->deps->urlGen->linkToRoute(
+                    'grauphel.api.user', array('username' => $username)
+                )
+            )
+        );
+        $syncdata = $this->notes->loadSyncData($username);
 
-        $data = array('note' => array($note));
-        $deps->renderer->sendJson($data);
+        $data = array(
+            'user-name'  => $username,
+            'first-name' => null,
+            'last-name'  => null,
+            'notes-ref'  => array(
+                'api-ref' => $this->deps->urlGen->getAbsoluteURL(
+                    $this->deps->urlGen->linkToRoute(
+                        'grauphel.api.notes', array('username' => $username)
+                    )
+                ),
+                'href'    => null,
+            ),
+            'latest-sync-revision' => $syncdata->latestSyncRevision,
+            'current-sync-guid'    => $syncdata->currentSyncGuid,
+        );
+        return new JSONResponse($data);
     }
 
     /**
-     * GET|PUT /api/1.0/$user/notes
+     * GET /api/1.0/$user/notes
      *
      * @NoAdminRequired
      * @NoCSRFRequired
      * @PublicPage
      */
-    public function notes()
+    public function notes($username)
     {
-        $deps = Dependencies::get();
-        $username = $deps->urlGen->loadUsername();
-        $oauth = new \OAuth();
-        $oauth->setDeps($deps);
-        $oauth->verifyOAuthUser($username, $deps->urlGen->notes($username));
+        $this->verifyUser(
+            $username,
+            $this->deps->urlGen->getAbsoluteURL(
+                $this->deps->urlGen->linkToRoute(
+                    'grauphel.api.notes', array('username' => $username)
+                )
+            )
+        );
+        $syncdata = $this->notes->loadSyncData($username);
+        return $this->fetchNotes($username, $syncdata);
+    }
 
-        $syncdata = $deps->notes->loadSyncData($username);
+    /**
+     * PUT /api/1.0/$user/notes
+     *
+     * @NoAdminRequired
+     * @NoCSRFRequired
+     * @PublicPage
+     */
+    public function notesSave($username)
+    {
+        $this->verifyUser(
+            $username,
+            $this->deps->urlGen->getAbsoluteURL(
+                $this->deps->urlGen->linkToRoute(
+                    'grauphel.api.notesSave', array('username' => $username)
+                )
+            )
+        );
+        $syncdata = $this->notes->loadSyncData($username);
+        
+        $res = $this->handleNoteSave($username, $syncdata);
+        if ($res instanceof \OCP\AppFramework\Http\Response) {
+            return $res;
+        }
 
-        $this->handleNoteSave($username, $syncdata);
+        return $this->fetchNotes($username, $syncdata);
+    }
 
+    protected function fetchNotes($username, $syncdata)
+    {
         $since = null;
         if (isset($_GET['since'])) {
             $since = (int) $_GET['since'];
         }
 
         if (isset($_GET['include_notes']) && $_GET['include_notes']) {
-            $notes = $deps->notes->loadNotesFull($username, $since);
+            $notes = $this->notes->loadNotesFull($username, $since);
         } else {
-            $notes = $deps->notes->loadNotesOverview($username, $since);
+            $notes = $this->notes->loadNotesOverview($username, $since);
         }
 
         //work around bug https://bugzilla.gnome.org/show_bug.cgi?id=734313
@@ -165,7 +239,7 @@ class ApiController extends Controller
             'latest-sync-revision' => $syncdata->latestSyncRevision,
             'notes' => $notes,
         );
-        $deps->renderer->sendJson($data);
+        return new JSONResponse($data);
     }
 
     protected function handleNoteSave($username, $syncdata)
@@ -174,80 +248,99 @@ class ApiController extends Controller
             return;
         }
 
-        $data = file_get_contents('php://input');
-        $putObj = json_decode($data);
-        if ($putObj === NULL) {
-            errorOut('Invalid JSON data in PUT request');
-        }
+        //note that we have more data in $arPut than just our JSON
+        // request object merges it with other data
+        $arPut = $this->request->put;
 
         //structural validation
-        if (!isset($putObj->{'latest-sync-revision'})) {
-            errorOut('Missing "latest-sync-revision"');
+        if (!isset($arPut['latest-sync-revision'])) {
+            return new ErrorResponse('Missing "latest-sync-revision"');
         }
-        if (!isset($putObj->{'note-changes'})) {
-            errorOut('Missing "note-changes"');
+        if (!isset($arPut['note-changes'])) {
+            return new ErrorResponse('Missing "note-changes"');
         }
-        foreach ($putObj->{'note-changes'} as $note) {
+        foreach ($arPut['note-changes'] as $note) {
+            //owncloud converts object to array, so we reverse
+            $note = (object) $note;
             if (!isset($note->guid) || $note->guid == '') {
-                errorOut('Missing "guid" on note');
+                return new ErrorResponse('Missing "guid" on note');
             }
         }
 
         //content validation
-        if ($putObj->{'latest-sync-revision'} != $syncdata->latestSyncRevision +1
+        if ($arPut['latest-sync-revision'] != $syncdata->latestSyncRevision +1
             && $syncdata->latestSyncRevision != -1
         ) {
-            errorOut('Wrong "latest-sync-revision". You are not up to date.');
+            return new ErrorResponse(
+                'Wrong "latest-sync-revision". You are not up to date.'
+            );
         }
 
         //update
-        $deps = Dependencies::get();
         ++$syncdata->latestSyncRevision;
-        foreach ($putObj->{'note-changes'} as $noteUpdate) {
-            $note = $deps->notes->load($username, $noteUpdate->guid);
+        foreach ($arPut['note-changes'] as $noteUpdate) {
+            //owncloud converts object to array, so we reverse
+            $noteUpdate = (object) $noteUpdate;
+
+            $note = $this->notes->load($username, $noteUpdate->guid);
             if (isset($noteUpdate->command) && $noteUpdate->command == 'delete') {
-                $deps->notes->delete($username, $noteUpdate->guid);
+                $this->notes->delete($username, $noteUpdate->guid);
             } else {
-                $deps->notes->update(
+                $this->notes->update(
                     $note, $noteUpdate, $syncdata->latestSyncRevision
                 );
-                $deps->notes->save($username, $note);
+                $this->notes->save($username, $note);
             }
         }
 
-        $deps->notes->saveSyncData($username, $syncdata);
+        $this->notes->saveSyncData($username, $syncdata);
     }
 
     /**
-     * GET /api/1.0/$user
+     * GET /api/1.0/$user/notes/$noteguid
      *
      * @NoAdminRequired
      * @NoCSRFRequired
      * @PublicPage
      */
-    public function user()
+    public function note()
     {
+        //FIXME
         $deps = Dependencies::get();
         $username = $deps->urlGen->loadUsername();
-
+        $guid     = $deps->urlGen->loadGuid();
         $oauth = new \OAuth();
         $oauth->setDeps($deps);
-        $oauth->verifyOAuthUser($username, $deps->urlGen->user($username));
+        $oauth->verifyOAuthUser($username, $deps->urlGen->note($username, $guid));
 
-        $syncdata = $deps->notes->loadSyncData($username);
+        $note = $this->notes->load($username, $guid, false);
+        if ($note === null) {
+            header('HTTP/1.0 404 Not Found');
+            header('Content-type: text/plain');
+            echo "Note does not exist\n";
+            exit(1);
+        }
 
-        $data = array(
-            'user-name'  => $username,
-            'first-name' => null,
-            'last-name'  => null,
-            'notes-ref'  => array(
-                'api-ref' => $deps->urlGen->notes($username),
-                'href'    => null,
-            ),
-            'latest-sync-revision' => $syncdata->latestSyncRevision,
-            'current-sync-guid'    => $syncdata->currentSyncGuid,
-        );
+        $data = array('note' => array($note));
         $deps->renderer->sendJson($data);
     }
+
+    /**
+     * Checks if the given user is authorized (by oauth token or normal login)
+     *
+     * @param string $username Username to verify
+     *
+     * @return boolean True if all is fine, Response in case of an error
+     */
+    protected function verifyUser($username, $curUrl)
+    {
+        if ($this->user !== null && $this->user->getUID() == $username) {
+            return true;
+        }
+
+        $oauth = new OAuth();
+        $oauth->setDeps($this->deps);
+        $oauth->verifyOAuthUser($username, $curUrl);
+    }
 }
 ?>