Skip to content

Commit

Permalink
feat: updated rate limiting for enhance security
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeSoft007 committed Aug 23, 2024
1 parent 2b8e6c1 commit 5c0da95
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 127 deletions.
5 changes: 3 additions & 2 deletions api/v1/routes/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,10 +310,11 @@ async def verify_signin_token(
@auth.post("/magic-link", status_code=status.HTTP_200_OK)
@limiter.limit("1000/minute") # Limit to 1000 requests per minute per IP
def request_magic_link(
request: MagicLinkRequest, background_tasks: BackgroundTasks,
request: Request,
requests: MagicLinkRequest, background_tasks: BackgroundTasks,
response: Response, db: Session = Depends(get_db)
):
user = user_service.fetch_by_email(db=db, email=request.email)
user = user_service.fetch_by_email(db=db, email=requests.email)
magic_link_token = user_service.create_access_token(user_id=user.id)
magic_link = f"https://anchor-python.teams.hng.tech/login/magic-link?token={magic_link_token}"

Expand Down
106 changes: 85 additions & 21 deletions tests/v1/auth/test_magic_link.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import pytest
from fastapi.testclient import TestClient
from unittest.mock import patch, MagicMock
Expand All @@ -10,27 +9,21 @@
from fastapi import status
from datetime import datetime, timezone


client = TestClient(app)
MAGIC_ENDPOINT = '/api/v1/auth/magic-link'


@pytest.fixture
def mock_db_session():
"""Fixture to create a mock database session."""

with patch("api.v1.services.user.get_db", autospec=True) as mock_get_db:
mock_db = MagicMock()
# mock_get_db.return_value.__enter__.return_value = mock_db
app.dependency_overrides[get_db] = lambda: mock_db
yield mock_db
app.dependency_overrides = {}


@pytest.fixture
def mock_user_service():
"""Fixture to create a mock user service."""

with patch("api.v1.services.user.user_service", autospec=True) as mock_service:
yield mock_service

Expand All @@ -57,21 +50,92 @@ def test_request_magic_link(mock_user_service, mock_db_session):
mock_smtp_instance = MagicMock()
mock_smtp.return_value = mock_smtp_instance


# Test for requesting magic link for an existing user
magic_login = client.post(MAGIC_ENDPOINT, json={
"email": mock_user.email
})
assert magic_login.status_code == status.HTTP_200_OK
response = magic_login.json()
#assert response.get("status_code") == status.HTTP_200_OK # check for the right response before proceeding
assert response.get("message") == f"Magic link sent to {mock_user.email}"
response = client.post(MAGIC_ENDPOINT, json={"email": mock_user.email})
assert response.status_code == status.HTTP_200_OK
assert response.json().get("message") == f"Magic link sent to {mock_user.email}"

# Test for requesting magic link for a non-existing user
mock_db_session.query.return_value.filter.return_value.first.return_value = None
magic_login = client.post(MAGIC_ENDPOINT, json={
"email": "[email protected]"
})
response = magic_login.json()
assert response.get("status_code") == status.HTTP_404_NOT_FOUND # check for the right response before proceeding
assert response.get("message") == "User not found"
response = client.post(MAGIC_ENDPOINT, json={"email": "[email protected]"})
assert response.status_code == status.HTTP_404_NOT_FOUND
assert response.json().get("message") == "User not found"



# import pytest
# from fastapi.testclient import TestClient
# from unittest.mock import patch, MagicMock
# from main import app
# from api.v1.models.user import User
# from api.v1.services.user import user_service
# from uuid_extensions import uuid7
# from api.db.database import get_db
# from fastapi import status
# from datetime import datetime, timezone


# client = TestClient(app)
# MAGIC_ENDPOINT = '/api/v1/auth/magic-link'


# @pytest.fixture
# def mock_db_session():
# """Fixture to create a mock database session."""

# with patch("api.v1.services.user.get_db", autospec=True) as mock_get_db:
# mock_db = MagicMock()
# # mock_get_db.return_value.__enter__.return_value = mock_db
# app.dependency_overrides[get_db] = lambda: mock_db
# yield mock_db
# app.dependency_overrides = {}


# @pytest.fixture
# def mock_user_service():
# """Fixture to create a mock user service."""

# with patch("api.v1.services.user.user_service", autospec=True) as mock_service:
# yield mock_service

# @pytest.mark.usefixtures("mock_db_session", "mock_user_service")
# def test_request_magic_link(mock_user_service, mock_db_session):
# """Test for requesting magic link"""

# # Create a mock user
# mock_user = User(
# id=str(uuid7()),
# email="[email protected]",
# password=user_service.hash_password("Testpassword@123"),
# first_name='Test',
# last_name='User',
# is_active=False,
# is_superadmin=False,
# created_at=datetime.now(timezone.utc),
# updated_at=datetime.now(timezone.utc)
# )
# mock_db_session.query.return_value.filter.return_value.first.return_value = mock_user

# with patch("api.utils.send_mail.smtplib.SMTP_SSL") as mock_smtp:
# # Configure the mock SMTP server
# mock_smtp_instance = MagicMock()
# mock_smtp.return_value = mock_smtp_instance


# # Test for requesting magic link for an existing user
# magic_login = client.post(MAGIC_ENDPOINT, json={
# "email": mock_user.email
# })
# assert magic_login.status_code == status.HTTP_200_OK
# response = magic_login.json()
# #assert response.get("status_code") == status.HTTP_200_OK # check for the right response before proceeding
# assert response.get("message") == f"Magic link sent to {mock_user.email}"

# # Test for requesting magic link for a non-existing user
# mock_db_session.query.return_value.filter.return_value.first.return_value = None
# magic_login = client.post(MAGIC_ENDPOINT, json={
# "email": "[email protected]"
# })
# response = magic_login.json()
# assert response.get("status_code") == status.HTTP_404_NOT_FOUND # check for the right response before proceeding
# assert response.get("message") == "User not found"
104 changes: 0 additions & 104 deletions tests/v1/testimonial/test_create_testimonial.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,107 +142,3 @@ def test_create_testimonial_missing_ratings(client_with_mocks):
retrieved_testimonial = mock_db.query(Testimonial).get(testimonial_id)

assert retrieved_testimonial.ratings == 0











# import pytest
# from tests.database import session, client
# from api.v1.models import * # noqa: F403

# auth_token = None

# payload = [
# {
# "content": "Testimonial 1",
# "ratings": 2.5,
# # expected
# "status_code": 201,
# },
# {
# "content": "Testimonial 2",
# "ratings": 3.5,
# # expected
# "status_code": 201,
# },
# { # missing content
# "ratings": 3.5,
# # expected
# "status_code": 422,
# },
# { # missing ratings
# "content": "Testimonial 2",
# # expected
# "status_code": 201,
# },
# ]

# # before all tests generate an access token
# @pytest.fixture(autouse=True)
# def before_all(client: client, session: session, mock_send_email) -> pytest.fixture:
# # create a user
# user = client.post(
# "/api/v1/auth/register",
# json={
# "password": "strin8Hsg263@",
# "first_name": "string",
# "last_name": "string",
# "email": "[email protected]",
# }
# )
# global auth_token
# auth_token = user.json()["access_token"]


# def test_create_testimonial(client: client, session: session) -> pytest:
# status_code = payload[0].pop("status_code")
# res = client.post(
# "api/v1/testimonials/",
# json=payload[0],
# headers={"Authorization": f"Bearer {auth_token}"},
# )

# assert res.status_code == status_code
# testimonial_id = res.json()["data"]["id"]
# testimonial = session.query(Testimonial).get(testimonial_id)
# assert testimonial.content == payload[0]["content"]
# assert testimonial.ratings == payload[0]["ratings"]

# def test_create_testimonial_unauthorized(client: client, session: session) -> pytest:
# status_code = 401
# res = client.post(
# "api/v1/testimonials/",
# json=payload[1],
# )

# assert res.status_code == status_code

# def test_create_testimonial_missing_content(client: client, session: session) -> pytest:
# status_code = payload[2].pop("status_code")
# res = client.post(
# "api/v1/testimonials/",
# json=payload[2],
# headers={"Authorization": f"Bearer {auth_token}"},
# )

# assert res.status_code == status_code

# def test_create_testimonial_missing_ratings(client: client, session: session) -> pytest:
# status_code = payload[3].pop("status_code")
# res = client.post(
# "api/v1/testimonials/",
# json=payload[3],
# headers={"Authorization": f"Bearer {auth_token}"},
# )

# assert res.status_code == status_code
# testimonial_id = res.json()["data"]["id"]
# testimonial = session.query(Testimonial).get(testimonial_id)
# assert testimonial.ratings == 0

0 comments on commit 5c0da95

Please sign in to comment.