Пример #1
0
def make_app(controller_klass, environ={}):
    """Creates a ``TestApp`` instance."""
    # The basic middleware:
    app = ControllerWrap(controller_klass)
    app = SetupCacheGlobal(app, environ, setup_cache=True, setup_session=True)
    app = RegistryManager(app)
    app = SessionMiddleware(app, {}, data_dir=session_dir)
    app = CacheMiddleware(app, {}, data_dir=os.path.join(data_dir, 'cache'))

    # We're not going to use groups or permissions-related predicates here:
    groups_adapters = None
    permissions_adapters = None

    # Setting repoze.who up:
    cookie = AuthTktCookiePlugin('secret', 'authtkt')
    identifiers = [('cookie', cookie)]

    app = setup_auth(app,
                     groups_adapters,
                     permissions_adapters,
                     identifiers=identifiers,
                     authenticators=[],
                     challengers=[],
                     skip_authentication=True)

    app = httpexceptions.make_middleware(app)
    return TestApp(app)
Пример #2
0
    def make_auth_app(global_conf, **app_conf):
        """example authenticated app with an htpasswd file"""

        assert 'auth.htpasswd' in app_conf
        assert os.path.exists(app_conf['auth.htpasswd'])

        app_conf['traclegos.auth'] = True

        # make the app
        app = make_app(global_conf, **app_conf)

        # wrap in repoze.who authentication middleware
        htpasswd_auth = HTPasswdPlugin(app_conf['auth.htpasswd'], check)
        auth_tkt = AuthTktCookiePlugin('secret', 'auth_tkt')
        form = RedirectingFormPlugin('/', '/login', '/logout', 'auth_tkt')
        identifiers = [('form', form), ('auth_tkt', auth_tkt)]
        authenticators = [('htpasswd_auth', htpasswd_auth)]
        challengers = [('form', form)]

        from repoze.who.classifiers import default_request_classifier
        from repoze.who.classifiers import default_challenge_decider
        log_stream = None

        return PluggableAuthenticationMiddleware(app,
                                                 identifiers,
                                                 authenticators,
                                                 challengers, [],
                                                 default_request_classifier,
                                                 default_challenge_decider,
                                                 log_stream=None,
                                                 log_level=logging.DEBUG)
Пример #3
0
def make_app(controller_klass,
             environ=None,
             with_errors=False,
             config_options=None):
    """Creates a ``TestApp`` instance."""
    authmetadata = TestAuthMetadata()

    config_options = config_options or {}
    config_options.setdefault('sa_auth', {})

    sa_auth = config_options['sa_auth']
    sa_auth.update({'authmetadata': authmetadata})

    app = base_make_app(controller_klass, environ or {}, config_options,
                        with_errors).app

    # Setting repoze.who up:
    from repoze.who.plugins.auth_tkt import AuthTktCookiePlugin
    cookie = AuthTktCookiePlugin('secret', 'authtkt')
    identifiers = [('cookie', cookie)]

    app = setup_auth(app,
                     identifiers=identifiers,
                     skip_authentication=True,
                     authenticators=[],
                     challengers=[])

    # As setup_auth with skip_authentication sets empty authenticators always
    # we must manually append it after creating the middleware.
    app.api_factory.authenticators.append(('cookie', cookie))

    return TestApp(app)
Пример #4
0
    def _makeApp(self, groups, permissions, **who_args):
        cookie = AuthTktCookiePlugin('secret', 'authtkt')

        form = RedirectingFormPlugin('/login',
                                     '/login_handler',
                                     '/logout_handler',
                                     rememberer_name='cookie')

        identifiers = [('main_identifier', form), ('cookie', cookie)]

        authenticators = [('fake_authenticator', FakeAuthenticator())]

        challengers = [('form', form)]

        if groups is None:
            app_with_auth = setup_auth(DummyApp(),
                                       identifiers=identifiers,
                                       authenticators=authenticators,
                                       challengers=challengers,
                                       **who_args)
        else:
            app_with_auth = setup_auth(DummyApp(),
                                       groups,
                                       permissions,
                                       identifiers=identifiers,
                                       authenticators=authenticators,
                                       challengers=challengers,
                                       **who_args)
        return app_with_auth
Пример #5
0
def make_app(controller_klass, environ={}, with_errors=False):
    """Creates a ``TestApp`` instance."""
    # The basic middleware:
    app = TGApp(config=default_config)
    app.controller_classes['root'] = ControllerWrap(controller_klass)

    app = FakeRoutes(app)
    
    if with_errors:
        app = ErrorHandler(app, {}, debug=False)
        app = StatusCodeRedirect(app, [403, 404, 500])
    app = RegistryManager(app)
    app = SessionMiddleware(app, {}, data_dir=session_dir)
    app = CacheMiddleware(app, {}, data_dir=os.path.join(data_dir, 'cache'))

    # Setting repoze.who up:
    from repoze.who.plugins.auth_tkt import AuthTktCookiePlugin
    cookie = AuthTktCookiePlugin('secret', 'authtkt')
    identifiers = [('cookie', cookie)]

    app = setup_auth(app, TGAuthMetadata(),
                     identifiers=identifiers, skip_authentication=True,
                     authenticators=[], challengers=[])

    return TestApp(app)
Пример #6
0
 def test_skip_authentication_is_not_boolean(self):
     identifiers = [('cookie', AuthTktCookiePlugin('something'))]
     authenticators = challengers = mdproviders = []
     # Skipping authentication:
     mw = make_middleware('True', None, identifiers, authenticators,
                          challengers, mdproviders, None, None)
     self.assertEqual(mw.__class__, AuthenticationForgerMiddleware)
     # With authentication:
     mw = make_middleware('False', None, identifiers, authenticators,
                          challengers, mdproviders, None, None)
     self.assertEqual(mw.__class__, PluggableAuthenticationMiddleware)
     # With skip_authentication==None -> authentication enabled:
     mw = make_middleware(None, None, identifiers, authenticators,
                          challengers, mdproviders, None, None)
     self.assertEqual(mw.__class__, PluggableAuthenticationMiddleware)
Пример #7
0
 def test_without_skipping_authentication(self):
     identifiers = [('cookie', AuthTktCookiePlugin('something'))]
     authenticators = challengers = mdproviders = []
     mw = make_middleware(False, None, identifiers, authenticators,
                          challengers, mdproviders, None, None)
     assert isinstance(mw, PluggableAuthenticationMiddleware)
     # Checking the identifiers:
     final_identifiers = mw.registry[IIdentifier]
     self.assertEqual(1, len(final_identifiers))
     assert isinstance(final_identifiers[0], AuthTktCookiePlugin)
     # Checking the other plugins:
     assert IAuthenticator not in mw.registry
     assert IChallenger not in mw.registry
     assert IMetadataProvider not in mw.registry
     # Checking REMOTE_USER keys:
     self.assertEqual(mw.remote_user_key, 'REMOTE_USER')
Пример #8
0
 def test_it_with_fake_user_key(self):
     identifiers = [('cookie', AuthTktCookiePlugin('something'))]
     authenticators = challengers = mdproviders = []
     mw = AuthenticationForgerMiddleware(None, identifiers, authenticators,
                                         challengers, mdproviders, None,
                                         None,
                                         remote_user_key='userid')
     assert isinstance(mw, AuthenticationForgerMiddleware)
     final_identifiers = mw.registry[IIdentifier]
     auth_forger = final_identifiers[0]
     # Checking REMOTE_USER keys:
     self.assertEqual(mw.remote_user_key, 'repoze.who.testutil.userid')
     self.assertEqual(mw.actual_remote_user_key, 'userid')
     # Finally, let's check the AuthenticationForgerPlugin in detail:
     self.assertEqual(auth_forger.fake_user_key, 'userid')
     self.assertEqual(auth_forger.remote_user_key,
                      'repoze.who.testutil.userid')
Пример #9
0
def AuthBasicMiddleware(app, conf, user_class):
    groups = GroupAdapter(user_class)
    groups = {'all_groups': groups}
    permissions = {'all_perms': PermissionAdapter(conf["couchdb.db"])}

    basicauth = BasicAuth()
    cookie = AuthTktCookiePlugin(conf['cookies.secret'])

    who_args = {}
    who_args['authenticators'] = [('accounts', Authenticator(user_class))]
    who_args['challengers'] = [('basicauth', basicauth)]
    who_args['identifiers'] = [('basicauth', basicauth), ('cookie', cookie)]
    who_args['mdproviders'] = [('accounts', MDPlugin(user_class))]
    who_args['log_stream'] = sys.stdout
    who_args['log_level'] = logging.DEBUG

    return setup_auth(app, groups, permissions, **who_args)
Пример #10
0
    def make_ldap_auth_app(global_conf, **app_conf):
        """example authenticated app with ldap"""

        assert 'auth.base_dn' in app_conf, "No base_dn specified"
        assert 'auth.ldap_host' in app_conf, "No ldap_host specified"

        app_conf['traclegos.auth'] = True

        # make the app
        app = make_app(global_conf, **app_conf)

        # XXX bad touch
        # this should really be passed to the make_app factory and used there
        # but there's no current way of doing this intelligently
        app.application.remote_user_name = ldap_remote_user

        # get the ldap connection
        conn = ldap.open(app_conf['auth.ldap_host'])
        if app_conf.get('auth.use_tls', 'False').lower() == 'true':
            conn.start_tls_s()

        # wrap in repoze.who authentication middleware
        ldap_auth = LDAPAuthenticatorPlugin(conn, app_conf['auth.base_dn'])
        auth_tkt = AuthTktCookiePlugin('secret', 'auth_tkt')
        form = RedirectingFormPlugin('/', '/login', '/logout', 'auth_tkt')
        identifiers = [('form', form), ('auth_tkt', auth_tkt)]
        authenticators = [('ldap_auth', ldap_auth)]
        challengers = [('form', form)]

        from repoze.who.classifiers import default_request_classifier
        from repoze.who.classifiers import default_challenge_decider
        log_stream = None

        #import logging
        #logger = logging.getLogger('something')
        #logger.setLevel(logging.DEBUG)
        return PluggableAuthenticationMiddleware(app,
                                                 identifiers,
                                                 authenticators,
                                                 challengers, [],
                                                 default_request_classifier,
                                                 default_challenge_decider,
                                                 log_stream=None,
                                                 log_level=logging.DEBUG)
Пример #11
0
def make_app(controller_klass, environ={}, with_errors=False):
    """Creates a ``TestApp`` instance."""
    # The basic middleware:
    app = ControllerWrap(controller_klass)
    app = SetupCacheGlobal(app, environ, setup_cache=True, setup_session=True)
    if with_errors:
        app = ErrorHandler(app, {}, debug=False)
        app = StatusCodeRedirect(app, [403, 404, 500])
    app = RegistryManager(app)
    app = SessionMiddleware(app, {}, data_dir=session_dir)
    app = CacheMiddleware(app, {}, data_dir=os.path.join(data_dir, 'cache'))

    # Setting repoze.who up:
    cookie = AuthTktCookiePlugin('secret', 'authtkt')
    identifiers = [('cookie', cookie)]

    app = setup_auth(app, TGAuthMetadata(),
                     identifiers=identifiers, skip_authentication=True,
                     authenticators=[], challengers=[])

    app = httpexceptions.make_middleware(app)
    return TestApp(app)
Пример #12
0
def make_app(controller_klass, environ=None, with_errors=False, config_options=None):
    """Creates a ``TestApp`` instance."""

    # Setting repoze.who up:
    from repoze.who.plugins.auth_tkt import AuthTktCookiePlugin
    cookie = AuthTktCookiePlugin('secret', 'authtkt')

    from tg.configurator.base import ConfigurationComponent
    class ForceAuthenticatorComponent(ConfigurationComponent):
        id = "test_force_auth"

        def get_actions(self):
            from tg.configurator.base import AppReadyConfigurationAction
            return (
                AppReadyConfigurationAction(self._add_middleware),
            )

        def _add_middleware(self, conf, app):
            # As setup_auth with skip_authentication sets empty authenticators always
            # we must manually append it after creating the middleware.
            app.api_factory.authenticators.append(('cookie', cookie))
            return app

    config_options = config_options or {}
    config_options.setdefault('sa_auth', {})
    sa_auth = config_options['sa_auth']
    sa_auth.update({
        'authmetadata': TestAuthMetadata(),
        'challengers': [],
        'identifiers': [('cookie', cookie)],
        'form_identifies': True
    })

    config_options['skip_authentication'] = True
    config_options['auth_backend'] = 'sqlalchemy'
    conf = base_make_app(controller_klass, with_errors=with_errors, config_options=config_options,
                         make_app=False)
    conf._configurator.register(ForceAuthenticatorComponent, after='sa_auth')
    return TestApp(conf.make_wsgi_app())
Пример #13
0
def AuthenticationMiddleware(app):
    import isitopen.model as model
    import isitopen.lib.helpers as h
    modelpassword = ModelPasswordPlugin(model)
    basicauth = BasicAuthPlugin('repoze.who')
    auth_tkt = AuthTktCookiePlugin('secret', 'auth_tkt')
    form = RedirectingFormPlugin(
        login_form_url=h.url_for(controller='account', action='login'),
        login_handler_path=h.url_for('login-handler'),
        logout_handler_path=h.url_for('logout-handler'),
        rememberer_name='auth_tkt',
    )

    form.classifications = { IIdentifier:['browser'],
                             IChallenger:['browser'] } # only for browser
    identifiers = [('form', form),('auth_tkt',auth_tkt),('basicauth',basicauth)]
    authenticators = [('modelpassword', modelpassword)]
    challengers = [('form',form), ('basicauth',basicauth)]
    mdproviders = []

    from repoze.who.classifiers import default_request_classifier
    from repoze.who.classifiers import default_challenge_decider
    log_stream = None
    import os
    if os.environ.get('WHO_LOG'):
        log_stream = sys.stdout

    return PluggableAuthenticationMiddleware(
        app,
        identifiers,
        authenticators,
        challengers,
        mdproviders,
        default_request_classifier,
        default_challenge_decider,
        log_stream = log_stream,
        log_level = logging.DEBUG
    )
Пример #14
0
 def test_skipping_authentication(self):
     identifiers = [('cookie', AuthTktCookiePlugin('something'))]
     authenticators = challengers = mdproviders = []
     mw = make_middleware(True, None, identifiers, authenticators,
                          challengers, mdproviders, None, None)
     assert isinstance(mw, AuthenticationForgerMiddleware)
     # Checking the identifiers:
     final_identifiers = mw.registry[IIdentifier]
     self.assertEqual(2, len(final_identifiers))
     assert isinstance(final_identifiers[0], AuthenticationForgerPlugin)
     assert isinstance(final_identifiers[1], AuthTktCookiePlugin)
     # Checking the other plugins:
     auth_forger = final_identifiers[0]
     self.assertEqual([auth_forger], mw.registry[IAuthenticator])
     self.assertEqual([auth_forger], mw.registry[IChallenger])
     assert IMetadataProvider not in mw.registry
     # Checking REMOTE_USER keys:
     self.assertEqual(mw.remote_user_key, 'repoze.who.testutil.userid')
     self.assertEqual(mw.actual_remote_user_key, 'REMOTE_USER')
     # Finally, let's check the AuthenticationForgerPlugin in detail:
     self.assertEqual(auth_forger.fake_user_key, 'REMOTE_USER')
     self.assertEqual(auth_forger.remote_user_key,
                      'repoze.who.testutil.userid')
Пример #15
0
def make_app(controller_klass, environ={}):
    """Creates a `TestApp` instance."""

    app = ControllerWrap(controller_klass)
    app = SetupCacheGlobal(app, environ, setup_cache=True, setup_session=True)
    app = RegistryManager(app)
    app = SessionMiddleware(app, {}, data_dir=session_dir)
    app = CacheMiddleware(app, {}, data_dir=os.path.join(data_dir, 'cache'))

    # Setting up the source adapters:
    groups_adapters = {'my_groups': FakeGroupSourceAdapter()}
    permissions_adapters = {'my_permissions': FakePermissionSourceAdapter()}
    
    # Setting up repoze.who:
    cookie = AuthTktCookiePlugin('secret', 'authtkt')
    
    identifiers = [('cookie', cookie)]
    app = setup_auth(app, groups_adapters, permissions_adapters, 
                     identifiers=identifiers, authenticators=[],
                     challengers=[], skip_authentication=True)

    app = httpexceptions.make_middleware(app)
    return TestApp(app)
Пример #16
0
def setup_sql_auth(app,
                   user_class,
                   group_class,
                   permission_class,
                   dbsession,
                   form_plugin=None,
                   form_identifies=True,
                   cookie_secret='secret',
                   cookie_name='authtkt',
                   login_url='/login',
                   login_handler='/login_handler',
                   post_login_url=None,
                   logout_handler='/logout_handler',
                   post_logout_url=None,
                   login_counter_name=None,
                   translations={},
                   **who_args):
    """
    Configure :mod:`repoze.who` and :mod:`repoze.what` with SQL-only 
    authentication and authorization, respectively.
    
    :param app: Your WSGI application.
    :param user_class: The SQLAlchemy/Elixir class for the users.
    :param group_class: The SQLAlchemy/Elixir class for the groups.
    :param permission_class: The SQLAlchemy/Elixir class for the permissions.
    :param dbsession: The SQLAlchemy/Elixir session.
    :param form_plugin: The main :mod:`repoze.who` challenger plugin; this is 
        usually a login form.
    :param form_identifies: Whether the ``form_plugin`` may and should act as
        an :mod:`repoze.who` identifier.
    :type form_identifies: bool
    :param cookie_secret: The "secret" for the AuthTktCookiePlugin.
    :type cookie_secret: str
    :param cookie_name: The name for the AuthTktCookiePlugin.
    :type cookie_name: str
    :param login_url: The URL where the login form is displayed.
    :type login_url: str
    :param login_handler: The URL where the login form is submitted.
    :type login_handler: str
    :param post_login_url: The URL/path where users should be redirected to
        after login.
    :type post_login_url: str
    :param logout_handler: The URL where the logout is handled.
    :type login_handler: str
    :param post_logout_url: The URL/path where users should be redirected to
        after logout.
    :type post_logout_url: str
    :param login_counter_name: The name of the variable in the query string
        that represents the login counter; defaults to ``__logins``.
    :type login_counter_name: str
    :param translations: The model translations.
    :type translations: dict
    :return: The WSGI application with authentication and authorization
        middleware.
    
    It configures :mod:`repoze.who` with the following plugins:
    
    * Identifiers:
    
      * :class:`repoze.who.plugins.friendlyform.FriendlyFormPlugin` as the 
        first identifier and challenger -- using ``login`` as the URL/path 
        where the login form will be displayed, ``login_handler`` as the 
        URL/path where the form will be sent and ``logout_handler`` as the 
        URL/path where the user will be logged out. The so-called *rememberer* 
        of such an identifier will be the identifier below.
        
        If ``post_login_url`` is defined, the user will be redirected to that
        page after login. Likewise, if ``post_logout_url`` is defined, the
        user will be redirected to that page after logout.
        
        You can override the 
        :class:`repoze.who.plugins.friendlyform.FriendlyFormPlugin`'s login 
        counter variable name (which defaults to ``__logins``) by defining
        ``login_counter_name``.
        
        .. tip::
        
            This plugin may be overridden with the ``form_plugin`` argument. 
            See also the ``form_identifies`` argument.
      * :class:`repoze.who.plugins.auth_tkt.AuthTktCookiePlugin`. You can
        customize the cookie name and secret using the ``cookie_name`` and
        ``cookie_secret`` arguments, respectively.
      
      Then it will append the identifiers you pass through the ``identifiers``
      keyword argument, if any.
    
    * Authenticators:
    
      * :class:`repoze.who.plugins.sa.SQLAlchemyAuthenticatorPlugin`, using
        the ``user_class`` and ``dbsession`` arguments as its user class and
        DB session, respectively.
      
      Then it will append the authenticators you pass through the 
      ``authenticators`` keyword argument, if any.
    
    * Challengers:
    
      * The same Form-based plugin used in the identifiers.
      
      Then it will append the challengers you pass through the 
      ``challengers`` keyword argument, if any.
    
    * Metadata providers:
    
      * :class:`repoze.who.plugins.sa.SQLAlchemyUserMDPlugin`, using
        the ``user_class`` and ``dbsession`` arguments as its user class and
        DB session, respectively.
      
      Then it will append the metadata providers you pass through the 
      ``mdproviders`` keyword argument, if any.
    
    Additional keyword arguments will be passed to 
    :class:`repoze.who.middleware.PluggableAuthenticationMiddleware`.
    
    .. note::
    
        If you don't want to use the groups/permissions-based authorization
        pattern, then set ``group_class`` and ``permission_class`` to ``None``.
    
    """
    plugin_translations = find_plugin_translations(translations)

    if group_class is None or permission_class is None:
        group_adapters = permission_adapters = None
    else:
        source_adapters = configure_sql_adapters(
            user_class, group_class, permission_class, dbsession,
            plugin_translations['group_adapter'],
            plugin_translations['permission_adapter'])
        group_adapters = {'sql_auth': source_adapters['group']}
        permission_adapters = {'sql_auth': source_adapters['permission']}

    # Setting the repoze.who authenticators:
    sqlauth = SQLAlchemyAuthenticatorPlugin(user_class, dbsession)
    sqlauth.translations.update(plugin_translations['authenticator'])
    if 'authenticators' not in who_args:
        who_args['authenticators'] = []
    who_args['authenticators'].append(('sqlauth', sqlauth))

    cookie = AuthTktCookiePlugin(cookie_secret, cookie_name)

    # Setting the repoze.who identifiers
    if 'identifiers' not in who_args:
        who_args['identifiers'] = []
    who_args['identifiers'].append(('cookie', cookie))

    if form_plugin is None:
        form = FriendlyFormPlugin(login_url,
                                  login_handler,
                                  post_login_url,
                                  logout_handler,
                                  post_logout_url,
                                  login_counter_name=login_counter_name,
                                  rememberer_name='cookie')
    else:
        form = form_plugin

    if form_identifies:
        who_args['identifiers'].insert(0, ('main_identifier', form))

    # Setting the repoze.who challengers:
    if 'challengers' not in who_args:
        who_args['challengers'] = []
    who_args['challengers'].append(('form', form))

    # Setting up the repoze.who mdproviders:
    sql_user_md = SQLAlchemyUserMDPlugin(user_class, dbsession)
    sql_user_md.translations.update(plugin_translations['mdprovider'])
    if 'mdproviders' not in who_args:
        who_args['mdproviders'] = []
    who_args['mdproviders'].append(('sql_user_md', sql_user_md))

    middleware = setup_auth(app, group_adapters, permission_adapters,
                            **who_args)
    return middleware
Пример #17
0
def make_test_middleware(app, global_conf):
    """ Functionally equivalent to

    [plugin:redirector]
    use = repoze.who.plugins.redirector.RedirectorPlugin
    login_url = /login.html

    [plugin:auth_tkt]
    use = repoze.who.plugins.auth_tkt:AuthTktCookiePlugin
    secret = SEEKRIT
    cookie_name = oatmeal

    [plugin:basicauth]
    use = repoze.who.plugins.basicauth.BasicAuthPlugin
    realm = repoze.who

    [plugin:htpasswd]
    use = repoze.who.plugins.htpasswd.HTPasswdPlugin
    filename = <...>
    check_fn = repoze.who.plugins.htpasswd:crypt_check

    [general]
    request_classifier = repoze.who.classifiers:default_request_classifier
    challenge_decider = repoze.who.classifiers:default_challenge_decider

    [identifiers]
    plugins = authtkt basicauth

    [authenticators]
    plugins = authtkt htpasswd

    [challengers]
    plugins = redirector:browser basicauth
    """
    # be able to test without a config file
    from repoze.who.plugins.basicauth import BasicAuthPlugin
    from repoze.who.plugins.auth_tkt import AuthTktCookiePlugin
    from repoze.who.plugins.redirector import RedirectorPlugin
    from repoze.who.plugins.htpasswd import HTPasswdPlugin
    io = StringIO()
    for name, password in [('admin', 'admin'), ('chris', 'chris')]:
        io.write('%s:%s\n' % (name, password))
    io.seek(0)

    def cleartext_check(password, hashed):
        return password == hashed  #pragma NO COVERAGE

    htpasswd = HTPasswdPlugin(io, cleartext_check)
    basicauth = BasicAuthPlugin('repoze.who')
    auth_tkt = AuthTktCookiePlugin('secret', 'auth_tkt')
    redirector = RedirectorPlugin('/login.html')
    redirector.classifications = {IChallenger: ['browser']}  # only for browser
    identifiers = [
        ('auth_tkt', auth_tkt),
        ('basicauth', basicauth),
    ]
    authenticators = [('htpasswd', htpasswd)]
    challengers = [('redirector', redirector), ('basicauth', basicauth)]
    mdproviders = []
    from repoze.who.classifiers import default_request_classifier
    from repoze.who.classifiers import default_challenge_decider
    log_stream = None
    import os
    if os.environ.get('WHO_LOG'):
        log_stream = sys.stdout
    middleware = PluggableAuthenticationMiddleware(app,
                                                   identifiers,
                                                   authenticators,
                                                   challengers,
                                                   mdproviders,
                                                   default_request_classifier,
                                                   default_challenge_decider,
                                                   log_stream=log_stream,
                                                   log_level=logging.DEBUG)
    return middleware
Пример #18
0
def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
    """Create a Pylons WSGI application and return it

    ``global_conf``
        The inherited configuration for this application. Normally from
        the [DEFAULT] section of the Paste ini file.

    ``full_stack``
        Whether this application provides a full WSGI stack (by default,
        meaning it handles its own exceptions and errors). Disable
        full_stack when this application is "managed" by another WSGI
        middleware.

    ``static_files``
        Whether this application serves its own static files; disable
        when another web server is responsible for serving them.

    ``app_conf``
        The application's local configuration. Normally specified in
        the [app:<name>] section of the Paste ini file (where <name>
        defaults to main).

    """
    # Configure the Pylons environment
    load_environment(global_conf, app_conf)

    # The Pylons WSGI app
    app = PylonsApp()

    # Routing/Session/Cache Middleware
    app = RoutesMiddleware(app, config['routes.map'])
    app = SessionMiddleware(app, config)
    app = CacheMiddleware(app, config)

    # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
    basicauth = BasicAuthPlugin('OpenSpending')
    auth_tkt = AuthTktCookiePlugin(
        'RANDOM_KEY_THAT_ONLY_LOOKS_LIKE_A_PLACEHOLDER',
        cookie_name='openspending_login',
        timeout=86400 * 90,
        reissue_time=3600)
    form = FriendlyFormPlugin('/login',
                              '/perform_login',
                              '/after_login',
                              '/logout',
                              '/after_logout',
                              rememberer_name='auth_tkt')
    identifiers = [('auth_tkt', auth_tkt), ('basicauth', basicauth),
                   ('form', form)]
    authenticators = [('auth_tkt', auth_tkt),
                      ('username', UsernamePasswordAuthenticator()),
                      ('apikey', ApiKeyAuthenticator())]
    challengers = [('form', form), ('basicauth', basicauth)]
    log_stream = sys.stdout
    app = PluggableAuthenticationMiddleware(app,
                                            identifiers,
                                            authenticators,
                                            challengers, [],
                                            default_request_classifier,
                                            default_challenge_decider,
                                            log_stream=log_stream,
                                            log_level=logging.WARN)

    if asbool(full_stack):
        # Handle Python exceptions
        app = ErrorHandler(app, global_conf, **config['pylons.errorware'])

        # Display error documents for 401, 403, 404 status codes (and
        # 500 when debug is disabled)
        if asbool(config['debug']):
            app = StatusCodeRedirect(app)
        else:
            app = StatusCodeRedirect(app, [400, 401, 403, 404, 500])

    # Establish the Registry for this application
    app = RegistryManager(app)

    if asbool(static_files):
        max_age = None if asbool(config['debug']) else 3600

        # Serve static files
        static_app = StaticURLParser(config['pylons.paths']['static_files'],
                                     cache_max_age=max_age)
        static_parsers = [static_app, app]
        app = Cascade(static_parsers)

    return app
Пример #19
0
def make_test_middleware(app, global_conf):
    """ Functionally equivalent to

    [plugin:form]
    use = repoze.who.plugins.form.FormPlugin
    rememberer_name = cookie
    login_form_qs=__do_login

    [plugin:cookie]
    use = repoze.who.plugins.cookie:InsecureCookiePlugin
    cookie_name = oatmeal

    [plugin:basicauth]
    use = repoze.who.plugins.basicauth.BasicAuthPlugin
    realm = repoze.who

    [plugin:htpasswd]
    use = repoze.who.plugins.htpasswd.HTPasswdPlugin
    filename = <...>
    check_fn = repoze.who.plugins.htpasswd:crypt_check

    [general]
    request_classifier = repoze.who.classifiers:default_request_classifier
    challenge_decider = repoze.who.classifiers:default_challenge_decider

    [identifiers]
    plugins = form:browser cookie basicauth

    [authenticators]
    plugins = htpasswd

    [challengers]
    plugins = form:browser basicauth
    """
    # be able to test without a config file
    from repoze.who.plugins.basicauth import BasicAuthPlugin
    from repoze.who.plugins.auth_tkt import AuthTktCookiePlugin
    from repoze.who.plugins.cookie import InsecureCookiePlugin
    from repoze.who.plugins.form import FormPlugin
    from repoze.who.plugins.htpasswd import HTPasswdPlugin
    io = StringIO()
    salt = 'aa'
    for name, password in [ ('admin', 'admin'), ('chris', 'chris') ]:
        io.write('%s:%s\n' % (name, password))
    io.seek(0)
    def cleartext_check(password, hashed):
        return password == hashed #pragma NO COVERAGE
    htpasswd = HTPasswdPlugin(io, cleartext_check)
    basicauth = BasicAuthPlugin('repoze.who')
    auth_tkt = AuthTktCookiePlugin('secret', 'auth_tkt')
    cookie = InsecureCookiePlugin('oatmeal')
    form = FormPlugin('__do_login', rememberer_name='auth_tkt')
    form.classifications = { IIdentifier:['browser'],
                             IChallenger:['browser'] } # only for browser
    identifiers = [('form', form),('auth_tkt',auth_tkt),('basicauth',basicauth)]
    authenticators = [('htpasswd', htpasswd)]
    challengers = [('form',form), ('basicauth',basicauth)]
    mdproviders = []
    from repoze.who.classifiers import default_request_classifier
    from repoze.who.classifiers import default_challenge_decider
    log_stream = None
    import os
    if os.environ.get('WHO_LOG'):
        log_stream = sys.stdout
    middleware = PluggableAuthenticationMiddleware(
        app,
        identifiers,
        authenticators,
        challengers,
        mdproviders,
        default_request_classifier,
        default_challenge_decider,
        log_stream = log_stream,
        log_level = logging.DEBUG
        )
    return middleware
Пример #20
0
    # Configure the repoze.who middleware:

    ## fake .htpasswd authentication source
    io = StringIO()
    for name, password in [('admin', 'admin'), ('user', 'user')]:
        io.write('%s:%s\n' % (name, password))
    io.seek(0)

    def cleartext_check(password, hashed):
        return password == hashed

    htpasswd = HTPasswdPlugin(io, cleartext_check)

    ## other plugins
    basicauth = BasicAuthPlugin('repoze.who')
    auth_tkt = AuthTktCookiePlugin('secret', 'auth_tkt', digest_algo="sha512")
    redirector = RedirectorPlugin(login_url='/login.html')
    redirector.classifications = {IChallenger: ['browser']}  # only for browser

    ## group / order plugins by function
    identifiers = [('auth_tkt', auth_tkt), ('basicauth', basicauth)]
    authenticators = [('auth_tkt', auth_tkt), ('htpasswd', htpasswd)]
    challengers = [('redirector', redirector), ('basicauth', basicauth)]
    mdproviders = []

    ## set up who logging, if desired
    log_stream = None
    if os.environ.get('WHO_LOG'):
        log_stream = sys.stdout

    # Wrap the middleware around the application.
Пример #21
0
from tg.configuration import AppConfig
from repoze.who.plugins.auth_tkt import AuthTktCookiePlugin
from repoze.who.plugins.basicauth import BasicAuthPlugin
import os

authtkt = AuthTktCookiePlugin('authtkt', 'authtkt')
basicauth = BasicAuthPlugin("something")

import pythondispatchms
from pythondispatchms import model, lib

base_config = AppConfig()
base_config.renderers = []

# True to prevent dispatcher from striping extensions
# For example /socket.io would be served by "socket_io"
# method instead of "socket".
base_config.disable_request_extensions = False

# Set None to disable escaping punctuation characters to "_"
# when dispatching methods.
# Set to a function to provide custom escaping.
base_config.dispatch_path_translator = True

base_config.prefer_toscawidgets2 = True

base_config.package = pythondispatchms

# Enable json in expose
base_config.renderers.append('json')
Пример #22
0
    # Configure the repoze.who middleware:

    ## fake .htpasswd authentication source
    io = StringIO()
    for name, password in [('admin', 'admin'), ('user', 'user')]:
        io.write('%s:%s\n' % (name, password))
    io.seek(0)

    def cleartext_check(password, hashed):
        return password == hashed

    htpasswd = HTPasswdPlugin(io, cleartext_check)

    ## other plugins
    basicauth = BasicAuthPlugin('repoze.who')
    auth_tkt = AuthTktCookiePlugin('secret', 'auth_tkt')
    redirector = RedirectorPlugin(login_url='/login.html')
    redirector.classifications = {IChallenger: ['browser']}  # only for browser

    ## group / order plugins by function
    identifiers = [('auth_tkt', auth_tkt), ('basicauth', basicauth)]
    authenticators = [('auth_tkt', auth_tkt), ('htpasswd', htpasswd)]
    challengers = [('redirector', redirector), ('basicauth', basicauth)]
    mdproviders = []

    ## set up who logging, if desired
    log_stream = None
    if os.environ.get('WHO_LOG'):
        log_stream = sys.stdout

    # Wrap the middleware around the application.
Пример #23
0
def setup_sql_auth(app, user_class, group_class, permission_class,
                   dbsession, form_plugin=None, form_identifies=True,
                   cookie_secret='secret', cookie_name='authtkt',
                   login_url='/login', login_handler='/login_handler',
                   post_login_url=None, logout_handler='/logout_handler',
                   post_logout_url=None, login_counter_name=None,
                   translations={}, cookie_timeout=None,
                   cookie_reissue_time=None, charset="iso-8859-1",
                   use_default_authenticator=True,
                   **who_args):
    """
    Configure :mod:`repoze.who` and :mod:`repoze.what` with SQL-only 
    authentication and authorization, respectively.
    
    :param app: Your WSGI application.
    :param user_class: The SQLAlchemy/Elixir class for the users.
    :param group_class: The SQLAlchemy/Elixir class for the groups.
    :param permission_class: The SQLAlchemy/Elixir class for the permissions.
    :param dbsession: The SQLAlchemy/Elixir session.
    :param form_plugin: The main :mod:`repoze.who` challenger plugin; this is 
        usually a login form.
    :param form_identifies: Whether the ``form_plugin`` may and should act as
        an :mod:`repoze.who` identifier.
    :type form_identifies: bool
    :param cookie_secret: The "secret" for the AuthTktCookiePlugin (**set a
        custom one!**).
    :type cookie_secret: str
    :param cookie_name: The name for the AuthTktCookiePlugin.
    :type cookie_name: str
    :param login_url: The URL where the login form is displayed.
    :type login_url: str
    :param login_handler: The URL where the login form is submitted.
    :type login_handler: str
    :param post_login_url: The URL/path where users should be redirected to
        after login.
    :type post_login_url: str
    :param logout_handler: The URL where the logout is handled.
    :type login_handler: str
    :param post_logout_url: The URL/path where users should be redirected to
        after logout.
    :type post_logout_url: str
    :param login_counter_name: The name of the variable in the query string
        that represents the login counter; defaults to ``__logins``.
    :type login_counter_name: str
    :param translations: The model translations.
    :type translations: dict
    :param cookie_timeout: The time (in seconds) during which the session cookie
        would be valid.
    :type cookie_timeout: :class:`int`
    :param cookie_reissue_time: How often should the session cookie be reissued
        (in seconds); must be less than ``timeout``.
    :type cookie_reissue_time: :class:`int`
    :param use_default_authenticator: Whether the default SQL authenticator
        should be used.
    :type use_default_authenticator: :class:`bool`
    :return: The WSGI application with authentication and authorization
        middleware.
    
    It configures :mod:`repoze.who` with the following plugins:
    
    * Identifiers:
    
      * :class:`repoze.who.plugins.friendlyform.FriendlyFormPlugin` as the 
        first identifier and challenger -- using ``login`` as the URL/path 
        where the login form will be displayed, ``login_handler`` as the 
        URL/path where the form will be sent and ``logout_handler`` as the 
        URL/path where the user will be logged out. The so-called *rememberer* 
        of such an identifier will be the identifier below.
        
        If ``post_login_url`` is defined, the user will be redirected to that
        page after login. Likewise, if ``post_logout_url`` is defined, the
        user will be redirected to that page after logout.
        
        You can override the 
        :class:`repoze.who.plugins.friendlyform.FriendlyFormPlugin`'s login 
        counter variable name (which defaults to ``__logins``) by defining
        ``login_counter_name``.
        
        .. tip::
        
            This plugin may be overridden with the ``form_plugin`` argument. 
            See also the ``form_identifies`` argument.
      * :class:`repoze.who.plugins.auth_tkt.AuthTktCookiePlugin`. You can
        customize the cookie name and secret using the ``cookie_name`` and
        ``cookie_secret`` arguments, respectively.
      
      Then it will append the identifiers you pass through the ``identifiers``
      keyword argument, if any.
    
    * Authenticators:
    
      * :class:`repoze.who.plugins.sa.SQLAlchemyAuthenticatorPlugin` (unless
        ``use_default_authenticator`` is ``False``), using the ``user_class``
        and ``dbsession`` arguments as its user class and DB session,
        respectively.
      
      Then it will be appended to the authenticators you pass through the 
      ``authenticators`` keyword argument, if any. The default authenticator
      would have the lowest precedence.
    
    * Challengers:
    
      * The same Form-based plugin used in the identifiers.
      
      Then it will append the challengers you pass through the 
      ``challengers`` keyword argument, if any.
    
    * Metadata providers:
    
      * :class:`repoze.who.plugins.sa.SQLAlchemyUserMDPlugin`, using
        the ``user_class`` and ``dbsession`` arguments as its user class and
        DB session, respectively.
      
      Then it will append the metadata providers you pass through the 
      ``mdproviders`` keyword argument, if any.
    
    The ``charset`` is passed to any component which needs to decode/encode
    data to/from the user. At present, only
    :class:`~repoze.who.plugins.friendlyform.FriendlyFormPlugin` does.
    
    Additional keyword arguments will be passed to 
    :class:`repoze.who.middleware.PluggableAuthenticationMiddleware`.
    
    .. warning::
    
        It's very important to set a custom ``cookie_secret``! It's the key to
        encrypt *and* decrypt the cookies, so you shouldn't leave the default
        one.
    
    .. note::
    
        If you don't want to use the groups/permissions-based authorization
        pattern, then set ``group_class`` and ``permission_class`` to ``None``.
    
    .. versionchanged:: 1.0.5
        Introduced the ``cookie_timeout`` and ``cookie_reissue_time`` arguments.
    
    .. versionchanged:: 1.0.6
        Introduced the ``charset`` argument.
    
    .. versionchanged:: 1.0.8
        Introduced the ``use_default_authenticator`` argument.
    
    """
    plugin_translations = find_plugin_translations(translations)
    source_adapters = configure_sql_adapters(
            user_class,
            group_class,
            permission_class,
            dbsession,
            plugin_translations['group_adapter'],
            plugin_translations['permission_adapter'])

    group_adapters= {}
    group_adapter = source_adapters.get('group')
    if group_adapter:
        group_adapters = {'sql_auth': group_adapter}

    permission_adapters = {}
    permission_adapter = source_adapters.get('permission')
    if permission_adapter:
        permission_adapters = {'sql_auth': permission_adapter}
    
    # Setting the repoze.who authenticators:
    if 'authenticators' not in who_args:
        who_args['authenticators'] = []
        
    if use_default_authenticator:
        sqlauth = SQLAlchemyAuthenticatorPlugin(user_class, dbsession)
        sqlauth.translations.update(plugin_translations['authenticator'])
        who_args['authenticators'].append(('sqlauth', sqlauth))
    
    cookie = AuthTktCookiePlugin(cookie_secret, cookie_name,
                                 timeout=cookie_timeout,
                                 reissue_time=cookie_reissue_time)
    
    # Setting the repoze.who identifiers
    if 'identifiers' not in who_args:
        who_args['identifiers'] = []
    who_args['identifiers'].append(('cookie', cookie))
    
    if form_plugin is None:
        form = FriendlyFormPlugin(
            login_url,
            login_handler,
            post_login_url,
            logout_handler,
            post_logout_url,
            login_counter_name=login_counter_name,
            rememberer_name='cookie',
            charset=charset,
            )
    else:
        form = form_plugin
    
    if form_identifies:
        who_args['identifiers'].insert(0, ('main_identifier', form))
    
    # Setting the repoze.who challengers:
    if 'challengers' not in who_args:
        who_args['challengers'] = []
    who_args['challengers'].append(('form', form))
    
    # Setting up the repoze.who mdproviders:
    sql_user_md = SQLAlchemyUserMDPlugin(user_class, dbsession)
    sql_user_md.translations.update(plugin_translations['mdprovider'])
    if 'mdproviders' not in who_args:
        who_args['mdproviders'] = []
    who_args['mdproviders'].append(('sql_user_md', sql_user_md))
    
    # Including logging
    log_file = who_args.pop('log_file', None)
    if log_file is not None:
        if log_file.lower() == 'stdout':
            log_stream = sys.stdout
        elif log_file.lower() == 'stderr':
            log_stream = sys.stderr
        else:
            log_stream = open(log_file, 'wb')
        who_args['log_stream'] = log_stream

    log_level = who_args.get('log_level', None)
    if log_level is None:
        log_level = logging.INFO
    else:
        log_level = _LEVELS[log_level.lower()]
    who_args['log_level'] = log_level

    middleware = setup_auth(app, group_adapters, permission_adapters, 
                            **who_args)
    return middleware
Пример #24
0
def setup_auth(app,
               authmetadata,
               form_plugin=None,
               form_identifies=True,
               cookie_secret='secret',
               cookie_name='authtkt',
               login_url='/login',
               login_handler='/login_handler',
               post_login_url=None,
               logout_handler='/logout_handler',
               post_logout_url=None,
               login_counter_name=None,
               cookie_timeout=None,
               cookie_reissue_time=None,
               **who_args):
    """
    Sets :mod:`repoze.who` up with the provided authenticators and
    options to create FriendlyFormPlugin/FastFormPlugin.

    It returns a middleware that provides identification,
    authentication and authorization in a way that is compatible
    with repoze.who and repoze.what.
    """
    if 'charset' in who_args:  #pragma: no cover
        log.warn('charset argument in authentication setup is ignored')
        who_args.pop('charset')

    # If no identifiers are provided in repoze setup arguments
    # then create a default one using AuthTktCookiePlugin.
    if 'identifiers' not in who_args:
        from repoze.who.plugins.auth_tkt import AuthTktCookiePlugin
        cookie = AuthTktCookiePlugin(cookie_secret,
                                     cookie_name,
                                     timeout=cookie_timeout,
                                     reissue_time=cookie_reissue_time)
        who_args['identifiers'] = [('cookie', cookie)]
        who_args['authenticators'].insert(0, ('cookie', cookie))

    # If no form plugin is provided then create a default
    # one using the provided options.
    if form_plugin is None:
        from tg.configuration.auth.fastform import FastFormPlugin
        form = FastFormPlugin(login_url,
                              login_handler,
                              post_login_url,
                              logout_handler,
                              post_logout_url,
                              rememberer_name='cookie',
                              login_counter_name=login_counter_name)
    else:
        form = form_plugin

    if form_identifies:
        who_args['identifiers'].insert(0, ('main_identifier', form))

    # Setting the repoze.who challengers:
    if 'challengers' not in who_args:
        who_args['challengers'] = []
    who_args['challengers'].append(('form', form))

    # Including logging
    log_file = who_args.pop('log_file', None)
    if log_file is not None:
        if log_file.lower() == 'stdout':
            log_stream = sys.stdout
        elif log_file.lower() == 'stderr':
            log_stream = sys.stderr
        else:
            log_stream = open(log_file, 'wb')
        who_args['log_stream'] = log_stream

    log_level = who_args.get('log_level', None)
    if log_level is None:
        log_level = logging.INFO
    else:
        log_level = _LEVELS[log_level.lower()]
    who_args['log_level'] = log_level

    # Setting up the metadata provider for the user informations
    if 'mdproviders' not in who_args:
        who_args['mdproviders'] = []

    if authmetadata:
        authmd = _AuthMetadataProvider(authmetadata)
        who_args['mdproviders'].append(('authmd', authmd))

    # Set up default classifier
    if 'classifier' not in who_args:
        who_args['classifier'] = default_request_classifier

    # Set up default challenger decider
    if 'challenge_decider' not in who_args:
        who_args['challenge_decider'] = turbogears_challenge_decider

    skip_authn = who_args.pop('skip_authentication', False)
    if asbool(skip_authn):
        return _AuthenticationForgerMiddleware(app, **who_args)
    else:
        return PluggableAuthenticationMiddleware(app, **who_args)
Пример #25
0
def add_auth(app, site_name, cookie_name, cookie_secret, login_url,
             login_handler_url, authenticators, mdproviders, groups,
             permissions):
    """
    Add authentication and authorization middleware to the ``app``.

    :param app: The WSGI application.
    :param site_name: the site name used in basic auth box.
    :param cookie_name: basic auth name and cookie name.
    :param cookie_secret: unique secret string used to protect sessions.
    :param login_url: the url for the login page
    :param login_handler_url: the url for the login handler
    :param authenticators: list of authenticator plugins
    :param mdproviders: list of mdprovider plugins
    :param groups: list of groups plugins
    :param permissions: list of permissions plugins
    :return: The same WSGI application, with authentication and
        authorization middleware.

    """

    get_log().info("add_auth: intialising Repoze")

    if not authenticators:
        raise ValueError("No authenticators provided")
    if not mdproviders:
        raise ValueError("No mdproviders provided")
    if not groups:
        raise ValueError("No groups provided")
    if not permissions:
        raise ValueError("No permissions provided")

    # If we ever change default behavior for challengers and identifiers,
    # move these to the above function
    logout_handler = None
    form = RedirectingFormPlugin(
        login_url,
        login_handler_url,
        logout_handler,
        rememberer_name='cookie',
    )

    cookie = AuthTktCookiePlugin(cookie_secret, cookie_name)

    #identifiers = [('main_identifier', form), ('basicauth', basicauth),\
    #   ('cookie', cookie)]
    #identifiers = [('basicauth', basicauth), ('cookie', cookie)]
    identifiers = [('form', form), ('cookie', cookie)]

    #challengers = [('form', form), ('basicauth', basicauth)]
    #challengers = [('basicauth', basicauth)]
    challengers = [('form', form)]

    #get_log().info(dict(groups))
    #get_log().info(    dict(permissions))
    #get_log().info(    identifiers)
    #get_log().info(    authenticators)
    #get_log().info(    challengers )
    #get_log().info(    mdproviders)
    app_with_auth = setup_auth(
        app=app,
        # # why these are dicts where all the other are lists...
        group_adapters=dict(groups),
        permission_adapters=dict(permissions),
        identifiers=identifiers,
        authenticators=authenticators,
        challengers=challengers,
        mdproviders=mdproviders,
        log_level=logging.DEBUG
    )

    get_log().info("add_auth: user/group/permission setup OK.")

    return app_with_auth