Skip to content

Commit e06290e

Browse files
authored
Merge pull request #13 from PythonToGo/dev-1
merge dev-v1 + dev
2 parents ae597d6 + 1dcb36f commit e06290e

18 files changed

+807
-134
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""add selected_repo to User model
2+
3+
Revision ID: 0110b0fe23e2
4+
Revises: dd6498244230
5+
Create Date: 2025-04-11 10:02:54.906969
6+
7+
"""
8+
from typing import Sequence, Union
9+
10+
from alembic import op
11+
import sqlalchemy as sa
12+
13+
14+
# revision identifiers, used by Alembic.
15+
revision: str = '0110b0fe23e2'
16+
down_revision: Union[str, None] = 'dd6498244230'
17+
branch_labels: Union[str, Sequence[str], None] = None
18+
depends_on: Union[str, Sequence[str], None] = None
19+
20+
21+
def upgrade() -> None:
22+
"""Upgrade schema."""
23+
# ### commands auto generated by Alembic - please adjust! ###
24+
op.alter_column('users', 'github_id',
25+
existing_type=sa.INTEGER(),
26+
type_=sa.String(),
27+
existing_nullable=True)
28+
# ### end Alembic commands ###
29+
30+
31+
def downgrade() -> None:
32+
"""Downgrade schema."""
33+
# ### commands auto generated by Alembic - please adjust! ###
34+
op.alter_column('users', 'github_id',
35+
existing_type=sa.String(),
36+
type_=sa.INTEGER(),
37+
existing_nullable=True)
38+
# ### end Alembic commands ###
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""add selected_repo to User model
2+
3+
Revision ID: 3941b5ea8743
4+
Revises: 0110b0fe23e2
5+
Create Date: 2025-04-11 10:32:09.102609
6+
7+
"""
8+
from typing import Sequence, Union
9+
10+
from alembic import op
11+
import sqlalchemy as sa
12+
13+
14+
# revision identifiers, used by Alembic.
15+
revision: str = '3941b5ea8743'
16+
down_revision: Union[str, None] = '0110b0fe23e2'
17+
branch_labels: Union[str, Sequence[str], None] = None
18+
depends_on: Union[str, Sequence[str], None] = None
19+
20+
21+
def upgrade() -> None:
22+
"""Upgrade schema."""
23+
# ### commands auto generated by Alembic - please adjust! ###
24+
pass
25+
# ### end Alembic commands ###
26+
27+
28+
def downgrade() -> None:
29+
"""Downgrade schema."""
30+
# ### commands auto generated by Alembic - please adjust! ###
31+
pass
32+
# ### end Alembic commands ###
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""add selected_repo to users
2+
3+
Revision ID: a37610476ce3
4+
Revises: 3941b5ea8743
5+
Create Date: 2025-04-11 17:07:29.751848
6+
7+
"""
8+
from typing import Sequence, Union
9+
10+
from alembic import op
11+
import sqlalchemy as sa
12+
13+
14+
# revision identifiers, used by Alembic.
15+
revision: str = 'a37610476ce3'
16+
down_revision: Union[str, None] = '3941b5ea8743'
17+
branch_labels: Union[str, Sequence[str], None] = None
18+
depends_on: Union[str, Sequence[str], None] = None
19+
20+
21+
def upgrade() -> None:
22+
"""Upgrade schema."""
23+
# ### commands auto generated by Alembic - please adjust! ###
24+
op.add_column('users', sa.Column('selected_repo', sa.String(), nullable=True))
25+
# ### end Alembic commands ###
26+
27+
28+
def downgrade() -> None:
29+
"""Downgrade schema."""
30+
# ### commands auto generated by Alembic - please adjust! ###
31+
op.drop_column('users', 'selected_repo')
32+
# ### end Alembic commands ###
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""make last_push and last_login nullable
2+
3+
Revision ID: fffe4c516230
4+
Revises: a37610476ce3
5+
Create Date: 2025-04-11 18:32:12.060038
6+
7+
"""
8+
from typing import Sequence, Union
9+
10+
from alembic import op
11+
import sqlalchemy as sa
12+
13+
14+
# revision identifiers, used by Alembic.
15+
revision: str = 'fffe4c516230'
16+
down_revision: Union[str, None] = 'a37610476ce3'
17+
branch_labels: Union[str, Sequence[str], None] = None
18+
depends_on: Union[str, Sequence[str], None] = None
19+
20+
21+
def upgrade() -> None:
22+
"""Upgrade schema."""
23+
# ### commands auto generated by Alembic - please adjust! ###
24+
pass
25+
# ### end Alembic commands ###
26+
27+
28+
def downgrade() -> None:
29+
"""Downgrade schema."""
30+
# ### commands auto generated by Alembic - please adjust! ###
31+
pass
32+
# ### end Alembic commands ###

backend/auth.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from fastapi import Header, HTTPException
44
import os
55
from dotenv import load_dotenv
6+
import traceback
67

78
# Load environment variables
89
def get_database_url():
@@ -31,14 +32,17 @@ def create_jwt_token(data: dict):
3132
to_encode = data.copy()
3233
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
3334
to_encode.update({"exp": expire})
34-
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
35+
jwt_token = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
36+
print(f"[auth.py] Created JWT token: {jwt_token[:20]}...")
37+
return jwt_token
3538

3639
def create_access_token(data: dict):
3740
"""Alias for create_jwt_token for backward compatibility"""
3841
return create_jwt_token(data)
3942

4043
def verify_token(token: str):
4144
"""Verify and decode a JWT token"""
45+
4246
try:
4347
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
4448
if "exp" not in payload:
@@ -51,21 +55,26 @@ def verify_token(token: str):
5155
return None
5256
except Exception as e:
5357
print(f"Token verification error: {str(e)}")
58+
5459
return None
5560

5661
async def get_current_user(authorization: str = Header(...)):
5762
"""Get current user from authorization header"""
5863
try:
64+
5965
token = authorization.replace("Bearer ", "")
6066
payload = verify_token(token)
6167
if not payload:
68+
6269
raise HTTPException(
6370
status_code=401,
6471
detail="Invalid or expired token"
6572
)
73+
6674
return payload
6775
except Exception as e:
6876
raise HTTPException(
6977
status_code=401,
7078
detail=f"Authorization failed: {str(e)}"
71-
)
79+
)
80+

backend/github_oauth.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
import os
22
import httpx
3-
from fastapi import Request
3+
import logging
4+
from fastapi import Request, HTTPException
5+
6+
logger = logging.getLogger(__name__)
47

58
GITHUB_CLIENT_ID = os.getenv("GITHUB_CLIENT_ID")
69
GITHUB_CLIENT_SECRET = os.getenv("GITHUB_CLIENT_SECRET")
710

811
if not GITHUB_CLIENT_ID or not GITHUB_CLIENT_SECRET:
12+
logger.error("GitHub OAuth credentials missing!")
13+
logger.error(f"GITHUB_CLIENT_ID: {'present' if GITHUB_CLIENT_ID else 'missing'}")
14+
logger.error(f"GITHUB_CLIENT_SECRET: {'present' if GITHUB_CLIENT_SECRET else 'missing'}")
915
raise ValueError("❌ GitHub OAuth credentials not found")
1016

1117
print(f"🔑 GitHub OAuth Configuration: Client ID: {GITHUB_CLIENT_ID[:5]}...")
1218

1319
async def exchange_code_for_token(code: str):
20+
1421
"""Exchange GitHub OAuth code for token data"""
1522
try:
1623
async with httpx.AsyncClient() as client:
@@ -26,13 +33,14 @@ async def exchange_code_for_token(code: str):
2633
headers={
2734
"Accept": "application/json"
2835
},
36+
2937
data={
3038
"client_id": GITHUB_CLIENT_ID,
3139
"client_secret": GITHUB_CLIENT_SECRET,
3240
"code": code
3341
}
3442
)
35-
43+
3644
print(f"✅ GitHub token exchange status: {response.status_code}")
3745
print(f"Response headers: {dict(response.headers)}")
3846

@@ -132,4 +140,4 @@ async def get_user_info(access_token: str):
132140

133141
except Exception as e:
134142
print(f"❌ Error getting user info: {str(e)}")
135-
raise
143+
raise

0 commit comments

Comments
 (0)