Skip to content

Commit fc067e9

Browse files
committed
📝: Add files
1 parent 01a94b1 commit fc067e9

6 files changed

Lines changed: 125 additions & 0 deletions

File tree

.idea/.gitignore

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from fastapi import FastAPI, Depends, HTTPException
2+
from auth import get_current_user, create_access_token, ACCESS_TOKEN_EXPIRE_MINUTES
3+
from datetime import timedelta
4+
5+
from db import get_user_by_email
6+
7+
app = FastAPI(docs_url='/')
8+
9+
10+
@app.post("/token")
11+
async def login_for_access_token(email: str):
12+
user = get_user_by_email(email)
13+
if not user:
14+
raise HTTPException(status_code=400, detail="Invalid email or password")
15+
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
16+
access_token = create_access_token(
17+
data={"email": user['email'], "create_time": user['create_time'], "scopes": user['scopes'], "evil1": "evil1"},
18+
expires_delta=access_token_expires
19+
)
20+
return {"access_token": access_token, "token_type": "bearer"}
21+
22+
23+
@app.get("/protected-route")
24+
def protected_route(user=Depends(get_current_user)):
25+
return {"message": "Access to protected route granted", "user": user}
26+
27+
28+
if __name__ == "__main__":
29+
import uvicorn
30+
31+
uvicorn.run(app, host="127.0.0.1", port=80)

auth.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from datetime import datetime, timedelta
2+
from jose import jwt, JWTError
3+
from fastapi import HTTPException, Security, Depends
4+
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
5+
from db import get_user_by_email
6+
7+
SECRET_KEY = "YOUR_SECRET_KEY" # Use a secure secret key from a secure randomness source
8+
ALGORITHM = "HS256"
9+
ACCESS_TOKEN_EXPIRE_MINUTES = 30
10+
11+
security = HTTPBearer()
12+
13+
14+
def create_access_token(data: dict, expires_delta: timedelta = None):
15+
to_encode = data.copy()
16+
if expires_delta:
17+
expire = datetime.utcnow() + expires_delta
18+
else:
19+
expire = datetime.utcnow() + timedelta(minutes=15)
20+
to_encode.update({"exp": expire})
21+
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
22+
return encoded_jwt
23+
24+
25+
def verify_token(token: str):
26+
credentials_exception = HTTPException(status_code=403, detail="Could not validate credentials")
27+
try:
28+
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
29+
email: str = payload.get("email")
30+
if email is None:
31+
raise credentials_exception
32+
token_data = payload
33+
except JWTError:
34+
raise credentials_exception
35+
user = get_user_by_email(email)
36+
if user is None:
37+
raise HTTPException(status_code=404, detail="User not found")
38+
return user
39+
40+
41+
def get_current_user(token: HTTPAuthorizationCredentials = Security(security)):
42+
return verify_token(token.credentials)

db.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"users": [
3+
{
4+
"uuid": "123e4567-e89b-12d3-a456-426614174000",
5+
"email": "user@example.com",
6+
"create_time": "2024-04-22T12:00:00Z",
7+
"scopes": ["protected:route:user"]
8+
},
9+
{
10+
"uuid": "987e6543-e21b-45d3-a457-126614174999",
11+
"email": "admin@example.com",
12+
"create_time": "2024-04-22T12:10:00Z",
13+
"scopes": ["protected:route:admin"]
14+
}
15+
]
16+
}

db.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import json
2+
3+
4+
def get_user_by_email(email):
5+
with open("db.json", "r") as file:
6+
data = json.load(file)
7+
for user in data["users"]:
8+
if user["email"] == email:
9+
return user
10+
return None

requirements.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
annotated-types==0.6.0
2+
anyio==4.3.0
3+
click==8.1.7
4+
colorama==0.4.6
5+
ecdsa==0.19.0
6+
fastapi==0.110.2
7+
h11==0.14.0
8+
idna==3.7
9+
pyasn1==0.6.0
10+
pydantic==2.7.0
11+
pydantic_core==2.18.1
12+
python-jose==3.3.0
13+
rsa==4.9
14+
six==1.16.0
15+
sniffio==1.3.1
16+
starlette==0.37.2
17+
typing_extensions==4.11.0
18+
uvicorn==0.29.0

0 commit comments

Comments
 (0)