Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introspectable configuration #47

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions docs/architecture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ be used individually for the authentication style desired.
Provider HTML Examples
======================

Every authentication provider that is available comes with a basic HTML
example illustrating the parameters it requires. The template generally
Every authentication provider that is available comes with a basic HTML
example illustrating the parameters it requires. The template generally
includes a logo when its a third party :term:`identity provider` to help
a website user find the preferred authentication option.

.. note::

While most websites will redirect to Velruse to handle the authentication
for a user to login or register, the authentication can be done anytime
for 'linking' an account to another provider as well.
Expand Down Expand Up @@ -47,6 +47,13 @@ Auth Provider's are usually setup under the :class:`~velruse.app.VelruseApp`
WSGI app, which is a minimal WSGI application that can dispatch to several
configured Auth Provider's based on a YAML configuration file.

Velruse webservices
=====================

velruse has some webservices to be queried to know its actual set of providers:

- /auth_providers_list : JSON mapping of providers and their relative login & process urls


UserStore Backends
==================
Expand Down
25 changes: 22 additions & 3 deletions docs/providers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,25 @@ Authentication Providers supply varying levels of information when
authentication has occurred. Some of them can also provide API access
tokens in addition to authenticating a user for sign-on.

Configuration hook
===================
You can integrate a python callable at the velruse initialization to configure dynamicly the providers.
For thus, make a toto python module containing your configuration stuff, for example ::


toto.py:
def cfg(config):
settings = config.registry.settings
settings['velruse.providers']='velruse.providers.foo'
settings['velruse.providers.foo.id'] = 'foo'
settings['velruse.providers.foo.secret'] = 'bar'


In velruse deployment config, add::

velruse.providers_hook = toto.callable


Facebook
========

Expand Down Expand Up @@ -332,7 +351,7 @@ Policy URL
Site's Privacy Policy URL, overrides the url specified during registration
of your application with Live Services.
Return URL
Site's Return URL, overrides the url specified during registration of
Site's Return URL, overrides the url specified during registration of
your application with Live Services. This is not *YOUR* applicaton's end
point! This should only be overriden if your registration url is not
the velruse url. For example http://YOURDOMAIN.COM/velruse/live/process.
Expand All @@ -347,7 +366,7 @@ POST Parameters
Complete Example:

.. code-block:: html
<form action="/velruse/live/login" method="post">

<form action="/velruse/live/auth" method="post">
<input type="submit" value="Login with Windows Live" />
</form>
67 changes: 65 additions & 2 deletions velruse/app.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import copy
import logging
import os
import re

from pyramid.config import Configurator
from pyramid.exceptions import ConfigurationError
Expand All @@ -13,6 +15,34 @@

log = logging.getLogger(__name__)

re_flags = re.U|re.X|re.S

def auth_providers_list(request):
"""Return a JSON mapping of the velruse offered providers.
This is to be used inside velruse front ends:
Something like ::

{
'velruse.providers.github': {
'login' : 'http://velrusehost/velruse/github/login',
'process' : 'http://velrusehost/velruse/github/process',
},
}


"""
settings = request.registry.settings
ifs = copy.deepcopy(
settings['velruse.providers_infos']
)
url_keys = ['login', 'process']
for item in ifs:
for key in ifs[item]:
for pattern in url_keys:
if re.compile(pattern, re_flags).search(key):
ifs[item][pattern] = request.route_url(ifs[item][key])
return ifs


@view_config(context='velruse.api.AuthenticationComplete')
def auth_complete_view(context, request):
Expand Down Expand Up @@ -69,6 +99,36 @@ def default_setup(config):
factory = UnencryptedCookieSessionFactoryConfig(secret)
config.set_session_factory(factory)

def providers_lookup(config):
"""Lookup for the providers to activate
Can be overridden by settings
velruse.providers_lookup = mymodule.hook
This can be useful for example if your authentication information
is stored on a relational database.
EG:
toto.py:
def cfg(config):
settings = config.registry.settings
settings['velruse.providers']='velruse.providers.foo'
settings['velruse.providers.foo.id'] = 'foo'
settings['velruse.providers.foo.secret'] = 'bar'

and in velruse deployment config:

velruse.providers_hook = toto.cfg
"""
settings = config.registry.settings
providers_hook = settings.get('velruse.providers_hook', '')
if providers_hook:
providers_hook = config.maybe_dotted(providers_hook)
providers_hook(config)
providers = []
for a in splitlines(
settings.get('velruse.providers', '')
):
providers.append(a)
settings['velruse.providers_infos'][a] = {}
return providers

def includeme(config, do_setup=True):
"""Configuration function to make a pyramid app a velruse one."""
Expand All @@ -94,14 +154,17 @@ def includeme(config, do_setup=True):
config.include(store)

# include providers
providers = settings.get('velruse.providers', '')
providers = splitlines(providers)
if not 'velruse.providers_infos' in settings:
settings['velruse.providers_infos'] = {}
providers = providers_lookup(config)

for provider in providers:
config.include(provider)

# add the error views
config.scan(__name__)
config.add_route("auth_providers_list", "/auth_providers_list")
config.add_view(auth_providers_list, route_name="auth_providers_list", renderer='json')

def make_app(**settings):
config = Configurator(settings=settings)
Expand Down