def authenticateCredentials(self, credentials): """ Place to actually validate the user credentials specified and return a tuple (login, login) on success or (None, None) on failure. If we find one and two-step verification is not enabled for the account, we consider the authentication passed and log the user in. If two-step verification has been enabled for the account, the first step of authentication is considered to be passed and we go to the next page (having the user and pass remembered), where we check for the token generated by the token generator (Google Authenticator). If the token is valid too, we log the user in. """ login = credentials['login'] password = credentials['password'] if not login: return None user = api.user.get(username=login) logger.debug("Found user: {0}".format(user.getProperty('username'))) two_factor_authentication_enabled = user.getProperty('enable_two_factor_authentication') logger.debug("Two-step verification enabled: {0}".format(two_factor_authentication_enabled)) if two_factor_authentication_enabled: # First see, if the password is correct. # We fetch the user manager plugin to chekc that. auth_plugins = self._getPAS().plugins.listPlugins( IAuthenticationPlugin ) user_manager = authorized = None for plugid, authplugin in auth_plugins: if 'user' in plugid: user_manager = authplugin break if user_manager: authorized = user_manager.authenticateCredentials(credentials) if authorized is None: return None if is_whitelisted_client(): return None # Setting the data in the session doesn't seem to work. That's why we use the `ska` package. # The secret key would be then a combination of username, secret stored in users' profile # and the browser version. request = self.REQUEST response = request['RESPONSE'] response.setCookie('__ac', '', path='/') # Redirect to token thing... signed_url = sign_user_data(request=request, user=user, url='@@google-authenticator-token') came_from_adapter = ICameFrom(request) # Appending possible `came_from`, but give it another name. came_from = came_from_adapter.getCameFrom() if came_from: signed_url = '{0}&next_url={1}'.format(signed_url, came_from) response.redirect(signed_url, lock=1) return None if credentials.get('extractor') != self.getId(): return None return None
def authenticateCredentials(self, credentials): """ Place to actually validate the user credentials specified and return a tuple (login, login) on success or (None, None) on failure. If we find one and two-step verification is not enabled for the account, we consider the authentication passed and log the user in. If two-step verification has been enabled for the account, the first step of authentication is considered to be passed and we go to the next page (having the user and pass remembered), where we check for the token generated by the token generator (Google Authenticator). If the token is valid too, we log the user in. """ if is_whitelisted_client(): return None login = credentials['login'] if not login: return None user = api.user.get(username=login) logger.debug("Found user: {0}".format(user.getProperty('username'))) two_factor_authentication_enabled = user.getProperty( 'enable_two_factor_authentication') logger.debug("Two-step verification enabled: {0}".format( two_factor_authentication_enabled)) if two_factor_authentication_enabled: # First see, if the password is correct. # We do this by allowing all IAuthenticationPlugin plugins to # authenticate the credentials, and pick the first one that is # successful. pas_plugins = self._getPAS().plugins auth_plugins = pas_plugins.listPlugins(IAuthenticationPlugin) authorized = None for plugid, authplugin in auth_plugins: if plugid == self.getId(): # Avoid infinite recursion continue try: authorized = authplugin.authenticateCredentials( credentials) except _SWALLOWABLE_PLUGIN_EXCEPTIONS: reraise(authplugin) msg = 'AuthenticationPlugin {0} error'.format(plugid) logger.info(msg, exc_info=True) continue if authorized is not None: # An auth plugin successfully authenticated the user break if authorized is None: # No auth plugin was able to authenticate the user return None # Consume the credentials after we verified the credentials above. # We need to do this to prevent later IAuthenticationPlugins # from authenticating the user before we verified the token. # This does produce a "Login failed" status message though that # we need to remove in the token validation view for key in credentials.keys(): del credentials[key] # Setting the data in the session doesn't seem to work. That's why # we use the `ska` package. # The secret key would be then a combination of username, secret # stored in users' profile and the browser version. request = self.REQUEST response = request['RESPONSE'] response.setCookie('__ac', '', path='/') # Redirect to token thing... signed_url = sign_user_data(request=request, user=user, url='@@google-authenticator-token') came_from_adapter = ICameFrom(request) # Appending possible `came_from`, but give it another name. came_from = came_from_adapter.getCameFrom() if came_from: signed_url = '{0}&next_url={1}'.format(signed_url, came_from) response.redirect(signed_url, lock=1) return None if credentials.get('extractor') != self.getId(): return None return None