Source code for oauthsub.configuration


import base64
import inspect
import logging
import os
import sys

logger = logging.getLogger("oauthsub")


[docs]def default_user_lookup(_, parsed_content): # pylint: disable=W0613 """ Default username resolution just returns the email address reported by the provider. """ return parsed_content.get("email")
[docs]def get_default(obj, default): """ If obj is not `None` then return it. Otherwise return default. """ if obj is None: return default return obj
[docs]class Configuration(object): """ Simple configuration object. Holds named members for different configuration options. Can be serialized to a dictionary which would be a valid kwargs for the constructor. """ # pylint: disable=too-many-arguments # pylint: disable=too-many-instance-attributes def __init__(self, rooturl=None, flask_debug=False, flask_privkey=None, response_header=None, allowed_domains=None, host=None, port=None, logdir=None, flaskopt=None, route_prefix=None, session_key_prefix=None, bypass_key=None, user_lookup=None, client_secrets=None, custom_template=None, enable_forbidden=True, server=None, **kwargs): self.rooturl = get_default(rooturl, 'http://localhost') self.flask_debug = flask_debug random_key = base64.b64encode(os.urandom(24)).decode("utf-8") self.flask_privkey = get_default(flask_privkey, random_key) self.response_header = response_header self.allowed_domains = get_default(allowed_domains, ['gmail.com']) self.host = get_default(host, '0.0.0.0') self.port = get_default(port, 8081) self.logdir = get_default(logdir, '/tmp/oauthsub/logs') self.flaskopt = get_default(flaskopt, { 'SESSION_TYPE': 'filesystem', 'SESSION_FILE_DIR': '/tmp/oauthsub/session_data', 'PERMANENT_SESSION_LIFETIME': 864000 }) self.route_prefix = get_default(route_prefix, '/auth') self.session_key_prefix = get_default(session_key_prefix, 'oauthsub-') self.bypass_key = bypass_key self.user_lookup = get_default(user_lookup, default_user_lookup) self.client_secrets = get_default(client_secrets, {}) self.custom_template = custom_template self.enable_forbidden = enable_forbidden self.server = get_default(server, "flask") extra_opts = [] for key, kwargval in kwargs.items(): if key.startswith('_'): continue if inspect.ismodule(kwargval): continue extra_opts.append(key) if extra_opts: logger.warning("Ignoring extra configuration options:\n %s", "\n ".join(extra_opts))
[docs] @classmethod def get_fields(cls): """ Return a list of field names in constructor order. """ # NOTE(josh): args[0] is `self` if sys.version_info < (3, 5, 0): # pylint: disable=W1505 return inspect.getargspec(cls.__init__).args[1:] sig = getattr(inspect, 'signature')(cls.__init__) return [field for field, _ in list(sig.parameters.items())[1:-1] if field not in ["user_lookup"]]
[docs] def serialize(self): """ Return a dictionary describing the configuration. """ return {field: getattr(self, field) for field in self.get_fields()}
VARDOCS = { "rooturl": "The root URL for browser redirects", "flask_debug": "Enable flask debugging for testing", "flask_privkey": "Secret key used to sign cookies", "response_header": ( "If specified, the authenticated user's ``username`` " "will be passed as a response header with this key."), "allowed_domains": ( "List of domains that we allow in the `hd` field of the" "google response. Set this to your company gsuite " "domains."), "host": "The address to listening on", "port": "The port to listen on", "logdir": "Directory where we store resource files", "flaskopt": "Flask configuration options. Set session config here.", "route_prefix": "All flask routes (endpoints) are prefixed with this", "session_key_prefix": "All session keys are prefixed with this", "bypass_key": ( "Secret string which can be used to bypass authorization" " if provided in an HTTP header `X-OAuthSub-Bypass`"), "client_secrets": ( "Dictionary mapping oauth privider names to the client" " secrets for that provider."), "custom_template": "Path to custom jinja template", "enable_forbidden": ( "If true, enables the /forbidden endpoint, to which you can redirect" " 401 errors from your reverse proxy. This page is a simple message " " with active template but includes login links that will redirect back" " to the forbidden page after a successful auth."), "server": ( "Which WGSI server to use (flask, gevent, twisted)" ) }