diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1d0a78cd590525830ff5c949ade0d1eaa0c1b9e0..573301f63869656fdcc1361ca2df7001bf0bef16 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -39,6 +39,9 @@ stages: test: stage: test + before_script: + - echo "Overwriting the test" + - apt-get update -y && apt-get install openssh-client gcc libxslt-dev libffi-dev libssl-dev build-essential python3-dev -y script: - pip install -r testing_requirements.txt - nosetests --with-coverage --cover-package=apiserver --cover-xml diff --git a/apiserver/main.py b/apiserver/main.py index e60ddc46ba59cb54f92a7f584eba2993c4509b91..8808ee96c311b2040fe3c8ffcd66d90d8f22d202 100644 --- a/apiserver/main.py +++ b/apiserver/main.py @@ -21,7 +21,7 @@ from .config import ApiserverSettings from .security import (ACCESS_TOKEN_EXPIRES_MINUTES, JsonDBInterface, Token, User, authenticate_user, create_access_token, get_current_user) -from .storage import JsonFileStorageAdapter, LocationData, LocationDataType, verify_oid, EncryptedJsonFileStorageAdapter +from .storage import JsonFileStorageAdapter, LocationData, LocationDataType, EncryptedJsonFileStorageAdapter log = logging.getLogger(__name__) @@ -104,7 +104,7 @@ async def get_types(request: Request = None): # uses first of json and html that is in the accept header; returns json if neither is found json_pos = accept_header.find(accept_json) html_pos = accept_header.find(accept_html) - + if json_pos == -1: json_pos = len(accept_header) if html_pos == -1: @@ -113,8 +113,8 @@ async def get_types(request: Request = None): if html_pos < json_pos: log.debug("Browser was redirected to index.html") return redirect_return - else: - return default_return + + return default_return @app.get("/{location_data_type}") @@ -163,8 +163,8 @@ async def list_dataset_secrets(location_data_type: LocationDataType, if user.has_secrets_access: log.debug("Authenticed User: '%s' listed the secrets of /%s/%s", user.username, location_data_type.value, dataset_id) return adapter.list_secrets(location_data_type, dataset_id, user) - else: - raise HTTPException(403) + + raise HTTPException(403) @app.get("/{location_data_type}/{dataset_id}/secrets_values") async def list_dataset_secrets(location_data_type: LocationDataType, @@ -186,8 +186,7 @@ async def get_dataset_secret(location_data_type: LocationDataType, if user.has_secrets_access: log.debug("Authenticed User: '%s' listed the secret %s of /%s/%s", user.username, key, location_data_type.value, dataset_id) return adapter.get_secret(location_data_type, dataset_id, key, user) - else: - raise HTTPException(403) + raise HTTPException(403) @app.post("/{location_data_type}/{dataset_id}/secrets") async def add_update_dataset_secret(location_data_type: LocationDataType, @@ -198,8 +197,7 @@ async def add_update_dataset_secret(location_data_type: LocationDataType, if user.has_secrets_access: log.debug("Authenticed User: '%s' added or updated the secret %s of /%s/%s", user.username, secret.key, location_data_type.value, dataset_id) return adapter.add_update_secret(location_data_type, dataset_id, secret.key, secret.secret, user) - else: - raise HTTPException(403) + raise HTTPException(403) @app.delete("/{location_data_type}/{dataset_id}/secrets/{key}") async def get_dataset_secrets(location_data_type: LocationDataType, @@ -210,8 +208,7 @@ async def get_dataset_secrets(location_data_type: LocationDataType, if user.has_secrets_access: log.debug("Authenticed User: '%s' deleted the secret %s from /%s/%s", user.username, key, location_data_type.value, dataset_id) return adapter.delete_secret(location_data_type, dataset_id, key, user) - else: - raise HTTPException(403) + raise HTTPException(403) diff --git a/apiserver/security/__init__.py b/apiserver/security/__init__.py index 8b778878abb3e5ae9dce12a65c22623b6169ccc7..71229825206b9fa247c4ad57de4d4237c44badb1 100644 --- a/apiserver/security/__init__.py +++ b/apiserver/security/__init__.py @@ -1 +1,3 @@ -from .user import User, UserInDB, AbstractDBInterface, JsonDBInterface, get_current_user, authenticate_user, create_access_token, Token, ACCESS_TOKEN_EXPIRES_MINUTES, get_password_hash \ No newline at end of file +from .user import (ACCESS_TOKEN_EXPIRES_MINUTES, AbstractDBInterface, + JsonDBInterface, Token, User, UserInDB, authenticate_user, + create_access_token, get_current_user, get_password_hash) diff --git a/apiserver/storage/JsonFileStorageAdapter.py b/apiserver/storage/JsonFileStorageAdapter.py index 054d95c92a775987fda266a2954579fac30d2c60..670be900af2278c46dfcc21ec0edb780164e30da 100644 --- a/apiserver/storage/JsonFileStorageAdapter.py +++ b/apiserver/storage/JsonFileStorageAdapter.py @@ -1,7 +1,7 @@ import json import os import uuid -from typing import Dict, List, Optional +from typing import Dict, List import logging from fastapi.exceptions import HTTPException @@ -70,7 +70,7 @@ class JsonFileStorageAdapter(AbstractLocationDataStorageAdapter): full_path = os.path.join(localpath, str(oid)) common = os.path.commonprefix((os.path.realpath(full_path),os.path.realpath(self.data_dir))) if common != os.path.realpath(self.data_dir): - log.error(f"Escaping the data dir! {common} {full_path}") + log.error("Escaping the data dir! %s %s", common, full_path) raise FileNotFoundError() if not os.path.isfile(full_path): @@ -86,8 +86,7 @@ class JsonFileStorageAdapter(AbstractLocationDataStorageAdapter): if not os.path.isfile(path): return {} with open(path, "r") as file: - dict = json.load(file) - return dict + return json.load(file) def __store_secrets(self, path: str, secrets: Dict[str, str]): with open(path, "w") as file: diff --git a/tests/apiserver_tests/test_responsiveness.py b/tests/apiserver_tests/test_responsiveness.py index 0848ab303859daae4fa357d9a5a94daa6bdfa02a..c9c85cdc1d37495dc3e77751188a1822c3ab4921 100644 --- a/tests/apiserver_tests/test_responsiveness.py +++ b/tests/apiserver_tests/test_responsiveness.py @@ -1,8 +1,8 @@ +import unittest + from fastapi.testclient import TestClient from context import apiserver, storage -import unittest - # a properly formatted uuidv4 to ensure the proper errors are returned by the api; the exact value is irrelevant proper_uuid = "3a33262e-276e-4de8-87bc-f2d5a0195faf" @@ -45,7 +45,7 @@ class NonAuthTests(unittest.TestCase): self.assertEqual(404, rsp.status_code) j = rsp.json() self.assertTrue('message' in j, f"{j} should contain message") - self.assertFalse('foo' in j['message'], f"error message should not contain object id (foo)") + self.assertFalse('foo' in j['message'], "error message should not contain object id (foo)") def test_get_invalid_oid(self): rsp = self.client.get('/dataset/invalid-uuid') @@ -57,30 +57,30 @@ class NonAuthTests(unittest.TestCase): header_accept_json = {'Accept' : "application/json"} header_accept_html = {'Accept' : "text/html"} header_accept_none = {'Accept' : ""} - + rsp = self.client.get("/", headers=header_accept_json) self.assertEqual(rsp.json(), [{element.value: "/" + element.value} for element in storage.LocationDataType]) - + rsp = self.client.get("/", headers=header_accept_html, allow_redirects=False) self.assertEqual(rsp.status_code, 307) - + rsp = self.client.get("/", headers=header_accept_html, allow_redirects=True) self.assertEqual(rsp.status_code, 422) # forwarded to /index.html which does not exist on the apiserver - + rsp = self.client.get("/", headers=header_accept_none) self.assertEqual(rsp.json(), [{element.value: "/" + element.value} for element in storage.LocationDataType]) - def test_secrets_access(self): + def test_secrets_access(self): # check if access for all secrets endpoints failed with 401 Auth required # list secrets, add secret, get secret, delete secret rsp = self.client.get(f'/dataset/{proper_uuid}/secrets') self.assertEqual(401, rsp.status_code) - + rsp = self.client.get(f'/dataset/{proper_uuid}/secrets/somespecificsecret') self.assertEqual(401, rsp.status_code) - + rsp = self.client.post(f'/dataset/{proper_uuid}/secrets', json={'key' : "somekey", "secret" : "somesecret"}) self.assertEqual(401, rsp.status_code) - + rsp = self.client.delete(f'/dataset/{proper_uuid}/secrets/somespecificsecret') self.assertEqual(401, rsp.status_code) diff --git a/userdb-cli.py b/userdb-cli.py index 54f5958584c1fe2533ee03670d790bea2408e607..90190b866b386e2ad7df367e8ffca5020f38a218 100755 --- a/userdb-cli.py +++ b/userdb-cli.py @@ -1,4 +1,4 @@ -#! /usr/bin/python3 +#!/usr/bin/env python import os, json, argparse, abc from pydantic import BaseModel