136 lines
4.2 KiB
Python
136 lines
4.2 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, Session
|
|
|
|
from sqlalchemy.dialects.postgresql import UUID
|
|
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", Integer, primary_key=True)
|
|
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)
|
|
|
|
def __init__(self, id_=None, name=None, enabled=False, otp=None, creation_date=None):
|
|
self.id = id_
|
|
self.name = name
|
|
self.enabled = enabled
|
|
self.otp = otp
|
|
self.creation_date = creation_date or datetime.utcnow()
|
|
|
|
@classmethod
|
|
def by_id(cls, id_: int, db: Session):
|
|
if id_ is None:
|
|
return None
|
|
if not isinstance(id_, int):
|
|
id_ = int(id_)
|
|
return db.query(cls).filter(cls.id == id_).first()
|
|
|
|
@classmethod
|
|
def create(cls, db: Session):
|
|
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)
|
|
db.add(client)
|
|
return client
|
|
|
|
|
|
user_roles = Table(
|
|
"user_roles",
|
|
Base.metadata,
|
|
Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4),
|
|
Column("user_id", UUID(as_uuid=True), ForeignKey("users.id"), nullable=False),
|
|
Column("role_id", UUID(as_uuid=True), ForeignKey("roles.id"), nullable=False),
|
|
UniqueConstraint("user_id", "role_id"),
|
|
)
|
|
|
|
role_permissions = Table(
|
|
"role_permissions",
|
|
Base.metadata,
|
|
Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4),
|
|
Column("permission_id", UUID(as_uuid=True), ForeignKey("permissions.id"), nullable=False),
|
|
Column("role_id", UUID(as_uuid=True), ForeignKey("roles.id"), nullable=False),
|
|
UniqueConstraint("permission_id", "role_id"),
|
|
)
|
|
|
|
|
|
class User(Base):
|
|
__tablename__ = "users"
|
|
|
|
id = Column("id", UUID(as_uuid=True), 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")
|
|
|
|
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, db: Session):
|
|
if password is None:
|
|
return None
|
|
user = db.query(User).filter(User.name.ilike(name)).first()
|
|
if not user:
|
|
return None
|
|
if user.password != encrypt(password) or user.locked_out:
|
|
return None
|
|
else:
|
|
return user
|
|
|
|
|
|
class Role(Base):
|
|
__tablename__ = "roles"
|
|
|
|
id = Column("id", UUID(as_uuid=True), 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", UUID(as_uuid=True), 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_
|