Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Base TestEndpoint class to handle auth #153

Merged
merged 6 commits into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
36 changes: 36 additions & 0 deletions backend/test_auth_server/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
index_bp = Blueprint("index", __name__)
index_endpoint = Api(index_bp)

# Take the key the same as the id, uid can then be used in backend
token_dict = {
"teacher1":{
"id":"Gunnar",
Expand Down Expand Up @@ -44,6 +45,41 @@
"admin1":{
"id":"admin_person",
"jobTitle":"admin"
},
# Lowest authorized user to test login requirement
"login": {
"id": "login",
"jobTitle": None
},
# Student authorization access, associated with valid_...
"student": {
"id": "student",
"jobTitle": None
},
# Student authorization access, other
"student_other": {
"id": "student_other",
"jobTitle": None
},
# Teacher authorization access, associated with valid_...
"teacher": {
"id": "teacher",
"jobTitle": "teacher"
},
# Teacher authorization access, other
"teacher_other": {
"id": "teacher_other",
"jobTitle": "teacher"
},
# Admin authorization access, associated with valid_...
"admin": {
"id": "admin",
"jobTitle": "admin"
},
# Admin authorization access, other
"admin_other": {
"id": "admin_other",
"jobTitle": "admin"
}
}

Expand Down
24 changes: 21 additions & 3 deletions backend/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from datetime import datetime
from zoneinfo import ZoneInfo
import pytest
from pytest import fixture
from project.sessionmaker import engine, Session
from project.db_in import db
from project.models.course import Course
Expand All @@ -11,7 +11,7 @@
from project.models.course_relation import CourseStudent,CourseAdmin
from project.models.submission import Submission, SubmissionStatus

@pytest.fixture
@fixture
def db_session():
"""Create a new database session for a test.
After the test, all changes are rolled back and the session is closed."""
Expand Down Expand Up @@ -123,7 +123,22 @@ def submissions(session):
)
]

@pytest.fixture
### AUTHENTICATION & AUTHORIZATION ###
def auth_tokens():
"""Add the authenticated users to the database"""

return [
User(uid="login", role=Role.STUDENT),
User(uid="student", role=Role.STUDENT),
User(uid="student_other", role=Role.STUDENT),
User(uid="teacher", role=Role.TEACHER),
User(uid="teacher_other", role=Role.TEACHER),
User(uid="admin", role=Role.ADMIN),
User(uid="admin_other", role=Role.ADMIN)
]

### SESSION ###
@fixture
def session():
"""Create a new database session for a test.
After the test, all changes are rolled back and the session is closed."""
Expand All @@ -132,6 +147,9 @@ def session():
session = Session()

try:
session.add_all(auth_tokens())
session.commit()
Gerwoud marked this conversation as resolved.
Show resolved Hide resolved

# Populate the database
session.add_all(users())
session.commit()
Expand Down
18 changes: 18 additions & 0 deletions backend/tests/endpoints/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from datetime import datetime
from zoneinfo import ZoneInfo
import pytest
from pytest import fixture, FixtureRequest
from flask.testing import FlaskClient
from sqlalchemy import create_engine
from sqlalchemy.exc import SQLAlchemyError
from project.models.user import User,Role
Expand All @@ -15,7 +17,23 @@
from project.models.submission import Submission, SubmissionStatus
from project.models.project import Project

### AUTHENTICATEN & AUTHORIZATION ###
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

authenticaten -> authentication

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commit f191ba3

@fixture
def auth_test(request: FixtureRequest, client: FlaskClient, valid_course_entry):
"""Add concrete test data"""
# endpoint, parameters, method, token, status
endpoint, parameters, method, *other = request.param

d = {
"course_id": valid_course_entry.course_id
}

for index, parameter in enumerate(parameters):
endpoint = endpoint.replace(f"@{index}", str(d[parameter]))

return endpoint, getattr(client, method), *other

### OTHER ###
@pytest.fixture
def valid_submission(valid_user_entry, valid_project_entry):
"""
Expand Down
56 changes: 56 additions & 0 deletions backend/tests/endpoints/endpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""Base class for endpoint tests"""

from typing import List, Tuple
from pytest import param

def authentication_tests(tests: List[Tuple[str, List[str], List[str]]]) -> List[any]:
"""Transform the format to single authentication tests"""

single_tests = []
for test in tests:
endpoint, parameters, methods = test
for method in methods:
single_tests.append(param(
(endpoint, parameters, method),
id = f"{endpoint} {method}"
))
return single_tests

def authorization_tests(tests: List[Tuple[str, List[str], str, List[str], List[str]]]) -> List[any]:
"""Transform the format to single authorization tests"""

single_tests = []
for test in tests:
endpoint, parameters, method, allowed_tokens, disallowed_tokens = test
for token in (allowed_tokens + disallowed_tokens):
allowed = token in allowed_tokens
single_tests.append(param(
(endpoint, parameters, method, token, allowed),
id = f"{endpoint} {method} {token} {'allowed' if allowed else 'disallowed'}"
))
return single_tests

class TestEndpoint:
"""Base class for endpoint tests"""

def authentication(self, authentication_parameter: Tuple[str, any]):
"""Test if the authentication for the given enpoint works"""

endpoint, method = authentication_parameter

response = method(endpoint)
assert response.status_code == 401

response = method(endpoint, headers = {"Authorization": "0123456789"})
assert response.status_code == 401

response = method(endpoint, headers = {"Authorization": "login"})
assert response.status_code != 401

def authorization(self, auth_parameter: Tuple[str, any, str, bool]):
"""Test if the authorization for the given endpoint works"""

endpoint, method, token, allowed = auth_parameter

response = method(endpoint, headers = {"Authorization": token})
assert allowed == (response.status_code != 403)
6 changes: 3 additions & 3 deletions backend/tests/models/user_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ def test_create_user(self, session: Session):
session.add(user)
session.commit()
assert session.get(User, "user01") is not None
assert session.query(User).count() == 5
assert session.query(User).count() == 12

def test_query_user(self, session: Session):
"""Test if a user can be queried"""
assert session.query(User).count() == 4
assert session.query(User).count() == 11
teacher = session.query(User).filter_by(uid="brinkmann").first()
assert teacher is not None
assert teacher.role == Role.ADMIN
Expand All @@ -36,7 +36,7 @@ def test_delete_user(self, session: Session):
session.delete(user)
session.commit()
assert session.get(User, user.uid) is None
assert session.query(User).count() == 3
assert session.query(User).count() == 10

@mark.parametrize("property_name", ["uid"])
def test_property_not_nullable(self, session: Session, property_name: str):
Expand Down