|
| 1 | +from datetime import datetime, timedelta |
1 | 2 | from http import HTTPStatus
|
2 | 3 | from io import StringIO
|
3 | 4 |
|
| 5 | +from django.conf import settings |
4 | 6 | from django.core.management import call_command
|
5 | 7 | from django.test import TestCase
|
6 | 8 | from django.urls import NoReverseMatch, get_resolver
|
@@ -164,3 +166,40 @@ def test_single_h1_per_page(self):
|
164 | 166 | response = self.client.get(url)
|
165 | 167 | self.assertEqual(response.status_code, 200)
|
166 | 168 | self.assertContains(response, "<h1", count=1)
|
| 169 | + |
| 170 | + |
| 171 | +class SecurityTxtFileTests(TestCase): |
| 172 | + """ |
| 173 | + Tests for the security.txt file. |
| 174 | + """ |
| 175 | + |
| 176 | + def test_security_txt_not_expired(self): |
| 177 | + """ |
| 178 | + The security.txt file should not be expired. |
| 179 | + """ |
| 180 | + FILE_PATH = settings.BASE_DIR / ".well-known" / "security.txt" |
| 181 | + with open(FILE_PATH) as f: |
| 182 | + content = f.read() |
| 183 | + # Read the line that starts with "Expires:", and parse the date. |
| 184 | + for line in content.splitlines(): |
| 185 | + if line.startswith("Expires:"): |
| 186 | + expires = line.strip("Expires: ") |
| 187 | + break |
| 188 | + else: |
| 189 | + self.fail("No Expires line found in security.txt") |
| 190 | + |
| 191 | + expires_date = datetime.strptime( |
| 192 | + expires, |
| 193 | + "%Y-%m-%dT%H:%M:%S.%fZ", |
| 194 | + ).date() |
| 195 | + # We should ideally be two weeks early with updating - active over reactive |
| 196 | + cutoff = (datetime.now() - timedelta(days=15)).date() |
| 197 | + self.assertGreater( |
| 198 | + expires_date, |
| 199 | + cutoff, |
| 200 | + "The security.txt file is close to expiring. \ |
| 201 | +Please update the 'Expires' line in to confirm the contents are \ |
| 202 | +still accurate: {}".format( |
| 203 | + FILE_PATH |
| 204 | + ), |
| 205 | + ) |
0 commit comments