witten
/
luminotes
Archived
1
0
Fork 0
This repository has been archived on 2023-12-16. You can view files and clone it, but cannot push or open issues or pull requests.
luminotes/model/User.py

123 lines
3.9 KiB
Python

import sha
import random
from copy import copy
from Persistent import Persistent
class User( Persistent ):
"""
A user of this application.
"""
SALT_CHARS = [ chr( c ) for c in range( ord( "!" ), ord( "~" ) + 1 ) ]
SALT_SIZE = 12
def __setstate__( self, state ):
if "_User__storage_bytes" not in state:
state[ "_User__storage_bytes" ] = 0
if "_User__rate_plan" not in state:
state[ "_User__rate_plan" ] = 0
self.__dict__.update( state )
def __init__( self, id, username, password, email_address, notebooks = None ):
"""
Create a new user with the given credentials and information.
@type id: unicode
@param id: id of the user
@type username: unicode
@param username: unique user identifier for login purposes
@type password: unicode
@param password: secret password for login purposes
@type email_address: unicode
@param email_address: a hopefully valid email address
@type notebooks: [ Notebook ]
@param notebooks: list of notebooks (read-only and read-write) that this user has access to
@rtype: User
@return: newly created user
"""
Persistent.__init__( self, id, secondary_id = username )
self.__salt = self.__create_salt()
self.__password_hash = self.__hash_password( password )
self.__email_address = email_address
self.__notebooks = notebooks or []
self.__storage_bytes = 0 # total storage bytes for this user's notebooks, notes, and revisions
self.__rate_plan = 0 # each rate plan is an integer index into the array in config/Common.py
def __create_salt( self ):
return "".join( [ random.choice( self.SALT_CHARS ) for i in range( self.SALT_SIZE ) ] )
def __hash_password( self, password ):
if password is None or len( password ) == 0:
return None
return sha.new( self.__salt + password ).hexdigest()
def check_password( self, password ):
"""
Check that the given password matches this user's password.
@type password: unicode
@param password: password to check
@rtype: bool
@return: True if the password matches
"""
if self.__password_hash == None:
return False
hash = self.__hash_password( password )
if hash == self.__password_hash:
return True
return False
def has_access( self, notebook_id ):
if notebook_id in [ notebook.object_id for notebook in self.__notebooks ]:
return True
# a user who has read-write access to a notebook also has access to that notebook's trash
if notebook_id in [ notebook.trash.object_id for notebook in self.__notebooks if notebook.trash ]:
return True
return False
def to_dict( self ):
d = Persistent.to_dict( self )
d.update( dict(
username = self.username,
storage_bytes = self.__storage_bytes,
rate_plan = self.__rate_plan,
) )
return d
def __set_email_address( self, email_address ):
self.update_revision()
self.__email_address = email_address
def __set_password( self, password ):
self.update_revision()
self.__salt = self.__create_salt()
self.__password_hash = self.__hash_password( password )
def __set_notebooks( self, notebooks ):
self.update_revision()
self.__notebooks = notebooks
def __set_storage_bytes( self, storage_bytes ):
self.update_revision()
self.__storage_bytes = storage_bytes
def __set_rate_plan( self, rate_plan ):
self.update_revision()
self.__rate_plan = rate_plan
username = property( lambda self: self.secondary_id )
email_address = property( lambda self: self.__email_address, __set_email_address )
password = property( None, __set_password )
storage_bytes = property( lambda self: self.__storage_bytes, __set_storage_bytes )
rate_plan = property( lambda self: self.__rate_plan, __set_rate_plan )
# the notebooks (read-only and read-write) that this user has access to
notebooks = property( lambda self: copy( self.__notebooks ), __set_notebooks )