Skip to content
Merged
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 .github/workflows/build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ runs:
run: docker-compose build ${{ inputs.images }}
- name: Build e2e2 Image
shell: bash
run: docker-compose -f docker-compose.yml -f docker-compose.test-e2e2.yml build test-e2e2
run: docker-compose -f docker-compose.yml -f docker-compose.test-e2e2.yml build libfaketime && docker-compose -f docker-compose.yml -f docker-compose.test-e2e2.yml build test-e2e2
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ While there are certainly many ways to get started hacking desec-stack, here is
For desec-stack, [docker](https://docs.docker.com/install/linux/docker-ce/ubuntu/) and [docker-compose](https://docs.docker.com/compose/install/) are required.
Further tools that are required to start hacking are git and curl.
Recommended, but not strictly required for desec-stack development is to use certbot along with Let's Encrypt and PyCharm.
jq, httpie, libmariadbclient-dev, libpq-dev, python3-dev (>= 3.8) and python3-venv (>= 3.8) are useful if you want to follow this guide.
jq, httpie, libmariadbclient-dev, libpq-dev, python3-dev (>= 3.11) and python3-venv (>= 3.11) are useful if you want to follow this guide.
The webapp requires nodejs. To install everything you need for this guide except docker and docker-compose, use

sudo apt install certbot curl git httpie jq libmariadbclient-dev libpq-dev nodejs npm python3-dev python3-venv libmemcached-dev
Expand Down Expand Up @@ -324,7 +324,7 @@ While there are certainly many ways to get started hacking desec-stack, here is
In the project root,

cd api
python3 -m venv venv
python3 -m venv venv # Python >= 3.11
source venv/bin/activate
pip install wheel
pip install -r requirements.txt
Expand Down
2 changes: 1 addition & 1 deletion api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.10-alpine
FROM python:3.11-alpine

COPY --from=trajano/alpine-libfaketime /faketime.so /lib/libfaketime.so
RUN mkdir -p /etc/faketime
Expand Down
6 changes: 2 additions & 4 deletions api/desecapi/authentication.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import base64
import datetime
from datetime import datetime, UTC
from ipaddress import ip_address

from django.contrib.auth.hashers import PBKDF2PasswordHasher
Expand Down Expand Up @@ -178,9 +178,7 @@ def authenticate_credentials(self, context):
serializer.is_valid(raise_exception=True)
user = serializer.validated_data["user"]

email_verified = datetime.datetime.fromtimestamp(
serializer.timestamp, datetime.timezone.utc
)
email_verified = datetime.fromtimestamp(serializer.timestamp, UTC)
user.email_verified = max(user.email_verified or email_verified, email_verified)
user.save()

Expand Down
2 changes: 1 addition & 1 deletion api/desecapi/tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -979,7 +979,7 @@ def random_domain_name(cls, suffix=None):
if not suffix:
suffix = cls.PUBLIC_SUFFIXES
if isinstance(suffix, set):
suffix = random.sample(suffix, 1)[0]
suffix = random.sample(list(suffix), 1)[0]
return (
random.choice(string.ascii_letters)
+ cls.random_string()
Expand Down
12 changes: 6 additions & 6 deletions api/desecapi/tests/test_rrsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -1242,7 +1242,7 @@ def test_update_my_rr_set_with_invalid_payload_type(self):
self.my_rr_set_domain.name, subname, "A", data
)
self.assertStatus(response, status.HTTP_400_BAD_REQUEST)
self.assertEquals(
self.assertEqual(
response.data["non_field_errors"][0],
"Invalid data. Expected a dictionary, but got list.",
)
Expand All @@ -1252,7 +1252,7 @@ def test_update_my_rr_set_with_invalid_payload_type(self):
self.my_rr_set_domain.name, subname, "A", data
)
self.assertStatus(response, status.HTTP_400_BAD_REQUEST)
self.assertEquals(
self.assertEqual(
response.data["non_field_errors"][0],
"Invalid data. Expected a dictionary, but got str.",
)
Expand Down Expand Up @@ -1333,19 +1333,19 @@ def test_update_essential_properties(self):
data = {"records": ["3.2.3.4"], "ttl": 3620, "subname": "test2", "type": "A"}
response = self.client.patch(url, data)
self.assertStatus(response, status.HTTP_400_BAD_REQUEST)
self.assertEquals(response.data["subname"][0].code, "read-only-on-update")
self.assertEqual(response.data["subname"][0].code, "read-only-on-update")
response = self.client.put(url, data)
self.assertStatus(response, status.HTTP_400_BAD_REQUEST)
self.assertEquals(response.data["subname"][0].code, "read-only-on-update")
self.assertEqual(response.data["subname"][0].code, "read-only-on-update")

# Changing the type is expected to cause an error
data = {"records": ["3.2.3.4"], "ttl": 3620, "subname": "test", "type": "TXT"}
response = self.client.patch(url, data)
self.assertStatus(response, status.HTTP_400_BAD_REQUEST)
self.assertEquals(response.data["type"][0].code, "read-only-on-update")
self.assertEqual(response.data["type"][0].code, "read-only-on-update")
response = self.client.put(url, data)
self.assertStatus(response, status.HTTP_400_BAD_REQUEST)
self.assertEquals(response.data["type"][0].code, "read-only-on-update")
self.assertEqual(response.data["type"][0].code, "read-only-on-update")

# Changing "created" is no-op
response = self.client.get(url)
Expand Down
2 changes: 1 addition & 1 deletion api/desecapi/tests/test_user_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ def test_registration_with_domain(self):
domain="co.uk",
expect_failure_response=self.assertRegistrationFailureDomainUnavailableResponse,
)
local_public_suffix = random.sample(self.AUTO_DELEGATION_DOMAINS, 1)[0]
local_public_suffix = random.sample(list(self.AUTO_DELEGATION_DOMAINS), 1)[0]
with self.get_psl_context_manager(local_public_suffix):
self._test_registration_with_domain(
domain=self.random_domain_name(suffix=local_public_suffix)
Expand Down
10 changes: 5 additions & 5 deletions api/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
captcha~=0.4.0
celery~=5.2.7
celery~=5.3.1
coverage~=7.2.7
cryptography~=41.0.1
Django~=4.1.0 # upgrade once django-pgtrigger is compatible
django-cors-headers~=4.0.0
Django~=4.2.2
django-cors-headers~=4.1.0
djangorestframework~=3.14.0
django-celery-email~=3.0.0
django-netfields~=1.3.0
django-pgtrigger~=4.6.0
django-pgtrigger~=4.7.0
django-prometheus~=2.3.1
dnspython~=2.3.0
httpretty~=1.0.5 # 1.1 breaks tests. Does not run in production, so stick to it.
pyotp~=2.8.0
psycopg2~=2.9.6 # replace with psycopg (3) once django-pgtrigger is compatible
psycopg~=3.1.9
prometheus-client~=0.17.0 # added to control django-prometheus' dependency version
psl-dns~=1.1.0
pylibmc~=1.6.3
Expand Down
5 changes: 5 additions & 0 deletions docker-compose.test-e2e2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ services:
- "www.desec.${DESECSTACK_DOMAIN}:${DESECSTACK_IPV4_REAR_PREFIX16}.0.128"
- "get.desec.${DESECSTACK_DOMAIN}:${DESECSTACK_IPV4_REAR_PREFIX16}.0.128"

libfaketime:
# trajano/alpine-libfaketime is incompatible is stale; its libfaketime
# version is incompatible with Python 3.11's time.sleep(). Rebuilding helps.
build: https://github.com/trajano/alpine-libfaketime.git

volumes:
autocert:
faketime:
4 changes: 2 additions & 2 deletions test/e2e2/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
FROM python:3.9-alpine
FROM python:3.11-alpine

RUN apk add --no-cache bash curl

COPY --from=trajano/alpine-libfaketime /faketime.so /lib/libfaketime.so
COPY --from=desec-stack_libfaketime /faketime.so /lib/libfaketime.so
RUN mkdir -p /etc/faketime

RUN mkdir /e2e
Expand Down
1 change: 1 addition & 0 deletions test/e2e2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ A collection of tests against the stack written in python and pytest.

The tests can be run from the **CLI** using

docker-compose -f docker-compose.yml -f docker-compose.test-e2e2.yml build libfaketime
docker-compose -f docker-compose.yml -f docker-compose.test-e2e2.yml build test-e2e2
docker-compose -f docker-compose.yml -f docker-compose.test-e2e2.yml up test-e2e2

Expand Down
5 changes: 3 additions & 2 deletions test/e2e2/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -495,9 +495,10 @@ def assert_all_ns(assertion: callable, retry_on=(AssertionError,)):

def faketime(t: str):
print('FAKETIME', t)
with open('/etc/faketime/faketime.rc', 'w') as f:
with open(os.environ['FAKETIME_TIMESTAMP_FILE'] + '.tmp', 'w') as f:
f.write(t + '\n')

# https://github.com/wolfcw/libfaketime/issues/392#issuecomment-1122344129
os.rename(os.environ['FAKETIME_TIMESTAMP_FILE'] + '.tmp', os.environ['FAKETIME_TIMESTAMP_FILE'])

def faketime_get():
try:
Expand Down
6 changes: 3 additions & 3 deletions www/webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
"lint:fix": "vue-cli-service lint --fix"
},
"dependencies": {
"@fontsource/roboto": "^4.5.8",
"@mdi/font": "^6.9.96",
"@fontsource/roboto": "^5.0.3",
"@mdi/font": "^7.2.96",
"@mdi/js": "~7.2.96",
"axios": "^0.27.2",
"axios": "^1.4.0",
"core-js": "^3.27.1",
"javascript-time-ago": "^2.5.9",
"pinia": "^2.0.30",
Expand Down
2 changes: 1 addition & 1 deletion www/webapp/src/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ router.beforeEach((to, from, next) => {
const user = useUserStore();
if (sessionStorage.getItem('token') && !user.authenticated) {
const token = JSON.parse(sessionStorage.getItem('token'));
HTTP.defaults.headers.common['Authorization'] = 'Token ' + token.token;
HTTP.defaults.headers.Authorization = 'Token ' + token.token;
user.login(token);
recovered = true
}
Expand Down
2 changes: 1 addition & 1 deletion www/webapp/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const HTTP = axios.create({

function clearToken() {
useUserStore().logout();
HTTP.defaults.headers.common.Authorization = '';
HTTP.defaults.headers.Authorization = '';
sessionStorage.removeItem('token');
}

Expand Down
4 changes: 2 additions & 2 deletions www/webapp/src/views/CrudListToken.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default {
value: 'perm_manage_tokens',
readonly: false,
writeOnCreate: true,
datatype: 'Switchbox',
datatype: 'GenericSwitchbox',
searchable: false,
advanced: true,
},
Expand Down Expand Up @@ -98,7 +98,7 @@ export default {
sortable: true,
value: 'is_valid',
readonly: true,
datatype: 'Checkbox',
datatype: 'GenericCheckbox',
searchable: false,
},
value: {
Expand Down
2 changes: 1 addition & 1 deletion www/webapp/src/views/LoginPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export default {
email: this.email,
password: this.password,
});
HTTP.defaults.headers.common.Authorization = `Token ${response.data.token}`;
HTTP.defaults.headers.Authorization = `Token ${response.data.token}`;
this.user.login(response.data);
if (this.useSessionStorage) {
sessionStorage.setItem('token', JSON.stringify(response.data));
Expand Down