import enum from typing import Set, Union import flask class Scope(enum.Enum): EMAIL = "email" NAME = "name" OPENID = "openid" AVATAR_URL = "avatar_url" class ResponseType(enum.Enum): CODE = "code" TOKEN = "token" ID_TOKEN = "id_token" # All the OIDC flows supported by SimpleLogin # CF https://medium.com/@darutk/diagrams-of-all-the-openid-connect-flows-6968e3990660 SUPPORTED_OPENID_FLOWS = [ {ResponseType.CODE}, {ResponseType.TOKEN}, {ResponseType.ID_TOKEN}, {ResponseType.ID_TOKEN, ResponseType.TOKEN}, {ResponseType.ID_TOKEN, ResponseType.CODE}, ] # String form of SUPPORTED_OPENID_FLOWS SUPPORTED_OPENID_FLOWS_STR = "code|token|id_token|id_token,token|id_token,code" def get_scopes(request: flask.Request) -> Set[Scope]: scope_strs = _split_arg(request.args.getlist("scope")) return set([Scope(scope_str) for scope_str in scope_strs]) def get_response_types(request: flask.Request) -> Set[ResponseType]: response_type_strs = _split_arg(request.args.getlist("response_type")) return set([ResponseType(r) for r in response_type_strs if r]) def get_response_types_from_str(response_type_str) -> Set[ResponseType]: response_type_strs = _split_arg(response_type_str) return set([ResponseType(r) for r in response_type_strs if r]) def response_types_to_str(response_types: [ResponseType]) -> str: """return a string representing a list of response type, for ex *code*, *id_token,token*,... """ return ",".join([r.value for r in response_types]) def _split_arg(arg_input: Union[str, list]) -> Set[str]: """convert input response_type/scope into a set of string. arg_input = request.args.getlist(response_type|scope) Take into account different variations and their combinations - the split character is " " or "," - the response_type/scope passed as a list ?scope=scope_1&scope=scope_2 """ res = set() if isinstance(arg_input, str): if " " in arg_input: for x in arg_input.split(" "): if x: res.add(x.lower()) elif "," in arg_input: for x in arg_input.split(","): if x: res.add(x.lower()) else: res.add(arg_input) else: for arg in arg_input: res = res.union(_split_arg(arg)) return res