open-law/app/models/user.py

70 lines
2.0 KiB
Python

from datetime import datetime
from uuid import uuid4
from flask_login import UserMixin, AnonymousUserMixin
from sqlalchemy import func
from sqlalchemy.ext.hybrid import hybrid_property
from werkzeug.security import generate_password_hash, check_password_hash
from app import db
from app.models.utils import ModelMixin
from app.logger import log
from app import schema as s
def gen_password_reset_id() -> str:
return str(uuid4())
class User(db.Model, UserMixin, ModelMixin):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(60), unique=True, nullable=False)
email = db.Column(db.String(255), unique=True, nullable=False)
password_hash = db.Column(db.String(255), default="")
activated = db.Column(db.Boolean, default=False)
created_at = db.Column(db.DateTime, default=datetime.now)
unique_id = db.Column(db.String(36), default=gen_password_reset_id)
reset_password_uid = db.Column(db.String(64), default=gen_password_reset_id)
@hybrid_property
def password(self):
return self.password_hash
@password.setter
def password(self, password):
self.password_hash = generate_password_hash(password)
@classmethod
def authenticate(cls, user_id, password):
user = cls.query.filter(
db.or_(
func.lower(cls.username) == func.lower(user_id),
func.lower(cls.email) == func.lower(user_id),
)
).first()
if not user:
log(log.WARNING, "user:[%s] not found", user_id)
if user is not None and check_password_hash(user.password, password):
return user
def reset_password(self):
self.password_hash = ""
self.reset_password_uid = gen_password_reset_id()
self.save()
def __repr__(self):
return f"<{self.id}: {self.username},{self.email}>"
@property
def json(self):
u = s.User.from_orm(self)
return u.json()
class AnonymousUser(AnonymousUserMixin):
pass