From 72f7d25a69b6ed41a15eef973f9fbb821931c901 Mon Sep 17 00:00:00 2001 From: Mike Crute Date: Tue, 18 Jul 2017 03:35:52 +0000 Subject: Initial import --- server.py | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 server.py (limited to 'server.py') diff --git a/server.py b/server.py new file mode 100644 index 0000000..0bebe2a --- /dev/null +++ b/server.py @@ -0,0 +1,87 @@ +import flask +import urllib.parse +from flask import request + + +# Application Config +OIDC_ISSUER = "https://id.crute.me/" +OIDC_AUTH_ENDPOINT = "{}login".format(OIDC_ISSUER) +OIDC_JWKS_ENDPOINT = "{}jwks".format(OIDC_ISSUER) +DOMAIN_WHITELIST = ["crute.me", "crute.us"] + + +# Generic Constants +JRD_MIMETYPE = "application/jrd+json" +OIDC_ISSUER_QUERY = "http://openid.net/specs/connect/1.0/issuer" +JRD_404 = flask.Response("Not found", status=404, mimetype=JRD_MIMETYPE) + + +app = flask.Flask(__name__) + + +def parse_email_addr(addr): + try: + user, domain = addr.split("@") + return user, domain + except ValueError: + return None + + +@app.route("/.well-known/webfinger", methods=["GET"]) +def webfinger(): + resource = request.args.get("resource") + rel = request.args.get("rel") + + # Only support OIDC queries + if not rel or not resource or not rel == OIDC_ISSUER_QUERY: + return JRD_404 + + # Only support email address queries + acct = urllib.parse.urlparse(resource) + if acct.scheme != "acct": + return JRD_404 + + # Ensure that the query is in a whitelisted domain + _, domain = parse_email_addr(acct.path) + if domain not in DOMAIN_WHITELIST: + return JRD_404 + + # We don't validate that the user exists to prevent leaking information + # about what users exist; plus, it doesn't really matter since the querier + # only cares about the OIDC issuer endpoint which is user independent + res = flask.jsonify({ + "subject": resource, + "links": [{ + "rel": OIDC_ISSUER_QUERY, + "href": OIDC_ISSUER, + }] + }) + res.mimetype = JRD_MIMETYPE + return res + + + +@app.route("/.well-known/openid-configuration", methods=["GET"]) +def openid_configuration(): + return flask.jsonify({ + "issuer": OIDC_ISSUER, + "authorization_endpoint": OIDC_AUTH_ENDPOINT, + "jwks_uri": OIDC_JWKS_ENDPOINT, + "scopes_supported": ["openid"], + "response_types_supported": ["id_token"], + "response_modes_supported": ["query"], + "grant_types_supported": ["implicit"], + "subject_types_supported": ["public"], + "id_token_signing_alg_values_supported": ["RS256"], + "acr_values_supported": ["want_mfa", "need_mfa"], + }) + + +@app.route("/login", methods=["GET", "POST"]) +def login(): + pass + + +@app.route("/jwks", methods=["GET"]) +def keys(): + pass -- cgit v1.2.3