Making various notebook/user functions support the new "owner" access flag.
This commit is contained in:
parent
274a87dee2
commit
1cb12f6ae4
|
@ -137,6 +137,9 @@ class Notebooks( object ):
|
|||
if not self.__users.check_access( user_id, notebook_id, read_write = True ):
|
||||
notebook.read_write = False
|
||||
|
||||
if not self.__users.check_access( user_id, notebook_id, owner = True ):
|
||||
notebook.owner = False
|
||||
|
||||
if note_id:
|
||||
note = self.__database.load( Note, note_id, revision )
|
||||
if note and note.notebook_id != notebook_id:
|
||||
|
@ -811,8 +814,8 @@ class Notebooks( object ):
|
|||
self.__database.save( notebook, commit = False )
|
||||
|
||||
# record the fact that the user has access to their new notebook
|
||||
self.__database.execute( user.sql_save_notebook( notebook_id, read_write = True ), commit = False )
|
||||
self.__database.execute( user.sql_save_notebook( trash_id, read_write = True ), commit = False )
|
||||
self.__database.execute( user.sql_save_notebook( notebook_id, read_write = True, owner = True ), commit = False )
|
||||
self.__database.execute( user.sql_save_notebook( trash_id, read_write = True, owner = True ), commit = False )
|
||||
|
||||
if commit:
|
||||
self.__database.commit()
|
||||
|
@ -842,7 +845,7 @@ class Notebooks( object ):
|
|||
@raise Validation_error: one of the arguments is invalid
|
||||
"""
|
||||
user = self.__database.load( User, user_id )
|
||||
if not self.__users.check_access( user_id, notebook_id, read_write = True ):
|
||||
if not self.__users.check_access( user_id, notebook_id, read_write = True, owner = True ):
|
||||
raise Access_error()
|
||||
|
||||
notebook = self.__database.load( Notebook, notebook_id )
|
||||
|
@ -892,7 +895,7 @@ class Notebooks( object ):
|
|||
|
||||
user = self.__database.load( User, user_id )
|
||||
|
||||
if not self.__users.check_access( user_id, notebook_id, read_write = True ):
|
||||
if not self.__users.check_access( user_id, notebook_id, read_write = True, owner = True ):
|
||||
raise Access_error()
|
||||
|
||||
notebook = self.__database.load( Notebook, notebook_id )
|
||||
|
@ -942,7 +945,7 @@ class Notebooks( object ):
|
|||
|
||||
user = self.__database.load( User, user_id )
|
||||
|
||||
if not self.__users.check_access( user_id, notebook_id, read_write = True ):
|
||||
if not self.__users.check_access( user_id, notebook_id, read_write = True, owner = True ):
|
||||
raise Access_error()
|
||||
|
||||
notebook = self.__database.load( Notebook, notebook_id )
|
||||
|
@ -982,7 +985,7 @@ class Notebooks( object ):
|
|||
if user_id is None:
|
||||
raise Access_error()
|
||||
|
||||
if not self.__users.check_access( user_id, notebook_id, read_write = True ):
|
||||
if not self.__users.check_access( user_id, notebook_id, read_write = True, owner = True ):
|
||||
raise Access_error()
|
||||
|
||||
notebook = self.__database.load( Notebook, notebook_id )
|
||||
|
|
|
@ -219,8 +219,8 @@ class Users( object ):
|
|||
self.__database.save( user, commit = False )
|
||||
|
||||
# record the fact that the new user has access to their new notebook
|
||||
self.__database.execute( user.sql_save_notebook( notebook_id, read_write = True ), commit = False )
|
||||
self.__database.execute( user.sql_save_notebook( trash_id, read_write = True ), commit = False )
|
||||
self.__database.execute( user.sql_save_notebook( notebook_id, read_write = True, owner = True ), commit = False )
|
||||
self.__database.execute( user.sql_save_notebook( trash_id, read_write = True, owner = True ), commit = False )
|
||||
self.__database.commit()
|
||||
|
||||
redirect = u"/notebooks/%s" % notebook.object_id
|
||||
|
@ -282,8 +282,8 @@ class Users( object ):
|
|||
self.__database.save( user, commit = False )
|
||||
|
||||
# record the fact that the new user has access to their new notebook
|
||||
self.__database.execute( user.sql_save_notebook( notebook_id, read_write = True ), commit = False )
|
||||
self.__database.execute( user.sql_save_notebook( trash_id, read_write = True ), commit = False )
|
||||
self.__database.execute( user.sql_save_notebook( notebook_id, read_write = True, owner = True ), commit = False )
|
||||
self.__database.execute( user.sql_save_notebook( trash_id, read_write = True, owner = True ), commit = False )
|
||||
self.__database.commit()
|
||||
|
||||
redirect = u"/notebooks/%s" % notebook.object_id
|
||||
|
@ -428,7 +428,7 @@ class Users( object ):
|
|||
|
||||
return user
|
||||
|
||||
def check_access( self, user_id, notebook_id, read_write = False ):
|
||||
def check_access( self, user_id, notebook_id, read_write = False, owner = False ):
|
||||
"""
|
||||
Determine whether the given user has access to the given notebook.
|
||||
|
||||
|
@ -438,20 +438,21 @@ class Users( object ):
|
|||
@param notebook_id: id of notebook to check access for
|
||||
@type read_write: bool
|
||||
@param read_write: True if read-write access is being checked, False if read-only access (defaults to False)
|
||||
@type owner: bool
|
||||
@param owner: True if owner-level access is being checked (defaults to False)
|
||||
@rtype: bool
|
||||
@return: True if the user has access
|
||||
"""
|
||||
# check if the anonymous user has access to this notebook
|
||||
anonymous = self.__database.select_one( User, User.sql_load_by_username( u"anonymous" ) )
|
||||
|
||||
if self.__database.select_one( bool, anonymous.sql_has_access( notebook_id, read_write ) ):
|
||||
if self.__database.select_one( bool, anonymous.sql_has_access( notebook_id, read_write, owner ) ):
|
||||
return True
|
||||
|
||||
if user_id:
|
||||
# check if the given user has access to this notebook
|
||||
user = self.__database.load( User, user_id )
|
||||
|
||||
if user and self.__database.select_one( bool, user.sql_has_access( notebook_id, read_write ) ):
|
||||
if user and self.__database.select_one( bool, user.sql_has_access( notebook_id, read_write, owner ) ):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
@ -469,7 +470,7 @@ class Users( object ):
|
|||
@type send_reset_button: unicode
|
||||
@param send_reset_button: ignored
|
||||
@rtype: json dict
|
||||
@return: { 'error': message }
|
||||
@return: { 'message': message }
|
||||
@raise Password_reset_error: an error occured when sending the password reset email
|
||||
@raise Validation_error: one of the arguments is invalid
|
||||
"""
|
||||
|
@ -630,3 +631,64 @@ class Users( object ):
|
|||
self.__database.commit()
|
||||
|
||||
return dict( redirect = u"/" )
|
||||
|
||||
@expose( view = Json )
|
||||
@validate(
|
||||
notebook_id = Valid_id(),
|
||||
email_address = ( Valid_string( min = 1, max = 60 ), valid_email_address ),
|
||||
read_write = Valid_bool(),
|
||||
owner = Valid_bool(),
|
||||
invite_button = unicode,
|
||||
)
|
||||
def send_invite( self, notebook_id, email_address, read_write, owner, invite_button ):
|
||||
"""
|
||||
Send a notebook invitation to the given email address.
|
||||
@type notebook_id: unicode
|
||||
@param notebook_id: id of the notebook that the invitation is for
|
||||
@type email_address: unicode
|
||||
@param email_address: an email address where the invitation should be sent
|
||||
@type read_write: bool
|
||||
@param read_write: whether the invitation is for read-write access
|
||||
@type owner: bool
|
||||
@param owner: whether the invitation is for owner-level access
|
||||
@type invite_button: unicode
|
||||
@param invite_button: ignored
|
||||
@rtype: json dict
|
||||
@return: { 'message': message }
|
||||
@raise Password_reset_error: an error occured when sending the password reset email
|
||||
@raise Validation_error: one of the arguments is invalid
|
||||
"""
|
||||
import sha
|
||||
import random
|
||||
import smtplib
|
||||
from email import Message
|
||||
|
||||
# record the sending of this reset email
|
||||
password_reset_id = self.__database.next_id( Password_reset, commit = False )
|
||||
password_reset = Password_reset.create( password_reset_id, email_address )
|
||||
self.__database.save( password_reset )
|
||||
|
||||
# create an email message with a unique link
|
||||
message = Message.Message()
|
||||
message[ u"from" ] = u"Luminotes support <%s>" % self.__support_email
|
||||
message[ u"to" ] = email_address
|
||||
message[ u"subject" ] = u"Luminotes password reset"
|
||||
message.set_payload(
|
||||
u"Someone has requested a password reset for a Luminotes user with your email\n" +
|
||||
u"address. If this someone is you, please visit the following link for a\n" +
|
||||
u"username reminder or a password reset:\n\n" +
|
||||
u"%s/r/%s\n\n" % ( self.__https_url or self.__http_url, password_reset.object_id ) +
|
||||
u"This link will expire in 24 hours.\n\n" +
|
||||
u"Thanks!"
|
||||
)
|
||||
|
||||
# send the message out through localhost's smtp server
|
||||
server = smtplib.SMTP()
|
||||
server.connect()
|
||||
server.sendmail( message[ u"from" ], [ email_address ], message.as_string() )
|
||||
server.quit()
|
||||
|
||||
return dict(
|
||||
message = u"Please check your inbox. A password reset email has been sent to %s" % email_address,
|
||||
)
|
||||
|
||||
|
|
|
@ -17,34 +17,35 @@ class Test_controller( object ):
|
|||
# SQL-returning methods in User, Note, and Notebook to return functions that manipulate data in
|
||||
# Stub_database directly instead. This is all a little fragile, but it's better than relying on
|
||||
# the presence of a real database for unit tests.
|
||||
def sql_save_notebook( self, notebook_id, read_write, database ):
|
||||
def sql_save_notebook( self, notebook_id, read_write, owner, database ):
|
||||
if self.object_id in database.user_notebook:
|
||||
database.user_notebook[ self.object_id ].append( ( notebook_id, read_write ) )
|
||||
database.user_notebook[ self.object_id ].append( ( notebook_id, read_write, owner ) )
|
||||
else:
|
||||
database.user_notebook[ self.object_id ] = [ ( notebook_id, read_write ) ]
|
||||
database.user_notebook[ self.object_id ] = [ ( notebook_id, read_write, owner ) ]
|
||||
|
||||
User.sql_save_notebook = lambda self, notebook_id, read_write = False: \
|
||||
lambda database: sql_save_notebook( self, notebook_id, read_write, database )
|
||||
User.sql_save_notebook = lambda self, notebook_id, read_write = False, owner = False: \
|
||||
lambda database: sql_save_notebook( self, notebook_id, read_write, owner, database )
|
||||
|
||||
def sql_remove_notebook( self, notebook_id, database ):
|
||||
if self.object_id in database.user_notebook:
|
||||
for access_tuple in database.user_notebook[ self.object_id ]:
|
||||
if access_tuple[ 0 ] == notebook_id:
|
||||
database.user_notebook[ self.object_id ].remove( access_tuple )
|
||||
for notebook_info in database.user_notebook[ self.object_id ]:
|
||||
if notebook_info[ 0 ] == notebook_id:
|
||||
database.user_notebook[ self.object_id ].remove( notebook_info )
|
||||
|
||||
User.sql_remove_notebook = lambda self, notebook_id: \
|
||||
lambda database: sql_remove_notebook( self, notebook_id, database )
|
||||
|
||||
def sql_load_notebooks( self, parents_only, undeleted_only, database ):
|
||||
notebooks = []
|
||||
notebook_tuples = database.user_notebook.get( self.object_id )
|
||||
notebook_infos = database.user_notebook.get( self.object_id )
|
||||
|
||||
if not notebook_tuples: return []
|
||||
if not notebook_infos: return []
|
||||
|
||||
for notebook_tuple in notebook_tuples:
|
||||
( notebook_id, read_write ) = notebook_tuple
|
||||
for notebook_info in notebook_infos:
|
||||
( notebook_id, read_write, owner ) = notebook_info
|
||||
notebook = database.objects.get( notebook_id )[ -1 ]
|
||||
notebook._Notebook__read_write = read_write
|
||||
notebook.read_write = read_write
|
||||
notebook.owner = owner
|
||||
if parents_only and notebook.trash_id is None:
|
||||
continue
|
||||
if undeleted_only and notebook.deleted is True:
|
||||
|
@ -88,20 +89,22 @@ class Test_controller( object ):
|
|||
User.sql_calculate_storage = lambda self: \
|
||||
lambda database: sql_calculate_storage( self, database )
|
||||
|
||||
def sql_has_access( self, notebook_id, read_write, database ):
|
||||
for ( user_id, notebook_tuples ) in database.user_notebook.items():
|
||||
for notebook_tuple in notebook_tuples:
|
||||
( db_notebook_id, db_read_write ) = notebook_tuple
|
||||
def sql_has_access( self, notebook_id, read_write, owner, database ):
|
||||
for ( user_id, notebook_infos ) in database.user_notebook.items():
|
||||
for notebook_info in notebook_infos:
|
||||
( db_notebook_id, db_read_write, db_owner ) = notebook_info
|
||||
|
||||
if self.object_id == user_id and notebook_id == db_notebook_id:
|
||||
if read_write is True and db_read_write is False:
|
||||
return False
|
||||
if owner is True and db_owner is False:
|
||||
return False
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
User.sql_has_access = lambda self, notebook_id, read_write = False: \
|
||||
lambda database: sql_has_access( self, notebook_id, read_write, database )
|
||||
User.sql_has_access = lambda self, notebook_id, read_write = False, owner = False: \
|
||||
lambda database: sql_has_access( self, notebook_id, read_write, owner, database )
|
||||
|
||||
def sql_load_revisions( self, database ):
|
||||
note_list = database.objects.get( self.object_id )
|
||||
|
|
|
@ -48,12 +48,12 @@ class Test_notebooks( Test_controller ):
|
|||
def make_users( self ):
|
||||
self.user = User.create( self.database.next_id( User ), self.username, self.password, self.email_address )
|
||||
self.database.save( self.user, commit = False )
|
||||
self.database.execute( self.user.sql_save_notebook( self.notebook.object_id, read_write = True ) )
|
||||
self.database.execute( self.user.sql_save_notebook( self.notebook.trash_id, read_write = True ) )
|
||||
self.database.execute( self.user.sql_save_notebook( self.notebook.object_id, read_write = True, owner = True ) )
|
||||
self.database.execute( self.user.sql_save_notebook( self.notebook.trash_id, read_write = True, owner = True ) )
|
||||
|
||||
self.anonymous = User.create( self.database.next_id( User ), u"anonymous" )
|
||||
self.database.save( self.anonymous, commit = False )
|
||||
self.database.execute( self.user.sql_save_notebook( self.anon_notebook.object_id, read_write = False ) )
|
||||
self.database.execute( self.user.sql_save_notebook( self.anon_notebook.object_id, read_write = False, owner = False ) )
|
||||
|
||||
def test_default_without_login( self ):
|
||||
result = self.http_get(
|
||||
|
@ -181,6 +181,7 @@ class Test_notebooks( Test_controller ):
|
|||
|
||||
assert notebook.object_id == self.notebook.object_id
|
||||
assert notebook.read_write == True
|
||||
assert notebook.owner == True
|
||||
assert len( startup_notes ) == 1
|
||||
assert startup_notes[ 0 ].object_id == self.note.object_id
|
||||
user = self.database.load( User, self.user.object_id )
|
||||
|
@ -199,6 +200,7 @@ class Test_notebooks( Test_controller ):
|
|||
|
||||
assert notebook.object_id == self.notebook.object_id
|
||||
assert notebook.read_write == True
|
||||
assert notebook.owner == True
|
||||
assert len( startup_notes ) == 1
|
||||
assert startup_notes[ 0 ].object_id == self.note.object_id
|
||||
|
||||
|
@ -226,6 +228,7 @@ class Test_notebooks( Test_controller ):
|
|||
|
||||
assert notebook.object_id == self.notebook.object_id
|
||||
assert notebook.read_write == True
|
||||
assert notebook.owner == True
|
||||
assert len( startup_notes ) == 1
|
||||
assert startup_notes[ 0 ].object_id == self.note.object_id
|
||||
|
||||
|
@ -272,6 +275,7 @@ class Test_notebooks( Test_controller ):
|
|||
|
||||
assert notebook.object_id == self.anon_notebook.object_id
|
||||
assert notebook.read_write == False
|
||||
assert notebook.owner == False
|
||||
assert len( startup_notes ) == 0
|
||||
user = self.database.load( User, self.user.object_id )
|
||||
assert user.storage_bytes == 0
|
||||
|
@ -1740,6 +1744,7 @@ class Test_notebooks( Test_controller ):
|
|||
assert notebook.object_id == new_notebook_id
|
||||
assert notebook.name == u"new notebook"
|
||||
assert notebook.read_write == True
|
||||
assert notebook.owner == True
|
||||
assert notebook.trash_id
|
||||
|
||||
def test_contents_after_create( self ):
|
||||
|
@ -1760,6 +1765,7 @@ class Test_notebooks( Test_controller ):
|
|||
|
||||
assert notebook.object_id == new_notebook_id
|
||||
assert notebook.read_write == True
|
||||
assert notebook.owner == True
|
||||
|
||||
def test_create_without_login( self ):
|
||||
result = self.http_post( "/notebooks/create", dict() )
|
||||
|
@ -1853,6 +1859,7 @@ class Test_notebooks( Test_controller ):
|
|||
assert notebook.object_id == remaining_notebook_id
|
||||
assert notebook.name == u"my notebook"
|
||||
assert notebook.read_write == True
|
||||
assert notebook.owner == True
|
||||
assert notebook.trash_id
|
||||
|
||||
def test_delete_with_multiple_notebooks( self ):
|
||||
|
@ -1861,8 +1868,8 @@ class Test_notebooks( Test_controller ):
|
|||
self.database.save( trash, commit = False )
|
||||
notebook = Notebook.create( self.database.next_id( Notebook ), u"notebook", trash.object_id )
|
||||
self.database.save( notebook, commit = False )
|
||||
self.database.execute( self.user.sql_save_notebook( notebook.object_id, read_write = True ) )
|
||||
self.database.execute( self.user.sql_save_notebook( notebook.trash_id, read_write = True ) )
|
||||
self.database.execute( self.user.sql_save_notebook( notebook.object_id, read_write = True, owner = True ) )
|
||||
self.database.execute( self.user.sql_save_notebook( notebook.trash_id, read_write = True, owner = True ) )
|
||||
self.database.commit()
|
||||
|
||||
self.login()
|
||||
|
@ -2017,6 +2024,7 @@ class Test_notebooks( Test_controller ):
|
|||
assert notebook.object_id == notebook_id
|
||||
assert notebook.name == self.notebook.name
|
||||
assert notebook.read_write == True
|
||||
assert notebook.owner == True
|
||||
assert notebook.trash_id
|
||||
|
||||
def test_contents_after_undelete( self ):
|
||||
|
@ -2074,6 +2082,7 @@ class Test_notebooks( Test_controller ):
|
|||
assert notebook.object_id == notebook_id
|
||||
assert notebook.name == self.notebook.name
|
||||
assert notebook.read_write == True
|
||||
assert notebook.owner == True
|
||||
assert notebook.trash_id
|
||||
|
||||
def test_recent_notes( self ):
|
||||
|
|
|
@ -59,8 +59,8 @@ class Test_users( Test_controller ):
|
|||
|
||||
self.user = User.create( self.database.next_id( User ), self.username, self.password, self.email_address )
|
||||
self.database.save( self.user, commit = False )
|
||||
self.database.execute( self.user.sql_save_notebook( notebook_id1, read_write = True ), commit = False )
|
||||
self.database.execute( self.user.sql_save_notebook( notebook_id2, read_write = True ), commit = False )
|
||||
self.database.execute( self.user.sql_save_notebook( notebook_id1, read_write = True, owner = True ), commit = False )
|
||||
self.database.execute( self.user.sql_save_notebook( notebook_id2, read_write = True, owner = True ), commit = False )
|
||||
|
||||
self.user2 = User.create( self.database.next_id( User ), self.username2, self.password2, self.email_address2 )
|
||||
self.database.save( self.user2, commit = False )
|
||||
|
@ -131,6 +131,7 @@ class Test_users( Test_controller ):
|
|||
assert notebook.name == u"my notebook"
|
||||
assert notebook.trash_id
|
||||
assert notebook.read_write == True
|
||||
assert notebook.owner == True
|
||||
|
||||
notebook = notebooks[ 1 ]
|
||||
assert notebook.object_id == notebooks[ 0 ].trash_id
|
||||
|
@ -138,6 +139,7 @@ class Test_users( Test_controller ):
|
|||
assert notebook.name == u"trash"
|
||||
assert notebook.trash_id == None
|
||||
assert notebook.read_write == True
|
||||
assert notebook.owner == True
|
||||
|
||||
notebook = notebooks[ 2 ]
|
||||
assert notebook.object_id == self.anon_notebook.object_id
|
||||
|
@ -145,6 +147,7 @@ class Test_users( Test_controller ):
|
|||
assert notebook.name == self.anon_notebook.name
|
||||
assert notebook.trash_id == None
|
||||
assert notebook.read_write == False
|
||||
assert notebook.owner == False
|
||||
|
||||
assert result.get( u"login_url" ) is None
|
||||
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/"
|
||||
|
@ -191,6 +194,7 @@ class Test_users( Test_controller ):
|
|||
assert notebook.name == u"my notebook"
|
||||
assert notebook.trash_id
|
||||
assert notebook.read_write == True
|
||||
assert notebook.owner == True
|
||||
|
||||
notebook = notebooks[ 1 ]
|
||||
assert notebook.object_id == notebooks[ 0 ].trash_id
|
||||
|
@ -198,6 +202,7 @@ class Test_users( Test_controller ):
|
|||
assert notebook.name == u"trash"
|
||||
assert notebook.trash_id == None
|
||||
assert notebook.read_write == True
|
||||
assert notebook.owner == True
|
||||
|
||||
notebook = notebooks[ 2 ]
|
||||
assert notebook.object_id == self.anon_notebook.object_id
|
||||
|
@ -205,6 +210,7 @@ class Test_users( Test_controller ):
|
|||
assert notebook.name == self.anon_notebook.name
|
||||
assert notebook.trash_id == None
|
||||
assert notebook.read_write == False
|
||||
assert notebook.owner == False
|
||||
|
||||
assert result.get( u"login_url" ) is None
|
||||
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/"
|
||||
|
@ -283,10 +289,13 @@ class Test_users( Test_controller ):
|
|||
assert len( result[ u"notebooks" ] ) == 3
|
||||
assert result[ u"notebooks" ][ 0 ].object_id == self.notebooks[ 0 ].object_id
|
||||
assert result[ u"notebooks" ][ 0 ].read_write == True
|
||||
assert result[ u"notebooks" ][ 0 ].owner == True
|
||||
assert result[ u"notebooks" ][ 1 ].object_id == self.notebooks[ 1 ].object_id
|
||||
assert result[ u"notebooks" ][ 1 ].read_write == True
|
||||
assert result[ u"notebooks" ][ 1 ].owner == True
|
||||
assert result[ u"notebooks" ][ 2 ].object_id == self.anon_notebook.object_id
|
||||
assert result[ u"notebooks" ][ 2 ].read_write == False
|
||||
assert result[ u"notebooks" ][ 2 ].owner == False
|
||||
assert result[ u"login_url" ] is None
|
||||
assert result[ u"logout_url" ] == self.settings[ u"global" ][ u"luminotes.https_url" ] + u"/"
|
||||
|
||||
|
@ -303,6 +312,7 @@ class Test_users( Test_controller ):
|
|||
assert result[ u"notebooks" ][ 0 ].object_id == self.anon_notebook.object_id
|
||||
assert result[ u"notebooks" ][ 0 ].name == self.anon_notebook.name
|
||||
assert result[ u"notebooks" ][ 0 ].read_write == False
|
||||
assert result[ u"notebooks" ][ 0 ].owner == False
|
||||
|
||||
login_note = self.database.select_one( Note, self.anon_notebook.sql_load_note_by_title( u"login" ) )
|
||||
assert result[ u"login_url" ] == u"%s/notebooks/%s?note_id=%s" % (
|
||||
|
@ -339,6 +349,46 @@ class Test_users( Test_controller ):
|
|||
assert self.user.storage_bytes == 0
|
||||
assert self.user.revision == original_revision
|
||||
|
||||
def test_check_access( self ):
|
||||
access = cherrypy.root.users.check_access( self.user.object_id, self.notebooks[ 0 ].object_id )
|
||||
|
||||
assert access is True
|
||||
|
||||
def test_check_access_read_write( self ):
|
||||
access = cherrypy.root.users.check_access( self.user.object_id, self.notebooks[ 0 ].object_id, read_write = True )
|
||||
|
||||
assert access is True
|
||||
|
||||
def test_check_access_owner( self ):
|
||||
access = cherrypy.root.users.check_access( self.user.object_id, self.notebooks[ 0 ].object_id, owner = True )
|
||||
|
||||
assert access is True
|
||||
|
||||
def test_check_access_full( self ):
|
||||
access = cherrypy.root.users.check_access( self.user.object_id, self.notebooks[ 0 ].object_id, read_write = True, owner = True )
|
||||
|
||||
assert access is True
|
||||
|
||||
def test_check_access_anon( self ):
|
||||
access = cherrypy.root.users.check_access( self.user.object_id, self.anon_notebook.object_id )
|
||||
|
||||
assert access is True
|
||||
|
||||
def test_check_access_anon_read_write( self ):
|
||||
access = cherrypy.root.users.check_access( self.user.object_id, self.anon_notebook.object_id, read_write = True )
|
||||
|
||||
assert access is False
|
||||
|
||||
def test_check_access_anon_owner( self ):
|
||||
access = cherrypy.root.users.check_access( self.user.object_id, self.anon_notebook.object_id, owner = True )
|
||||
|
||||
assert access is False
|
||||
|
||||
def test_check_access_anon_full( self ):
|
||||
access = cherrypy.root.users.check_access( self.user.object_id, self.anon_notebook.object_id, read_write = True, owner = True )
|
||||
|
||||
assert access is False
|
||||
|
||||
def test_send_reset( self ):
|
||||
# trick send_reset() into using a fake SMTP server
|
||||
Stub_smtp.reset()
|
||||
|
@ -392,6 +442,7 @@ class Test_users( Test_controller ):
|
|||
assert result[ u"notebooks" ][ 0 ].object_id == self.anon_notebook.object_id
|
||||
assert result[ u"notebooks" ][ 0 ].name == self.anon_notebook.name
|
||||
assert result[ u"notebooks" ][ 0 ].read_write == False
|
||||
assert result[ u"notebooks" ][ 0 ].owner == False
|
||||
|
||||
login_note = self.database.select_one( Note, self.anon_notebook.sql_load_note_by_title( u"login" ) )
|
||||
assert result[ u"login_url" ] == u"%s/notebooks/%s?note_id=%s" % (
|
||||
|
|
|
@ -17,7 +17,7 @@ class Invite( Persistent ):
|
|||
@type from_user_id: unicode or NoneType
|
||||
@param from_user_id: id of the user who sent the invite (optional)
|
||||
@type notebook_id: unicode or NoneType
|
||||
@param notebook_id: id of the notebook that the invitation is to
|
||||
@param notebook_id: id of the notebook that the invitation is for
|
||||
@type email_address: unicode or NoneType
|
||||
@param email_address: where the invitation was emailed (optional)
|
||||
@type read_write: bool or NoneType
|
||||
|
@ -47,7 +47,7 @@ class Invite( Persistent ):
|
|||
@type from_user_id: unicode or NoneType
|
||||
@param from_user_id: id of the user who sent the invite (optional)
|
||||
@type notebook_id: unicode or NoneType
|
||||
@param notebook_id: id of the notebook that the invitation is to
|
||||
@param notebook_id: id of the notebook that the invitation is for
|
||||
@type email_address: unicode or NoneType
|
||||
@param email_address: where the invitation was emailed (optional)
|
||||
@type read_write: bool or NoneType
|
||||
|
|
|
@ -12,7 +12,7 @@ class Notebook( Persistent ):
|
|||
WHITESPACE_PATTERN = re.compile( r"\s+" )
|
||||
SEARCH_OPERATORS = re.compile( r"[&|!()]" )
|
||||
|
||||
def __init__( self, object_id, revision = None, name = None, trash_id = None, deleted = False, user_id = None, read_write = True ):
|
||||
def __init__( self, object_id, revision = None, name = None, trash_id = None, deleted = False, user_id = None, read_write = True, owner = True ):
|
||||
"""
|
||||
Create a new notebook with the given id and name.
|
||||
|
||||
|
@ -30,6 +30,8 @@ class Notebook( Persistent ):
|
|||
@param user_id: id of the user who most recently updated this notebook object (optional)
|
||||
@type read_write: bool or NoneType
|
||||
@param read_write: whether this view of the notebook is currently read-write (optional, defaults to True)
|
||||
@type owner: bool or NoneType
|
||||
@param owner: whether this view of the notebook currently has owner-level access (optional, defaults to True)
|
||||
@rtype: Notebook
|
||||
@return: newly constructed notebook
|
||||
"""
|
||||
|
@ -39,9 +41,10 @@ class Notebook( Persistent ):
|
|||
self.__deleted = deleted
|
||||
self.__user_id = user_id
|
||||
self.__read_write = read_write
|
||||
self.__owner = owner
|
||||
|
||||
@staticmethod
|
||||
def create( object_id, name = None, trash_id = None, deleted = False, user_id = None, read_write = True ):
|
||||
def create( object_id, name = None, trash_id = None, deleted = False, user_id = None, read_write = True, owner = True ):
|
||||
"""
|
||||
Convenience constructor for creating a new notebook.
|
||||
|
||||
|
@ -57,10 +60,12 @@ class Notebook( Persistent ):
|
|||
@param user_id: id of the user who most recently updated this notebook object (optional)
|
||||
@type read_write: bool or NoneType
|
||||
@param read_write: whether this view of the notebook is currently read-write (optional, defaults to True)
|
||||
@type owner: bool or NoneType
|
||||
@param owner: whether this view of the notebook currently has owner-level access (optional, defaults to True)
|
||||
@rtype: Notebook
|
||||
@return: newly constructed notebook
|
||||
"""
|
||||
return Notebook( object_id, name = name, trash_id = trash_id, user_id = user_id, read_write = read_write )
|
||||
return Notebook( object_id, name = name, trash_id = trash_id, user_id = user_id, read_write = read_write, owner = owner )
|
||||
|
||||
@staticmethod
|
||||
def sql_load( object_id, revision = None ):
|
||||
|
@ -198,6 +203,7 @@ class Notebook( Persistent ):
|
|||
name = self.__name,
|
||||
trash_id = self.__trash_id,
|
||||
read_write = self.__read_write,
|
||||
owner = self.__owner,
|
||||
deleted = self.__deleted,
|
||||
user_id = self.__user_id,
|
||||
) )
|
||||
|
@ -213,6 +219,11 @@ class Notebook( Persistent ):
|
|||
# call update_revision().
|
||||
self.__read_write = read_write
|
||||
|
||||
def __set_owner( self, owner ):
|
||||
# The owner member isn't actually saved to the database, so setting it doesn't need to
|
||||
# call update_revision().
|
||||
self.__owner = owner
|
||||
|
||||
def __set_deleted( self, deleted ):
|
||||
self.__deleted = deleted
|
||||
self.update_revision()
|
||||
|
@ -220,5 +231,6 @@ class Notebook( Persistent ):
|
|||
name = property( lambda self: self.__name, __set_name )
|
||||
trash_id = property( lambda self: self.__trash_id )
|
||||
read_write = property( lambda self: self.__read_write, __set_read_write )
|
||||
owner = property( lambda self: self.__owner, __set_owner )
|
||||
deleted = property( lambda self: self.__deleted, __set_deleted )
|
||||
user_id = property( lambda self: self.__user_id )
|
||||
|
|
|
@ -144,17 +144,18 @@ class User( Persistent ):
|
|||
undeleted_only_clause = ""
|
||||
|
||||
return \
|
||||
"select notebook_current.*, user_notebook.read_write from user_notebook, notebook_current " + \
|
||||
"select notebook_current.*, user_notebook.read_write, user_notebook.owner from user_notebook, notebook_current " + \
|
||||
"where user_notebook.user_id = %s%s%s and user_notebook.notebook_id = notebook_current.id order by revision;" % \
|
||||
( quote( self.object_id ), parents_only_clause, undeleted_only_clause )
|
||||
|
||||
def sql_save_notebook( self, notebook_id, read_write = True ):
|
||||
def sql_save_notebook( self, notebook_id, read_write = True, owner = True ):
|
||||
"""
|
||||
Return a SQL string to save the id of a notebook to which this user has access.
|
||||
"""
|
||||
return \
|
||||
"insert into user_notebook ( user_id, notebook_id, read_write ) values " + \
|
||||
"( %s, %s, %s );" % ( quote( self.object_id ), quote( notebook_id ), quote( read_write and 't' or 'f' ) )
|
||||
"insert into user_notebook ( user_id, notebook_id, read_write, owner ) values " + \
|
||||
"( %s, %s, %s, %s );" % ( quote( self.object_id ), quote( notebook_id ), quote( read_write and 't' or 'f' ),
|
||||
quote( owner and 't' or 'f' ) )
|
||||
|
||||
def sql_remove_notebook( self, notebook_id ):
|
||||
"""
|
||||
|
@ -163,14 +164,22 @@ class User( Persistent ):
|
|||
return \
|
||||
"delete from user_notebook where user_id = %s and notebook_id = %s;" % ( quote( self.object_id ), quote( notebook_id ) )
|
||||
|
||||
def sql_has_access( self, notebook_id, read_write = False ):
|
||||
def sql_has_access( self, notebook_id, read_write = False, owner = False ):
|
||||
"""
|
||||
Return a SQL string to determine whether this user has access to the given notebook.
|
||||
"""
|
||||
if read_write is True:
|
||||
if read_write is True and owner is True:
|
||||
return \
|
||||
"select user_id from user_notebook where user_id = %s and notebook_id = %s and read_write = 't' and owner = 't';" % \
|
||||
( quote( self.object_id ), quote( notebook_id ) )
|
||||
elif read_write is True:
|
||||
return \
|
||||
"select user_id from user_notebook where user_id = %s and notebook_id = %s and read_write = 't';" % \
|
||||
( quote( self.object_id ), quote( notebook_id ) )
|
||||
elif owner is True:
|
||||
return \
|
||||
"select user_id from user_notebook where user_id = %s and notebook_id = %s and owner = 't';" % \
|
||||
( quote( self.object_id ), quote( notebook_id ) )
|
||||
else:
|
||||
return \
|
||||
"select user_id from user_notebook where user_id = %s and notebook_id = %s;" % \
|
||||
|
|
Reference in New Issue
Block a user