From 39899dda81f270bb275decb0cb4e853abacb1031 Mon Sep 17 00:00:00 2001 From: posativ Date: Tue, 23 Oct 2012 21:09:51 +0200 Subject: [PATCH] /comment/ -> /1.0/ --- Readme.md | 32 ++++++++++++------------- isso/__init__.py | 8 +++---- isso/comment.py | 2 +- isso/static/post.html | 6 ++--- specs/test_comment.py | 56 +++++++++++++++++++++---------------------- 5 files changed, 52 insertions(+), 52 deletions(-) diff --git a/Readme.md b/Readme.md index 0c22fc4..dd570e1 100644 --- a/Readme.md +++ b/Readme.md @@ -38,33 +38,33 @@ please file in a bug report \*including\* your dump. ## API -### fetch comments for /foo-bar/ +To fetch all comments for a path, run $ curl -H "Accept: application/json" http://example.org/comment/foo-bar/ -### comment at /foo-bar/ +To write a comment, you have to POST a JSON dictionary with the following key-value +pairs. Text is mandatory otherwise you'll get a 400 Bad Request. You'll also get +a 400 when your JSON is invalid. - $ curl -H "Accept: application/json" -X POST -d \ +Let's say you want to comment on /foo-bar/ + + $ curl http://example.org/comment/foo-bar/new -H "Accept: application/json" -X POST -d \ '{ "text": "Lorem ipsum ...", - - # optional "name": "Hans", "email": "foo@bla.org", "website": "http://blog/log/" - }' http://example.org/comment/foo-bar/new + }' -### modify 12. comment at /foo-bar/ +This will set a cookie, that expires in a few minutes (15 minutes per default). This +cookie allows you do modify or delete your comment. Don't try to modify that cookie, +it is cryptographically signed. If your cookie is outdated or modified, you'll get +a 403 Forbidden. - $ curl -H "Accept: application/json" -X PUT -d ... http://example.org/comment/foo-bar/12 +For each comment you'll post, you get an unique cookie. Let's try to remove your comment: -You can only modify your own comment in a given time range (defaults to 15 minutes). + $ curl -H ... -X DELETE http://example.org/comment/foo-bar/1 -### delete 2nd comment at /foo-bar/ - - $ curl -H ... -X DELETE http://example.org/comment/foo-bar/2 - -You can only delete your own comment in a given time range (defaults to 15 minutes). If -your comment has been referenced by another comment, your comment will be cleared but not -deleted to maintain depending comments. +If your comment has been referenced by another comment, your comment will be cleared but +not deleted to retain depending comments. ## Alternatives diff --git a/isso/__init__.py b/isso/__init__.py index 322552e..7f446ab 100644 --- a/isso/__init__.py +++ b/isso/__init__.py @@ -55,10 +55,10 @@ url_map = Map([ # comment API, note that the client side quotes the URL, but this is # actually unnecessary. PEP 333 aka WSGI always unquotes PATH_INFO. - url('/comment//', 'comment.get', ['GET']), - url('/comment//new', 'comment.create', ['POST']), - url('/comment//', 'comment.get', ['GET']), - url('/comment//', 'comment.modify', ['PUT', 'DELETE']), + url('/1.0//', 'comment.get', ['GET']), + url('/1.0//new', 'comment.create', ['POST']), + url('/1.0//', 'comment.get', ['GET']), + url('/1.0//', 'comment.modify', ['PUT', 'DELETE']), ], converters={'re': RegexConverter}) diff --git a/isso/comment.py b/isso/comment.py index 6754140..4c80d20 100644 --- a/isso/comment.py +++ b/isso/comment.py @@ -72,7 +72,7 @@ def modify(app, environ, request, path, id): abort(403) if not (rv[0] == '*' or rv[0:2] == [path, id]): - abort(401) + abort(403) if request.method == 'PUT': try: diff --git a/isso/static/post.html b/isso/static/post.html index 5a8e6bd..c315a9b 100644 --- a/isso/static/post.html +++ b/isso/static/post.html @@ -67,7 +67,7 @@ } $.ajax({ - url: '/comment/' + encodeURIComponent(window.location.pathname) + '/new', + url: '/1.0/' + encodeURIComponent(window.location.pathname) + '/new', method: 'POST', type: 'json', headers: { @@ -168,7 +168,7 @@ $('#isso_' + post['id'] + ' > footer .delete').on('click', function(event) { $.ajax({ - url: '/comment/' + encodeURIComponent(window.location.pathname) + '/' + post['id'], + url: '/1.0/' + encodeURIComponent(window.location.pathname) + '/' + post['id'], method: 'DELETE', error: function(resp) { alert('Mööp!'); @@ -196,7 +196,7 @@ var fetch = function(thread) { var rv = $.ajax({ - url: '/comment/' + encodeURIComponent(window.location.pathname) + '/', + url: '/1.0/' + encodeURIComponent(window.location.pathname) + '/', method: 'GET', type: 'json', headers: { diff --git a/specs/test_comment.py b/specs/test_comment.py index 0513d3a..16933b0 100644 --- a/specs/test_comment.py +++ b/specs/test_comment.py @@ -29,8 +29,8 @@ class TestComments(unittest.TestCase): def testGet(self): - self.post('/comment/path/new', data=json.dumps(comment(text='Lorem ipsum ...'))) - r = self.get('/comment/path/1') + self.post('/1.0/path/new', data=json.dumps(comment(text='Lorem ipsum ...'))) + r = self.get('/1.0/path/1') assert r.status_code == 200 rv = json.loads(r.data) @@ -40,7 +40,7 @@ class TestComments(unittest.TestCase): def testCreate(self): - rv = self.post('/comment/path/new', data=json.dumps(comment(text='Lorem ipsum ...'))) + rv = self.post('/1.0/path/new', data=json.dumps(comment(text='Lorem ipsum ...'))) assert rv.status_code == 201 assert len(filter(lambda header: header[0] == 'Set-Cookie', rv.headers)) == 1 @@ -54,9 +54,9 @@ class TestComments(unittest.TestCase): def testCreateAndGetMultiple(self): for i in range(20): - self.post('/comment/path/new', data=json.dumps(comment(text='Spam'))) + self.post('/1.0/path/new', data=json.dumps(comment(text='Spam'))) - r = self.get('/comment/path/') + r = self.get('/1.0/path/') assert r.status_code == 200 rv = json.loads(r.data) @@ -64,17 +64,17 @@ class TestComments(unittest.TestCase): def testGetInvalid(self): - assert self.get('/comment/path/123').status_code == 404 - assert self.get('/comment/path/spam/123').status_code == 404 - assert self.get('/comment/foo/').status_code == 404 + assert self.get('/1.0/path/123').status_code == 404 + assert self.get('/1.0/path/spam/123').status_code == 404 + assert self.get('/1.0/foo/').status_code == 404 def testUpdate(self): - self.post('/comment/path/new', data=json.dumps(comment(text='Lorem ipsum ...'))) - self.put('/comment/path/1', data=json.dumps(comment( + self.post('/1.0/path/new', data=json.dumps(comment(text='Lorem ipsum ...'))) + self.put('/1.0/path/1', data=json.dumps(comment( text='Hello World', author='me', website='http://example.com/'))) - r = self.get('/comment/path/1') + r = self.get('/1.0/path/1') assert r.status_code == 200 rv = json.loads(r.data) @@ -85,45 +85,45 @@ class TestComments(unittest.TestCase): def testDelete(self): - self.post('/comment/path/new', data=json.dumps(comment(text='Lorem ipsum ...'))) - r = self.delete('/comment/path/1') + self.post('/1.0/path/new', data=json.dumps(comment(text='Lorem ipsum ...'))) + r = self.delete('/1.0/path/1') assert r.status_code == 200 assert json.loads(r.data) == None - assert self.get('/comment/path/1').status_code == 404 + assert self.get('/1.0/path/1').status_code == 404 def testDeleteWithReference(self): client = Client(self.app, Response) - resp = client.post('/comment/path/new', data=json.dumps(comment(text='First'))) - self.post('/comment/path/new', data=json.dumps(comment(text='Second', parent=1))) + resp = client.post('/1.0/path/new', data=json.dumps(comment(text='First'))) + self.post('/1.0/path/new', data=json.dumps(comment(text='Second', parent=1))) - r = client.delete('/comment/path/1') + r = client.delete('/1.0/path/1') assert r.status_code == 200 assert Comment(**json.loads(r.data)).deleted - assert self.get('/comment/path/1').status_code == 200 - assert self.get('/comment/path/2').status_code == 200 + assert self.get('/1.0/path/1').status_code == 200 + assert self.get('/1.0/path/2').status_code == 200 def testPathVariations(self): - paths = ['/sub/path/', '/path.html', '/sub/path.html', '%2Fpath/%2F'] + paths = ['/sub/path/', '/path.html', '/sub/path.html', '%2Fpath/%2F', '/'] for path in paths: - assert self.post('/comment/' + path + '/new', + assert self.post('/1.0/' + path + '/new', data=json.dumps(comment(text='...'))).status_code == 201 for path in paths: - assert self.get('/comment/' + path) - assert self.get('/comment/' + path + '/1') + assert self.get('/1.0/' + path) + assert self.get('/1.0/' + path + '/1') def testDeleteAndCreateByDifferentUsersButSamePostId(self): mallory = Client(self.app, Response) - mallory.post('/comment/path/new', data=json.dumps(comment(text='Foo'))) - mallory.delete('/comment/path/1') + mallory.post('/1.0/path/new', data=json.dumps(comment(text='Foo'))) + mallory.delete('/1.0/path/1') bob = Client(self.app, Response) - bob.post('/comment/path/new', data=json.dumps(comment(text='Bar'))) + bob.post('/1.0/path/new', data=json.dumps(comment(text='Bar'))) - assert mallory.delete('/comment/path/1').status_code == 403 - assert bob.delete('/comment/path/1').status_code == 200 + assert mallory.delete('/1.0/path/1').status_code == 403 + assert bob.delete('/1.0/path/1').status_code == 200