#!/usr/bin/env python
import requests
import re
import json
import sys

"""
Extract all DWR endpoints functions from DWR JS interface files.

Documentation:
    https://github.com/directwebremoting/dwr
    https://en.wikipedia.org/wiki/Direct_Web_Remoting

Dependencies:
    pip install requests
"""
requests.packages.urllib3.disable_warnings(
    requests.packages.urllib3.exceptions.InsecureRequestWarning)
JS_INTERFACES_LIST = ["AdminService.js", "DocumentService.js", "DrawingBimService.js",
                      "DrawingSvgService.js", "SecurityService.js", "SmartClientConfigService.js",
                      "workflow.js"]
AUTH_COOKIES = "a=b"
PROXIES = {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"}
REGEX = r'dwr\.engine\._execute\((.*?)\)'

if len(sys.argv) < 2:
    print("Missing DWR JS interface base URL!")
    print(f" Syntax: {sys.argv[0]} [DWR_JS_BASE_URL]")
    print(f"Example: {sys.argv[0]} https://host.com/ctxtpath/dwr/interface/")
    sys.exit(1)
base_js_url = sys.argv[1]
if not base_js_url.endswith("/"):
    base_js_url += "/"
base_js_url += "%s"
sess = requests.Session()
sess.verify = False
sess.headers.update({"Cookie": AUTH_COOKIES})
endpoints = {}
print("[+] Search and extract endpoints functions...")
for js in JS_INTERFACES_LIST:
    resp = sess.get(base_js_url % js)  # proxies=PROXIES
    edps = re.findall(REGEX, resp.text)
    for edp in edps:
        call_args = edp.split(",")
        edp_name = call_args[1].strip(" '")
        func_name = call_args[2].strip(" '")
        if edp_name not in endpoints:
            endpoints[edp_name] = []
        if func_name not in endpoints[edp_name]:
            endpoints[edp_name].append(func_name)
            endpoints[edp_name].sort()
for k, v in endpoints.items():
    print(f"Interface {k:<30}: {str(len(v)).zfill(2)} functions.")
with open("endpoints.json", mode="w", encoding="utf-8") as f:
    json.dump(endpoints, f, ensure_ascii=False, indent=2)
print("[+] Collection of endpoints functions saved to file 'endpoints.json'.")
