diff --git a/bsition/api/endpoints/token.py b/bsition/api/endpoints/token.py index dce48f8..97442f5 100644 --- a/bsition/api/endpoints/token.py +++ b/bsition/api/endpoints/token.py @@ -4,6 +4,7 @@ from fastapi.security import OAuth2PasswordRequestForm from bsition.api.utils.jwt import write_token from bsition.api.utils.password import verify_password +from bsition.backend.redis.tokens import add_token from bsition.backend.postgres.users import get_user_by_username router = APIRouter() @@ -18,9 +19,11 @@ def login(form: OAuth2PasswordRequestForm = Depends()): detail="User not found.", ) + token = write_token({"sub": form.username}) + add_token(token, form.username) return JSONResponse( content={ - "access_token": write_token({"sub": form.username}), + "access_token": token, "token_type": "bearer", }, status_code=202, diff --git a/bsition/api/endpoints/users.py b/bsition/api/endpoints/users.py index c8723f7..c0110f0 100644 --- a/bsition/api/endpoints/users.py +++ b/bsition/api/endpoints/users.py @@ -4,6 +4,7 @@ from fastapi.responses import JSONResponse from bsition.api.models.user import User from bsition.api.utils.password import get_hashed_password from bsition.api.utils.security import get_current_user +from bsition.backend.redis import tokens as redis from bsition.backend.postgres import users as postgres router = APIRouter() @@ -43,4 +44,5 @@ def get_by_id(id: str): @router.put("/{id}") def edit_user(aux: User, id: str): postgres.edit_user(id, aux.username, get_hashed_password(aux.password)) + redis.remove_tokens(aux.username) return JSONResponse(content={"detail": "User updated."}, status_code=202) diff --git a/bsition/api/utils/security.py b/bsition/api/utils/security.py index 52a4d64..d2e6a09 100644 --- a/bsition/api/utils/security.py +++ b/bsition/api/utils/security.py @@ -4,6 +4,7 @@ from jwt import exceptions from starlette import status from bsition.api.utils.jwt import validate_token +from bsition.backend.redis.tokens import valid_token from bsition.backend.postgres.users import get_user_by_username oauth2_scheme = OAuth2PasswordBearer(tokenUrl="api/token") @@ -26,6 +27,10 @@ async def get_current_user(token: str = Depends(oauth2_scheme)): except exceptions.ExpiredSignatureError: raise credentials_exception + if not valid_token(token, username): + print("no es valido!") + raise credentials_exception + user = get_user_by_username(username) if user is None: raise credentials_exception diff --git a/bsition/backend/redis/tokens.py b/bsition/backend/redis/tokens.py index 63c4cce..a5c3845 100644 --- a/bsition/backend/redis/tokens.py +++ b/bsition/backend/redis/tokens.py @@ -1,15 +1,28 @@ -from dotenv import load_dotenv - -from redis import Redis +from redis.exceptions import ResponseError from bsition.backend.redis.utils import get_client +max_tokens = 10 -def test(): - load_dotenv() + +def add_token(token, username): client = get_client() - client.set("foo", "bar") - print(client.get("foo")) + try: + client.bf().reserve(username, 0.01, max_tokens, noScale=True) + except ResponseError: + pass + + if client.bf().info(username).insertedNum == max_tokens: + remove_tokens(username) + + client.bf().add(username, token) -test() +def remove_tokens(username): + client = get_client() + client.unlink(username) + + +def valid_token(token, username): + client = get_client() + return client.bf().exists(username, token) == 1 diff --git a/docker-compose.yml b/docker-compose.yml index 65241b3..abaf193 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,7 +41,7 @@ services: - "9300:9300" redis: - image: redis + image: redislabs/rebloom container_name: bsition-redis sysctls: - net.core.somaxconn=512