Source code for pacifica.auth.application

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""Base application module."""
from os import makedirs
from os.path import isdir, join, dirname
import json
import importlib
import cherrypy
from jinja2 import Environment, FileSystemLoader
from sqlalchemy import create_engine
from .satool import SATool
from .saplugin import SAEnginePlugin


[docs]def error_page_default(**kwargs): """Error page when something goes wrong.""" cherrypy.response.headers['Content-Type'] = 'application/json' return bytes(json.dumps(kwargs), 'utf-8')
[docs]def session_commit(): """Commit the user session to the database.""" # pylint: disable=no-member cherrypy.session.save()
[docs]def check_sa_module_class(args): """Check the combination of module and class.""" try: sa_module = importlib.import_module('social_core.backends.{}'.format(args.sa_module)) except ImportError as ex: raise ValueError('Module {} is not a social core backend'.format(args.sa_module)) from ex if not getattr(sa_module, args.sa_class, None): raise ValueError('Social core backend module {} has no class {}'.format(args.sa_module, args.sa_class))
[docs]def check_sa_settings(obj_str): """Verify social auth settings.""" if '=' not in obj_str: raise ValueError('{} must contain the "=" character'.format(obj_str)) parts = obj_str.split('=') return 'SOCIAL_AUTH_{}'.format(parts[0].upper()), parts[1]
[docs]def pacifica_auth_arguments(parser): """Add Pacifica authentication command line arguments.""" parser.add_argument( '--session-dir', dest='session_dir', default='sessions', help='Sesion directory for writing' ) parser.add_argument( '--db-url', dest='engine', type=create_engine, default='sqlite:///database.sqlite3', help='Database url to connect to' ) parser.add_argument( '--social-module', dest='sa_module', type=str, default='github', help='Social Core backend module name' ) parser.add_argument( '--social-class', dest='sa_class', type=str, default='GithubOAuth2', help='Social Core backend auth class' ) parser.add_argument( '--social-setting', dest='sa_settings', type=check_sa_settings, help='Social Core settings', action='append', default=[] ) parser.add_argument( '--app-dir', dest='app_dir', type=str, default='app', help='ReactJS App directory to serve' ) parser.add_argument( '--ssl-private-key', dest='ssl_private_key', type=str, default=None, help='OpenSSL private key file.' ) parser.add_argument( '--ssl-certificate', dest='ssl_certificate', type=str, default=None, help='OpenSSL certificate file.' ) parser.add_argument( '--ssl-certificate-chain', dest='ssl_certificate_chain', type=str, default=None, help='OpenSSL certificate chain file.' )
[docs]def social_settings(args, user_class, user_import_path): """Setup the social settings for pacifica auth.""" def load_user(): """Load the user into the request.""" # pylint: disable=no-member user_id = cherrypy.session.get('user_id') if user_id: cherrypy.request.user = cherrypy.request.db.query(user_class).get(user_id) else: cherrypy.request.user = None cherrypy.config.update({ 'SOCIAL_AUTH_USER_MODEL': user_import_path, 'SOCIAL_AUTH_LOGIN_URL': '/login', 'SOCIAL_AUTH_LOGIN_REDIRECT_URL': '/', 'SOCIAL_AUTH_TRAILING_SLASH': True, 'SOCIAL_AUTH_AUTHENTICATION_BACKENDS': ( 'social_core.backends.{}.{}'.format(args.sa_module, args.sa_class), ) }) for key, value in args.sa_settings: cherrypy.config.update({key: value}) check_sa_module_class(args) SAEnginePlugin(cherrypy.engine, args.engine.url).subscribe() if not isdir(args.session_dir): makedirs(args.session_dir) cherrypy.config.update({ 'tools.sessions.on': True, 'tools.sessions.storage_class': cherrypy.lib.sessions.FileSession, 'tools.sessions.storage_path': args.session_dir, 'tools.sessions.timeout': 60, 'tools.db.on': True, 'tools.authenticate.on': True, }) for ssl_config_key in ['ssl_private_key', 'ssl_certificate', 'ssl_certificate_chain']: if getattr(args, ssl_config_key, False): cherrypy.config.update({'cherrypy.server.{}'.format(ssl_config_key): getattr(args, ssl_config_key)}) cherrypy.tools.jinja2env = Environment( loader=FileSystemLoader(join(dirname(__file__), 'templates')) ) cherrypy.tools.db = SATool() cherrypy.tools.authenticate = cherrypy.Tool('before_handler', load_user) cherrypy.tools.session = cherrypy.Tool('on_end_resource', session_commit)