74 lines
No EOL
3.1 KiB
Python
74 lines
No EOL
3.1 KiB
Python
from sqlalchemy import Column, Integer, String, Boolean, TIMESTAMP, ForeignKey, Index, UniqueConstraint
|
|
from sqlalchemy.sql import func
|
|
from sqlalchemy.dialects.sqlite import JSON
|
|
from database import Base
|
|
|
|
|
|
class OAuthClient(Base):
|
|
"""OAuth 2.0 client registration.
|
|
|
|
Attributes:
|
|
client_secret: Should store a cryptographically hashed value, not plaintext.
|
|
redirect_uris: JSON array of allowed redirect URIs (list of strings).
|
|
grant_types: JSON array of allowed grant types (list of strings).
|
|
scopes: JSON array of available scopes (list of strings).
|
|
"""
|
|
__tablename__ = "oauth_clients"
|
|
|
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
client_id = Column(String(100), unique=True, nullable=False)
|
|
client_secret = Column(String(255), nullable=False) # Hashed secret
|
|
name = Column(String(200), nullable=False)
|
|
redirect_uris = Column(JSON, default=list) # List of allowed redirect URIs
|
|
grant_types = Column(JSON, default=list) # List of allowed grant types
|
|
scopes = Column(JSON, default=list) # List of available scopes
|
|
is_active = Column(Boolean, default=True)
|
|
created_at = Column(TIMESTAMP, server_default=func.now())
|
|
updated_at = Column(TIMESTAMP, server_default=func.now(), onupdate=func.now())
|
|
|
|
def __repr__(self):
|
|
return f"<OAuthClient {self.client_id} ({self.name})>"
|
|
|
|
|
|
class OAuthToken(Base):
|
|
__tablename__ = "oauth_tokens"
|
|
|
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
access_token = Column(String(1000), unique=True, nullable=False)
|
|
refresh_token = Column(String(1000), unique=True, nullable=True)
|
|
token_type = Column(String(50), default="Bearer")
|
|
expires_at = Column(TIMESTAMP, nullable=False, index=True)
|
|
scopes = Column(JSON, default=list)
|
|
client_id = Column(String(100), ForeignKey('oauth_clients.client_id'), nullable=False, index=True)
|
|
user_id = Column(Integer, ForeignKey('oauth_users.id'), nullable=True, index=True)
|
|
created_at = Column(TIMESTAMP, server_default=func.now())
|
|
updated_at = Column(TIMESTAMP, server_default=func.now(), onupdate=func.now())
|
|
|
|
__table_args__ = (
|
|
Index('ix_oauth_tokens_client_expires', 'client_id', 'expires_at'),
|
|
Index('ix_oauth_tokens_user_expires', 'user_id', 'expires_at'),
|
|
)
|
|
|
|
def __repr__(self):
|
|
return f"<OAuthToken {self.client_id} ({self.token_type})>"
|
|
|
|
|
|
class OAuthUser(Base):
|
|
"""OAuth 2.0 resource owner (user) account.
|
|
|
|
Attributes:
|
|
password_hash: Should store a cryptographically hashed value, not plaintext.
|
|
email: Unique when provided (nullable).
|
|
"""
|
|
__tablename__ = "oauth_users"
|
|
|
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
username = Column(String(100), unique=True, nullable=False)
|
|
password_hash = Column(String(255), nullable=False)
|
|
email = Column(String(255), nullable=True, unique=True)
|
|
is_active = Column(Boolean, default=True)
|
|
created_at = Column(TIMESTAMP, server_default=func.now())
|
|
updated_at = Column(TIMESTAMP, server_default=func.now(), onupdate=func.now())
|
|
|
|
def __repr__(self):
|
|
return f"<OAuthUser {self.username}>" |