9 * @author Christian Weiske <cweiske@cweiske.de>
10 * @copyright 2014 Christian Weiske
11 * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
12 * @link http://cweiske.de/grauphel.htm
14 namespace OCA\Grauphel\Controller;
16 use \OCP\AppFramework\Controller;
17 use \OCP\AppFramework\Http\JSONResponse;
19 use \OCA\Grauphel\Lib\NoteStorage;
20 use \OCA\Grauphel\Lib\OAuth;
21 use \OCA\Grauphel\Lib\Dependencies;
22 use \OCA\Grauphel\Lib\Response\ErrorResponse;
29 * @author Christian Weiske <cweiske@cweiske.de>
30 * @copyright 2014 Christian Weiske
31 * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
32 * @version Release: @package_version@
33 * @link http://cweiske.de/grauphel.htm
35 class ApiController extends Controller
38 * constructor of the controller
40 * @param string $appName Name of the app
41 * @param IRequest $request Instance of the request
43 public function __construct($appName, \OCP\IRequest $request, $user)
45 parent::__construct($appName, $request);
47 $this->deps = Dependencies::get();
48 $this->notes = new NoteStorage($this->deps->urlGen);
50 //default http header: we assume something is broken
51 header('HTTP/1.0 500 Internal Server Error');
61 public function index($route = 'grauphel.api.index')
63 $deps = Dependencies::get();
64 $authenticated = false;
66 $oauth->setDeps($deps);
67 $urlGen = $deps->urlGen;
70 $provider = new \OAuthProvider();
71 $oauth->registerHandler($provider)
72 ->registerAccessTokenHandler($provider);
73 $provider->checkOAuthRequest(
74 $urlGen->getAbsoluteURL(
75 $urlGen->linkToRoute($route)
78 $authenticated = true;
79 $token = $deps->tokens->load('access', $provider->token);
80 $username = $token->user;
82 } catch (\OAuth_Exception $e) {
83 return new ErrorResponse($e->getMessage());
84 } catch (\OAuthException $e) {
85 if ($e->getCode() != OAUTH_PARAMETER_ABSENT) {
88 if ($this->user !== null) {
89 $username = $this->user->getUID();
90 $authenticated = true;
95 'oauth_request_token_url' => $urlGen->getAbsoluteURL(
96 $urlGen->linkToRoute('grauphel.oauth.requestToken')
98 'oauth_authorize_url' => $urlGen->getAbsoluteURL(
99 $urlGen->linkToRoute('grauphel.oauth.authorize')
101 'oauth_access_token_url' => $urlGen->getAbsoluteURL(
102 $urlGen->linkToRoute('grauphel.oauth.accessToken')
104 'api-version' => '1.0',
107 if ($authenticated) {
108 $data['user-ref'] = array(
109 'api-ref' => $urlGen->getAbsoluteURL(
110 $urlGen->linkToRoute(
111 'grauphel.api.user', array('username' => $username)
114 'href' => null,//FIXME
118 return new JSONResponse($data);
128 public function indexSlash()
130 return $this->index('grauphel.api.indexSlash');
140 public function user($username)
144 $this->deps->urlGen->getAbsoluteURL(
145 $this->deps->urlGen->linkToRoute(
146 'grauphel.api.user', array('username' => $username)
150 $syncdata = $this->notes->loadSyncData($username);
153 'user-name' => $username,
154 'first-name' => null,
156 'notes-ref' => array(
157 'api-ref' => $this->deps->urlGen->getAbsoluteURL(
158 $this->deps->urlGen->linkToRoute(
159 'grauphel.api.notes', array('username' => $username)
164 'latest-sync-revision' => $syncdata->latestSyncRevision,
165 'current-sync-guid' => $syncdata->currentSyncGuid,
167 return new JSONResponse($data);
171 * GET /api/1.0/$user/notes
177 public function notes($username)
181 $this->deps->urlGen->getAbsoluteURL(
182 $this->deps->urlGen->linkToRoute(
183 'grauphel.api.notes', array('username' => $username)
187 $syncdata = $this->notes->loadSyncData($username);
188 return $this->fetchNotes($username, $syncdata);
192 * PUT /api/1.0/$user/notes
198 public function notesSave($username)
202 $this->deps->urlGen->getAbsoluteURL(
203 $this->deps->urlGen->linkToRoute(
204 'grauphel.api.notesSave', array('username' => $username)
208 $syncdata = $this->notes->loadSyncData($username);
210 $res = $this->handleNoteSave($username, $syncdata);
211 if ($res instanceof \OCP\AppFramework\Http\Response) {
215 return $this->fetchNotes($username, $syncdata);
218 protected function fetchNotes($username, $syncdata)
221 if (isset($_GET['since'])) {
222 $since = (int) $_GET['since'];
225 if (isset($_GET['include_notes']) && $_GET['include_notes']) {
226 $notes = $this->notes->loadNotesFull($username, $since);
228 $notes = $this->notes->loadNotesOverview($username, $since);
231 //work around bug https://bugzilla.gnome.org/show_bug.cgi?id=734313
232 foreach ($notes as $note) {
233 if (isset($note->{'note-content-version'})) {
234 $note->{'note-content-version'} = 0.3;
239 'latest-sync-revision' => $syncdata->latestSyncRevision,
242 return new JSONResponse($data);
245 protected function handleNoteSave($username, $syncdata)
247 if ($_SERVER['REQUEST_METHOD'] != 'PUT') {
251 //note that we have more data in $arPut than just our JSON
252 // request object merges it with other data
253 $arPut = $this->request->put;
255 //structural validation
256 if (!isset($arPut['latest-sync-revision'])) {
257 return new ErrorResponse('Missing "latest-sync-revision"');
259 if (!isset($arPut['note-changes'])) {
260 return new ErrorResponse('Missing "note-changes"');
262 foreach ($arPut['note-changes'] as $note) {
263 //owncloud converts object to array, so we reverse
264 $note = (object) $note;
265 if (!isset($note->guid) || $note->guid == '') {
266 return new ErrorResponse('Missing "guid" on note');
271 if ($arPut['latest-sync-revision'] != $syncdata->latestSyncRevision +1
272 && $syncdata->latestSyncRevision != -1
274 return new ErrorResponse(
275 'Wrong "latest-sync-revision". You are not up to date.'
280 ++$syncdata->latestSyncRevision;
281 foreach ($arPut['note-changes'] as $noteUpdate) {
282 //owncloud converts object to array, so we reverse
283 $noteUpdate = (object) $noteUpdate;
285 $note = $this->notes->load($username, $noteUpdate->guid);
286 if (isset($noteUpdate->command) && $noteUpdate->command == 'delete') {
287 $this->notes->delete($username, $noteUpdate->guid);
289 $this->notes->update(
290 $note, $noteUpdate, $syncdata->latestSyncRevision
292 $this->notes->save($username, $note);
296 $this->notes->saveSyncData($username, $syncdata);
300 * GET /api/1.0/$user/notes/$noteguid
306 public function note()
309 $deps = Dependencies::get();
310 $username = $deps->urlGen->loadUsername();
311 $guid = $deps->urlGen->loadGuid();
312 $oauth = new \OAuth();
313 $oauth->setDeps($deps);
314 $oauth->verifyOAuthUser($username, $deps->urlGen->note($username, $guid));
316 $note = $this->notes->load($username, $guid, false);
317 if ($note === null) {
318 header('HTTP/1.0 404 Not Found');
319 header('Content-type: text/plain');
320 echo "Note does not exist\n";
324 $data = array('note' => array($note));
325 $deps->renderer->sendJson($data);
329 * Checks if the given user is authorized (by oauth token or normal login)
331 * @param string $username Username to verify
333 * @return boolean True if all is fine, Response in case of an error
335 protected function verifyUser($username, $curUrl)
337 if ($this->user !== null && $this->user->getUID() == $username) {
341 $oauth = new OAuth();
342 $oauth->setDeps($this->deps);
343 $oauth->verifyOAuthUser($username, $curUrl);