Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix redis mocking #67

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
969c014
feat: moved advent folder -> puzzles, added some comments
May 22, 2022
a185ac6
merge: merged Ryan's database changes
May 22, 2022
3c6bf1b
feat(docker): start separation of dev and prod builds, add pytest fun…
May 24, 2022
058e55d
feat(docker): added dev/prod to frontend, transition frontend to yarn
May 25, 2022
8b881a3
merge: merged pipfile.lock changes
May 25, 2022
35f53c8
fix: remove .vscode folder
May 25, 2022
1048ded
fix(makefile): restructured makefile a bit
May 25, 2022
f23884d
feat: removed .vscode folder from git
May 26, 2022
af94b47
feat(auth): get rudimentary autotesting in place, created clear_datab…
May 31, 2022
2adacb2
feat(test): added all tests for auth/register
Jun 9, 2022
511b4a1
fix(puzzle): changed blueprint in routes/puzzle.py
Jun 12, 2022
6e89290
fix merge conflict from main
Jun 12, 2022
814909b
feat(auth): refactored registration system, database connections
Jul 2, 2022
88010fe
fix(auth): minor changes to constructor
Jul 2, 2022
03fb576
feat(auth): implement email verification endpoints
Jul 3, 2022
439491b
feat(test): using fixtures
Jul 3, 2022
9262969
feat(auth): finish autotests, still needs commenting
Jul 4, 2022
3f1aa59
feat(auth): finished writing tests for the most part
Jul 4, 2022
03274db
feat(auth): complete tests for basic auth system
Jul 20, 2022
4f9fe01
merged from main
Jul 20, 2022
689900e
fix(auth): removed duplicate clear_database function
Jul 20, 2022
5800055
fix(auth): add basic lockout functionality
Aug 4, 2022
fe4f962
merge: merged in new database stuff from main
Aug 4, 2022
8252711
fix(auth): fix clear_database utility function
Aug 9, 2022
6027f1d
fix(auth): change requests to conform with DB
Aug 9, 2022
1eb635b
fix(auth): add basic lockout to /login route
Aug 9, 2022
a27c0d9
merge: merged from main
Aug 9, 2022
77c2b16
feat(auth): add function to carry over CSRF in headers
Aug 9, 2022
6573b00
feat(auth): add timeout capabilities
Aug 24, 2022
fbda099
merge: merged authentication
Aug 24, 2022
b0f7e69
fix(auth): add back mock_redis
Aug 24, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions backend/common/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
port = os.environ["POSTGRES_PORT"]
database = os.environ["POSTGRES_DB"]

# TABLES = ["Users", "Questions", "Competitions", "Inputs", "Solves"]

def get_connection():
conn = psycopg2.connect(
user=user,
Expand Down Expand Up @@ -396,4 +394,3 @@ def add_user_with_uid(uid, email, username, password):
"""
cur.execute(query)
conn.commit()

2 changes: 2 additions & 0 deletions backend/routes/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ def reset_email_request():
verify_jwt_in_request()
except:
raise AuthError("Invalid token")
=======
>>>>>>> main



Expand Down
52 changes: 51 additions & 1 deletion backend/test/auth/login_test.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from datetime import datetime, timedelta

import pytest
from freezegun import freeze_time

# Import for pytest
from flask.testing import FlaskClient
from test.helpers import clear_all, db_add_user, generate_csrf_header
from test.fixtures import app, client

from test.mock.mock_redis import fake_redis

def test_no_users(client):
clear_all()
Expand Down Expand Up @@ -76,6 +79,53 @@ def test_lockout(client):

assert response.status_code == 401

def test_lockout_timing(client):
clear_all()

db_add_user("[email protected]", "asdf", "foobar")

# Incorrect login 3 times
for _ in range(3):
response = client.post("/auth/login", json={
"email": "[email protected]",
"password": "foobaz"
})

assert response.status_code == 401

timeout_over = datetime.now() + timedelta(minutes=1, seconds=5)

# Incorrect login again
with freeze_time(timeout_over):
response = client.post("/auth/login", json={
"email": "[email protected]",
"password": "foobaz"
})

assert response.status_code == 401

still_timeout = timeout_over + timedelta(minutes=1)

# Timeout is now 2 minutes
with freeze_time(still_timeout):
response = client.post("/auth/login", json={
"email": "[email protected]",
"password": "foobar"
})

assert response.status_code == 401

second_timeout_over = still_timeout + timedelta(minutes=1, seconds=5)

# Timeout is now 2 minutes
with freeze_time(second_timeout_over):
response = client.post("/auth/login", json={
"email": "[email protected]",
"password": "foobar"
})

assert response.status_code == 200

def test_protected_route(client: FlaskClient):
clear_all()

Expand Down
23 changes: 3 additions & 20 deletions backend/test/auth/register_verify_test.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
import email
import os
import poplib
import re
from datetime import datetime, timedelta

import fakeredis
import pytest
from freezegun import freeze_time
from pytest_mock import mocker

# Imports for pytest
import common
from test.helpers import clear_all
from test.fixtures import app, client
from test.mock.mock_mail import mailbox
Expand All @@ -37,31 +32,21 @@ def test_invalid_token(client):
assert response.status_code == 401

# TODO: try working on this, if not feasible delete this test and test manually
@pytest.mark.skip()
def test_token_expired(client, mocker):
clear_all()

fake = fakeredis.FakeStrictRedis()
mocker.patch.object(common.redis, "cache", return_value=fake)

mocker.patch("routes.auth.mail", mailbox)

register_response = client.post("/auth/register", json={
"email": "[email protected]",
"username": "asdf",
"password": "foobar"
})

print(fake.keys())

assert register_response.status_code == 200

# Check inbox
mailbox = poplib.POP3("pop3.mailtrap.io", 1100)
mailbox.user(os.environ["MAILTRAP_USERNAME"])
mailbox.pass_(os.environ["MAILTRAP_PASSWORD"])

# Check the contents of the email, and harvest the token from there
raw_email = b"\n".join(mailbox.retr(1)[1])
parsed_email = email.message_from_bytes(raw_email)
parsed_email = mailbox.get_message(-1)

# Assuming there's a HTML part
for part in parsed_email.walk():
Expand All @@ -74,8 +59,6 @@ def test_token_expired(client, mocker):
expired_time = datetime.now() + timedelta(hours=2)

with freeze_time(expired_time):
print(fake.keys())

response = client.post("/auth/register/verify", json={
"token": token
})
Expand Down
6 changes: 5 additions & 1 deletion backend/test/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
from pytest_mock import mocker

from test.mock.mock_mail import mailbox
from test.mock.mock_redis import fake_redis

@pytest.fixture()
def app(mocker):
# Mock only where the data is being used
# Mock mailbox
mocker.patch("app.mail", mailbox)
mocker.patch("common.plugins.mail", mailbox)

# Mock redis
mocker.patch("common.redis.cache", fake_redis)

app = create_app({"TESTING": True})
yield app

Expand Down
5 changes: 0 additions & 5 deletions backend/test/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,3 @@ def get_cookie_from_header(response, cookie_name):
def generate_csrf_header(response):
csrf_token = get_cookie_from_header(response, "csrf_access_token")["csrf_access_token"]
return {"X-CSRF-TOKEN": csrf_token}

## EMAIL MOCKING

def get_emails():
pass
3 changes: 3 additions & 0 deletions backend/test/mock/mock_redis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import fakeredis

fake_redis = fakeredis.FakeStrictRedis()