From 9906795d6d3d625f1882a20690dcf6459a4f200d Mon Sep 17 00:00:00 2001 From: Holger Frey Date: Wed, 27 Sep 2017 10:11:48 +0200 Subject: [PATCH] added user model --- ordr2/models/__init__.py | 2 +- ordr2/models/mymodel.py | 18 -------- ordr2/models/user.py | 81 +++++++++++++++++++++++++++++++++++ ordr2/scripts/initializedb.py | 12 ++++-- setup.py | 1 + 5 files changed, 92 insertions(+), 22 deletions(-) delete mode 100644 ordr2/models/mymodel.py create mode 100644 ordr2/models/user.py diff --git a/ordr2/models/__init__.py b/ordr2/models/__init__.py index 3d04458..616e3ac 100644 --- a/ordr2/models/__init__.py +++ b/ordr2/models/__init__.py @@ -5,7 +5,7 @@ import zope.sqlalchemy # import or define all models here to ensure they are attached to the # Base.metadata prior to any initialization routines -from .mymodel import MyModel # flake8: noqa +from .user import User, Role # flake8: noqa # run configure_mappers after defining all of the models to ensure # all relationships can be setup diff --git a/ordr2/models/mymodel.py b/ordr2/models/mymodel.py deleted file mode 100644 index 8c9d701..0000000 --- a/ordr2/models/mymodel.py +++ /dev/null @@ -1,18 +0,0 @@ -from sqlalchemy import ( - Column, - Index, - Integer, - Text, - ) - -from .meta import Base - - -class MyModel(Base): - __tablename__ = 'models' - id = Column(Integer, primary_key=True) - name = Column(Text) - value = Column(Integer) - - -Index('my_index', MyModel.name, unique=True, mysql_length=255) diff --git a/ordr2/models/user.py b/ordr2/models/user.py new file mode 100644 index 0000000..400e675 --- /dev/null +++ b/ordr2/models/user.py @@ -0,0 +1,81 @@ +import bcrypt +import enum + +from collections import namedtuple +from datetime import datetime +from sqlalchemy import ( + Column, + Date, + Enum, + Integer, + Text, + ) + +from .meta import Base + + +class Role(enum.Enum): + ''' roles of the user ''' + NEW = 'new' + USER = 'user' + PURCHASER = 'purchaser' + ADMIN = 'admin' + INACTIVE = 'inactive' + + @property + def principal(self): + return 'role:' + self.value + + +class User(Base): + ''' A user of the application ''' + + __tablename__ = 'users' + + id = Column(Integer, primary_key=True) + + user_name = Column(Text, nullable=False, unique=True) + first_name = Column(Text, nullable=False) + last_name = Column(Text, nullable=False) + email = Column(Text, nullable=False, unique=True) + password_hash = Column(Text, nullable=False) + role = Column(Enum(Role), nullable=False) + date_created = Column(Date, nullable=False, default=datetime.utcnow) + + @property + def principal(self): + ''' returns the principal identifier for the user ''' + return 'user:' + str(self.id) + + @property + def role_principals(self): + ''' returns the principal identifiers for the user's role ''' + principals = [self.role.principal] + if self.role is Role.PURCHASER: + principals.append(Role.USER.principal) + elif self.role is Role.ADMIN: + principals.append(Role.USER.principal) + principals.append(Role.PURCHASER.principal) + return principals + + @property + def is_active(self): + ''' check if it is an active user account ''' + return self.role in (Role.USER, Role.PURCHASER, Role.ADMIN) + + def set_password(self, password): + ''' hashes a new password ''' + pwhash = bcrypt.hashpw(password.encode('utf8'), bcrypt.gensalt()) + self.password_hash = pwhash.decode('utf8') + + def check_password(self, password): + ''' compares a password with a stored password hash ''' + if self.password_hash: + expected_hash = self.password_hash.encode('utf8') + return bcrypt.checkpw(password.encode('utf8'), expected_hash) + return False + + def __str__(self): + ''' string representation ''' + return '{!s}'.format(self.user_name) + diff --git a/ordr2/scripts/initializedb.py b/ordr2/scripts/initializedb.py index 7307ecc..924285e 100644 --- a/ordr2/scripts/initializedb.py +++ b/ordr2/scripts/initializedb.py @@ -15,7 +15,7 @@ from ..models import ( get_session_factory, get_tm_session, ) -from ..models import MyModel +from ..models import User, Role def usage(argv): @@ -41,5 +41,11 @@ def main(argv=sys.argv): with transaction.manager: dbsession = get_tm_session(session_factory, transaction.manager) - model = MyModel(name='one', value=1) - dbsession.add(model) + model = User( + user_name='HolgerFrey', + first_name='Holger', + last_name='Frey', + email='frey@imtek.de', + role=Role.ADMIN + ) + model.set_password('holgi') diff --git a/setup.py b/setup.py index 4f49334..130f8f1 100644 --- a/setup.py +++ b/setup.py @@ -20,6 +20,7 @@ requirements = [ 'transaction', 'zope.sqlalchemy', 'waitress', + 'bcrypt', ] setup_requirements = [