anyonehomep1mane commited on
Commit
1c46e60
·
1 Parent(s): 9f04b39

SQLLite Changes

Browse files
auth_service/app/auth.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime, timedelta
2
+ from jose import JWTError, jwt
3
+ from fastapi import HTTPException, status, Depends
4
+ from fastapi.security import OAuth2PasswordBearer
5
+ from sqlalchemy.ext.asyncio import AsyncSession
6
+ from . import schemas, database, models
7
+ from sqlalchemy import select
8
+
9
+ SECRET_KEY = "a866319fb3f839e693191763019cf0dd3d78473d4d3d06d99afb3ef0b14bd0d5"
10
+ ALGORITHM = "HS256"
11
+ ACCESS_TOKEN_EXPIRE_MINUTES = 30
12
+
13
+ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
14
+
15
+ def create_access_token(data: dict):
16
+ to_encode = data.copy()
17
+ expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
18
+ to_encode.update({"exp": expire})
19
+ encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
20
+ return encoded_jwt
21
+
22
+ async def get_current_user(token: str = Depends(oauth2_scheme), db: AsyncSession = Depends(database.get_db)):
23
+ credentials_exception = HTTPException(
24
+ status_code=status.HTTP_401_UNAUTHORIZED,
25
+ detail="Could not validate credentials",
26
+ headers={"WWW-Authenticate": "Bearer"},
27
+ )
28
+ try:
29
+ payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
30
+ username: str = payload.get("sub")
31
+ if username is None:
32
+ raise credentials_exception
33
+ except JWTError:
34
+ raise credentials_exception
35
+ stmt = select(models.User).where(models.User.username == username)
36
+ result = await db.execute(stmt)
37
+ user = result.scalars().first()
38
+ if user is None:
39
+ raise credentials_exception
40
+ return user
auth_service/app/database.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
3
+ from sqlalchemy.orm import sessionmaker, declarative_base
4
+
5
+ # Configure logging
6
+ logging.basicConfig(level=logging.INFO)
7
+ logger = logging.getLogger(__name__)
8
+
9
+ DATABASE_URL = "sqlite+aiosqlite:///./auth.db"
10
+
11
+ engine = create_async_engine(
12
+ DATABASE_URL,
13
+ echo=False,
14
+ future=True
15
+ )
16
+
17
+ AsyncSessionLocal = sessionmaker(
18
+ engine,
19
+ class_=AsyncSession,
20
+ expire_on_commit=False
21
+ )
22
+
23
+ Base = declarative_base()
24
+
25
+ async def init_db():
26
+ from .models import Base
27
+ logger.info("Initializing SQLite database at data/auth.db")
28
+ try:
29
+ async with engine.begin() as conn:
30
+ await conn.run_sync(Base.metadata.create_all)
31
+ logger.info("Database initialized successfully")
32
+ except Exception as e:
33
+ logger.error(f"Failed to initialize database: {str(e)}")
34
+ raise
35
+
36
+ async def get_db():
37
+ async with AsyncSessionLocal() as session:
38
+ yield session
auth_service/app/main.py CHANGED
@@ -1,5 +1,14 @@
1
- from fastapi import FastAPI
 
 
 
 
 
 
2
 
 
 
 
3
  app = FastAPI(
4
  title="Auth Service",
5
  root_path="/auth",
@@ -7,6 +16,25 @@ app = FastAPI(
7
  openapi_url="/openapi.json"
8
  )
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  @app.get("/")
11
  def root():
12
  return {
@@ -27,3 +55,66 @@ def hello(name: str):
27
  "service": "auth",
28
  "hello": name
29
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException, Depends
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from fastapi.security import OAuth2PasswordRequestForm
4
+ from sqlalchemy.ext.asyncio import AsyncSession
5
+ from sqlalchemy import select
6
+ from . import schemas, database, models, auth
7
+ from passlib.context import CryptContext
8
 
9
+ from . import schemas, database, models, auth
10
+
11
+ # 🔑 IMPORTANT: root_path="/auth" (for NGINX + HF Spaces)
12
  app = FastAPI(
13
  title="Auth Service",
14
  root_path="/auth",
 
16
  openapi_url="/openapi.json"
17
  )
18
 
19
+ # Enable CORS
20
+ app.add_middleware(
21
+ CORSMiddleware,
22
+ allow_origins=["*"], # Allows all origins; adjust as needed
23
+ allow_credentials=True,
24
+ allow_methods=["*"], # Allows all methods
25
+ allow_headers=["*"], # Allows all headers
26
+ )
27
+
28
+ pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
29
+
30
+ @app.on_event("startup")
31
+ async def startup():
32
+ await database.init_db()
33
+
34
+ async def get_db():
35
+ async with database.AsyncSessionLocal() as session:
36
+ yield session
37
+
38
  @app.get("/")
39
  def root():
40
  return {
 
55
  "service": "auth",
56
  "hello": name
57
  }
58
+
59
+ @app.post("/users/", response_model=schemas.User)
60
+ async def create_user(user: schemas.UserCreate, db: AsyncSession = Depends(get_db)):
61
+ stmt = select(models.User).where(models.User.username == user.username)
62
+ result = await db.execute(stmt)
63
+ if result.scalars().first():
64
+ raise HTTPException(status_code=400, detail="Username already exists")
65
+ hashed_password = pwd_context.hash(user.password)
66
+ db_user = models.User(username=user.username, hashed_password=hashed_password)
67
+ db.add(db_user)
68
+ await db.commit()
69
+ await db.refresh(db_user)
70
+ return db_user
71
+
72
+ @app.get("/users/", response_model=list[schemas.User])
73
+ async def get_users(db: AsyncSession = Depends(get_db), current_user: schemas.User = Depends(auth.get_current_user)):
74
+ stmt = select(models.User)
75
+ result = await db.execute(stmt)
76
+ return result.scalars().all()
77
+
78
+ @app.get("/users/{username}", response_model=schemas.User)
79
+ async def get_user(username: str, db: AsyncSession = Depends(get_db), current_user: schemas.User = Depends(auth.get_current_user)):
80
+ stmt = select(models.User).where(models.User.username == username)
81
+ result = await db.execute(stmt)
82
+ user = result.scalars().first()
83
+ if not user:
84
+ raise HTTPException(status_code=404, detail="User not found")
85
+ return user
86
+
87
+ @app.put("/users/{username}", response_model=schemas.User)
88
+ async def update_user(username: str, user_update: schemas.UserCreate, db: AsyncSession = Depends(get_db), current_user: schemas.User = Depends(auth.get_current_user)):
89
+ stmt = select(models.User).where(models.User.username == username)
90
+ result = await db.execute(stmt)
91
+ db_user = result.scalars().first()
92
+ if not db_user:
93
+ raise HTTPException(status_code=404, detail="User not found")
94
+ db_user.hashed_password = pwd_context.hash(user_update.password)
95
+ await db.commit()
96
+ await db.refresh(db_user)
97
+ return db_user
98
+
99
+ @app.delete("/users/{username}", status_code=204)
100
+ async def delete_user(username: str, db: AsyncSession = Depends(get_db), current_user: schemas.User = Depends(auth.get_current_user)):
101
+ stmt = select(models.User).where(models.User.username == username)
102
+ result = await db.execute(stmt)
103
+ db_user = result.scalars().first()
104
+ if not db_user:
105
+ raise HTTPException(status_code=404, detail="User not found")
106
+ await db.delete(db_user)
107
+ await db.commit()
108
+ return {
109
+ "message": "User deleted."
110
+ }
111
+
112
+ @app.post("/token", response_model=schemas.Token)
113
+ async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends(), db: AsyncSession = Depends(get_db)):
114
+ stmt = select(models.User).where(models.User.username == form_data.username)
115
+ result = await db.execute(stmt)
116
+ user = result.scalars().first()
117
+ if not user or not pwd_context.verify(form_data.password, user.hashed_password):
118
+ raise HTTPException(status_code=401, detail="Incorrect username or password")
119
+ access_token = auth.create_access_token(data={"sub": user.username})
120
+ return {"access_token": access_token, "token_type": "bearer"}
auth_service/app/models.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy import Column, Integer, String
2
+ from sqlalchemy.ext.declarative import declarative_base
3
+
4
+ Base = declarative_base()
5
+
6
+ class User(Base):
7
+ __tablename__ = "users"
8
+ id = Column(Integer, primary_key=True, index=True)
9
+ username = Column(String, unique=True, index=True)
10
+ hashed_password = Column(String)
auth_service/app/schemas.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel
2
+
3
+ class UserCreate(BaseModel):
4
+ username: str
5
+ password: str
6
+
7
+ class User(BaseModel):
8
+ id: int
9
+ username: str
10
+
11
+ class Config:
12
+ from_attributes = True
13
+
14
+ class Token(BaseModel):
15
+ access_token: str
16
+ token_type: str
requirements.txt CHANGED
@@ -1,2 +1,11 @@
1
  fastapi
2
- uvicorn[standard]
 
 
 
 
 
 
 
 
 
 
1
  fastapi
2
+ uvicorn[standard]
3
+ pydantic
4
+ sqlalchemy
5
+ asyncio
6
+ aiosqlite
7
+ python-jose
8
+ cryptography
9
+ python-multipart
10
+ passlib==1.7.4
11
+ bcrypt==3.2.2