brewman/brewman/brewman/models/auth.py

168 lines
4.9 KiB
Python
Raw Normal View History

import random
import string
import uuid
2020-10-07 15:18:43 +00:00
from datetime import datetime
2020-10-07 15:18:43 +00:00
from hashlib import md5
2020-10-07 15:18:43 +00:00
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__(
2020-10-07 15:18:43 +00:00
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
2020-10-07 16:59:24 +00:00
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)
2020-10-07 16:59:24 +00:00
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"),)
2020-10-07 16:59:24 +00:00
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_