IPFilterMiddleware matches the raw TCP peer address, which is 127.0.0.1 only
when firegex shares the host's network namespace. Behind a published docker
port the peer is the bridge gateway instead, so the scenario allowing
127.0.0.1/32,::1/128 got a 403 and the suite failed everywhere except
standalone mode.
Allow loopback plus the private ranges a docker bridge can occupy. The check
keeps its meaning: the deny scenario uses 203.0.113.0/24 (TEST-NET-3), which no
real peer can fall into, so the allow/deny pair still exercises the middleware.
- CI is release.yml and runs only on `release: published`, gating the publish
jobs. The documented docker-image.yml no longer exists, and nothing validates
a push or a pull request.
- nginx_test.py is gone; document ipfilter_test.py instead, including that it
drives run.py itself and is not part of run_tests.sh.
- `restart` now force-recreates the container, so it re-applies compose env
vars; note that, and that most start/restart flags persist to the config file.
- Describe the authentication surface: everything hangs off the `api` router
dependency plus the socket.io connect handler, with three routes deliberately
declared on `app`. Cover --unsafe-disable-auth and the fail-closed IP filter.
Rename the flag to --unsafe-disable-auth so the risk is visible at the call
site, and close the ways the mode could outlive itself:
- Keep an explicit -P/--startup-psw instead of dropping it. Without a password
in the database, --no-unsafe-disable-auth brought firegex up in its
initial-setup state, where anyone able to reach it could choose the password.
- Refuse /api/login, /api/set-password and /api/change-password while
authentication is disabled: an anonymous caller could otherwise plant a
credential that kept working once authentication was turned back on.
run.py config --password still works, writing to the database from the host.
- Print a banner on every start/restart with authentication disabled. The flag
is persisted in the config file, so a later bare `run.py start` inherits it.
- Report the change in `run.py config --unsafe-disable-auth`, which claimed
"No configuration changes specified" while persisting it, and stop that
command from nulling the stored port and host on the way.
- Expose the state as auth_disabled in /api/status and hide the logout button
and the change-password entry, which were silent no-ops in this mode.
Tests cover both directions of the toggle, the socket.io handler, the password
endpoints and the -P handling.
Objects archived in the history deques no longer carry their own
_history snapshot, breaking the recursive chain where each historical
entry held copies of all prior entries. The .history property on
archived objects now returns an empty HttpHistory([], []) instead.
- Fix parameter order sensitivity in HttpHistory._fetch_packet when history is first argument
- Delegate total_size and should_upgrade to _message instead of live _parser
- Sanitize FGEX_MAX_HISTORY_SIZE with max(0, int(val)) and dynamically sync deque maxlen