diff options
Diffstat (limited to 'db/migrations/versions/202607021740-fc6608d3f9cc_added_oauth_models.py')
| -rw-r--r-- | db/migrations/versions/202607021740-fc6608d3f9cc_added_oauth_models.py | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/db/migrations/versions/202607021740-fc6608d3f9cc_added_oauth_models.py b/db/migrations/versions/202607021740-fc6608d3f9cc_added_oauth_models.py new file mode 100644 index 0000000..5498291 --- /dev/null +++ b/db/migrations/versions/202607021740-fc6608d3f9cc_added_oauth_models.py | |||
| @@ -0,0 +1,104 @@ | |||
| 1 | """Added oauth models | ||
| 2 | |||
| 3 | Revision ID: fc6608d3f9cc | ||
| 4 | Revises: 115caa5a76d0 | ||
| 5 | Create Date: 2026-07-02 17:40:58.968553 | ||
| 6 | |||
| 7 | """ | ||
| 8 | import json | ||
| 9 | import os | ||
| 10 | from datetime import datetime, UTC | ||
| 11 | from secrets import token_hex | ||
| 12 | from random import randbytes | ||
| 13 | from typing import Sequence, Union | ||
| 14 | from uuid import uuid4, uuid7 | ||
| 15 | |||
| 16 | from alembic import op | ||
| 17 | import sqlalchemy as sa | ||
| 18 | import sqlmodel | ||
| 19 | from authlib.integrations.sqla_oauth2 import OAuth2ClientMixin | ||
| 20 | |||
| 21 | # revision identifiers, used by Alembic. | ||
| 22 | revision: str = 'fc6608d3f9cc' | ||
| 23 | down_revision: Union[str, Sequence[str], None] = '115caa5a76d0' | ||
| 24 | branch_labels: Union[str, Sequence[str], None] = None | ||
| 25 | depends_on: Union[str, Sequence[str], None] = None | ||
| 26 | |||
| 27 | |||
| 28 | def upgrade() -> None: | ||
| 29 | """Upgrade schema.""" | ||
| 30 | # ### commands auto generated by Alembic - please adjust! ### | ||
| 31 | client_application = op.create_table('clientapplication', | ||
| 32 | sa.Column('id', sa.Uuid(), nullable=False), | ||
| 33 | sa.Column('name', sqlmodel.sql.sqltypes.AutoString(), nullable=False), | ||
| 34 | sa.Column('client_id', sa.String(length=48), nullable=True), | ||
| 35 | sa.Column('client_secret', sa.String(length=120), nullable=True), | ||
| 36 | sa.Column('client_id_issued_at', sa.Integer(), nullable=False), | ||
| 37 | sa.Column('client_secret_expires_at', sa.Integer(), nullable=False), | ||
| 38 | sa.Column('client_metadata', sa.Text(), nullable=True), | ||
| 39 | sa.PrimaryKeyConstraint('id') | ||
| 40 | ) | ||
| 41 | op.create_index(op.f('ix_clientapplication_client_id'), 'clientapplication', ['client_id'], unique=False) | ||
| 42 | op.create_table('authcode', | ||
| 43 | sa.Column('id', sa.Uuid(), nullable=False), | ||
| 44 | sa.Column('user_id', sa.Uuid(), nullable=False), | ||
| 45 | sa.Column('code', sa.String(length=120), nullable=False), | ||
| 46 | sa.Column('client_id', sa.String(length=48), nullable=True), | ||
| 47 | sa.Column('redirect_uri', sa.Text(), nullable=True), | ||
| 48 | sa.Column('response_type', sa.Text(), nullable=True), | ||
| 49 | sa.Column('scope', sa.Text(), nullable=True), | ||
| 50 | sa.Column('nonce', sa.Text(), nullable=True), | ||
| 51 | sa.Column('auth_time', sa.Integer(), nullable=False), | ||
| 52 | sa.Column('acr', sa.Text(), nullable=True), | ||
| 53 | sa.Column('amr', sa.Text(), nullable=True), | ||
| 54 | sa.Column('code_challenge', sa.Text(), nullable=True), | ||
| 55 | sa.Column('code_challenge_method', sa.String(length=48), nullable=True), | ||
| 56 | sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), | ||
| 57 | sa.PrimaryKeyConstraint('id'), | ||
| 58 | sa.UniqueConstraint('code') | ||
| 59 | ) | ||
| 60 | op.create_table('authtoken', | ||
| 61 | sa.Column('id', sa.Uuid(), nullable=False), | ||
| 62 | sa.Column('user_id', sa.Uuid(), nullable=False), | ||
| 63 | sa.Column('client_id', sa.String(length=48), nullable=True), | ||
| 64 | sa.Column('token_type', sa.String(length=40), nullable=True), | ||
| 65 | sa.Column('access_token', sa.String(length=255), nullable=False), | ||
| 66 | sa.Column('refresh_token', sa.String(length=255), nullable=True), | ||
| 67 | sa.Column('scope', sa.Text(), nullable=True), | ||
| 68 | sa.Column('issued_at', sa.Integer(), nullable=False), | ||
| 69 | sa.Column('access_token_revoked_at', sa.Integer(), nullable=False), | ||
| 70 | sa.Column('refresh_token_revoked_at', sa.Integer(), nullable=False), | ||
| 71 | sa.Column('expires_in', sa.Integer(), nullable=False), | ||
| 72 | sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), | ||
| 73 | sa.PrimaryKeyConstraint('id'), | ||
| 74 | sa.UniqueConstraint('access_token') | ||
| 75 | ) | ||
| 76 | op.create_index(op.f('ix_authtoken_refresh_token'), 'authtoken', ['refresh_token'], unique=False) | ||
| 77 | |||
| 78 | op.bulk_insert(client_application, [ | ||
| 79 | { | ||
| 80 | 'id': uuid7(), | ||
| 81 | 'name': 'TTUN', | ||
| 82 | 'client_id': uuid4().hex, | ||
| 83 | 'client_secret': token_hex(32), | ||
| 84 | 'client_id_issued_at': datetime.now(tz=UTC).timestamp(), | ||
| 85 | 'client_secret_expires_at': datetime.now(tz=UTC).timestamp() + 3600, | ||
| 86 | 'client_metadata': json.dumps({ | ||
| 87 | 'redirect_uris': [ | ||
| 88 | f'//{os.environ['TUNNEL_DOMAIN']}/oauth/callback' | ||
| 89 | ], | ||
| 90 | }) | ||
| 91 | } | ||
| 92 | ]) | ||
| 93 | # ### end Alembic commands ### | ||
| 94 | |||
| 95 | |||
| 96 | def downgrade() -> None: | ||
| 97 | """Downgrade schema.""" | ||
| 98 | # ### commands auto generated by Alembic - please adjust! ### | ||
| 99 | op.drop_index(op.f('ix_authtoken_refresh_token'), table_name='authtoken') | ||
| 100 | op.drop_table('authtoken') | ||
| 101 | op.drop_table('authcode') | ||
| 102 | op.drop_index(op.f('ix_clientapplication_client_id'), table_name='clientapplication') | ||
| 103 | op.drop_table('clientapplication') | ||
| 104 | # ### end Alembic commands ### | ||
