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
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)
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)
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)
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')
# * "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()
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
# 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()
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)
"""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()