fix: /connect ohne Login erreichbar (Anmeldung direkt als technisches Konto), offene Anfragen begrenzt
Claude-Session: https://claude.ai/code/session_01SqzF6qT3TQ8ej3wigEuMSu
This commit is contained in:
3 files changed
+12
-3
No files matched your search
+2
-3
@@ -19,9 +19,8 @@
|
|||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<p>The collection mailbox is not connected yet. In a private window: open this page, sign in with
|
<p>The collection mailbox is not connected yet. Open <code>/connect</code> of this site in a private
|
||||||
<strong>your own account</strong>, click “Connect mailbox”, then sign in as
|
window and sign in as <strong>{{ email_address }}</strong> (technical account).</p>
|
||||||
<strong>{{ email_address }}</strong> (technical account).</p>
|
|
||||||
<form action="/connect" method="get">
|
<form action="/connect" method="get">
|
||||||
<button type="submit" class="btn-primary">Connect mailbox</button>
|
<button type="submit" class="btn-primary">Connect mailbox</button>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ from cryptography.fernet import Fernet, InvalidToken
|
|||||||
SCOPES = "openid profile email offline_access"
|
SCOPES = "openid profile email offline_access"
|
||||||
REFRESH_MARGIN_SEC = 60
|
REFRESH_MARGIN_SEC = 60
|
||||||
PENDING_TTL_SEC = 600
|
PENDING_TTL_SEC = 600
|
||||||
|
MAX_PENDING = 20 # /connect is reachable without login: bound the open requests
|
||||||
|
|
||||||
|
|
||||||
class OAuthError(Exception):
|
class OAuthError(Exception):
|
||||||
@@ -108,6 +109,8 @@ class MailboxOAuth:
|
|||||||
now = self.clock()
|
now = self.clock()
|
||||||
with self._lock:
|
with self._lock:
|
||||||
self._pending = {k: v for k, v in self._pending.items() if now - v[1] < PENDING_TTL_SEC}
|
self._pending = {k: v for k, v in self._pending.items() if now - v[1] < PENDING_TTL_SEC}
|
||||||
|
while len(self._pending) >= MAX_PENDING:
|
||||||
|
del self._pending[min(self._pending, key=lambda k: self._pending[k][1])]
|
||||||
self._pending[state] = (verifier, now)
|
self._pending[state] = (verifier, now)
|
||||||
query = {
|
query = {
|
||||||
"response_type": "code",
|
"response_type": "code",
|
||||||
|
|||||||
@@ -166,3 +166,10 @@ def test_callback_error_is_shown(monkeypatch):
|
|||||||
monkeypatch.setattr(unsub, "OAUTH", FakeOAuth())
|
monkeypatch.setattr(unsub, "OAUTH", FakeOAuth())
|
||||||
r = unsub.app.test_client().get("/oidc/callback?state=s&code=c")
|
r = unsub.app.test_client().get("/oidc/callback?state=s&code=c")
|
||||||
assert r.status_code == 400 and "expected unsubscribe-bot" in r.get_data(as_text=True)
|
assert r.status_code == 400 and "expected unsubscribe-bot" in r.get_data(as_text=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_pending_requests_are_bounded(tmp_path):
|
||||||
|
mb = _mb(tmp_path, [])
|
||||||
|
for _ in range(oauth.MAX_PENDING + 15):
|
||||||
|
mb.start()
|
||||||
|
assert len(mb._pending) == oauth.MAX_PENDING
|
||||||
Reference in new issue
Block a user