Commit 0bd2a558 authored by Richard Fernando Heise Ferreira's avatar Richard Fernando Heise Ferreira
Browse files

Merge branch 'issue/1-criar-rota-de-autenticacao' into 'main'

Issue #1: Create authentication routes

See merge request !2
1 merge request!2Issue #1: Create authentication routes
Showing with 1001 additions and 49 deletions
+1001 -49
.env 0 → 100644
SECRET_KEY = b487aa6fca542b8330d8dcfe30361225fea9d15b9e70377fd4e5f9ae8b36aae5
ALGORITHM = HS256
from fastapi import FastAPI
from fastapi import FastAPI, Depends, HTTPException, status, Request, Response, APIRouter
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from typing import Annotated
from passlib.context import CryptContext
from jose import JWTError, jwt
from datetime import datetime, timedelta
from src.prisma import prisma, get_user
from src.User import User
from src.Token import Token
import routers.users as users
import routers.oauth as oauth
app = FastAPI()
fake_db = []
app.include_router(users.router)
app.include_router(oauth.router)
@app.on_event("startup")
async def startup():
await prisma.connect()
@app.on_event("shutdown")
async def shutdown():
await prisma.disconnect()
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
@app.get("/")
async def root():
return fake_db
def get_password_hash(password):
return pwd_context.hash(password)
@app.post("/signup")
async def create_user(user: User):
fake_db.append(user)
return fake_db
find_user = await get_user(user.email)
if not find_user:
new_user = await prisma.user.create({
"email": user.email,
"name": user.username,
"password": get_password_hash(user.password)
})
return new_user
return {"message": "email já cadastrado!"}
def verify_password(plain_password, hashed_password):
return pwd_context.verify(plain_password, hashed_password)
@app.post("/signin")
async def login_user(user_login: User):
user = await get_user(user_login.email)
if not user:
return {"message": "usuario nao encontrado!"}
if verify_password(user_login.password, user.password):
return {"message": "login efetuado com sucesso!"}
else:
return {"message": "senha incorreta!"}
\ No newline at end of file
This diff is collapsed.
-- CreateTable
CREATE TABLE "User" (
"id" SERIAL NOT NULL,
"email" TEXT NOT NULL,
"name" TEXT NOT NULL,
"password" TEXT NOT NULL,
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"
\ No newline at end of file
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-py"
}
datasource db {
provider = "postgresql"
url = "postgresql://postgres:1234@localhost:5431/postgres"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String
password String
}
\ No newline at end of file
......@@ -10,7 +10,14 @@ packages = [{include = "portalmec_python_back"}]
python = "^3.11"
fastapi = "^0.93.0"
uvicorn = {extras = ["standard"], version = "^0.20.0"}
pydantic = "^1.10.6"
pydantic = {extras = ["email"], version = "^1.10.7"}
prisma = "^0.8.2"
passlib = {extras = ["bcrypt"], version = "^1.7.4"}
python-jose = {extras = ["crypthography"], version = "^3.3.0"}
python-dotenv = "^1.0.0"
google-api-python-client = "^2.84.0"
google-auth-httplib2 = "^0.1.0"
google-auth-oauthlib = "^1.0.0"
[build-system]
......
import os
from fastapi import FastAPI, Depends, HTTPException, status, Request, Response, APIRouter
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from dotenv import load_dotenv
from jose import JWTError, jwt
from datetime import datetime, timedelta
from src.prisma import prisma, get_user
load_dotenv()
SECRET_KEY = os.environ.get("SECRET_KEY")
ALGORITHM = os.environ.get("ALGORITHM")
ACCESS_TOKEN_EXPIRE_MINUTES = 30
router = APIRouter(
prefix="/oauth",
tags=["oauth"]
)
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/oauth/token")
def create_access_token(data: dict, expires_delta: timedelta | None = None):
to_encode = data.copy()
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(minutes=15)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
@router.post("/token")
async def gen_token_to_login(input_data : OAuth2PasswordRequestForm = Depends()):
user = await get_user(input_data.username)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
headers={"WWW-Authenticate": "Bearer"},
)
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token(
data={"sub": user.email}, expires_delta=access_token_expires
)
return {"access_token": access_token, "token_type": "bearer"}
\ No newline at end of file
import os
from fastapi import FastAPI, Depends, HTTPException, status, Request, Response, APIRouter
from jose import JWTError, jwt
from datetime import datetime, timedelta
from dotenv import load_dotenv
from routers.oauth import oauth2_scheme
from src.prisma import prisma, get_user
from src.Token import Token
load_dotenv()
SECRET_KEY = os.environ.get("SECRET_KEY")
ALGORITHM = os.environ.get("ALGORITHM")
ACCESS_TOKEN_EXPIRE_MINUTES = 30
router = APIRouter(
prefix="/users",
tags=["users"]
)
@router.get("/me")
async def get_current_user(token: Token = Depends(oauth2_scheme)):
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
email: str = payload.get("sub")
if email is None:
raise credentials_exception
except JWTError:
raise credentials_exception
current_user = await get_user(email)
return current_user
from pydantic import BaseModel
class Token(BaseModel):
access_token: str
from pydantic import BaseModel, Field
from pydantic import BaseModel, Field, EmailStr
class User(BaseModel):
username: str
email: str = Field(regex="([A-Za-z0-9]+[.-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(\.[A-Z|a-z]{2,})+")
username: str | None= None
email: EmailStr = Field(...)
password: str = Field(min_length=8)
\ No newline at end of file
from prisma import Prisma
prisma = Prisma()
async def get_user(email: str):
return await prisma.user.find_unique(
where = {"email": email}
)
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment