def test_with_translations(self): group_translations = { 'item_name': 'member_name', 'items': 'members'} permission_translations = { 'section_name': 'authorization_name', 'sections': 'authorizations'} adapters = configure_sql_adapters(User, Group, Permission, DBSession, group_translations, permission_translations) group_adapter = adapters['group'] permission_adapter = adapters['permission'] # The verifications... self.assertEqual(group_adapter.translations['item_name'], group_translations['item_name']) self.assertEqual(group_adapter.translations['items'], group_translations['items']) self.assertEqual(permission_adapter.translations['section_name'], permission_translations['section_name']) self.assertEqual(permission_adapter.translations['sections'], permission_translations['sections']) # Checking that the default translation is used when not overriden: self.assertEquals(group_adapter.translations['section_name'], permission_adapter.translations['item_name'], 'group_name')
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
def test_without_translations(self): adapters = configure_sql_adapters(User, Group, Permission, DBSession) group_adapter = adapters['group'] permission_adapter = adapters['permission'] assert isinstance(group_adapter, SqlGroupsAdapter) assert isinstance(permission_adapter, SqlPermissionsAdapter) self.assertEquals(DBSession, group_adapter.dbsession, permission_adapter.dbsession) self.assertEqual(User, group_adapter.children_class) self.assertEquals(Group, group_adapter.parent_class, permission_adapter.children_class) self.assertEqual(Permission, permission_adapter.parent_class)
def test_with_translations(self): group_translations = {'item_name': 'member_name', 'items': 'members'} permission_translations = { 'section_name': 'authorization_name', 'sections': 'authorizations' } adapters = configure_sql_adapters(User, Group, Permission, DBSession, group_translations, permission_translations) group_adapter = adapters['group'] permission_adapter = adapters['permission'] # The verifications... self.assertEqual(group_adapter.translations['item_name'], group_translations['item_name']) self.assertEqual(group_adapter.translations['items'], group_translations['items']) self.assertEqual(permission_adapter.translations['section_name'], permission_translations['section_name']) self.assertEqual(permission_adapter.translations['sections'], permission_translations['sections']) # Checking that the default translation is used when not overriden: self.assertEquals(group_adapter.translations['section_name'], permission_adapter.translations['item_name'], 'group_name')
# * "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
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
# * "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, meta.Session, # group_translations={'section_name': 'name', # 'item_name': 'username'}, # permission_translations={'section_name': 'name', # 'item_name': 'username'}) adapters = configure_sql_adapters(User, Group, Permission, meta.Session) user = SQLAlchemyUserMDPlugin(User, meta.Session) #user.translations['user_name'] = 'username' 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()
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
# 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()
"""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 astportal2 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() #class CAS_metadata(object): # print ' * * * class CAS_metadata' #
# License: GNU GPL v2 <http://www.gnu.org/licenses/gpl-2.0.html> """ Configuration de modules fournissant des métadonnées pour le framework repoze.who. Ce module ajoute automatiquement les instances des groupes d'utilisateurs auxquels l'utilisateur identifié appartient dans l'environnement de la requête. """ from repoze.what.plugins.sql import configure_sql_adapters from repoze.what.middleware import AuthorizationMetadata from vigilo.models import tables, session from .translation import translations _source_adapters = configure_sql_adapters( tables.User, tables.UserGroup, tables.Permission, session.DBSession, translations['group_adapter'], translations['permission_adapter'], ) # Fournisseur de méta-données. plugin = AuthorizationMetadata( {'sqlauth': _source_adapters['group']}, {'sqlauth': _source_adapters['permission']}, )
"""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()
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