geenforce: IP allowlist for client endpoints + admin Settings tab

This commit is contained in:
2026-07-27 14:13:50 -04:00
parent ab1622ae58
commit 4ed1296d5e
5 changed files with 232 additions and 11 deletions

View File

@@ -115,6 +115,38 @@ def test_unauthenticated_rejected(client, db, app):
assert resp.status_code == 401
def _set_allowlist(app, value):
from shopdb.api import Setting
with app.app_context():
Setting.set('geenforce_allowed_cidrs', value, 'string', 'geenforce')
service.db.session.commit()
def test_ip_allowlist_allows_without_token(client, db, app):
# An allowlisted caller reaches the manifest with NO token (vault trust).
_seed_and_publish(app)
_set_allowlist(app, '127.0.0.0/8, 10.134.48.0/23') # test client is 127.0.0.1
resp = client.get('/api/geenforce/manifest?pctype=gea-shopfloor-cmm')
assert resp.status_code == 200, resp.data
assert b'Alpha' in resp.data
def test_ip_not_in_allowlist_still_rejected(client, db, app):
# A caller outside the allowlist and with no token is refused (fail-closed).
_seed_and_publish(app)
_set_allowlist(app, '10.0.0.0/8') # test client 127.0.0.1 is NOT in 10/8
resp = client.get('/api/geenforce/manifest?pctype=gea-shopfloor-cmm')
assert resp.status_code == 401
def test_empty_allowlist_keeps_token_required(client, db, app):
# Empty/unset allowlist = disabled; token stays the only path (back-compat).
_seed_and_publish(app)
_set_allowlist(app, '')
resp = client.get('/api/geenforce/manifest?pctype=gea-shopfloor-cmm')
assert resp.status_code == 401
def test_wrong_scope_rejected(client, db, app, auth_headers):
_seed_and_publish(app)
resp = client.post('/api/apitokens',