54 lines
3.6 KiB
Python
54 lines
3.6 KiB
Python
|
|
"""Isolated provider contract test. Never loads production config or credentials."""
|
||
|
|
import contextlib,io,json,logging,os,tempfile,time,base64,hmac,hashlib,struct,urllib.parse
|
||
|
|
from pathlib import Path
|
||
|
|
result={"success":False};phase="isolation"
|
||
|
|
def check(name,condition):
|
||
|
|
result[name]=bool(condition)
|
||
|
|
if not condition:raise ValueError(name)
|
||
|
|
def run():
|
||
|
|
global phase
|
||
|
|
for k in list(os.environ):
|
||
|
|
if k.startswith("PRIVACYIDEA_"):del os.environ[k]
|
||
|
|
logging.disable(logging.CRITICAL)
|
||
|
|
with tempfile.TemporaryDirectory(prefix="provider-contract-") as d:
|
||
|
|
root=Path(d);(root/'enckey').write_bytes(os.urandom(96))
|
||
|
|
cfg=root/'fixture.cfg';cfg.write_text("SQLALCHEMY_DATABASE_URI='sqlite:///PLACEHOLDER_DB'\nSECRET_KEY='isolated-fixture-only'\nPI_PEPPER='isolated-fixture-only'\nPI_NO_RESPONSE_SIGN=True\nPI_AUDIT_NO_SIGN=True\nPI_LOGFILE="+repr(str(root/'log'))+"\nPI_ENCFILE="+repr(str(root/'enckey'))+"\nPI_TRUSTED_JWT=[]\n")
|
||
|
|
cfg.write_text(cfg.read_text().replace('PLACEHOLDER_DB', str(root/'fixture.sqlite')))
|
||
|
|
with cfg.open('a') as f:f.write('PI_AUDIT_SQL_URI='+repr('sqlite:///'+str(root/'audit.sqlite'))+'\n')
|
||
|
|
from privacyidea.app import create_app
|
||
|
|
from privacyidea.models import db
|
||
|
|
from privacyidea.lib.policy import set_policy,enable_policy
|
||
|
|
from privacyidea.lib.resolver import save_resolver
|
||
|
|
from privacyidea.lib.realm import set_realm
|
||
|
|
from privacyidea.lib.auth import create_db_admin
|
||
|
|
from privacyidea.lib.resolvers.PasswdIdResolver import crypt_ctx
|
||
|
|
app=create_app(config_name="testing",config_file=str(cfg),silent=True)
|
||
|
|
app.config["PI_INIT_CHECK_HOOK"]="keycape_onboarding_guard.check"
|
||
|
|
phase="fixture_database"
|
||
|
|
with app.app_context():
|
||
|
|
check('database_isolated',str(db.engine.url)=='sqlite:///'+str(root/'fixture.sqlite'));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)
|
||
|
|
passwd=root/'users';passwd.write_text('alice:'+crypt_ctx.hash('fixture-password',scheme='sha512_crypt')+':1001:1001:Fixture:/tmp:/bin/false\n')
|
||
|
|
with passwd.open('a') as f:f.write('native-alice:'+crypt_ctx.hash('fixture-password',scheme='sha512_crypt')+':1002:1002:Native fixture:/tmp:/bin/false\n')
|
||
|
|
save_resolver({'resolver':'fixture-users','type':'passwdresolver','fileName':str(passwd)})
|
||
|
|
set_realm('fixture',[{'name':'fixture-users'}])
|
||
|
|
create_db_admin('fixture-reader',password='fixture-service-password')
|
||
|
|
set_policy(name='fixture-admin-baseline',scope='admin',action='*',adminuser=['*','!fixture-reader'])
|
||
|
|
set_policy(name='fixture-reader',scope='admin',action='tokenlist',adminuser='fixture-reader',realm='fixture')
|
||
|
|
set_policy(name='fixture-user',scope='user',action='enrollTOTP',realm='fixture')
|
||
|
|
set_policy(name='fixture-pending-cancel',scope='user',action='delete',realm='fixture',conditions=[('token','rollout_state','equals','verify',True)])
|
||
|
|
set_policy(name='fixture-confirmation',scope='enrollment',action='verify_enrollment=totp',realm='fixture')
|
||
|
|
set_policy(name='fixture-passthru',scope='authentication',action='passthru',realm='fixture')
|
||
|
|
from privacyidea.lib.token import init_token
|
||
|
|
probe=init_token({'serial':'P06SCOPEPROBE','type':'hotp','genkey':1,'realm':'fixture'})
|
||
|
|
probe.token.active=False;probe.token.save()
|
||
|
|
print(json.dumps({"fixture_ready":True,"production_database":False}),flush=True)
|
||
|
|
app.run(host="0.0.0.0",port=8088,debug=False,use_reloader=False)
|
||
|
|
if __name__=="__main__":
|
||
|
|
try:run()
|
||
|
|
except Exception as error:
|
||
|
|
print(json.dumps({"fixture_failure":type(error).__name__,"phase":phase}),flush=True)
|
||
|
|
raise SystemExit(1)
|