class TestMDProviderWithTranslations(unittest.TestCase):
    """Tests for the translation functionality"""
    
    def setUp(self):
        databasesetup_sa.setup_database_with_translations()
    
    def tearDown(self):
        databasesetup_sa.teardownDatabase()
    
    def test_it(self):
        self.plugin = SQLAlchemyUserMDPlugin(sa_model.Member,
                                             sa_model.DBSession)
        # Updating the translations...
        self.plugin.translations['user_name'] = 'member_name'
        # Testing it...
        member = sa_model.DBSession.query(sa_model.Member).\
                 filter(sa_model.Member.member_name==compat.u('rms')).one()
        identity = {'repoze.who.userid': member.member_name}
        expected_identity = {
            'repoze.who.userid': member.member_name,
            'user': member}
        self.plugin.add_metadata(None, identity)
        
        self.assertEqual(expected_identity.keys(), identity.keys())
        self.assertEqual(
            expected_identity['repoze.who.userid'],
            identity['repoze.who.userid'],
            )
        self.assertEqual(
            expected_identity['user'].member_name,
            identity['user'].member_name,
            )
 def test_it(self):
     user = sa_model.DBSession.query(sa_model.User).filter(sa_model.User.user_name == u"rms").one()
     identity = {"repoze.who.userid": user.user_name}
     expected_identity = {"repoze.who.userid": user.user_name, "user": user}
     plugin = SQLAlchemyUserMDPlugin(sa_model.User, sa_model.DBSession)
     plugin.add_metadata(None, identity)
     self.assertEqual(identity, expected_identity)
class TestMDProviderWithTranslations(unittest.TestCase):
    """Tests for the translation functionality"""
    def setUp(self):
        databasesetup_sa.setup_database_with_translations()

    def tearDown(self):
        databasesetup_sa.teardownDatabase()

    def test_it(self):
        self.plugin = SQLAlchemyUserMDPlugin(sa_model.Member,
                                             sa_model.DBSession)
        # Updating the translations...
        self.plugin.translations['user_name'] = 'member_name'
        # Testing it...
        member = sa_model.DBSession.query(sa_model.Member).\
                 filter(sa_model.Member.member_name==compat.u('rms')).one()
        identity = {'repoze.who.userid': member.member_name}
        expected_identity = {
            'repoze.who.userid': member.member_name,
            'user': member
        }
        self.plugin.add_metadata(None, identity)

        self.assertEqual(expected_identity.keys(), identity.keys())
        self.assertEqual(
            expected_identity['repoze.who.userid'],
            identity['repoze.who.userid'],
        )
        self.assertEqual(
            expected_identity['user'].member_name,
            identity['user'].member_name,
        )
def who_config(config):
    auth_by_username = MediaCoreAuthenticatorPlugin(User, DBSession)
    
    form = FriendlyFormPlugin(
        login_form_url,
        login_handler_url,
        post_login_url,
        logout_handler_url,
        post_logout_url,
        rememberer_name='cookie',
        charset='iso-8859-1',
    )
    cookie_secret = config['sa_auth.cookie_secret']
    seconds_30_days = 30*24*60*60 # session expires after 30 days
    cookie = MediaCoreCookiePlugin(cookie_secret, 
        cookie_name='authtkt', 
        timeout=seconds_30_days, # session expires after 30 days
        reissue_time=seconds_30_days/2, # reissue cookie after 15 days
    )

    sql_user_md = SQLAlchemyUserMDPlugin(User, DBSession)
    sql_user_md.translations['user_name'] = 'user_id'

    who_args = {
        'authenticators': [
            ('auth_by_username', auth_by_username)
        ],
        'challenge_decider': default_challenge_decider,
        'challengers': [('form', form)],
        'classifier': classifier_for_flash_uploads,
        'identifiers': [('main_identifier', form), ('cookie', cookie)],
        'mdproviders': [('sql_user_md', sql_user_md)],
    }
    return who_args
Exemple #5
0
def wsgi_authorization(app, app_conf):
    """Add a WSGI middleware wrapper to this application."""
    source_adapters = configure_sql_adapters(
        FullUser,
        Group,
        Permission,
        meta.Session,
        dict(section_name='name', item_name='username'),
        dict(section_name='name', item_name='name')
        )
    group_adapters = {'sql_auth': source_adapters['group']}
    permission_adapters = {'sql_auth': source_adapters['permission']}

    auth_tkt = AuthTktCookiePlugin(')h,&xCWlS}+u:<yD]BJV', 'auth_tkt', userid_checker=valid_user)
    openid = OpenIdIdentificationPlugin('file', # 'mem'
            openid_field = 'openid',
            error_field = 'error',
            session_name = 'beaker.session',
            login_form_url = '/login_form',
            login_handler_path = '/_do_login',
            logout_handler_path = '/logout',
            store_file_path = path.join(config['pylons.cache_dir'], 'sstore'),
            logged_in_url = '/success',
            logged_out_url = '/',
            came_from_field = 'came_from',
            rememberer_name = 'auth_tkt',
            sql_associations_table = '',
            sql_nonces_table = '',
            sql_connstring = ''
            )

    formplugin = RedirectingFormPlugin('/login', '/do_login', '/logout', rememberer_name='auth_tkt')
    sqlauth = CAModelAuthenticator()

    sqlmetadata = SQLAlchemyUserMDPlugin(FullUser, meta.Session)
    sqlmetadata.translations['user_name'] = 'username'
    authorization = AuthorizationMetadata(group_adapters,
                                          permission_adapters)

    identifiers = [('form', formplugin), ('openid', openid),('auth_tkt',auth_tkt)]
    authenticators = [('sqlauth', sqlauth), ('openid', openid)]
    challengers = [('form', formplugin), ('openid', openid)]
    mdproviders = [('sqlmetadata', sqlmetadata), ('authorization_md', authorization)]
    log_stream = None
    #if config.get('WHO_LOG'):
    log_stream = sys.stdout

    app = PluggableAuthenticationMiddleware(
        app,
        identifiers,
        authenticators,
        challengers,
        mdproviders,
        default_request_classifier,
        default_challenge_decider,
        log_stream = log_stream,
        log_level=app_conf.get('who.log_level','ERROR')
        )
    return app
class TestMDProvider(unittest.TestCase):
    """Tests for the authenticator function"""
    
    def setUp(self):
        databasesetup_sa.setup_database()
        self.plugin = SQLAlchemyUserMDPlugin(sa_model.User, sa_model.DBSession)
    
    def tearDown(self):
        databasesetup_sa.teardownDatabase()

    def test_implements(self):
        verifyClass(IMetadataProvider, SQLAlchemyUserMDPlugin, tentative=True)
        
    def test_it(self):
        user = sa_model.DBSession.query(sa_model.User).\
               filter(sa_model.User.user_name==compat.u('rms')).one()
        identity = {'repoze.who.userid': user.user_name}
        expected_identity = {
            'repoze.who.userid': user.user_name,
            'user': user}
        self.plugin.add_metadata(None, identity)
        
        self.assertEqual(identity.keys(), expected_identity.keys())
        self.assertEqual(
            expected_identity['repoze.who.userid'],
            identity['repoze.who.userid'],
            )
        self.assertEqual(
            expected_identity['user'].user_name,
            identity['user'].user_name,
            )
        
    
    def test_rollback(self):
        """The session must be rolled back before use."""
        # Make the transaction invalid by attempting to add an existing user:
        try:
            user = sa_model.User()
            user.user_name = compat.u("rms")
            user.password = "******"
            sa_model.DBSession.add(user)
            sa_model.DBSession.commit()
        except IntegrityError:
            pass
        else:
            self.fail("An IntegrityError must've been raised")
        
        identity = {'repoze.who.userid': compat.u("rms")}
        self.plugin.add_metadata(None, identity)
Exemple #7
0
 def test_it(self):
     self.plugin = SQLAlchemyUserMDPlugin(sa_model.Member,
                                          sa_model.DBSession)
     # Updating the translations...
     self.plugin.translations['user_name'] = 'member_name'
     # Testing it...
     member = sa_model.DBSession.query(sa_model.Member).\
              filter(sa_model.Member.member_name==u'rms').one()
     identity = {'repoze.who.userid': member.member_name}
     expected_identity = {
         'repoze.who.userid': member.member_name,
         'user': member
     }
     self.plugin.add_metadata(None, identity)
     self.assertEqual(expected_identity, identity)
class TestMDProviderWithTranslations(BaseDMTester):
    """Tests for the translation functionality"""

    def setUp(self):
        databasesetup_sa.setup_database_with_translations()

    def test_it(self):
        self.plugin = SQLAlchemyUserMDPlugin(sa_model.Member, sa_model.DBSession)
        # Updating the translations...
        self.plugin.translations["user_name"] = "member_name"
        # Testing it...
        member = sa_model.DBSession.query(sa_model.Member).filter(sa_model.Member.member_name == u"rms").one()
        identity = {"repoze.who.userid": member.member_name}
        expected_identity = {"repoze.who.userid": member.member_name, "user": member}
        self.plugin.add_metadata(None, identity)
        self.assertEqual(expected_identity, identity)
class TestMDProvider(unittest.TestCase):
    """Tests for the authenticator function"""
    def setUp(self):
        databasesetup_sa.setup_database()
        self.plugin = SQLAlchemyUserMDPlugin(sa_model.User, sa_model.DBSession)

    def tearDown(self):
        databasesetup_sa.teardownDatabase()

    def test_implements(self):
        verifyClass(IMetadataProvider, SQLAlchemyUserMDPlugin, tentative=True)

    def test_it(self):
        user = sa_model.DBSession.query(sa_model.User).\
               filter(sa_model.User.user_name==compat.u('rms')).one()
        identity = {'repoze.who.userid': user.user_name}
        expected_identity = {'repoze.who.userid': user.user_name, 'user': user}
        self.plugin.add_metadata(None, identity)

        self.assertEqual(identity.keys(), expected_identity.keys())
        self.assertEqual(
            expected_identity['repoze.who.userid'],
            identity['repoze.who.userid'],
        )
        self.assertEqual(
            expected_identity['user'].user_name,
            identity['user'].user_name,
        )

    def test_rollback(self):
        """The session must be rolled back before use."""
        # Make the transaction invalid by attempting to add an existing user:
        try:
            user = sa_model.User()
            user.user_name = compat.u("rms")
            user.password = "******"
            sa_model.DBSession.add(user)
            sa_model.DBSession.commit()
        except IntegrityError:
            pass
        else:
            self.fail("An IntegrityError must've been raised")

        identity = {'repoze.who.userid': compat.u("rms")}
        self.plugin.add_metadata(None, identity)
 def test_it(self):
     self.plugin = SQLAlchemyUserMDPlugin(sa_model.Member, sa_model.DBSession)
     # Updating the translations...
     self.plugin.translations["user_name"] = "member_name"
     # Testing it...
     member = sa_model.DBSession.query(sa_model.Member).filter(sa_model.Member.member_name == u"rms").one()
     identity = {"repoze.who.userid": member.member_name}
     expected_identity = {"repoze.who.userid": member.member_name, "user": member}
     self.plugin.add_metadata(None, identity)
     self.assertEqual(expected_identity, identity)
Exemple #11
0
class TestMDProvider(unittest.TestCase):
    """Tests for the authenticator function"""
    def setUp(self):
        databasesetup_sa.setup_database()
        self.plugin = SQLAlchemyUserMDPlugin(sa_model.User, sa_model.DBSession)

    def tearDown(self):
        databasesetup_sa.teardownDatabase()

    def test_implements(self):
        verifyClass(IMetadataProvider, SQLAlchemyUserMDPlugin, tentative=True)

    def test_it(self):
        user = sa_model.DBSession.query(sa_model.User).\
               filter(sa_model.User.user_name==u'rms').one()
        identity = {'repoze.who.userid': user.user_name}
        expected_identity = {'repoze.who.userid': user.user_name, 'user': user}
        self.plugin.add_metadata(None, identity)
        self.assertEqual(identity, expected_identity)
class TestMDProvider(unittest.TestCase):
    """Tests for the authenticator function"""
    
    def setUp(self):
        databasesetup_sa.setup_database()
        self.plugin = SQLAlchemyUserMDPlugin(sa_model.User, sa_model.DBSession)
    
    def tearDown(self):
        databasesetup_sa.teardownDatabase()

    def test_implements(self):
        verifyClass(IMetadataProvider, SQLAlchemyUserMDPlugin, tentative=True)
        
    def test_it(self):
        user = sa_model.DBSession.query(sa_model.User).\
               filter(sa_model.User.user_name==u'rms').one()
        identity = {'repoze.who.userid': user.user_name}
        expected_identity = {
            'repoze.who.userid': user.user_name,
            'user': user}
        self.plugin.add_metadata(None, identity)
        self.assertEqual(identity, expected_identity)
 def test_it(self):
     self.plugin = SQLAlchemyUserMDPlugin(sa_model.Member,
                                          sa_model.DBSession)
     # Updating the translations...
     self.plugin.translations['user_name'] = 'member_name'
     # Testing it...
     member = sa_model.DBSession.query(sa_model.Member).\
              filter(sa_model.Member.member_name==u'rms').one()
     identity = {'repoze.who.userid': member.member_name}
     expected_identity = {
         'repoze.who.userid': member.member_name,
         'user': member}
     self.plugin.add_metadata(None, identity)
     self.assertEqual(expected_identity, identity)
Exemple #14
0
def setup_auth(app, config):
    groupadapter = InstanceGroupSourceAdapter()
    #groupadapter.translations.update({'sections': 'groups'})
    permissionadapter = SqlPermissionsAdapter(model.Permission,
                                              model.Group,
                                              model.meta.Session)
    #permissionadapter.translations.update(permission_translations)

    group_adapters = {'sql_auth': groupadapter}
    permission_adapters = {'sql_auth': permissionadapter}

    basicauth = BasicAuthPlugin('Adhocracy HTTP Authentication')
    auth_tkt = InstanceAuthTktCookiePlugin(
        '41d207498d3812741e27c6441760ae494a4f9fbf',
        cookie_name='adhocracy_login', timeout=86400 * 2,
        reissue_time=3600)

    form = FriendlyFormPlugin(
            '/login',
            '/perform_login',
            '/post_login',
            '/logout',
            '/post_logout',
            login_counter_name='_login_tries',
            rememberer_name='auth_tkt')

    sqlauth = SQLAlchemyAuthenticatorPlugin(model.User, model.meta.Session)
    sql_user_md = SQLAlchemyUserMDPlugin(model.User, model.meta.Session)

    identifiers = [('form', form),
                   ('basicauth', basicauth),
                   ('auth_tkt', auth_tkt)]
    authenticators = [('sqlauth', sqlauth), ('auth_tkt', auth_tkt)]
    challengers = [('form', form), ('basicauth', basicauth)]
    mdproviders = [('sql_user_md', sql_user_md)]

    log_stream = None
    #log_stream = sys.stdout

    return setup_what(app, group_adapters, permission_adapters,
                      identifiers=identifiers,
                      authenticators=authenticators,
                      challengers=challengers,
                      mdproviders=mdproviders,
                      log_stream=log_stream,
                      log_level=logging.DEBUG,
                      # kwargs passed to repoze.who.plugins.testutils:
                      skip_authentication=config.get('skip_authentication'),
                      remote_user_key='HTTP_REMOTE_USER')
Exemple #15
0
#    * "sections" (default: "permissions"): The permissions granted to a given
#      group.
#    * "item_name" (default: "group_name"): The name of the table field that
#      contains the primary key in the groups table.
#    * "items" (default: "groups"): The groups that are granted a given
#      permission.
adapters = configure_sql_adapters(User,
                                  Group,
                                  Permission,
                                  DBSession,
                                  group_translations={
                                      'section_name': 'id',
                                      'item_name': 'email'
                                  },
                                  permission_translations={
                                      'section_name': 'name',
                                      'item_name': 'id'
                                  })

user = SQLAlchemyUserMDPlugin(User, DBSession)
# we get metadata based on user id, the only attribute an user is guaranteed to
# have regardles the authentication method he/she uses (Form, Facebook, Twitter)
user.translations['user_name'] = 'email'

group = AuthorizationMetadata({'sqlauth': adapters['group']},
                              {'sqlauth': adapters['permission']})

# THIS IS CRITICALLY IMPORTANT!  Without this your site will
# consider every repoze.what predicate True!
booleanize_predicates()
Exemple #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={}, 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
 def setUp(self):
     databasesetup_sa.setup_database()
     self.plugin = SQLAlchemyUserMDPlugin(sa_model.User, sa_model.DBSession)
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
Exemple #19
0
#      contains the primary key in the groups table.
#    * "sections" (default: "groups"): The groups to which a given user belongs.
#    * "item_name" (default: "user_name"): The name of the table field that
#      contains the primary key in the users table.
#    * "items" (default: "users"): The users that belong to a given group.
#  * Permission source adapter:
#    * "section_name" (default: "permission_name"): The name of the table field
#      that contains the primary key in the permissions table.
#    * "sections" (default: "permissions"): The permissions granted to a given
#      group.
#    * "item_name" (default: "group_name"): The name of the table field that
#      contains the primary key in the groups table.
#    * "items" (default: "groups"): The groups that are granted a given
#      permission.
adapters = configure_sql_adapters(User, Group, Permission, DBSession,
                                  group_translations={'section_name': 'id',
                                                      'item_name': 'email'},
                                  permission_translations={'section_name': 'name',
                                                           'item_name': 'id'})
 
user = SQLAlchemyUserMDPlugin(User, DBSession)
# we get metadata based on user id, the only attribute an user is guaranteed to
# have regardles the authentication method he/she uses (Form, Facebook, Twitter)
user.translations['user_name'] = 'email'
 
group = AuthorizationMetadata({'sqlauth': adapters['group']}, {'sqlauth': adapters['permission']})
 
# THIS IS CRITICALLY IMPORTANT!  Without this your site will
# consider every repoze.what predicate True!
booleanize_predicates()
Exemple #20
0
def setup_auth(app, config):
    groupadapter = InstanceGroupSourceAdapter()
    #groupadapter.translations.update({'sections': 'groups'})
    permissionadapter = SqlPermissionsAdapter(model.Permission, model.Group,
                                              model.meta.Session)
    #permissionadapter.translations.update(permission_translations)

    group_adapters = {'sql_auth': groupadapter}
    permission_adapters = {'sql_auth': permissionadapter}

    basicauth = BasicAuthPlugin('Adhocracy HTTP Authentication')
    auth_tkt = InstanceAuthTktCookiePlugin(
        config,
        config.get('adhocracy.auth.secret', config['beaker.session.secret']),
        cookie_name='adhocracy_login',
        timeout=86400 * 2,
        reissue_time=3600,
        secure=config.get('adhocracy.protocol', 'http') == 'https')

    sqlauth = EmailSQLAlchemyAuthenticatorPlugin(model.User,
                                                 model.meta.Session)
    sql_user_md = SQLAlchemyUserMDPlugin(model.User, model.meta.Session)

    login_urls = [
        '/login',
        '/perform_login',
        '/post_login',
        '/logout',
        '/post_logout',
    ]
    login_options = dict(
        login_counter_name='_login_tries',
        rememberer_name='auth_tkt',
        charset='utf-8',
    )
    if config.get('adhocracy.login_style') == 'alternate':
        form = AlternateLoginFriendlyFormPlugin(sqlauth.get_user, *login_urls,
                                                **login_options)
    else:
        form = FriendlyFormPlugin(*login_urls, **login_options)

    identifiers = [('form', form), ('basicauth', basicauth),
                   ('auth_tkt', auth_tkt)]
    authenticators = [('sqlauth', sqlauth), ('auth_tkt', auth_tkt)]
    challengers = [('form', form), ('basicauth', basicauth)]
    mdproviders = [('sql_user_md', sql_user_md)]

    welcome.setup_auth(config, identifiers, authenticators)

    log_stream = None
    #log_stream = sys.stdout

    # If a webserver already sets a HTTP_REMOTE_USER environment variable,
    # repoze.who merely acts as a pass through and doesn't set up the proper
    # environment (e.g. environ['repoze.who.api'] is missing).
    #
    # This happens for example in the case of Shibboleth based authentication -
    # we weren't able to prevent mod_shibboleth from setting the header.
    # Therefore the remote user key to look for is not set to HTTP_REMOTE_USER,
    # but to the non-existing DONT_USE_HTTP_REMOTE_USER environment variable.

    REMOTE_USER_KEY = 'DONT_USE_HTTP_REMOTE_USER'

    return setup_what(
        app,
        group_adapters,
        permission_adapters,
        identifiers=identifiers,
        authenticators=authenticators,
        challengers=challengers,
        mdproviders=mdproviders,
        log_stream=log_stream,
        log_level=logging.DEBUG,
        # kwargs passed to repoze.who.plugins.testutils:
        skip_authentication=config.get('skip_authentication'),
        remote_user_key=REMOTE_USER_KEY)
Exemple #21
0
"""Example of a simplistic, importable authenticator plugin

Intended to work like a quick-started SQLAlchemy plugin"""
from repoze.who.plugins.sa import (
    SQLAlchemyAuthenticatorPlugin,
    SQLAlchemyUserMDPlugin,
)
from repoze.what.plugins.sql import configure_sql_adapters
from repoze.what.middleware import AuthorizationMetadata

from bq.core import model
auth_plugin = SQLAlchemyAuthenticatorPlugin(model.User, model.DBSession)
md_plugin = SQLAlchemyUserMDPlugin(model.User, model.DBSession)
_source_adapters = configure_sql_adapters(
    model.User,
    model.Group,
    model.Permission,
    model.DBSession,
)
md_group_plugin = AuthorizationMetadata(
    {'sqlauth': _source_adapters['group']},
    {'sqlauth': _source_adapters['permission']},
)

# THIS IS CRITICALLY IMPORTANT!  Without this your site will
# consider every repoze.what predicate True!
from repoze.what.plugins.pylonshq import booleanize_predicates
booleanize_predicates()
Exemple #22
0
 def setUp(self):
     databasesetup_sa.setup_database()
     self.plugin = SQLAlchemyUserMDPlugin(sa_model.User, sa_model.DBSession)