From 805ddf8c81d26cea59b4c4112a19649e7d2f02e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Victor=20L=C3=B6fgren?= <viclo211@student.liu.se>
Date: Tue, 27 Apr 2021 22:34:11 +0200
Subject: [PATCH] Add some authorization tests

---
 server/app/apis/__init__.py  |  5 +--
 server/app/apis/answers.py   |  8 ++---
 server/tests/test_app.py     | 64 +++++++++++++++++++++++++++++++++++-
 server/tests/test_helpers.py | 18 ++++++++--
 4 files changed, 86 insertions(+), 9 deletions(-)

diff --git a/server/app/apis/__init__.py b/server/app/apis/__init__.py
index b02b154a..e5ec3d2c 100644
--- a/server/app/apis/__init__.py
+++ b/server/app/apis/__init__.py
@@ -18,6 +18,7 @@ def _is_allowed(allowed, actual):
 
 
 def _has_access(in_claim, in_route):
+    in_route = int(in_route) if in_route else None
     return not in_route or in_claim and in_claim == in_route
 
 
@@ -49,7 +50,7 @@ def protect_route(allowed_roles=None, allowed_views=None):
                 )
 
             claim_competition_id = claims.get("competition_id")
-            route_competition_id = int(kwargs.get("competition_id"))
+            route_competition_id = kwargs.get("competition_id")
             if not _has_access(claim_competition_id, route_competition_id):
                 abort(
                     http_codes.UNAUTHORIZED,
@@ -58,7 +59,7 @@ def protect_route(allowed_roles=None, allowed_views=None):
 
             if view == "Team":
                 claim_team_id = claims.get("team_id")
-                route_team_id = int(kwargs.get("team_id"))
+                route_team_id = kwargs.get("team_id")
                 if not _has_access(claim_team_id, route_team_id):
                     abort(
                         http_codes.UNAUTHORIZED,
diff --git a/server/app/apis/answers.py b/server/app/apis/answers.py
index e7f54c0c..8f72d3bd 100644
--- a/server/app/apis/answers.py
+++ b/server/app/apis/answers.py
@@ -22,12 +22,12 @@ question_answer_edit_parser.add_argument("score", type=int, default=None, locati
 @api.route("")
 @api.param("competition_id, team_id")
 class QuestionAnswerList(Resource):
-    @protect_route(allowed_roles=["*"], allowed_views=["Team", "Judge"])
+    @protect_route(allowed_roles=["*"], allowed_views=["*"])
     def get(self, competition_id, team_id):
         items = dbc.get.question_answer_list(competition_id, team_id)
         return list_response(list_schema.dump(items))
 
-    @protect_route(allowed_roles=["*"], allowed_views=["Team", "Judge"])
+    @protect_route(allowed_roles=["*"], allowed_views=["*"])
     def post(self, competition_id, team_id):
         args = question_answer_parser.parse_args(strict=True)
         item = dbc.add.question_answer(**args, team_id=team_id)
@@ -37,12 +37,12 @@ class QuestionAnswerList(Resource):
 @api.route("/<answer_id>")
 @api.param("competition_id, team_id, answer_id")
 class QuestionAnswers(Resource):
-    @protect_route(allowed_roles=["*"], allowed_views=["Team", "Judge"])
+    @protect_route(allowed_roles=["*"], allowed_views=["*"])
     def get(self, competition_id, team_id, answer_id):
         item = dbc.get.question_answer(competition_id, team_id, answer_id)
         return item_response(schema.dump(item))
 
-    @protect_route(allowed_roles=["*"], allowed_views=["Team", "Judge"])
+    @protect_route(allowed_roles=["*"], allowed_views=["*"])
     def put(self, competition_id, team_id, answer_id):
         args = question_answer_edit_parser.parse_args(strict=True)
         item = dbc.get.question_answer(competition_id, team_id, answer_id)
diff --git a/server/tests/test_app.py b/server/tests/test_app.py
index 199df387..79b73e22 100644
--- a/server/tests/test_app.py
+++ b/server/tests/test_app.py
@@ -3,6 +3,7 @@ This file tests the api function calls.
 """
 
 import app.core.http_codes as codes
+from app.database.controller.add import competition
 from app.database.models import Slide
 
 from tests import app, client, db
@@ -342,7 +343,7 @@ def test_question_api(client):
     slide_order = 1
     response, body = get(client, f"/api/competitions/{CID}/questions", headers=headers)
     assert response.status_code == codes.OK
-    assert body["count"] == 1
+    assert body["count"] == 2
 
     # Get questions from another competition that should have some questions
     CID = 3
@@ -385,3 +386,64 @@ def test_question_api(client):
     response, _ = delete(client, f"/api/competitions/{CID}/slides/{NEW_slide_order}/questions/{QID}", headers=headers)
     assert response.status_code == codes.NOT_FOUND
     """
+
+
+def test_authorization(client):
+    add_default_values()
+
+    #### TEAM ####
+    # Login in with team code
+    response, body = post(client, "/api/auth/login/code", {"code": "111111"})
+    assert response.status_code == codes.OK
+    headers = {"Authorization": "Bearer " + body["access_token"]}
+
+    competition_id = body["competition_id"]
+    team_id = body["team_id"]
+
+    # Get competition team is in
+    response, body = get(client, f"/api/competitions/{competition_id}", headers=headers)
+    assert response.status_code == codes.OK
+
+    # Try to delete competition team is in
+    response, body = delete(client, f"/api/competitions/{competition_id}", headers=headers)
+    assert response.status_code == codes.UNAUTHORIZED
+
+    # Try to get a different competition
+    response, body = get(client, f"/api/competitions/{competition_id+1}", headers=headers)
+    assert response.status_code == codes.UNAUTHORIZED
+
+    # Get own answers
+    response, body = get(client, f"/api/competitions/{competition_id}/teams/{team_id}/answers", headers=headers)
+    assert response.status_code == codes.OK
+
+    # Try to get another teams answers
+    response, body = get(client, f"/api/competitions/{competition_id}/teams/{team_id+1}/answers", headers=headers)
+    assert response.status_code == codes.UNAUTHORIZED
+
+    #### JUDGE ####
+    # Login in with judge code
+    response, body = post(client, "/api/auth/login/code", {"code": "222222"})
+    assert response.status_code == codes.OK
+    headers = {"Authorization": "Bearer " + body["access_token"]}
+
+    competition_id = body["competition_id"]
+
+    # Get competition judge is in
+    response, body = get(client, f"/api/competitions/{competition_id}", headers=headers)
+    assert response.status_code == codes.OK
+
+    # Try to delete competition judge is in
+    response, body = delete(client, f"/api/competitions/{competition_id}", headers=headers)
+    assert response.status_code == codes.UNAUTHORIZED
+
+    # Try to get a different competition
+    response, body = get(client, f"/api/competitions/{competition_id+1}", headers=headers)
+    assert response.status_code == codes.UNAUTHORIZED
+
+    # Get team answers
+    response, body = get(client, f"/api/competitions/{competition_id}/teams/{team_id}/answers", headers=headers)
+    assert response.status_code == codes.OK
+
+    # Also get antoher teams answers
+    response, body = get(client, f"/api/competitions/{competition_id}/teams/{team_id+1}/answers", headers=headers)
+    assert response.status_code == codes.OK
\ No newline at end of file
diff --git a/server/tests/test_helpers.py b/server/tests/test_helpers.py
index b5f1e54e..5dabdbbe 100644
--- a/server/tests/test_helpers.py
+++ b/server/tests/test_helpers.py
@@ -3,14 +3,14 @@ import json
 import app.core.http_codes as codes
 import app.database.controller as dbc
 from app.core import db
-from app.database.models import City, Role
+from app.database.models import City, Code, Role
 
 
 def add_default_values():
     media_types = ["Image", "Video"]
     question_types = ["Boolean", "Multiple", "Text"]
     component_types = ["Text", "Image"]
-    view_types = ["Team", "Judge", "Audience"]
+    view_types = ["Team", "Judge", "Audience", "Operator"]
 
     roles = ["Admin", "Editor"]
     cities = ["Linköping", "Testköping"]
@@ -40,6 +40,20 @@ def add_default_values():
 
     # Add competitions
     item_competition = dbc.add.competition("Tom tävling", 2012, item_city.id)
+
+    item_question = dbc.add.question("hej", 5, 1, item_competition.slides[0].id)
+
+    item_team1 = dbc.add.team("Hej lag 3", item_competition.id)
+    item_team2 = dbc.add.team("Hej lag 4", item_competition.id)
+
+    db.session.add(Code("111111", 1, item_competition.id, item_team1.id))  # Team
+    db.session.add(Code("222222", 2, item_competition.id))  # Judge
+
+    dbc.add.QuestionAnswer("hej", 5, item_question.id, item_team1)
+    dbc.add.QuestionAnswer("då", 5, item_question.id, item_team2)
+
+    db.session.commit()
+
     for j in range(2):
         item_comp = dbc.add.competition(f"Tävling {j}", 2012, item_city.id)
         # Add two more slides to competition
-- 
GitLab