Holger Frey
7 years ago
5 changed files with 183 additions and 19 deletions
@ -1,18 +0,0 @@
@@ -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) |
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
''' User Account and Roles Models ''' |
||||
|
||||
import enum |
||||
|
||||
from datetime import datetime |
||||
from sqlalchemy import ( |
||||
Column, |
||||
Date, |
||||
Enum, |
||||
Integer, |
||||
Text, |
||||
) |
||||
|
||||
from .meta import Base |
||||
|
||||
|
||||
class Role(enum.Enum): |
||||
''' roles of user accounts ''' |
||||
|
||||
#: new user, email address was not validated |
||||
UNVALIDATED = 'unvalidated' |
||||
|
||||
#: new user, email address validated, not activated by admin |
||||
NEW = 'new' |
||||
|
||||
#: standard user of the system, can place and view orders |
||||
USER = 'user' |
||||
|
||||
#: privileged user of the system, can edit orders |
||||
PURCHASER = 'purchaser' |
||||
|
||||
#: privileged user, can edit orders, users and consumables |
||||
ADMIN = 'admin' |
||||
|
||||
#: a user that is no longer activated |
||||
INACTIVE = 'inactive' |
||||
|
||||
@property |
||||
def principal(self): |
||||
''' returns the principal identifier of the role ''' |
||||
return 'role:' + self.value.lower() |
||||
|
||||
def __str__(self): |
||||
''' string representation ''' |
||||
return self.value.capitalize() |
||||
|
||||
|
||||
class User(Base): |
||||
''' A user of the application ''' |
||||
|
||||
__tablename__ = 'users' |
||||
|
||||
#: primary key |
||||
id = Column(Integer, primary_key=True) |
||||
#: unique user name |
||||
username = Column(Text, nullable=False, unique=True) |
||||
#: hashed password, see ``ordr2.security`` |
||||
password_hash = Column(Text, nullable=False) |
||||
#: role of the user, see ``ordr2.models.users.Role`` |
||||
role = Column(Enum(Role), nullable=False) |
||||
|
||||
first_name = Column(Text, nullable=False) |
||||
last_name = Column(Text, nullable=False) |
||||
email = Column(Text, nullable=False, unique=True) |
||||
date_created = Column(Date, nullable=False, default=datetime.utcnow) |
||||
|
||||
@property |
||||
def principal(self): |
||||
''' returns the principal identifier for the user ''' |
||||
return 'user:{}'.format(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: |
||||
# a purchaser is also a user |
||||
principals.append(Role.USER.principal) |
||||
elif self.role is Role.ADMIN: |
||||
# an admin is also a purchaser and a user |
||||
principals.append(Role.PURCHASER.principal) |
||||
principals.append(Role.USER.principal) |
||||
return principals |
||||
|
||||
@property |
||||
def is_active(self): |
||||
''' is true if the user has an active role ''' |
||||
return self.role in (Role.USER, Role.PURCHASER, Role.ADMIN) |
||||
|
||||
def __str__(self): |
||||
''' string representation ''' |
||||
return str(self.username) |
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
''' Test package for ordr2.models ''' |
@ -0,0 +1,89 @@
@@ -0,0 +1,89 @@
|
||||
''' Test package for ordr2.models.users ''' |
||||
|
||||
import pytest |
||||
|
||||
|
||||
# tests for users.Role |
||||
|
||||
def test_role_principals(): |
||||
''' test Role.principal, a caluclated property ''' |
||||
from ordr2.models.users import Role |
||||
|
||||
assert Role.UNVALIDATED.principal == 'role:unvalidated' |
||||
assert Role.NEW.principal == 'role:new' |
||||
assert Role.USER.principal == 'role:user' |
||||
assert Role.PURCHASER.principal == 'role:purchaser' |
||||
assert Role.ADMIN.principal == 'role:admin' |
||||
assert Role.INACTIVE.principal == 'role:inactive' |
||||
|
||||
|
||||
def test_role_str(): |
||||
''' test the string representation of roles ''' |
||||
from ordr2.models.users import Role |
||||
|
||||
assert str(Role.UNVALIDATED) == 'Unvalidated' |
||||
assert str(Role.NEW) == 'New' |
||||
assert str(Role.USER) == 'User' |
||||
assert str(Role.PURCHASER) == 'Purchaser' |
||||
assert str(Role.ADMIN) == 'Admin' |
||||
assert str(Role.INACTIVE) == 'Inactive' |
||||
|
||||
|
||||
# tests for users.User |
||||
|
||||
def test_user_principal(): |
||||
''' test the user principal calculated property ''' |
||||
from ordr2.models.users import User |
||||
|
||||
user = User(id=3) |
||||
|
||||
assert user.principal == 'user:3' |
||||
|
||||
|
||||
@pytest.mark.parametrize( |
||||
'role_name, principals', [ |
||||
('UNVALIDATED', ['role:unvalidated']), |
||||
('NEW', ['role:new']), |
||||
('USER', ['role:user']), |
||||
('PURCHASER', ['role:purchaser', 'role:user']), |
||||
('ADMIN', ['role:admin', 'role:purchaser', 'role:user']), |
||||
('INACTIVE', ['role:inactive']) |
||||
] |
||||
) |
||||
def test_user_role_principals(role_name, principals): |
||||
''' test the user's role principals calculated property ''' |
||||
from ordr2.models.users import User, Role |
||||
|
||||
role = Role[role_name] |
||||
user = User(role=role) |
||||
|
||||
assert user.role_principals == principals |
||||
|
||||
|
||||
@pytest.mark.parametrize( |
||||
'role_name, is_active', [ |
||||
('UNVALIDATED', False), |
||||
('NEW', False), |
||||
('USER', True), |
||||
('PURCHASER', True), |
||||
('ADMIN', True), |
||||
('INACTIVE', False) |
||||
] |
||||
) |
||||
def test_user_is_active(role_name, is_active): |
||||
''' test if is_active returns correct value based on the user's role ''' |
||||
from ordr2.models.users import User, Role |
||||
|
||||
role = Role[role_name] |
||||
user = User(role=role) |
||||
|
||||
assert user.is_active == is_active |
||||
|
||||
|
||||
def test_user_string_representation(): |
||||
''' test the string representation of the user ''' |
||||
from ordr2.models.users import User, Role |
||||
|
||||
user = User(username='FooBar') |
||||
|
||||
assert str(user) == 'FooBar' |
Reference in new issue