Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a1346b-72a4-7d40-b8bd-8b8ca346cfa2
84 lines
4.9 KiB
Python
84 lines
4.9 KiB
Python
"""Disposable privacyIDEA 3.12.2 HTTP and database proof, no production config."""
|
|
import contextlib
|
|
import io
|
|
import json
|
|
import logging
|
|
import os
|
|
from pathlib import Path
|
|
import sys
|
|
import tempfile
|
|
import threading
|
|
|
|
|
|
def run():
|
|
for name in list(os.environ):
|
|
if name.startswith('PRIVACYIDEA_'):del os.environ[name]
|
|
logging.disable(logging.CRITICAL)
|
|
sys.path.insert(0,str(Path(__file__).resolve().parents[1]/'sso-mfa/k8s/privacyidea'))
|
|
import realm_bootstrap as r
|
|
from privacyidea.app import create_app
|
|
from privacyidea.models import db
|
|
from privacyidea.lib.auth import create_db_admin
|
|
from privacyidea.lib.policy import PolicyClass,set_policy
|
|
from privacyidea.lib.resolver import get_resolver_config,save_resolver
|
|
from privacyidea.lib.realm import set_realm,set_default_realm
|
|
from werkzeug.serving import make_server
|
|
with tempfile.TemporaryDirectory(prefix='realm-native-') as directory:
|
|
root=Path(directory);(root/'enckey').write_bytes(os.urandom(96))
|
|
cfg=root/'fixture.cfg'
|
|
config=dict(SQLALCHEMY_DATABASE_URI='sqlite:///'+str(root/'db.sqlite'),SECRET_KEY='fixture-secret-key',
|
|
PI_PEPPER='fixture-pepper',PI_ENCFILE=str(root/'enckey'),PI_NO_RESPONSE_SIGN=True,
|
|
PI_AUDIT_NO_SIGN=True,PI_LOGFILE=str(root/'log'),PI_TRUSTED_JWT=[],
|
|
PI_AUDIT_SQL_URI='sqlite:///'+str(root/'audit.sqlite'))
|
|
cfg.write_text('\n'.join(k+'='+repr(v) for k,v in config.items()))
|
|
app=create_app(config_name='testing',config_file=str(cfg),silent=True)
|
|
with app.app_context():
|
|
assert str(db.engine.url)==config['SQLALCHEMY_DATABASE_URI'];db.create_all()
|
|
from privacyidea.lib.audit import getAudit
|
|
from privacyidea.lib.auditmodules.sqlaudit import LogEntry
|
|
LogEntry.__table__.create(getAudit(app.config).engine,checkfirst=True)
|
|
create_db_admin('pi-admin',password='fixture-admin-password')
|
|
policies=PolicyClass().policies
|
|
server=make_server('127.0.0.1',0,app);thread=threading.Thread(target=server.serve_forever,daemon=True);thread.start()
|
|
try:
|
|
client=r.Client(f'http://127.0.0.1:{server.server_port}','fixture-admin-password')
|
|
preview=r.repair(client,lambda:None)
|
|
assert preview['configuration_writes']==0
|
|
result=r.repair(client,lambda:'fixture-bind-password',apply=True)
|
|
assert result['actions']==['create-resolver','create-realm','set-first-realm-default'],result
|
|
with app.app_context():
|
|
assert get_resolver_config(r.RESOLVER)['BINDPW']=='fixture-bind-password'
|
|
assert PolicyClass().policies==policies
|
|
set_policy(name='totp-self-enrollment',scope='user',action='enrollTOTP',realm='coulomb')
|
|
set_policy(name='keycape-pending-enrollment-cancel',scope='user',action='delete',realm='coulomb',conditions=[('token','rollout_state','equals','verify',True)])
|
|
set_policy(name='mfa-passthru-phase1',scope='authentication',action='passthru',realm='coulomb',active=False)
|
|
policies=PolicyClass().policies
|
|
save_resolver({'resolver':r.RESOLVER,'type':'ldapresolver','TIMEOUT':'','SIZELIMIT':'777','TLS_VERIFY':True,'CACHE_TIMEOUT':'333'})
|
|
set_realm('other',[]);set_default_realm('other')
|
|
before=client.snapshot()
|
|
result=r.repair(client,lambda:(_ for _ in ()).throw(AssertionError()),apply=True)
|
|
assert result['actions']==['fill-missing-tuning']
|
|
after=client.snapshot()
|
|
assert after['realms']==before['realms']
|
|
assert after['resolver']['data']['TIMEOUT']=='5'
|
|
for key,value in before['resolver']['data'].items():
|
|
if key!='TIMEOUT':assert after['resolver']['data'][key]==value
|
|
with app.app_context():
|
|
assert get_resolver_config(r.RESOLVER)['BINDPW']=='fixture-bind-password'
|
|
assert PolicyClass().policies==policies
|
|
assert r.repair(client,lambda:None,apply=True)['configuration_writes']==0
|
|
return {'native_create_and_readback':True,'native_minimal_update_preserves_omitted_fields':True,
|
|
'native_bind_password_preserved':True,'native_hardened_policies_preserved':True,
|
|
'native_existing_default_preserved':True,'native_repeat_is_noop':True}
|
|
finally:server.shutdown();thread.join();server.server_close()
|
|
|
|
|
|
if __name__=='__main__':
|
|
try:
|
|
with contextlib.redirect_stdout(io.StringIO()),contextlib.redirect_stderr(io.StringIO()):result=run()
|
|
print(json.dumps(result,sort_keys=True))
|
|
except Exception as exc:
|
|
import traceback
|
|
frame=traceback.extract_tb(exc.__traceback__)[-1]
|
|
print(json.dumps({'result':'failed','type':type(exc).__name__,'file':Path(frame.filename).name,'line':frame.lineno}))
|
|
raise SystemExit(1)
|