Files
syndarix/backend/app/models/oauth_account.py
Felipe Cardoso b3f0dd4005 Add full OAuth provider functionality and enhance flows
- Implemented OAuth 2.0 Authorization Server endpoints per RFCs, including token, introspection, revocation, and metadata discovery.
- Added user consent submission, listing, and revocation APIs alongside frontend integration for improved UX.
- Enforced stricter OAuth security measures (PKCE, state validation, scopes).
- Refactored schemas and services for consistency and expanded coverage of OAuth workflows.
- Updated documentation and type definitions for new API behaviors.
2025-11-26 13:23:44 +01:00

56 lines
1.9 KiB
Python
Executable File

"""OAuth account model for linking external OAuth providers to users."""
from sqlalchemy import Column, DateTime, ForeignKey, Index, String, UniqueConstraint
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
from .base import Base, TimestampMixin, UUIDMixin
class OAuthAccount(Base, UUIDMixin, TimestampMixin):
"""
Links OAuth provider accounts to users.
Supports multiple OAuth providers per user (e.g., user can have both
Google and GitHub connected). Each provider account is uniquely identified
by (provider, provider_user_id).
"""
__tablename__ = "oauth_accounts"
# Link to user
user_id = Column(
UUID(as_uuid=True),
ForeignKey("users.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
# OAuth provider identification
provider = Column(
String(50), nullable=False, index=True
) # google, github, microsoft
provider_user_id = Column(String(255), nullable=False) # Provider's unique user ID
provider_email = Column(
String(255), nullable=True, index=True
) # Email from provider (for reference)
# Optional: store provider tokens for API access
# These should be encrypted at rest in production
access_token_encrypted = Column(String(2048), nullable=True)
refresh_token_encrypted = Column(String(2048), nullable=True)
token_expires_at = Column(DateTime(timezone=True), nullable=True)
# Relationship
user = relationship("User", back_populates="oauth_accounts")
__table_args__ = (
# Each provider account can only be linked to one user
UniqueConstraint("provider", "provider_user_id", name="uq_oauth_provider_user"),
# Index for finding all OAuth accounts for a user + provider
Index("ix_oauth_accounts_user_provider", "user_id", "provider"),
)
def __repr__(self):
return f"<OAuthAccount {self.provider}:{self.provider_user_id}>"