[auth] Use pyramid_multiauth
It makes it easier to finely tune what parts of the default authentication stack
we want to use or not.
It also makes it possible for any cube to add its own policy in addition to the
others.
Related to #4985962
import os
import wsgicors
from cubicweb.cwconfig import CubicWebConfiguration as cwcfg
from pyramid.config import Configurator
from pyramid.settings import asbool, aslist
try:
from configparser import SafeConfigParser
except ImportError:
from ConfigParser import SafeConfigParser
def make_cubicweb_application(cwconfig):
"""
Create a pyramid-based CubicWeb instance from a cubicweb configuration.
It is initialy meant to be used by the 'pyramid' command of cubicweb-ctl.
:param cwconfig: A CubicWeb configuration
:returns: A Pyramid config object
"""
settings_filenames = [os.path.join(cwconfig.apphome, 'pyramid.ini')]
settings = {}
if cwconfig.debugmode:
settings_filenames.insert(
0, os.path.join(cwconfig.apphome, 'pyramid-debug.ini'))
settings.update({
'pyramid.debug_authorization': True,
'pyramid.debug_notfound': True,
'pyramid.debug_routematch': True,
})
for fname in settings_filenames:
if os.path.exists(fname):
cp = SafeConfigParser()
cp.read(fname)
settings.update(cp.items('main'))
break
config = Configurator(settings=settings)
if cwconfig.debugmode:
config.include('pyramid_debugtoolbar')
config.registry['cubicweb.config'] = cwconfig
config.registry['cubicweb.repository'] = repo = cwconfig.repository()
config.registry['cubicweb.registry'] = repo.vreg
if asbool(config.registry.settings.get('cubicweb.defaults', True)):
config.include('pyramid_cubicweb.defaults')
for name in aslist(config.registry.settings.get('cubicweb.includes', [])):
config.include(name)
config.include('pyramid_cubicweb.tools')
config.include('pyramid_cubicweb.core')
if asbool(config.registry.settings.get('cubicweb.bwcompat', True)):
config.include('pyramid_cubicweb.bwcompat')
return config
def wsgi_application_from_cwconfig(
cwconfig,
profile=False, profile_output=None, profile_dump_every=None):
""" Build a WSGI application from a cubicweb configuration
:param cwconfig: A CubicWeb configuration
:param profile: Enable profiling. See :ref:`profiling`.
:param profile_output: Profiling output filename. See :ref:`profiling`.
:param profile_dump_every: Profiling number of requests before dumping the
stats. See :ref:`profiling`.
:returns: A fully operationnal WSGI application
"""
config = make_cubicweb_application(cwconfig)
profile = profile or asbool(config.registry.settings.get(
'cubicweb.profile.enable', False))
if profile:
config.add_route('profile_ping', '_profile/ping')
config.add_route('profile_cnx', '_profile/cnx')
config.scan('pyramid_cubicweb.profile')
app = config.make_wsgi_app()
# This replaces completely web/cors.py, which is not used by
# pyramid_cubicweb anymore
app = wsgicors.CORS(
app,
origin=' '.join(cwconfig['access-control-allow-origin']),
headers=', '.join(cwconfig['access-control-allow-headers']),
methods=', '.join(cwconfig['access-control-allow-methods']),
credentials='true')
if profile:
from pyramid_cubicweb.profile import wsgi_profile
filename = profile_output or config.registry.settings.get(
'cubicweb.profile.output', 'program.prof')
dump_every = profile_dump_every or config.registry.settings.get(
'cubicweb.profile.dump_every', 100)
app = wsgi_profile(app, filename=filename, dump_every=dump_every)
return app
def wsgi_application(instance_name=None, debug=None):
""" Build a WSGI application from a cubicweb instance name
:param instance_name: Name of the cubicweb instance (optional). If not
provided, :envvar:`CW_INSTANCE` must exists.
:param debug: Enable/disable the debug mode. If defined to True or False,
overrides :envvar:`CW_DEBUG`.
The following environment variables are used if they exist:
.. envvar:: CW_INSTANCE
A CubicWeb instance name.
.. envvar:: CW_DEBUG
If defined, the debugmode is enabled.
The function can be used as an entry-point for third-party wsgi containers.
Below is a sample uswgi configuration file:
.. code-block:: ini
[uwsgi]
http = 127.0.1.1:8080
env = CW_INSTANCE=myinstance
env = CW_DEBUG=1
module = pyramid_cubicweb:wsgi_application()
virtualenv = /home/user/.virtualenvs/myvirtualenv
processes = 1
threads = 8
stats = 127.0.0.1:9191
plugins = http,python
"""
if instance_name is None:
instance_name = os.environ.get('CW_INSTANCE')
if debug is None:
debug = 'CW_DEBUG' in os.environ
cwconfig = cwcfg.config_for(instance_name, debugmode=debug)
return wsgi_application_from_cwconfig(cwconfig)