Initial implementation of OAuth models, endpoints, and migrations

- Added models for `OAuthClient`, `OAuthState`, and `OAuthAccount`.
- Created Pydantic schemas to support OAuth flows, client management, and linked accounts.
- Implemented skeleton endpoints for OAuth Provider mode: authorization, token, and revocation.
- Updated router imports to include new `/oauth` and `/oauth/provider` routes.
- Added Alembic migration script to create OAuth-related database tables.
- Enhanced `users` table to allow OAuth-only accounts by making `password_hash` nullable.
This commit is contained in:
Felipe Cardoso
2025-11-25 00:37:23 +01:00
parent e6792c2d6c
commit 16ee4e0cb3
23 changed files with 4109 additions and 13 deletions

View File

@@ -154,18 +154,25 @@ def test_user_required_fields(db_session):
db_session.commit()
db_session.rollback()
# Missing password_hash
def test_user_oauth_only_without_password(db_session):
"""Test that OAuth-only users can be created without password_hash."""
# OAuth-only users don't have a password set
user_no_password = User(
id=uuid.uuid4(),
email="nopassword@example.com",
# password_hash is missing
first_name="Test",
email="oauthonly@example.com",
password_hash=None, # OAuth-only user
first_name="OAuth",
last_name="User",
)
db_session.add(user_no_password)
with pytest.raises(IntegrityError):
db_session.commit()
db_session.rollback()
db_session.commit()
# Retrieve and verify
retrieved = db_session.query(User).filter_by(email="oauthonly@example.com").first()
assert retrieved is not None
assert retrieved.password_hash is None
assert retrieved.has_password is False # Test has_password property
def test_user_defaults(db_session):