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\OAuthException;
22 use \OCA\Grauphel\Lib\Dependencies;
23 use \OCA\Grauphel\Lib\Response\ErrorResponse;
30 * @author Christian Weiske <cweiske@cweiske.de>
31 * @copyright 2014 Christian Weiske
32 * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
33 * @version Release: @package_version@
34 * @link http://cweiske.de/grauphel.htm
36 class ApiController extends Controller
39 * constructor of the controller
41 * @param string $appName Name of the app
42 * @param IRequest $request Instance of the request
44 public function __construct($appName, \OCP\IRequest $request, $user)
46 parent::__construct($appName, $request);
48 $this->deps = Dependencies::get();
49 $this->notes = new NoteStorage($this->deps->urlGen);
51 //default http header: we assume something is broken
52 header('HTTP/1.0 500 Internal Server Error');
62 public function index($route = 'grauphel.api.index')
64 $deps = Dependencies::get();
65 $authenticated = false;
67 $oauth->setDeps($deps);
68 $urlGen = $deps->urlGen;
71 $provider = OAuth::getProvider();
72 $oauth->registerHandler($provider)
73 ->registerAccessTokenHandler($provider);
74 $provider->checkOAuthRequest(
75 $urlGen->getAbsoluteURL(
76 $urlGen->linkToRoute($route)
79 $authenticated = true;
80 $token = $deps->tokens->load('access', $provider->token);
81 $username = $token->user;
83 } catch (OAuthException $e) {
84 return new ErrorResponse($e->getMessage());
85 } catch (\OAuthException $e) {
86 if ($e->getCode() != OAUTH_PARAMETER_ABSENT) {
89 if ($this->user !== null) {
90 $username = $this->user->getUID();
91 $authenticated = true;
96 'oauth_request_token_url' => $urlGen->getAbsoluteURL(
97 $urlGen->linkToRoute('grauphel.oauth.requestToken')
99 'oauth_authorize_url' => $urlGen->getAbsoluteURL(
100 $urlGen->linkToRoute('grauphel.oauth.authorize')
102 'oauth_access_token_url' => $urlGen->getAbsoluteURL(
103 $urlGen->linkToRoute('grauphel.oauth.accessToken')
105 'api-version' => '1.0',
108 if ($authenticated) {
109 $data['user-ref'] = array(
110 'api-ref' => $urlGen->getAbsoluteURL(
111 $urlGen->linkToRoute(
112 'grauphel.api.user', array('username' => $username)
115 'href' => null,//FIXME
119 return new JSONResponse($data);
129 public function indexSlash()
131 return $this->index('grauphel.api.indexSlash');
141 public function user($username)
145 $this->deps->urlGen->getAbsoluteURL(
146 $this->deps->urlGen->linkToRoute(
147 'grauphel.api.user', array('username' => $username)
151 $syncdata = $this->notes->loadSyncData();
154 'user-name' => $username,
155 'first-name' => null,
157 'notes-ref' => array(
158 'api-ref' => $this->deps->urlGen->getAbsoluteURL(
159 $this->deps->urlGen->linkToRoute(
160 'grauphel.api.notes', array('username' => $username)
165 'latest-sync-revision' => $syncdata->latestSyncRevision,
166 'current-sync-guid' => $syncdata->currentSyncGuid,
168 return new JSONResponse($data);
172 * GET /api/1.0/$user/notes
178 public function notes($username)
182 $this->deps->urlGen->getAbsoluteURL(
183 $this->deps->urlGen->linkToRoute(
184 'grauphel.api.notes', array('username' => $username)
188 $syncdata = $this->notes->loadSyncData();
189 return $this->fetchNotes($syncdata);
193 * PUT /api/1.0/$user/notes
199 public function notesSave($username)
203 $this->deps->urlGen->getAbsoluteURL(
204 $this->deps->urlGen->linkToRoute(
205 'grauphel.api.notesSave', array('username' => $username)
209 $syncdata = $this->notes->loadSyncData();
211 $res = $this->handleNoteSave($username, $syncdata);
212 if ($res instanceof \OCP\AppFramework\Http\Response) {
216 return $this->fetchNotes($syncdata);
219 protected function fetchNotes($syncdata)
222 if (isset($_GET['since'])) {
223 $since = (int) $_GET['since'];
226 if (isset($_GET['include_notes']) && $_GET['include_notes']) {
227 $notes = $this->notes->loadNotesFull($since);
229 $notes = $this->notes->loadNotesOverview($since);
232 //work around bug https://bugzilla.gnome.org/show_bug.cgi?id=734313
233 foreach ($notes as $note) {
234 if (isset($note->{'note-content-version'})) {
235 $note->{'note-content-version'} = 0.3;
240 'latest-sync-revision' => $syncdata->latestSyncRevision,
243 return new JSONResponse($data);
246 protected function handleNoteSave($username, $syncdata)
248 if ($_SERVER['REQUEST_METHOD'] != 'PUT') {
252 //note that we have more data in $arPut than just our JSON
253 // request object merges it with other data
254 $arPut = $this->request->put;
256 //structural validation
257 if (!isset($arPut['latest-sync-revision'])) {
258 return new ErrorResponse('Missing "latest-sync-revision"');
260 if (!isset($arPut['note-changes'])) {
261 return new ErrorResponse('Missing "note-changes"');
263 foreach ($arPut['note-changes'] as $note) {
264 //owncloud converts object to array, so we reverse
265 $note = (object) $note;
266 if (!isset($note->guid) || $note->guid == '') {
267 return new ErrorResponse('Missing "guid" on note');
272 if ($arPut['latest-sync-revision'] != $syncdata->latestSyncRevision +1
273 && $syncdata->latestSyncRevision != -1
275 return new ErrorResponse(
276 'Wrong "latest-sync-revision". You are not up to date.'
281 ++$syncdata->latestSyncRevision;
282 foreach ($arPut['note-changes'] as $noteUpdate) {
283 //owncloud converts object to array, so we reverse
284 $noteUpdate = (object) $noteUpdate;
286 $note = $this->notes->load($noteUpdate->guid);
287 if (isset($noteUpdate->command) && $noteUpdate->command == 'delete') {
288 $this->notes->delete($noteUpdate->guid);
290 $this->notes->update(
291 $note, $noteUpdate, $syncdata->latestSyncRevision
293 $this->notes->save($note);
297 $this->notes->saveSyncData($syncdata);
301 * GET /api/1.0/$user/notes/$noteguid
307 public function note($username, $guid)
311 $this->deps->urlGen->getAbsoluteURL(
312 $this->deps->urlGen->linkToRoute(
314 array('username' => $username, 'guid' => $guid)
319 $note = $this->notes->load($guid, false);
320 if ($note === null) {
321 header('HTTP/1.0 404 Not Found');
322 header('Content-type: text/plain');
323 echo "Note does not exist\n";
327 return new JSONResponse($note);
331 * Checks if the given user is authorized (by oauth token or normal login)
333 * @param string $username Username to verify
335 * @return boolean True if all is fine, Response in case of an error
337 protected function verifyUser($username, $curUrl)
339 if ($this->user !== null && $this->user->getUid() == $username) {
340 $this->notes->setUsername($username);
344 $oauth = new OAuth();
345 $oauth->setDeps($this->deps);
346 $oauth->verifyOAuthUser($username, $curUrl);
348 $this->notes->setUsername($username);