Initial commit - Customer Portal for Coolify
This commit is contained in:
72
customer_portal/models/admin_user.py
Executable file
72
customer_portal/models/admin_user.py
Executable file
@@ -0,0 +1,72 @@
|
||||
"""Admin User model with separate authentication."""
|
||||
|
||||
from datetime import UTC, datetime
|
||||
|
||||
from sqlalchemy import Boolean, Column, DateTime, Integer, String
|
||||
from werkzeug.security import check_password_hash, generate_password_hash
|
||||
|
||||
from customer_portal.models import Base
|
||||
|
||||
|
||||
class AdminUser(Base):
|
||||
"""Admin user with username/password authentication.
|
||||
|
||||
Separate from Customer - admins have their own login.
|
||||
"""
|
||||
|
||||
__tablename__ = "admin_users"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
username = Column(String(100), unique=True, nullable=False, index=True)
|
||||
password_hash = Column(String(255), nullable=False)
|
||||
name = Column(String(255), nullable=False)
|
||||
email = Column(String(255))
|
||||
is_active = Column(Boolean, default=True)
|
||||
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(UTC))
|
||||
last_login_at = Column(DateTime)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<AdminUser {self.username}>"
|
||||
|
||||
def set_password(self, password: str) -> None:
|
||||
"""Hash and set password."""
|
||||
self.password_hash = generate_password_hash(password)
|
||||
|
||||
def check_password(self, password: str) -> bool:
|
||||
"""Verify password against hash."""
|
||||
return check_password_hash(self.password_hash, password)
|
||||
|
||||
@classmethod
|
||||
def get_by_username(cls, db, username: str):
|
||||
"""Get admin by username.
|
||||
|
||||
Args:
|
||||
db: Database session
|
||||
username: Admin username
|
||||
|
||||
Returns:
|
||||
AdminUser instance or None
|
||||
"""
|
||||
return (
|
||||
db.query(cls)
|
||||
.filter(cls.username == username, cls.is_active == True) # noqa: E712
|
||||
.first()
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def authenticate(cls, db, username: str, password: str):
|
||||
"""Authenticate admin with username and password.
|
||||
|
||||
Args:
|
||||
db: Database session
|
||||
username: Admin username
|
||||
password: Plain text password
|
||||
|
||||
Returns:
|
||||
AdminUser instance if valid, None otherwise
|
||||
"""
|
||||
admin = cls.get_by_username(db, username)
|
||||
if admin and admin.check_password(password):
|
||||
return admin
|
||||
return None
|
||||
Reference in New Issue
Block a user