154 lines
5.0 KiB
Python
154 lines
5.0 KiB
Python
import random
|
|
import string
|
|
import uuid
|
|
from hashlib import md5
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy.schema import ForeignKey, Table
|
|
from sqlalchemy import Column, Boolean, Unicode, Integer, DateTime, UniqueConstraint
|
|
from sqlalchemy.orm import synonym, relationship
|
|
|
|
from barker.models.guidtype import GUID
|
|
from .meta import Base
|
|
|
|
|
|
def encrypt(val):
|
|
return md5(val.encode('utf-8') + "v2".encode('utf-8')).hexdigest()
|
|
|
|
|
|
class Client(Base):
|
|
__tablename__ = 'clients'
|
|
|
|
id = Column('id', GUID(), primary_key=True, default=uuid.uuid4)
|
|
code = Column('code', Integer, unique=True, nullable=False)
|
|
name = Column('name', Unicode(255), unique=True, nullable=False)
|
|
enabled = Column('enabled', Boolean, nullable=False)
|
|
otp = Column('otp', Integer)
|
|
creation_date = Column('creation_date', DateTime(timezone=True), nullable=False)
|
|
|
|
login_history = relationship('LoginHistory', backref='client')
|
|
|
|
def __init__(self, code=None, name=None, enabled=False, otp=None, creation_date=None, id=None):
|
|
self.code = code
|
|
self.name = name
|
|
self.enabled = enabled
|
|
self.otp = otp
|
|
self.creation_date = datetime.utcnow() if creation_date is None else creation_date
|
|
self.id = id
|
|
|
|
@classmethod
|
|
def by_code(cls, code, dbsession):
|
|
if code is None:
|
|
return None
|
|
if not isinstance(code, int):
|
|
code = int(code)
|
|
return dbsession.query(cls).filter(cls.code == code).first()
|
|
|
|
@classmethod
|
|
def create(cls, dbsession):
|
|
client_code = random.randint(1000, 9999)
|
|
otp = random.randint(1000, 9999)
|
|
name = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(6))
|
|
client = Client(client_code, name, False, otp)
|
|
dbsession.add(client)
|
|
return client
|
|
|
|
|
|
user_roles = Table(
|
|
'user_roles', Base.metadata,
|
|
Column('id', GUID(), primary_key=True, default=uuid.uuid4),
|
|
Column('user_id', GUID(), ForeignKey('users.id'), nullable=False),
|
|
Column('role_id', GUID(), ForeignKey('roles.id'), nullable=False),
|
|
UniqueConstraint('user_id', 'role_id')
|
|
)
|
|
|
|
role_permissions = Table(
|
|
'role_permissions', Base.metadata,
|
|
Column('id', GUID(), primary_key=True, default=uuid.uuid4),
|
|
Column('permission_id', GUID(), ForeignKey('permissions.id'), nullable=False),
|
|
Column('role_id', GUID(), ForeignKey('roles.id'), nullable=False),
|
|
UniqueConstraint('permission_id', 'role_id')
|
|
)
|
|
|
|
|
|
class User(Base):
|
|
__tablename__ = 'users'
|
|
|
|
id = Column('id', GUID(), primary_key=True, default=uuid.uuid4)
|
|
name = Column('name', Unicode(255), unique=True, nullable=False)
|
|
_password = Column('password', Unicode(60), nullable=False)
|
|
locked_out = Column('locked_out', Boolean, nullable=False)
|
|
|
|
roles = relationship("Role", secondary=user_roles, order_by="Role.name")
|
|
login_history = relationship('LoginHistory', backref='user')
|
|
|
|
def _get_password(self):
|
|
return self._password
|
|
|
|
def _set_password(self, password):
|
|
self._password = encrypt(password)
|
|
|
|
password = property(_get_password, _set_password)
|
|
password = synonym('_password', descriptor=password)
|
|
|
|
@property
|
|
def __name__(self):
|
|
return self.name
|
|
|
|
def __init__(self, name=None, password=None, locked_out=None, id=None):
|
|
self.name = name
|
|
self.password = password
|
|
self.locked_out = locked_out
|
|
self.id = id
|
|
|
|
@classmethod
|
|
def auth(cls, name, password, dbsession):
|
|
if password is None:
|
|
return False, None
|
|
user = dbsession.query(User).filter(User.name.ilike(name)).first()
|
|
if not user:
|
|
return False, None
|
|
if user.password != encrypt(password) or user.locked_out:
|
|
return False, None
|
|
else:
|
|
return True, user
|
|
|
|
|
|
class LoginHistory(Base):
|
|
__tablename__ = 'login_history'
|
|
__table_args__ = (UniqueConstraint('user_id', 'client_id', 'date'),)
|
|
id = Column('login_history_id', GUID(), primary_key=True, default=uuid.uuid4)
|
|
user_id = Column('user_id', GUID(), ForeignKey('users.id'), nullable=False)
|
|
client_id = Column('client_id', GUID(), ForeignKey('clients.id'), nullable=False)
|
|
date = Column('date', DateTime(timezone=True), nullable=False)
|
|
|
|
def __init__(self, user_id=None, client_id=None, date=None, id=None):
|
|
self.user_id = user_id
|
|
self.client_id = client_id
|
|
self.date = datetime.utcnow() if date is None else date
|
|
self.id = id
|
|
|
|
|
|
class Role(Base):
|
|
__tablename__ = 'roles'
|
|
|
|
id = Column('id', GUID(), primary_key=True, default=uuid.uuid4)
|
|
name = Column('name', Unicode(255), unique=True)
|
|
|
|
def __init__(self, name=None, id=None):
|
|
self.name = name
|
|
self.id = id
|
|
|
|
|
|
class Permission(Base):
|
|
__tablename__ = 'permissions'
|
|
|
|
id = Column('id', GUID(), primary_key=True, default=uuid.uuid4)
|
|
name = Column('name', Unicode(255), unique=True)
|
|
|
|
roles = relationship("Role", secondary=role_permissions, backref="permissions")
|
|
|
|
def __init__(self, name=None, id=None):
|
|
self.name = name
|
|
self.id = id
|