From fb28c648390464c75ba4903b0e1e0ff2642c8ffb Mon Sep 17 00:00:00 2001 From: Tom van der Lee Date: Thu, 2 Jul 2026 18:34:39 +0200 Subject: Added users and migrations --- .../versions/202607012255-40e20fbf63c9_.py | 35 ------- .../versions/202607012255-6ebaa6ab0f48_.py | 39 -------- .../202607021719-115caa5a76d0_added_user_model.py | 40 ++++++++ ...202607021740-fc6608d3f9cc_added_oauth_models.py | 104 +++++++++++++++++++++ .../202607021803-ac4fbf1fea31_added_password.py | 33 +++++++ 5 files changed, 177 insertions(+), 74 deletions(-) delete mode 100644 db/migrations/versions/202607012255-40e20fbf63c9_.py delete mode 100644 db/migrations/versions/202607012255-6ebaa6ab0f48_.py create mode 100644 db/migrations/versions/202607021719-115caa5a76d0_added_user_model.py create mode 100644 db/migrations/versions/202607021740-fc6608d3f9cc_added_oauth_models.py create mode 100644 db/migrations/versions/202607021803-ac4fbf1fea31_added_password.py (limited to 'db/migrations/versions') diff --git a/db/migrations/versions/202607012255-40e20fbf63c9_.py b/db/migrations/versions/202607012255-40e20fbf63c9_.py deleted file mode 100644 index a32131a..0000000 --- a/db/migrations/versions/202607012255-40e20fbf63c9_.py +++ /dev/null @@ -1,35 +0,0 @@ -"""empty message - -Revision ID: 40e20fbf63c9 -Revises: 6ebaa6ab0f48 -Create Date: 2026-07-01 22:55:55.017591 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa -import sqlmodel - - -# revision identifiers, used by Alembic. -revision: str = '40e20fbf63c9' -down_revision: Union[str, Sequence[str], None] = '6ebaa6ab0f48' -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None - - -def upgrade() -> None: - """Upgrade schema.""" - # ### commands auto generated by Alembic - please adjust! ### - op.add_column('user', sa.Column('external_id', sa.Uuid(), nullable=False, server_default=sa.text('gen_random_uuid()'))) - op.create_index(op.f('ix_user_external_id'), 'user', ['external_id'], unique=True) - # ### end Alembic commands ### - - -def downgrade() -> None: - """Downgrade schema.""" - # ### commands auto generated by Alembic - please adjust! ### - op.drop_index(op.f('ix_user_external_id'), table_name='user') - op.drop_column('user', 'external_id') - # ### end Alembic commands ### diff --git a/db/migrations/versions/202607012255-6ebaa6ab0f48_.py b/db/migrations/versions/202607012255-6ebaa6ab0f48_.py deleted file mode 100644 index 9d4daa2..0000000 --- a/db/migrations/versions/202607012255-6ebaa6ab0f48_.py +++ /dev/null @@ -1,39 +0,0 @@ -"""empty message - -Revision ID: 6ebaa6ab0f48 -Revises: -Create Date: 2026-07-01 22:55:14.146711 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa -import sqlmodel - - -# revision identifiers, used by Alembic. -revision: str = '6ebaa6ab0f48' -down_revision: Union[str, Sequence[str], None] = None -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None - - -def upgrade() -> None: - """Upgrade schema.""" - # ### commands auto generated by Alembic - please adjust! ### - op.create_table('user', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('username', sqlmodel.sql.sqltypes.AutoString(), nullable=False), - sa.PrimaryKeyConstraint('id') - ) - op.create_index(op.f('ix_user_username'), 'user', ['username'], unique=True) - # ### end Alembic commands ### - - -def downgrade() -> None: - """Downgrade schema.""" - # ### commands auto generated by Alembic - please adjust! ### - op.drop_index(op.f('ix_user_username'), table_name='user') - op.drop_table('user') - # ### end Alembic commands ### diff --git a/db/migrations/versions/202607021719-115caa5a76d0_added_user_model.py b/db/migrations/versions/202607021719-115caa5a76d0_added_user_model.py new file mode 100644 index 0000000..3ccb92d --- /dev/null +++ b/db/migrations/versions/202607021719-115caa5a76d0_added_user_model.py @@ -0,0 +1,40 @@ +"""Added user model + +Revision ID: 115caa5a76d0 +Revises: +Create Date: 2026-07-02 17:19:07.082841 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +import sqlmodel + + +# revision identifiers, used by Alembic. +revision: str = '115caa5a76d0' +down_revision: Union[str, Sequence[str], None] = None +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + """Upgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('user', + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('username', sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.Column('email', sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.PrimaryKeyConstraint('id') + ) + op.create_index(op.f('ix_user_username'), 'user', ['username'], unique=True) + # ### end Alembic commands ### + + +def downgrade() -> None: + """Downgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index(op.f('ix_user_username'), table_name='user') + op.drop_table('user') + # ### end Alembic commands ### 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 @@ +"""Added oauth models + +Revision ID: fc6608d3f9cc +Revises: 115caa5a76d0 +Create Date: 2026-07-02 17:40:58.968553 + +""" +import json +import os +from datetime import datetime, UTC +from secrets import token_hex +from random import randbytes +from typing import Sequence, Union +from uuid import uuid4, uuid7 + +from alembic import op +import sqlalchemy as sa +import sqlmodel +from authlib.integrations.sqla_oauth2 import OAuth2ClientMixin + +# revision identifiers, used by Alembic. +revision: str = 'fc6608d3f9cc' +down_revision: Union[str, Sequence[str], None] = '115caa5a76d0' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + """Upgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + client_application = op.create_table('clientapplication', + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('name', sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.Column('client_id', sa.String(length=48), nullable=True), + sa.Column('client_secret', sa.String(length=120), nullable=True), + sa.Column('client_id_issued_at', sa.Integer(), nullable=False), + sa.Column('client_secret_expires_at', sa.Integer(), nullable=False), + sa.Column('client_metadata', sa.Text(), nullable=True), + sa.PrimaryKeyConstraint('id') + ) + op.create_index(op.f('ix_clientapplication_client_id'), 'clientapplication', ['client_id'], unique=False) + op.create_table('authcode', + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('code', sa.String(length=120), nullable=False), + sa.Column('client_id', sa.String(length=48), nullable=True), + sa.Column('redirect_uri', sa.Text(), nullable=True), + sa.Column('response_type', sa.Text(), nullable=True), + sa.Column('scope', sa.Text(), nullable=True), + sa.Column('nonce', sa.Text(), nullable=True), + sa.Column('auth_time', sa.Integer(), nullable=False), + sa.Column('acr', sa.Text(), nullable=True), + sa.Column('amr', sa.Text(), nullable=True), + sa.Column('code_challenge', sa.Text(), nullable=True), + sa.Column('code_challenge_method', sa.String(length=48), nullable=True), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('code') + ) + op.create_table('authtoken', + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('client_id', sa.String(length=48), nullable=True), + sa.Column('token_type', sa.String(length=40), nullable=True), + sa.Column('access_token', sa.String(length=255), nullable=False), + sa.Column('refresh_token', sa.String(length=255), nullable=True), + sa.Column('scope', sa.Text(), nullable=True), + sa.Column('issued_at', sa.Integer(), nullable=False), + sa.Column('access_token_revoked_at', sa.Integer(), nullable=False), + sa.Column('refresh_token_revoked_at', sa.Integer(), nullable=False), + sa.Column('expires_in', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('access_token') + ) + op.create_index(op.f('ix_authtoken_refresh_token'), 'authtoken', ['refresh_token'], unique=False) + + op.bulk_insert(client_application, [ + { + 'id': uuid7(), + 'name': 'TTUN', + 'client_id': uuid4().hex, + 'client_secret': token_hex(32), + 'client_id_issued_at': datetime.now(tz=UTC).timestamp(), + 'client_secret_expires_at': datetime.now(tz=UTC).timestamp() + 3600, + 'client_metadata': json.dumps({ + 'redirect_uris': [ + f'//{os.environ['TUNNEL_DOMAIN']}/oauth/callback' + ], + }) + } + ]) + # ### end Alembic commands ### + + +def downgrade() -> None: + """Downgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index(op.f('ix_authtoken_refresh_token'), table_name='authtoken') + op.drop_table('authtoken') + op.drop_table('authcode') + op.drop_index(op.f('ix_clientapplication_client_id'), table_name='clientapplication') + op.drop_table('clientapplication') + # ### end Alembic commands ### diff --git a/db/migrations/versions/202607021803-ac4fbf1fea31_added_password.py b/db/migrations/versions/202607021803-ac4fbf1fea31_added_password.py new file mode 100644 index 0000000..116d27e --- /dev/null +++ b/db/migrations/versions/202607021803-ac4fbf1fea31_added_password.py @@ -0,0 +1,33 @@ +"""Added password + +Revision ID: ac4fbf1fea31 +Revises: fc6608d3f9cc +Create Date: 2026-07-02 18:03:17.190700 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +import sqlmodel + + +# revision identifiers, used by Alembic. +revision: str = 'ac4fbf1fea31' +down_revision: Union[str, Sequence[str], None] = 'fc6608d3f9cc' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + """Upgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('user', sa.Column('password', sqlmodel.sql.sqltypes.AutoString(), nullable=False)) + # ### end Alembic commands ### + + +def downgrade() -> None: + """Downgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('user', 'password') + # ### end Alembic commands ### -- cgit v1.2.3