-
Notifications
You must be signed in to change notification settings - Fork 0
feat(auth): Google OAuth with domain-based access control #226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
69db61d
cfe47c0
c1f35d3
df31cb6
4e8f935
883c855
2132108
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,6 +5,7 @@ | |||||||||||||||||||
|
|
||||||||||||||||||||
| _pool: asyncpg.Pool | None = None | ||||||||||||||||||||
| _pool_lock: asyncio.Lock | None = None | ||||||||||||||||||||
| _users_table_ensured: bool = False | ||||||||||||||||||||
| _DEFAULT_POOL_MIN_SIZE = 2 | ||||||||||||||||||||
| _DEFAULT_POOL_MAX_SIZE = 10 | ||||||||||||||||||||
| _DEFAULT_POOL_RETRIES = 5 | ||||||||||||||||||||
|
|
@@ -31,8 +32,28 @@ def _float_env(name: str, default: float, minimum: float = 0.0) -> float: | |||||||||||||||||||
| return default | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| async def ensure_users_table(pool: asyncpg.Pool) -> None: | ||||||||||||||||||||
| """Create the users table if it does not already exist (idempotent).""" | ||||||||||||||||||||
| async with pool.acquire() as conn: | ||||||||||||||||||||
| await conn.execute( | ||||||||||||||||||||
| """ | ||||||||||||||||||||
| CREATE TABLE IF NOT EXISTS users ( | ||||||||||||||||||||
| id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text, | ||||||||||||||||||||
| email TEXT UNIQUE NOT NULL, | ||||||||||||||||||||
| name TEXT, | ||||||||||||||||||||
| image TEXT, | ||||||||||||||||||||
| approved BOOLEAN NOT NULL DEFAULT FALSE, | ||||||||||||||||||||
| domain TEXT NOT NULL, | ||||||||||||||||||||
| created_at TIMESTAMPTZ NOT NULL DEFAULT now(), | ||||||||||||||||||||
| last_login_at TIMESTAMPTZ NOT NULL DEFAULT now() | ||||||||||||||||||||
| ); | ||||||||||||||||||||
| CREATE INDEX IF NOT EXISTS idx_users_email ON users(email); | ||||||||||||||||||||
| """ | ||||||||||||||||||||
| ) | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| async def get_pool() -> asyncpg.Pool: | ||||||||||||||||||||
| global _pool, _pool_lock | ||||||||||||||||||||
| global _pool, _pool_lock, _users_table_ensured | ||||||||||||||||||||
| if _pool_lock is None: | ||||||||||||||||||||
| _pool_lock = asyncio.Lock() | ||||||||||||||||||||
| if _pool is not None: | ||||||||||||||||||||
|
|
@@ -65,6 +86,16 @@ async def get_pool() -> asyncpg.Pool: | |||||||||||||||||||
| await asyncio.sleep(retry_delay * (attempt + 1)) | ||||||||||||||||||||
| if _pool is None and last_error is not None: | ||||||||||||||||||||
| raise last_error | ||||||||||||||||||||
| if _pool is not None and not _users_table_ensured: | ||||||||||||||||||||
| try: | ||||||||||||||||||||
| await ensure_users_table(_pool) | ||||||||||||||||||||
| _users_table_ensured = True | ||||||||||||||||||||
| except Exception: | ||||||||||||||||||||
| import logging | ||||||||||||||||||||
|
|
||||||||||||||||||||
| logging.getLogger(__name__).warning( | ||||||||||||||||||||
| "Could not create users table — DB may not be ready yet" | ||||||||||||||||||||
| ) | ||||||||||||||||||||
|
Comment on lines
+93
to
+98
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Swallowing the exception makes it difficult to diagnose why the table creation failed (e.g., permission issues or syntax errors). Using
Suggested change
Comment on lines
+89
to
+98
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
여기서 예외를 삼키고 계속 진행하면, Line 59가 이후 호출에서 🔧 수정 방향 예시 async def get_pool() -> asyncpg.Pool:
global _pool, _pool_lock, _users_table_ensured
if _pool_lock is None:
_pool_lock = asyncio.Lock()
- if _pool is not None:
+ if _pool is not None and _users_table_ensured:
return _pool
async with _pool_lock:
- if _pool is not None:
+ if _pool is not None and _users_table_ensured:
return _pool
database_url = os.environ.get("DATABASE_URL", "")
if not database_url:
raise RuntimeError("DATABASE_URL environment variable is required")
@@
- if _pool is not None and not _users_table_ensured:
+ if _pool is not None and not _users_table_ensured:
try:
await ensure_users_table(_pool)
_users_table_ensured = True
- except Exception:
+ except Exception:
import logging
logging.getLogger(__name__).warning(
- "Could not create users table — DB may not be ready yet"
+ "Could not create users table — DB may not be ready yet",
+ exc_info=True,
)
return _pool🤖 Prompt for AI Agents |
||||||||||||||||||||
| return _pool | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This index is redundant. The
emailcolumn is already defined with aUNIQUEconstraint on line 42, and PostgreSQL automatically creates a unique index for every unique constraint. Removing it will save storage and slightly improve write performance.