168 lines
4.9 KiB
Python
168 lines
4.9 KiB
Python
import random
|
|
import string
|
|
import uuid
|
|
|
|
from datetime import datetime
|
|
from hashlib import md5
|
|
|
|
from sqlalchemy import Boolean, Column, DateTime, Integer, Unicode, UniqueConstraint
|
|
from sqlalchemy.dialects.postgresql import UUID
|
|
from sqlalchemy.orm import Session, relationship, synonym
|
|
from sqlalchemy.schema import ForeignKey, Table
|
|
|
|
from .meta import Base
|
|
|
|
|
|
def encrypt(val):
|
|
return md5(val.encode("utf-8") + "Salt".encode("utf-8")).hexdigest()
|
|
|
|
|
|
class Client(Base):
|
|
__tablename__ = "auth_clients"
|
|
|
|
id = Column("client_id", UUID(as_uuid=True), 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 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_role = 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("auth_users.id")),
|
|
Column("role_id", UUID(as_uuid=True), ForeignKey("auth_roles.id")),
|
|
)
|
|
|
|
role_permission = 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("auth_permissions.id")),
|
|
Column("role_id", UUID(as_uuid=True), ForeignKey("auth_roles.id")),
|
|
)
|
|
|
|
|
|
class User(Base):
|
|
__tablename__ = "auth_users"
|
|
|
|
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
name = Column("username", Unicode(255), unique=True)
|
|
_password = Column("password", Unicode(60))
|
|
locked_out = Column("disabled", Boolean)
|
|
|
|
roles = relationship("Role", secondary=user_role)
|
|
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, db) -> any:
|
|
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 LoginHistory(Base):
|
|
__tablename__ = "auth_login_history"
|
|
__table_args__ = (UniqueConstraint("user_id", "client_id", "date"),)
|
|
id = Column(
|
|
"login_history_id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4
|
|
)
|
|
user_id = Column(
|
|
"user_id", UUID(as_uuid=True), ForeignKey("auth_users.id"), nullable=False
|
|
)
|
|
client_id = Column(
|
|
"client_id",
|
|
UUID(as_uuid=True),
|
|
ForeignKey("auth_clients.client_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__ = "auth_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__ = "auth_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_permission, backref="permissions")
|
|
|
|
def __init__(self, name=None, id_=None):
|
|
self.name = name
|
|
self.id = id_
|