commit 4dd522697f70a2304d5550bc5b2e6c5621cc6ae4 Author: Nathan Windisch Date: Thu Mar 20 03:58:59 2025 +0000 created uv project structure, added Docker integration, updated README.md with some general info diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..505a3b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Python-generated files +__pycache__/ +*.py[oc] +build/ +dist/ +wheels/ +*.egg-info + +# Virtual environments +.venv diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..e4fba21 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.12 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..bc738bc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.12-slim-bookworm +COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ +ADD . /app +WORKDIR /app +RUN uv sync --frozen +EXPOSE 8000 +CMD ["uv", "run", "fastapi", "dev", "main.py", "--host", "0.0.0.0"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..12cd034 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# autodiscover-proxy + +A simple proxy server used to expose domains associated with a given domain via Microsoft's AutoDiscover.svc. + +## Usage + +Running locally: +```bash +uv run fastapi dev main.py +``` + +Running in Docker: +```bash +docker run -p 8000:8000 -it git.wnd.sh/n/autodiscover-proxy +# or +docker build -t autodiscover-proxy . +docker run -p 8000:8000 -it autodiscover-proxy +``` diff --git a/main.py b/main.py new file mode 100644 index 0000000..bcf36c5 --- /dev/null +++ b/main.py @@ -0,0 +1,50 @@ +from typing import Annotated +from fastapi import FastAPI, Query +from fastapi.responses import JSONResponse +import xml.etree.ElementTree as xml +import requests +import json + +app = FastAPI() + +@app.get("/{domain}") +def read_root( + domain: str, + platform: Annotated[ + str | None, + Query(pattern="^default|gcc|gcc_high$") + ] = "default", +): + + match platform: + case "gcc_high": base_uri = "autodiscover-s.office365.us" + case "gcc": base_uri = "autodiscover-s-dod.office365.us" + case "default": base_uri = "autodiscover-s.outlook.com" + + headers = { "Content-Type": "text/xml; charset=utf-8", "SOAPAction": "http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetFederationInformation" } + uri = f"https://{base_uri}/autodiscover/autodiscover.svc" + data = f""" + + + http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetFederationInformation + {uri} + http://www.w3.org/2005/08/addressing/anonymous + + + + + {domain} + + + + + """ + + response = requests.post(uri, data=data, headers=headers) + if (not response.ok): return { "error": f"Error contacting autodiscover service for {domain}" } + + root = xml.fromstring(response.text) + content = [i.text for i in root[1][0][0][3]] # root/body/GetFederationInformationResponseMessage/Domains + + return JSONResponse(content=content, headers={"Cache-Control": "max-age=604800, public"}) + diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..8c167d2 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,7 @@ +[project] +name = "autodiscover-proxy" +version = "0.1.0" +description = "A simple proxy server used to expose domains associated with a given domain via Microsoft's AutoDiscover.svc." +readme = "README.md" +requires-python = ">=3.12" +dependencies = ['fastapi[standard]', 'requests'] diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..c31020e --- /dev/null +++ b/uv.lock @@ -0,0 +1,7 @@ +version = 1 +requires-python = ">=3.12" + +[[package]] +name = "autodiscover-proxy" +version = "0.1.0" +source = { virtual = "." }