login corrected

pull/1/head
ahmed.mujtaba 2026-08-04 16:44:43 +05:00
parent ef07694254
commit 8bdd740404
5 changed files with 29 additions and 20 deletions

2
.gitignore vendored
View File

@ -42,3 +42,5 @@ env/
tmp/
temp/
.cache/
**.pdf

View File

@ -1,12 +1,9 @@
from typing import Annotated
from fastapi import APIRouter,Depends, Query
from fastapi.responses import JSONResponse
from fastapi import HTTPException
from fastapi.security import OAuth2PasswordRequestForm
from db_setup import get_session
from sqlalchemy.ext.asyncio import AsyncSession
from pydantic import BaseModel, EmailStr
from pydantic import BaseModel, EmailStr, model_validator
from users.views import User
from users.permissions import CurrentUser
from users.serializers import serialize_token
@ -33,18 +30,27 @@ class UserUpdate(BaseModel):
is_active: bool | None = None
class UserLogin(BaseModel):
password: str
email: EmailStr | None = None
username: str | None = None
@model_validator(mode="after")
def require_email_or_username(self):
if not self.email and not self.username:
raise ValueError("email or username is required")
return self
class TokenRefresh(BaseModel):
refresh_token: str
@router.post("/users/login")
async def login(
form_data: Annotated[OAuth2PasswordRequestForm, Depends()],
session: AsyncSession = Depends(get_session),
):
async def login(payload: UserLogin,session: AsyncSession = Depends(get_session)):
try:
service=User(session=session)
user=await service.authenticate_user(form_data.username,form_data.password)
user=await service.authenticate_user(payload.email or payload.username,payload.password)
tokens=serialize_token(create_access_token(user),create_refresh_token(user),user)
return JSONResponse(content={**tokens,"status_code":200})
except HTTPException:
@ -77,11 +83,12 @@ async def me(current_user: CurrentUser):
@router.post("/users/create")
async def create_user(payload: UserCreate,current_user: CurrentUser,session: AsyncSession = Depends(get_session)):
async def create_user(payload: UserCreate,session: AsyncSession = Depends(get_session)):
try:
service=User(session=session)
data=await service.create_user(payload.model_dump())
return JSONResponse(content={"data":data,"status_code":200})
user=await service.create_user(payload.model_dump())
tokens=serialize_token(create_access_token(user),create_refresh_token(user),user)
return JSONResponse(content={**tokens,"status_code":200})
except HTTPException:
raise
except Exception as e:

View File

@ -15,7 +15,7 @@ class Users(SQLModel, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
name: str
email: str = Field(unique=True)
role_id: int | None = Field(default=None, foreign_key="roles.id")
role_id: int | None = Field(nullable=True, foreign_key="roles.id")
role: Roles | None = Relationship(back_populates="users")
password: str
created_at: datetime = Field(default_factory=datetime.now)

View File

@ -1,4 +1,4 @@
"""OAuth2 bearer scheme and the current-user dependency for `/users/*` routes."""
"""HTTP Bearer scheme and the current-user dependency for `/users/*` routes."""
from __future__ import annotations
@ -6,7 +6,7 @@ from typing import Annotated
import jwt
from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from sqlalchemy.ext.asyncio import AsyncSession
from db_setup import get_session
@ -14,11 +14,11 @@ from users.models import Users
from users.plugins import decode_token
from users.serializers import serialize_user
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="users/login")
bearer_scheme = HTTPBearer()
async def get_current_user(
token: Annotated[str, Depends(oauth2_scheme)],
credentials: Annotated[HTTPAuthorizationCredentials, Depends(bearer_scheme)],
session: Annotated[AsyncSession, Depends(get_session)],
) -> dict:
credentials_exception = HTTPException(
@ -27,7 +27,7 @@ async def get_current_user(
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = decode_token(token, expected_type="access")
payload = decode_token(credentials.credentials, expected_type="access")
except jwt.PyJWTError:
raise credentials_exception
@ -42,3 +42,4 @@ async def get_current_user(
CurrentUser = Annotated[dict, Depends(get_current_user)]

View File

@ -19,8 +19,7 @@ class User:
fields=clean_user_payload(payload)
if not fields.get("password"):
raise HTTPException(status_code=400,detail="Password is required")
user=await Users.insert_user(self.session,fields)
return serialize_user(user)
return await Users.insert_user(self.session,fields)
async def get_users(self,top,skip,search=None):
users=await Users.get_users(self.session,top,skip,search)