brewman/brewman/brewman/routers/login.py

110 lines
3.1 KiB
Python
Raw Normal View History

from datetime import timedelta
2020-05-31 09:11:11 +00:00
from fastapi import (
APIRouter,
Cookie,
2020-10-07 15:18:43 +00:00
Depends,
2020-05-31 09:11:11 +00:00
Form,
2020-10-07 15:18:43 +00:00
HTTPException,
2020-05-31 09:11:11 +00:00
Response,
2020-10-07 15:18:43 +00:00
Security,
status,
2020-05-31 09:11:11 +00:00
)
from fastapi.responses import JSONResponse
2020-10-07 15:18:43 +00:00
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session
2020-10-07 15:18:43 +00:00
from .. import __version__
2020-10-07 15:18:43 +00:00
from ..core.config import settings
from ..core.security import (
Token,
authenticate_user,
2020-10-07 15:18:43 +00:00
client_allowed,
2020-05-31 09:11:11 +00:00
create_access_token,
get_current_active_user,
)
from ..db.session import SessionLocal
from ..schemas.auth import UserToken
2020-10-07 15:18:43 +00:00
router = APIRouter()
# Dependency
def get_db():
try:
db = SessionLocal()
yield db
finally:
db.close()
@router.post("/token", response_model=Token)
async def login_for_access_token(
response: Response,
form_data: OAuth2PasswordRequestForm = Depends(),
client_id: int = Cookie(None),
otp: int = Form(None),
db: Session = Depends(get_db),
):
user = authenticate_user(form_data.username, form_data.password, client_id, otp, db)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
headers={"WWW-Authenticate": "Bearer"},
)
allowed, c_id = client_allowed(user, client_id, otp, db)
db.commit()
if c_id and c_id != client_id:
2020-10-07 16:59:24 +00:00
response.set_cookie(
key="client_id", value=str(c_id), max_age=10 * 365 * 24 * 60 * 60
)
if not allowed:
not_allowed_response = JSONResponse(
status_code=status.HTTP_401_UNAUTHORIZED,
headers={"WWW-Authenticate": "Bearer"},
2020-05-31 09:11:11 +00:00
content={"detail": "Client is not registered"},
)
2020-10-07 16:59:24 +00:00
not_allowed_response.set_cookie(
key="client_id", value=str(c_id), max_age=10 * 365 * 24 * 60 * 60
)
return not_allowed_response
access_token_expires = timedelta(minutes=settings.JWT_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token(
data={
"sub": user.name,
"scopes": ["authenticated"]
2020-10-07 16:59:24 +00:00
+ list(
set(
[
p.name.replace(" ", "-").lower()
for r in user.roles
for p in r.permissions
]
)
),
"userId": str(user.id),
"lockedOut": user.locked_out,
"ver": __version__.__version__,
},
expires_delta=access_token_expires,
)
return {"access_token": access_token, "token_type": "bearer"}
@router.post("/refresh", response_model=Token)
2020-05-31 09:11:11 +00:00
async def refresh_token(user: UserToken = Security(get_current_active_user)):
access_token_expires = timedelta(minutes=settings.JWT_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token(
2020-10-07 15:18:43 +00:00
data={
"sub": user.name,
"scopes": user.permissions,
"userId": str(user.id_),
"lockedOut": user.locked_out,
"ver": __version__.__version__,
2020-10-07 15:18:43 +00:00
},
expires_delta=access_token_expires,
)
return {"access_token": access_token, "token_type": "bearer"}