aboutsummaryrefslogtreecommitdiffstats
path: root/db
diff options
context:
space:
mode:
authorGravatar Tom van der Lee <tom@vanderlee.io>2026-09-04 17:09:24 +0200
committerGravatar Tom van der Lee <tom@vanderlee.io>2026-09-04 17:09:24 +0200
commit6b6f20a032eb31d747366c8bc270ca81731eaf6a (patch)
treeada48080495267bebde4ee1251bbbe77d629745f /db
parent2d22158dd95f76399f5716d556be60c77da04a46 (diff)
downloadserver-v3.tar.gz
server-v3.tar.bz2
server-v3.zip
Fixed pre-commit issuesv3
Diffstat (limited to 'db')
-rw-r--r--db/migrations/README2
-rw-r--r--db/migrations/env.py10
-rw-r--r--db/migrations/versions/202607021719-115caa5a76d0_added_user_model.py33
-rw-r--r--db/migrations/versions/202607021740-fc6608d3f9cc_added_oauth_models.py160
-rw-r--r--db/migrations/versions/202607021803-ac4fbf1fea31_added_password.py21
-rw-r--r--db/migrations/versions/202607031440-69d8b4938a12_added_more_fields_and_session.py113
-rw-r--r--db/models.py21
-rw-r--r--db/session.py17
8 files changed, 228 insertions, 149 deletions
diff --git a/db/migrations/README b/db/migrations/README
index 98e4f9c..2500aa1 100644
--- a/db/migrations/README
+++ b/db/migrations/README
@@ -1 +1 @@
Generic single-database configuration. \ No newline at end of file Generic single-database configuration.
diff --git a/db/migrations/env.py b/db/migrations/env.py
index f1b3156..9c901da 100644
--- a/db/migrations/env.py
+++ b/db/migrations/env.py
@@ -1,9 +1,7 @@
1from logging.config import fileConfig 1from logging.config import fileConfig
2 2
3from sqlalchemy import engine_from_config
4from sqlalchemy import pool
5
6from alembic import context 3from alembic import context
4from sqlalchemy import engine_from_config, pool
7 5
8from conf import DATABASE_URL 6from conf import DATABASE_URL
9from db.models import * 7from db.models import *
@@ -27,7 +25,7 @@ target_metadata = SQLModel.metadata
27# can be acquired: 25# can be acquired:
28# my_important_option = config.get_main_option("my_important_option") 26# my_important_option = config.get_main_option("my_important_option")
29# ... etc. 27# ... etc.
30config.set_main_option('sqlalchemy.url', DATABASE_URL) 28config.set_main_option("sqlalchemy.url", DATABASE_URL)
31 29
32 30
33def run_migrations_offline() -> None: 31def run_migrations_offline() -> None:
@@ -68,9 +66,7 @@ def run_migrations_online() -> None:
68 ) 66 )
69 67
70 with connectable.connect() as connection: 68 with connectable.connect() as connection:
71 context.configure( 69 context.configure(connection=connection, target_metadata=target_metadata)
72 connection=connection, target_metadata=target_metadata
73 )
74 70
75 with context.begin_transaction(): 71 with context.begin_transaction():
76 context.run_migrations() 72 context.run_migrations()
diff --git a/db/migrations/versions/202607021719-115caa5a76d0_added_user_model.py b/db/migrations/versions/202607021719-115caa5a76d0_added_user_model.py
index 3ccb92d..0bb3076 100644
--- a/db/migrations/versions/202607021719-115caa5a76d0_added_user_model.py
+++ b/db/migrations/versions/202607021719-115caa5a76d0_added_user_model.py
@@ -1,40 +1,41 @@
1"""Added user model 1"""Added user model
2 2
3Revision ID: 115caa5a76d0 3Revision ID: 115caa5a76d0
4Revises: 4Revises:
5Create Date: 2026-07-02 17:19:07.082841 5Create Date: 2026-07-02 17:19:07.082841
6 6
7""" 7"""
8from typing import Sequence, Union
9 8
10from alembic import op 9from collections.abc import Sequence
10
11import sqlalchemy as sa 11import sqlalchemy as sa
12import sqlmodel 12import sqlmodel
13 13from alembic import op
14 14
15# revision identifiers, used by Alembic. 15# revision identifiers, used by Alembic.
16revision: str = '115caa5a76d0' 16revision: str = "115caa5a76d0"
17down_revision: Union[str, Sequence[str], None] = None 17down_revision: str | Sequence[str] | None = None
18branch_labels: Union[str, Sequence[str], None] = None 18branch_labels: str | Sequence[str] | None = None
19depends_on: Union[str, Sequence[str], None] = None 19depends_on: str | Sequence[str] | None = None
20 20
21 21
22def upgrade() -> None: 22def upgrade() -> None:
23 """Upgrade schema.""" 23 """Upgrade schema."""
24 # ### commands auto generated by Alembic - please adjust! ### 24 # ### commands auto generated by Alembic - please adjust! ###
25 op.create_table('user', 25 op.create_table(
26 sa.Column('id', sa.Uuid(), nullable=False), 26 "user",
27 sa.Column('username', sqlmodel.sql.sqltypes.AutoString(), nullable=False), 27 sa.Column("id", sa.Uuid(), nullable=False),
28 sa.Column('email', sqlmodel.sql.sqltypes.AutoString(), nullable=False), 28 sa.Column("username", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
29 sa.PrimaryKeyConstraint('id') 29 sa.Column("email", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
30 sa.PrimaryKeyConstraint("id"),
30 ) 31 )
31 op.create_index(op.f('ix_user_username'), 'user', ['username'], unique=True) 32 op.create_index(op.f("ix_user_username"), "user", ["username"], unique=True)
32 # ### end Alembic commands ### 33 # ### end Alembic commands ###
33 34
34 35
35def downgrade() -> None: 36def downgrade() -> None:
36 """Downgrade schema.""" 37 """Downgrade schema."""
37 # ### commands auto generated by Alembic - please adjust! ### 38 # ### commands auto generated by Alembic - please adjust! ###
38 op.drop_index(op.f('ix_user_username'), table_name='user') 39 op.drop_index(op.f("ix_user_username"), table_name="user")
39 op.drop_table('user') 40 op.drop_table("user")
40 # ### end Alembic commands ### 41 # ### 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
index 5498291..b94ffb8 100644
--- a/db/migrations/versions/202607021740-fc6608d3f9cc_added_oauth_models.py
+++ b/db/migrations/versions/202607021740-fc6608d3f9cc_added_oauth_models.py
@@ -5,100 +5,116 @@ Revises: 115caa5a76d0
5Create Date: 2026-07-02 17:40:58.968553 5Create Date: 2026-07-02 17:40:58.968553
6 6
7""" 7"""
8
8import json 9import json
9import os 10import os
10from datetime import datetime, UTC 11from collections.abc import Sequence
12from datetime import UTC, datetime
11from secrets import token_hex 13from secrets import token_hex
12from random import randbytes
13from typing import Sequence, Union
14from uuid import uuid4, uuid7 14from uuid import uuid4, uuid7
15 15
16from alembic import op
17import sqlalchemy as sa 16import sqlalchemy as sa
18import sqlmodel 17import sqlmodel
19from authlib.integrations.sqla_oauth2 import OAuth2ClientMixin 18from alembic import op
20 19
21# revision identifiers, used by Alembic. 20# revision identifiers, used by Alembic.
22revision: str = 'fc6608d3f9cc' 21revision: str = "fc6608d3f9cc"
23down_revision: Union[str, Sequence[str], None] = '115caa5a76d0' 22down_revision: str | Sequence[str] | None = "115caa5a76d0"
24branch_labels: Union[str, Sequence[str], None] = None 23branch_labels: str | Sequence[str] | None = None
25depends_on: Union[str, Sequence[str], None] = None 24depends_on: str | Sequence[str] | None = None
26 25
27 26
28def upgrade() -> None: 27def upgrade() -> None:
29 """Upgrade schema.""" 28 """Upgrade schema."""
30 # ### commands auto generated by Alembic - please adjust! ### 29 # ### commands auto generated by Alembic - please adjust! ###
31 client_application = op.create_table('clientapplication', 30 client_application = op.create_table(
32 sa.Column('id', sa.Uuid(), nullable=False), 31 "clientapplication",
33 sa.Column('name', sqlmodel.sql.sqltypes.AutoString(), nullable=False), 32 sa.Column("id", sa.Uuid(), nullable=False),
34 sa.Column('client_id', sa.String(length=48), nullable=True), 33 sa.Column("name", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
35 sa.Column('client_secret', sa.String(length=120), nullable=True), 34 sa.Column("client_id", sa.String(length=48), nullable=True),
36 sa.Column('client_id_issued_at', sa.Integer(), nullable=False), 35 sa.Column("client_secret", sa.String(length=120), nullable=True),
37 sa.Column('client_secret_expires_at', sa.Integer(), nullable=False), 36 sa.Column("client_id_issued_at", sa.Integer(), nullable=False),
38 sa.Column('client_metadata', sa.Text(), nullable=True), 37 sa.Column("client_secret_expires_at", sa.Integer(), nullable=False),
39 sa.PrimaryKeyConstraint('id') 38 sa.Column("client_metadata", sa.Text(), nullable=True),
39 sa.PrimaryKeyConstraint("id"),
40 )
41 op.create_index(
42 op.f("ix_clientapplication_client_id"),
43 "clientapplication",
44 ["client_id"],
45 unique=False,
40 ) 46 )
41 op.create_index(op.f('ix_clientapplication_client_id'), 'clientapplication', ['client_id'], unique=False) 47 op.create_table(
42 op.create_table('authcode', 48 "authcode",
43 sa.Column('id', sa.Uuid(), nullable=False), 49 sa.Column("id", sa.Uuid(), nullable=False),
44 sa.Column('user_id', sa.Uuid(), nullable=False), 50 sa.Column("user_id", sa.Uuid(), nullable=False),
45 sa.Column('code', sa.String(length=120), nullable=False), 51 sa.Column("code", sa.String(length=120), nullable=False),
46 sa.Column('client_id', sa.String(length=48), nullable=True), 52 sa.Column("client_id", sa.String(length=48), nullable=True),
47 sa.Column('redirect_uri', sa.Text(), nullable=True), 53 sa.Column("redirect_uri", sa.Text(), nullable=True),
48 sa.Column('response_type', sa.Text(), nullable=True), 54 sa.Column("response_type", sa.Text(), nullable=True),
49 sa.Column('scope', sa.Text(), nullable=True), 55 sa.Column("scope", sa.Text(), nullable=True),
50 sa.Column('nonce', sa.Text(), nullable=True), 56 sa.Column("nonce", sa.Text(), nullable=True),
51 sa.Column('auth_time', sa.Integer(), nullable=False), 57 sa.Column("auth_time", sa.Integer(), nullable=False),
52 sa.Column('acr', sa.Text(), nullable=True), 58 sa.Column("acr", sa.Text(), nullable=True),
53 sa.Column('amr', sa.Text(), nullable=True), 59 sa.Column("amr", sa.Text(), nullable=True),
54 sa.Column('code_challenge', sa.Text(), nullable=True), 60 sa.Column("code_challenge", sa.Text(), nullable=True),
55 sa.Column('code_challenge_method', sa.String(length=48), nullable=True), 61 sa.Column("code_challenge_method", sa.String(length=48), nullable=True),
56 sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), 62 sa.ForeignKeyConstraint(["user_id"], ["user.id"], ondelete="CASCADE"),
57 sa.PrimaryKeyConstraint('id'), 63 sa.PrimaryKeyConstraint("id"),
58 sa.UniqueConstraint('code') 64 sa.UniqueConstraint("code"),
59 ) 65 )
60 op.create_table('authtoken', 66 op.create_table(
61 sa.Column('id', sa.Uuid(), nullable=False), 67 "authtoken",
62 sa.Column('user_id', sa.Uuid(), nullable=False), 68 sa.Column("id", sa.Uuid(), nullable=False),
63 sa.Column('client_id', sa.String(length=48), nullable=True), 69 sa.Column("user_id", sa.Uuid(), nullable=False),
64 sa.Column('token_type', sa.String(length=40), nullable=True), 70 sa.Column("client_id", sa.String(length=48), nullable=True),
65 sa.Column('access_token', sa.String(length=255), nullable=False), 71 sa.Column("token_type", sa.String(length=40), nullable=True),
66 sa.Column('refresh_token', sa.String(length=255), nullable=True), 72 sa.Column("access_token", sa.String(length=255), nullable=False),
67 sa.Column('scope', sa.Text(), nullable=True), 73 sa.Column("refresh_token", sa.String(length=255), nullable=True),
68 sa.Column('issued_at', sa.Integer(), nullable=False), 74 sa.Column("scope", sa.Text(), nullable=True),
69 sa.Column('access_token_revoked_at', sa.Integer(), nullable=False), 75 sa.Column("issued_at", sa.Integer(), nullable=False),
70 sa.Column('refresh_token_revoked_at', sa.Integer(), nullable=False), 76 sa.Column("access_token_revoked_at", sa.Integer(), nullable=False),
71 sa.Column('expires_in', sa.Integer(), nullable=False), 77 sa.Column("refresh_token_revoked_at", sa.Integer(), nullable=False),
72 sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), 78 sa.Column("expires_in", sa.Integer(), nullable=False),
73 sa.PrimaryKeyConstraint('id'), 79 sa.ForeignKeyConstraint(["user_id"], ["user.id"], ondelete="CASCADE"),
74 sa.UniqueConstraint('access_token') 80 sa.PrimaryKeyConstraint("id"),
81 sa.UniqueConstraint("access_token"),
82 )
83 op.create_index(
84 op.f("ix_authtoken_refresh_token"), "authtoken", ["refresh_token"], unique=False
75 ) 85 )
76 op.create_index(op.f('ix_authtoken_refresh_token'), 'authtoken', ['refresh_token'], unique=False)
77 86
78 op.bulk_insert(client_application, [ 87 op.bulk_insert(
79 { 88 client_application,
80 'id': uuid7(), 89 [
81 'name': 'TTUN', 90 {
82 'client_id': uuid4().hex, 91 "id": uuid7(),
83 'client_secret': token_hex(32), 92 "name": "TTUN",
84 'client_id_issued_at': datetime.now(tz=UTC).timestamp(), 93 "client_id": uuid4().hex,
85 'client_secret_expires_at': datetime.now(tz=UTC).timestamp() + 3600, 94 "client_secret": token_hex(32),
86 'client_metadata': json.dumps({ 95 "client_id_issued_at": datetime.now(tz=UTC).timestamp(),
87 'redirect_uris': [ 96 "client_secret_expires_at": datetime.now(tz=UTC).timestamp() + 3600,
88 f'//{os.environ['TUNNEL_DOMAIN']}/oauth/callback' 97 "client_metadata": json.dumps(
89 ], 98 {
90 }) 99 "redirect_uris": [
91 } 100 f"//{os.environ['TUNNEL_DOMAIN']}/oauth/callback"
92 ]) 101 ],
102 }
103 ),
104 }
105 ],
106 )
93 # ### end Alembic commands ### 107 # ### end Alembic commands ###
94 108
95 109
96def downgrade() -> None: 110def downgrade() -> None:
97 """Downgrade schema.""" 111 """Downgrade schema."""
98 # ### commands auto generated by Alembic - please adjust! ### 112 # ### commands auto generated by Alembic - please adjust! ###
99 op.drop_index(op.f('ix_authtoken_refresh_token'), table_name='authtoken') 113 op.drop_index(op.f("ix_authtoken_refresh_token"), table_name="authtoken")
100 op.drop_table('authtoken') 114 op.drop_table("authtoken")
101 op.drop_table('authcode') 115 op.drop_table("authcode")
102 op.drop_index(op.f('ix_clientapplication_client_id'), table_name='clientapplication') 116 op.drop_index(
103 op.drop_table('clientapplication') 117 op.f("ix_clientapplication_client_id"), table_name="clientapplication"
118 )
119 op.drop_table("clientapplication")
104 # ### end Alembic commands ### 120 # ### end Alembic commands ###
diff --git a/db/migrations/versions/202607021803-ac4fbf1fea31_added_password.py b/db/migrations/versions/202607021803-ac4fbf1fea31_added_password.py
index 116d27e..5ad10c9 100644
--- a/db/migrations/versions/202607021803-ac4fbf1fea31_added_password.py
+++ b/db/migrations/versions/202607021803-ac4fbf1fea31_added_password.py
@@ -5,29 +5,32 @@ Revises: fc6608d3f9cc
5Create Date: 2026-07-02 18:03:17.190700 5Create Date: 2026-07-02 18:03:17.190700
6 6
7""" 7"""
8from typing import Sequence, Union
9 8
10from alembic import op 9from collections.abc import Sequence
10
11import sqlalchemy as sa 11import sqlalchemy as sa
12import sqlmodel 12import sqlmodel
13 13from alembic import op
14 14
15# revision identifiers, used by Alembic. 15# revision identifiers, used by Alembic.
16revision: str = 'ac4fbf1fea31' 16revision: str = "ac4fbf1fea31"
17down_revision: Union[str, Sequence[str], None] = 'fc6608d3f9cc' 17down_revision: str | Sequence[str] | None = "fc6608d3f9cc"
18branch_labels: Union[str, Sequence[str], None] = None 18branch_labels: str | Sequence[str] | None = None
19depends_on: Union[str, Sequence[str], None] = None 19depends_on: str | Sequence[str] | None = None
20 20
21 21
22def upgrade() -> None: 22def upgrade() -> None:
23 """Upgrade schema.""" 23 """Upgrade schema."""
24 # ### commands auto generated by Alembic - please adjust! ### 24 # ### commands auto generated by Alembic - please adjust! ###
25 op.add_column('user', sa.Column('password', sqlmodel.sql.sqltypes.AutoString(), nullable=False)) 25 op.add_column(
26 "user",
27 sa.Column("password", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
28 )
26 # ### end Alembic commands ### 29 # ### end Alembic commands ###
27 30
28 31
29def downgrade() -> None: 32def downgrade() -> None:
30 """Downgrade schema.""" 33 """Downgrade schema."""
31 # ### commands auto generated by Alembic - please adjust! ### 34 # ### commands auto generated by Alembic - please adjust! ###
32 op.drop_column('user', 'password') 35 op.drop_column("user", "password")
33 # ### end Alembic commands ### 36 # ### end Alembic commands ###
diff --git a/db/migrations/versions/202607031440-69d8b4938a12_added_more_fields_and_session.py b/db/migrations/versions/202607031440-69d8b4938a12_added_more_fields_and_session.py
index ec5031b..40b8a70 100644
--- a/db/migrations/versions/202607031440-69d8b4938a12_added_more_fields_and_session.py
+++ b/db/migrations/versions/202607031440-69d8b4938a12_added_more_fields_and_session.py
@@ -5,52 +5,101 @@ Revises: ac4fbf1fea31
5Create Date: 2026-07-03 14:40:55.628816 5Create Date: 2026-07-03 14:40:55.628816
6 6
7""" 7"""
8from typing import Sequence, Union
9 8
10from alembic import op 9from collections.abc import Sequence
11import sqlalchemy as sa
12import sqlmodel
13 10
11import sqlalchemy as sa
12from alembic import op
14 13
15# revision identifiers, used by Alembic. 14# revision identifiers, used by Alembic.
16revision: str = '69d8b4938a12' 15revision: str = "69d8b4938a12"
17down_revision: Union[str, Sequence[str], None] = 'ac4fbf1fea31' 16down_revision: str | Sequence[str] | None = "ac4fbf1fea31"
18branch_labels: Union[str, Sequence[str], None] = None 17branch_labels: str | Sequence[str] | None = None
19depends_on: Union[str, Sequence[str], None] = None 18depends_on: str | Sequence[str] | None = None
20 19
21 20
22def upgrade() -> None: 21def upgrade() -> None:
23 """Upgrade schema.""" 22 """Upgrade schema."""
24 # ### commands auto generated by Alembic - please adjust! ### 23 # ### commands auto generated by Alembic - please adjust! ###
25 op.create_table('session', 24 op.create_table(
26 sa.Column('id', sa.Uuid(), nullable=False), 25 "session",
27 sa.Column('created', sa.DateTime(timezone=True), nullable=False, server_default=sa.text('now()')), 26 sa.Column("id", sa.Uuid(), nullable=False),
28 sa.Column('updated', sa.DateTime(timezone=True), nullable=True), 27 sa.Column(
29 sa.Column('user_id', sa.Uuid(), nullable=False), 28 "created",
30 sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), 29 sa.DateTime(timezone=True),
31 sa.PrimaryKeyConstraint('id') 30 nullable=False,
31 server_default=sa.text("now()"),
32 ),
33 sa.Column("updated", sa.DateTime(timezone=True), nullable=True),
34 sa.Column("user_id", sa.Uuid(), nullable=False),
35 sa.ForeignKeyConstraint(
36 ["user_id"],
37 ["user.id"],
38 ),
39 sa.PrimaryKeyConstraint("id"),
40 )
41 op.add_column(
42 "authcode",
43 sa.Column(
44 "created",
45 sa.DateTime(timezone=True),
46 nullable=False,
47 server_default=sa.text("now()"),
48 ),
49 )
50 op.add_column(
51 "authcode", sa.Column("updated", sa.DateTime(timezone=True), nullable=True)
52 )
53 op.add_column(
54 "authtoken",
55 sa.Column(
56 "created",
57 sa.DateTime(timezone=True),
58 nullable=False,
59 server_default=sa.text("now()"),
60 ),
61 )
62 op.add_column(
63 "authtoken", sa.Column("updated", sa.DateTime(timezone=True), nullable=True)
64 )
65 op.add_column(
66 "clientapplication",
67 sa.Column(
68 "created",
69 sa.DateTime(timezone=True),
70 nullable=False,
71 server_default=sa.text("now()"),
72 ),
73 )
74 op.add_column(
75 "clientapplication",
76 sa.Column("updated", sa.DateTime(timezone=True), nullable=True),
77 )
78 op.add_column(
79 "user",
80 sa.Column(
81 "created",
82 sa.DateTime(timezone=True),
83 nullable=False,
84 server_default=sa.text("now()"),
85 ),
86 )
87 op.add_column(
88 "user", sa.Column("updated", sa.DateTime(timezone=True), nullable=True)
32 ) 89 )
33 op.add_column('authcode', sa.Column('created', sa.DateTime(timezone=True), nullable=False, server_default=sa.text('now()')))
34 op.add_column('authcode', sa.Column('updated', sa.DateTime(timezone=True), nullable=True))
35 op.add_column('authtoken', sa.Column('created', sa.DateTime(timezone=True), nullable=False, server_default=sa.text('now()')))
36 op.add_column('authtoken', sa.Column('updated', sa.DateTime(timezone=True), nullable=True))
37 op.add_column('clientapplication', sa.Column('created', sa.DateTime(timezone=True), nullable=False, server_default=sa.text('now()')))
38 op.add_column('clientapplication', sa.Column('updated', sa.DateTime(timezone=True), nullable=True))
39 op.add_column('user', sa.Column('created', sa.DateTime(timezone=True), nullable=False, server_default=sa.text('now()')))
40 op.add_column('user', sa.Column('updated', sa.DateTime(timezone=True), nullable=True))
41 # ### end Alembic commands ### 90 # ### end Alembic commands ###
42 91
43 92
44def downgrade() -> None: 93def downgrade() -> None:
45 """Downgrade schema.""" 94 """Downgrade schema."""
46 # ### commands auto generated by Alembic - please adjust! ### 95 # ### commands auto generated by Alembic - please adjust! ###
47 op.drop_column('user', 'updated') 96 op.drop_column("user", "updated")
48 op.drop_column('user', 'created') 97 op.drop_column("user", "created")
49 op.drop_column('clientapplication', 'updated') 98 op.drop_column("clientapplication", "updated")
50 op.drop_column('clientapplication', 'created') 99 op.drop_column("clientapplication", "created")
51 op.drop_column('authtoken', 'updated') 100 op.drop_column("authtoken", "updated")
52 op.drop_column('authtoken', 'created') 101 op.drop_column("authtoken", "created")
53 op.drop_column('authcode', 'updated') 102 op.drop_column("authcode", "updated")
54 op.drop_column('authcode', 'created') 103 op.drop_column("authcode", "created")
55 op.drop_table('session') 104 op.drop_table("session")
56 # ### end Alembic commands ### 105 # ### end Alembic commands ###
diff --git a/db/models.py b/db/models.py
index 8a01c8c..8946bd2 100644
--- a/db/models.py
+++ b/db/models.py
@@ -1,13 +1,16 @@
1import re 1import re
2from datetime import datetime, UTC 2from datetime import UTC, datetime
3from urllib.parse import urlsplit 3from uuid import UUID, uuid7
4from uuid import uuid4, UUID, uuid7
5 4
6from sqlalchemy import DateTime 5from sqlalchemy import DateTime
7from sqlmodel import SQLModel, Field, Relationship 6from sqlmodel import Field, Relationship, SQLModel
8from starlette.authentication import BaseUser 7from starlette.authentication import BaseUser
9 8
10from authentication.mixins import OAuth2ClientMixin, OAuth2AuthorizationCodeMixin, OAuth2TokenMixin 9from authentication.mixins import (
10 OAuth2AuthorizationCodeMixin,
11 OAuth2ClientMixin,
12 OAuth2TokenMixin,
13)
11from authentication.utils import bcrypt_sha256_hash 14from authentication.utils import bcrypt_sha256_hash
12 15
13 16
@@ -21,7 +24,7 @@ class BaseModel(SQLModel):
21 default=None, 24 default=None,
22 nullable=True, 25 nullable=True,
23 sa_column_kwargs={ 26 sa_column_kwargs={
24 'onupdate': lambda: datetime.now(tz=UTC), 27 "onupdate": lambda: datetime.now(tz=UTC),
25 }, 28 },
26 sa_type=DateTime(timezone=True), 29 sa_type=DateTime(timezone=True),
27 ) 30 )
@@ -39,10 +42,12 @@ class User(BaseModel, BaseUser, table=True):
39 def is_authenticated(self) -> bool: 42 def is_authenticated(self) -> bool:
40 return True 43 return True
41 44
45
42class Session(BaseModel, table=True): 46class Session(BaseModel, table=True):
43 user_id: UUID = Field(foreign_key='user.id', exclude=True) 47 user_id: UUID = Field(foreign_key="user.id", exclude=True)
44 user: User = Relationship() 48 user: User = Relationship()
45 49
50
46class ClientApplication(BaseModel, OAuth2ClientMixin, table=True): 51class ClientApplication(BaseModel, OAuth2ClientMixin, table=True):
47 name: str 52 name: str
48 53
@@ -52,10 +57,12 @@ class ClientApplication(BaseModel, OAuth2ClientMixin, table=True):
52 for pattern in self.redirect_uris 57 for pattern in self.redirect_uris
53 ) 58 )
54 59
60
55class AuthCode(BaseModel, OAuth2AuthorizationCodeMixin, table=True): 61class AuthCode(BaseModel, OAuth2AuthorizationCodeMixin, table=True):
56 user_id: UUID = Field(foreign_key="user.id", ondelete="CASCADE") 62 user_id: UUID = Field(foreign_key="user.id", ondelete="CASCADE")
57 user: User = Relationship() 63 user: User = Relationship()
58 64
65
59class AuthToken(BaseModel, OAuth2TokenMixin, table=True): 66class AuthToken(BaseModel, OAuth2TokenMixin, table=True):
60 user_id: UUID = Field(foreign_key="user.id", ondelete="CASCADE") 67 user_id: UUID = Field(foreign_key="user.id", ondelete="CASCADE")
61 user: User = Relationship() 68 user: User = Relationship()
diff --git a/db/session.py b/db/session.py
index 82c0211..48ef3b6 100644
--- a/db/session.py
+++ b/db/session.py
@@ -1,21 +1,28 @@
1from contextlib import contextmanager 1from contextlib import contextmanager
2 2
3from sqlalchemy.orm import sessionmaker, scoped_session 3from sqlalchemy.orm import scoped_session, sessionmaker
4from sqlmodel import create_engine 4from sqlmodel import Session, create_engine
5from sqlmodel import Session
6 5
7from conf import DATABASE_URL 6from conf import DATABASE_URL
8from utils.json import json_serializer 7from utils.json import json_serializer
9 8
10 9engine = create_engine(
11engine = create_engine(DATABASE_URL, echo=True, future=True, json_serializer=json_serializer, pool_size=100, pool_recycle=3600) 10 DATABASE_URL,
11 echo=True,
12 future=True,
13 json_serializer=json_serializer,
14 pool_size=100,
15 pool_recycle=3600,
16)
12session_factory = sessionmaker(engine, class_=Session) 17session_factory = sessionmaker(engine, class_=Session)
13ScopedSession = scoped_session(session_factory=session_factory) 18ScopedSession = scoped_session(session_factory=session_factory)
14 19
20
15def get_session(): 21def get_session():
16 with ScopedSession() as session: 22 with ScopedSession() as session:
17 yield session 23 yield session
18 24
25
19@contextmanager 26@contextmanager
20def get_session_context(autocommit=True): 27def get_session_context(autocommit=True):
21 session = next(get_session()) 28 session = next(get_session())