Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM debian:trixie
FROM debian:bookworm
ENV PYTHONUNBUFFERED 1
ENV PYTHONPATH /app/
ENV DEBIAN_FRONTEND noninteractive
Expand Down
2 changes: 1 addition & 1 deletion api/build_runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
set -eu
export DEBIAN_FRONTEND=noninteractive

echo 'deb http://deb.debian.org/debian trixie-backports main' \
echo 'deb http://deb.debian.org/debian bookworm-backports main' \
> /etc/apt/sources.list.d/backports.list

# Install ca-certificates and gnupg first
Expand Down
6 changes: 3 additions & 3 deletions api/ooniapi/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import datetime
import logging
import os
import json
import os
import re
import sys
from collections import deque
Expand Down Expand Up @@ -33,7 +33,7 @@
APP_DIR = os.path.dirname(__file__)


class JSONEncoderWithDates(json.JSONEncoder):
class FlaskJSONEncoder(json.JSONEncoder):
# Special JSON encoder that handles dates
def default(self, o):
if isinstance(o, datetime.datetime):
Expand Down Expand Up @@ -177,7 +177,7 @@ def create_app(*args, testmode=False, **kw):
from ooniapi import views

app = Flask(__name__)
app.json_encoder = JSONEncoderWithDates
app.json_encoder = FlaskJSONEncoder

# Order matters
init_app(app, testmode=testmode)
Expand Down
2 changes: 1 addition & 1 deletion api/ooniapi/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from flask import current_app

from sqlalchemy.dialects import postgresql
from sqlalchemy.orm import declarative_base
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.sql.elements import TextClause
from sqlalchemy.sql.selectable import Select

Expand Down
15 changes: 1 addition & 14 deletions api/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,8 @@ def app():

@pytest.fixture
def client(app):
"""
Overriding the `client` fixture from pytest_flask to fix this bug:
https://github.com/pytest-dev/pytest-flask/issues/42
"""
with app.test_client() as client:
yield client

# deprecated name _request_ctx_stack and marked as not a bug on issue #42
#while True:
# top = flask._request_ctx_stack.top
# if top is not None and top.preserved:
# top.pop()
# else:
# break

return client

@pytest.fixture(autouse=True)
def disable_rate_limits(app):
Expand Down
2 changes: 1 addition & 1 deletion api/tests/integ/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ def test_get_measurement_meta_not_found(client):
resp = client.get(url)
# TODO: is this a bug?
assert resp.status_code == 200
assert resp.json == {}
assert resp.get_json() == {}


def FIXME_MISSING_MSMT____test_get_measurement_meta_input_none_from_fp(client):
Expand Down
38 changes: 22 additions & 16 deletions api/tests/integ/test_probe_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,28 @@ def getjson(client, url):
response = client.get(url)
assert response.status_code == 200
assert response.is_json
return response.json
return response.get_json()


def getjsonh(client, url, headers=None):
response = client.get(url, headers=headers)
assert response.status_code == 200
assert response.is_json
return response.json
return response.get_json()


def post(client, url, data):
response = client.post(url, data=data)
assert response.status_code == 200
assert response.is_json
return response.json
return response.get_json()


def postj(client, url, **kw):
response = client.post(url, json=kw)
assert response.status_code == 200
assert response.is_json
return response.json
return response.get_json()


def test_index(client):
Expand Down Expand Up @@ -231,26 +231,30 @@ def test_register(client):
assert len(c["client_id"]) == 132


def test_register_then_login(client):
def test_register_then_login(client, app):
pwd = "HLdywVhzVCNqLvHCfmnMhIXqGmUFMTuYjmuGZhNlRTeIyvxeQTnjVJsiRkutHCSw"
c = _register(client)
assert "client_id" in c
assert len(c["client_id"]) == 132
tok = ooniapi.auth.decode_jwt(c["client_id"], audience="probe_login")
with app.app_context():
tok = ooniapi.auth.decode_jwt(c["client_id"], audience="probe_login")

client_id = c["client_id"]
c = postj(client, "/api/v1/login", username=client_id, password=pwd)
tok = ooniapi.auth.decode_jwt(c["token"], audience="probe_token")
assert tok["registration_time"] is not None
with app.app_context():
tok = ooniapi.auth.decode_jwt(c["token"], audience="probe_token")
assert tok["registration_time"] is not None

# Login with a bogus client id emulating probes before 2022
client_id = "BOGUSBOGUS"
j = dict(username=client_id, password=pwd)
r = client.post("/api/v1/login", json=j)
assert r.status_code == 200
token = r.json["token"]
tok = ooniapi.auth.decode_jwt(token, audience="probe_token")
assert tok["registration_time"] is None # we don't know the reg. time

with app.app_context():
tok = ooniapi.auth.decode_jwt(token, audience="probe_token")
assert tok["registration_time"] is None # we don't know the reg. time

# Expect failed login
resp = client.post("/api/v1/login", json=dict())
Expand All @@ -263,15 +267,16 @@ def test_test_helpers(client):


@patch("ooniapi.probe_services._load_json")
def test_psiphon(mock_load_json, client):
def test_psiphon(mock_load_json, client, app):

# register and login
pwd = "HLdywVhzVCNqLvHCfmnMhIXqGmUFMTuYjmuGZhNlRTeIyvxeQTnjVJsiRkutHCSw"
client_id = _register(client)["client_id"]

c = postj(client, "/api/v1/login", username=client_id, password=pwd)
tok = ooniapi.auth.decode_jwt(c["token"], audience="probe_token")
assert tok["registration_time"] is not None
with app.app_context():
tok = ooniapi.auth.decode_jwt(c["token"], audience="probe_token")
assert tok["registration_time"] is not None

url = "/api/v1/test-list/psiphon-config"
# broken token
Expand All @@ -289,14 +294,15 @@ def test_psiphon(mock_load_json, client):


@patch("ooniapi.probe_services._load_json")
def test_tor_targets(mock_load_json, client):
def test_tor_targets(mock_load_json, client, app):
# register and login
pwd = "HLdywVhzVCNqLvHCfmnMhIXqGmUFMTuYjmuGZhNlRTeIyvxeQTnjVJsiRkutHCSw"
client_id = _register(client)["client_id"]

c = postj(client, "/api/v1/login", username=client_id, password=pwd)
tok = ooniapi.auth.decode_jwt(c["token"], audience="probe_token")
assert tok["registration_time"] is not None
with app.app_context():
tok = ooniapi.auth.decode_jwt(c["token"], audience="probe_token")
assert tok["registration_time"] is not None

url = "/api/v1/test-list/tor-targets"
# broken token
Expand Down
1 change: 0 additions & 1 deletion api/tests/unit/test_probe_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ def test_web_test_helpers(mock):
"https://1.th.ooni.org",
"https://2.th.ooni.org",
"https://3.th.ooni.org",
"https://4.th.ooni.org",
]
)
r2 = round_robin_web_test_helpers()
Expand Down
Loading