diff --git a/controller/Forums.py b/controller/Forums.py index 34b85ad..221cc55 100644 --- a/controller/Forums.py +++ b/controller/Forums.py @@ -98,4 +98,6 @@ class Forums( object ): return result # threads() is just an alias for Notebooks.default() - threads = Notebooks.default + def threads( self, *args, **kwargs ): + return self.__notebooks.default( *args, **kwargs ) + threads.exposed = True diff --git a/controller/Users.py b/controller/Users.py index ebc4557..fa53077 100644 --- a/controller/Users.py +++ b/controller/Users.py @@ -748,13 +748,14 @@ class Users( object ): return None # if a particular note_id is given, and the notebook is READ_WRITE_FOR_OWN_NOTES, then check - # that the user is associated with that note + # that the user is associated with that note (if the note exists). this prevents a user + # from modifying someone else's note in a READ_WRITE_FOR_OWN_NOTES notebook if note_id and notebook.read_write == Notebook.READ_WRITE_FOR_OWN_NOTES: note = self.__database.load( Note, note_id ) - if not note: - return None - - if user_id != note.user_id or notebook_id != note.notebook_id: + if note and ( + ( note.user_id and user_id != note.user_id ) or + ( note.notebook_id and notebook_id != note.notebook_id ) + ): return None return notebook diff --git a/controller/test/Test_notebooks.py b/controller/test/Test_notebooks.py index 2aa59bc..c9b5388 100644 --- a/controller/test/Test_notebooks.py +++ b/controller/test/Test_notebooks.py @@ -2412,6 +2412,48 @@ class Test_notebooks( Test_controller ): def test_save_new_startup_note( self ): self.test_save_new_note( startup = True ) + def test_save_new_note_with_notebook_read_write_for_own_notes( self ): + self.login() + + self.database.execute( self.user.sql_update_access( + self.notebook.object_id, read_write = Notebook.READ_WRITE_FOR_OWN_NOTES, owner = True, + ) ) + + # save a completely new note + new_note = Note.create( "55", u"

newest title

foo" ) + previous_revision = new_note.revision + result = self.http_post( "/notebooks/save_note/", dict( + notebook_id = self.notebook.object_id, + note_id = new_note.object_id, + contents = new_note.contents, + startup = False, + previous_revision = None, + ), session_id = self.session_id ) + + assert result[ "new_revision" ] + assert result[ "new_revision" ] != previous_revision + assert result[ "new_revision" ].user_id == self.user.object_id + assert result[ "new_revision" ].username == self.username + assert result[ "previous_revision" ] == None + user = self.database.load( User, self.user.object_id ) + assert user.storage_bytes > 0 + assert result[ "storage_bytes" ] == user.storage_bytes + + # make sure the new title is now loadable + result = self.http_post( "/notebooks/load_note_by_title/", dict( + notebook_id = self.notebook.object_id, + note_title = new_note.title, + ), session_id = self.session_id ) + + note = result[ "note" ] + + assert note.object_id == new_note.object_id + assert note.title == new_note.title + assert note.contents == new_note.contents + assert note.startup == True # startup is forced to True in READ_WRITE_FOR_OWN_NOTES notebook + assert note.user_id == self.user.object_id + assert note.rank == 0 + def test_save_new_note_with_disallowed_tags( self ): self.login() diff --git a/controller/test/Test_users.py b/controller/test/Test_users.py index bbe2c00..1aaf6fa 100644 --- a/controller/test/Test_users.py +++ b/controller/test/Test_users.py @@ -974,7 +974,24 @@ class Test_users( Test_controller ): notebook = cherrypy.root.users.load_notebook( self.user.object_id, self.notebooks[ 0 ].object_id, note_id = u"unknownid" ) - assert notebook is None + # an unknown note id indicates that a new note is being created, which is allowed in a + # READ_WRITE_FOR_OWN_NOTES notebooks + assert notebook + assert notebook.object_id == self.notebooks[ 0 ].object_id + + def test_load_notebook_with_stub_note( self ): + # don't fully create a note, but reserve an id for it + note_id = self.database.next_id( Note ) + + self.database.execute( self.user.sql_update_access( + self.notebooks[ 0 ].object_id, read_write = Notebook.READ_WRITE_FOR_OWN_NOTES, owner = False, + ) ) + + notebook = cherrypy.root.users.load_notebook( self.user.object_id, self.notebooks[ 0 ].object_id, + note_id = note_id ) + + assert notebook + assert notebook.object_id == self.notebooks[ 0 ].object_id def test_load_notebook_with_note_id_in_another_notebook( self ): self.database.execute( self.user.sql_update_access(