Flask backend with Vue 3 frontend for shop floor machine management. Includes database schema export for MySQL shopdb_flask database. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
74 lines
2.1 KiB
Python
74 lines
2.1 KiB
Python
"""User and authentication models."""
|
|
|
|
from datetime import datetime
|
|
from shopdb.extensions import db
|
|
from .base import BaseModel
|
|
|
|
|
|
# Association table for user roles (many-to-many)
|
|
userroles = db.Table(
|
|
'userroles',
|
|
db.Column('userid', db.Integer, db.ForeignKey('users.userid'), primary_key=True),
|
|
db.Column('roleid', db.Integer, db.ForeignKey('roles.roleid'), primary_key=True)
|
|
)
|
|
|
|
|
|
class Role(BaseModel):
|
|
"""User role model."""
|
|
__tablename__ = 'roles'
|
|
|
|
roleid = db.Column(db.Integer, primary_key=True)
|
|
rolename = db.Column(db.String(50), unique=True, nullable=False)
|
|
description = db.Column(db.Text)
|
|
|
|
def __repr__(self):
|
|
return f"<Role {self.rolename}>"
|
|
|
|
|
|
class User(BaseModel):
|
|
"""User model for authentication."""
|
|
__tablename__ = 'users'
|
|
|
|
userid = db.Column(db.Integer, primary_key=True)
|
|
username = db.Column(db.String(100), unique=True, nullable=False, index=True)
|
|
email = db.Column(db.String(255), unique=True, nullable=False)
|
|
passwordhash = db.Column(db.String(255), nullable=False)
|
|
|
|
# Profile
|
|
firstname = db.Column(db.String(100))
|
|
lastname = db.Column(db.String(100))
|
|
|
|
# Status
|
|
lastlogindate = db.Column(db.DateTime)
|
|
failedlogins = db.Column(db.Integer, default=0)
|
|
lockeduntil = db.Column(db.DateTime)
|
|
|
|
# Relationships
|
|
roles = db.relationship(
|
|
'Role',
|
|
secondary=userroles,
|
|
backref=db.backref('users', lazy='dynamic')
|
|
)
|
|
|
|
def __repr__(self):
|
|
return f"<User {self.username}>"
|
|
|
|
@property
|
|
def islocked(self):
|
|
"""Check if account is locked."""
|
|
if self.lockeduntil:
|
|
return datetime.utcnow() < self.lockeduntil
|
|
return False
|
|
|
|
def hasrole(self, rolename: str) -> bool:
|
|
"""Check if user has a specific role."""
|
|
return any(r.rolename == rolename for r in self.roles)
|
|
|
|
def getpermissions(self) -> list:
|
|
"""Get list of permission names from roles."""
|
|
# Simple role-based permissions
|
|
perms = []
|
|
for role in self.roles:
|
|
perms.append(role.rolename)
|
|
return perms
|