fix(roster): strip Secrets Manager token whitespace

A file:// secret commonly includes a trailing newline, so compare_digest
must strip the cached value the same way it strips the Bearer header.
This commit is contained in:
Adam Moussa 2026-09-09 17:09:40 -04:00
parent 8155e8ec90
commit 94bcf551ce
No known key found for this signature in database
2 changed files with 22 additions and 1 deletions

View file

@ -111,7 +111,10 @@ def _expected_token() -> str:
except Exception: except Exception:
logger.exception("roster api token secret read failed") logger.exception("roster api token secret read failed")
raise SecretUnavailable from None raise SecretUnavailable from None
if not isinstance(token, str) or not token: if not isinstance(token, str):
raise SecretUnavailable
token = token.strip()
if not token:
raise SecretUnavailable raise SecretUnavailable
_cached_token = token _cached_token = token
return token return token

View file

@ -145,6 +145,24 @@ def test_401_wrong_token(rosterapi_app, schedule, secrets):
assert schedule.get_employee_by_extension("110") is None assert schedule.get_employee_by_extension("110") is None
def test_authorize_strips_secret_trailing_newline(
rosterapi_app, schedule, env, monkeypatch
):
monkeypatch.setattr(rosterapi_app, "get_secret", lambda _id: TOKEN + "\n")
rosterapi_app._cached_token = None
result = rosterapi_app.handler(_event(body=_put_body()), None)
assert result["statusCode"] == 200
assert schedule.get_employee_by_extension("110")["slack_user_id"] == "U123ABCDE"
def test_503_when_secret_is_whitespace_only(rosterapi_app, schedule, env, monkeypatch):
monkeypatch.setattr(rosterapi_app, "get_secret", lambda _id: "\n")
rosterapi_app._cached_token = None
result = rosterapi_app.handler(_event(body=_put_body()), None)
assert result["statusCode"] == 503
assert schedule.get_employee_by_extension("110") is None
def test_503_when_secret_read_fails(rosterapi_app, schedule, env, monkeypatch): def test_503_when_secret_read_fails(rosterapi_app, schedule, env, monkeypatch):
def boom(_id): def boom(_id):
raise RuntimeError("secrets down") raise RuntimeError("secrets down")