Ali2206 commited on
Commit
23bcd24
·
verified ·
1 Parent(s): 6f51619

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +24 -18
app.py CHANGED
@@ -2,54 +2,54 @@ from fastapi import FastAPI, HTTPException, Depends
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.security import OAuth2PasswordRequestForm
4
  from pydantic import BaseModel, EmailStr
5
- from jose import JWTError, jwt
6
  from passlib.context import CryptContext
7
  from motor.motor_asyncio import AsyncIOMotorClient
8
  import certifi
9
- import os
10
  import datetime
 
11
 
12
- # === Environment and config ===
13
  SECRET_KEY = os.getenv("SECRET_KEY", "your-secret-key")
14
  ALGORITHM = "HS256"
15
  ACCESS_TOKEN_EXPIRE_MINUTES = 30
16
-
17
  MONGO_URI = os.getenv("MONGO_URI")
 
18
  if not MONGO_URI:
19
- raise RuntimeError("MONGO_URI not set")
20
 
21
- # === MongoDB client ===
22
  client = AsyncIOMotorClient(MONGO_URI, tls=True, tlsCAFile=certifi.where())
23
  db = client["cps_db"]
24
  users_collection = db["users"]
25
 
26
- # === App setup ===
27
  app = FastAPI()
28
  app.add_middleware(
29
  CORSMiddleware,
30
- allow_origins=["*"], # Replace with frontend origin in prod
31
  allow_credentials=True,
32
  allow_methods=["*"],
33
  allow_headers=["*"],
34
  )
35
 
36
- # === Password hashing ===
37
  pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
38
 
39
- def verify_password(plain: str, hashed: str) -> bool:
40
- return pwd_context.verify(plain, hashed)
41
-
42
  def hash_password(password: str) -> str:
43
  return pwd_context.hash(password)
44
 
45
- # === JWT ===
 
 
 
46
  def create_access_token(data: dict, expires_delta: datetime.timedelta = None):
47
  to_encode = data.copy()
48
  expire = datetime.datetime.utcnow() + (expires_delta or datetime.timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
49
  to_encode.update({"exp": expire})
50
  return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
51
 
52
- # === Schemas ===
53
  class SignupForm(BaseModel):
54
  email: EmailStr
55
  password: str
@@ -58,16 +58,22 @@ class TokenResponse(BaseModel):
58
  access_token: str
59
  token_type: str
60
 
61
- # === Routes ===
62
  @app.post("/signup")
63
  async def signup(data: SignupForm):
64
  email = data.email.lower().strip()
65
  existing = await users_collection.find_one({"email": email})
66
  if existing:
67
  raise HTTPException(status_code=409, detail="Email already exists")
 
68
  hashed_pw = hash_password(data.password)
69
- await users_collection.insert_one({"email": email, "password": hashed_pw})
70
- return {"success": True, "message": "Account created successfully"}
 
 
 
 
 
71
 
72
  @app.post("/login", response_model=TokenResponse)
73
  async def login(form_data: OAuth2PasswordRequestForm = Depends()):
@@ -81,4 +87,4 @@ async def login(form_data: OAuth2PasswordRequestForm = Depends()):
81
 
82
  @app.get("/")
83
  def root():
84
- return {"message": " Auth-secured FastAPI + MongoDB backend is running"}
 
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.security import OAuth2PasswordRequestForm
4
  from pydantic import BaseModel, EmailStr
5
+ from jose import jwt, JWTError
6
  from passlib.context import CryptContext
7
  from motor.motor_asyncio import AsyncIOMotorClient
8
  import certifi
 
9
  import datetime
10
+ import os
11
 
12
+ # Environment variables
13
  SECRET_KEY = os.getenv("SECRET_KEY", "your-secret-key")
14
  ALGORITHM = "HS256"
15
  ACCESS_TOKEN_EXPIRE_MINUTES = 30
 
16
  MONGO_URI = os.getenv("MONGO_URI")
17
+
18
  if not MONGO_URI:
19
+ raise RuntimeError("MONGO_URI not set!")
20
 
21
+ # Database connection
22
  client = AsyncIOMotorClient(MONGO_URI, tls=True, tlsCAFile=certifi.where())
23
  db = client["cps_db"]
24
  users_collection = db["users"]
25
 
26
+ # App setup
27
  app = FastAPI()
28
  app.add_middleware(
29
  CORSMiddleware,
30
+ allow_origins=["*"], # 🔐 Replace with frontend domain in prod
31
  allow_credentials=True,
32
  allow_methods=["*"],
33
  allow_headers=["*"],
34
  )
35
 
36
+ # Hashing setup
37
  pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
38
 
 
 
 
39
  def hash_password(password: str) -> str:
40
  return pwd_context.hash(password)
41
 
42
+ def verify_password(plain: str, hashed: str) -> bool:
43
+ return pwd_context.verify(plain, hashed)
44
+
45
+ # JWT generation
46
  def create_access_token(data: dict, expires_delta: datetime.timedelta = None):
47
  to_encode = data.copy()
48
  expire = datetime.datetime.utcnow() + (expires_delta or datetime.timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
49
  to_encode.update({"exp": expire})
50
  return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
51
 
52
+ # Pydantic models
53
  class SignupForm(BaseModel):
54
  email: EmailStr
55
  password: str
 
58
  access_token: str
59
  token_type: str
60
 
61
+ # Routes
62
  @app.post("/signup")
63
  async def signup(data: SignupForm):
64
  email = data.email.lower().strip()
65
  existing = await users_collection.find_one({"email": email})
66
  if existing:
67
  raise HTTPException(status_code=409, detail="Email already exists")
68
+
69
  hashed_pw = hash_password(data.password)
70
+ user_doc = {
71
+ "email": email,
72
+ "password": hashed_pw,
73
+ "created_at": datetime.datetime.utcnow()
74
+ }
75
+ await users_collection.insert_one(user_doc)
76
+ return {"success": True, "message": "Account created"}
77
 
78
  @app.post("/login", response_model=TokenResponse)
79
  async def login(form_data: OAuth2PasswordRequestForm = Depends()):
 
87
 
88
  @app.get("/")
89
  def root():
90
+ return {"message": "🚀 FastAPI MongoDB with JWT & timestamps is running"}