Skip to content
Snippets Groups Projects
mdproxy.py 1.71 KiB
#!/usr/bin/env python
import requests
from lxml import etree as ET
from flask import Flask, Response
from urllib.parse import unquote
from dateutil import parser, tz
from datetime import datetime

from utils import read_config, hasher, Entity

config = read_config('mdproxy.yaml')
app = Flask(__name__)


# Find all IdP's in edugain metadata
cached = {}


@app.route('/<domain>/entities/<path:eid>', methods=['GET'])
def serve(domain, eid):
    entityID = unquote(eid)
    if entityID[:6] == "{sha1}":
        entityID = entityID[6:]
    else:
        entityID = hasher(entityID)

    response = Response()
    response.headers['Content-Type'] = "application/samlmetadata+xml"
    response.headers['Content-Disposition'] = "filename = \"metadata.xml\""

    cached[domain] = cached.get(domain, {})
    if entityID in cached[domain]:
        if cached[domain][entityID].valid_until > datetime.now(tz.tzutc()):
            print(f"serve {entityID}")
            return cached[domain][entityID].md
    else:
        print(f"request {entityID}")
        data = requests.get(f"{config[domain]['signer']}/{domain}/entities/{{sha1}}{entityID}").text
        try:
            parsed = ET.fromstring(data)
            validUntil = parsed.get('validUntil')
            # cacheDuration = parsed.get('cacheDuration')
            cached_entity = Entity()
            cached_entity.md = data
            cached_entity.valid_until = parser.isoparse(validUntil)
            cached[domain][entityID] = cached_entity
        except ET.XMLSyntaxError:
            data = "No valid metadata\n"
            response.headers['Content-type'] = "text/html"
            response.status = 404

        response.data = data
        return response


app.run(host='0.0.0.0', port=80)