Пример #1
0
 def testInfiniteTokenLifetime(self):
     """ Test that the token lifetime of the new auth token can be infinite. """
     tokenLifetime = None
     newAuthToken = 'newAuthTokenWithoutChangedLifetime'
     tokenResource = TokenResource(self._TOKEN_FACTORY,
                                   self._PERSISTENT_STORAGE,
                                   self._REFRESH_TOKEN_STORAGE,
                                   self._AUTH_TOKEN_STORAGE,
                                   self._CLIENT_STORAGE,
                                   authTokenLifeTime=tokenLifetime,
                                   passwordManager=self._PASSWORD_MANAGER)
     request = self.generateValidTokenRequest(
         arguments={
             'grant_type': 'refresh_token',
             'refresh_token': self._VALID_REFRESH_TOKEN
         },
         authentication=self._VALID_CLIENT)
     self._TOKEN_FACTORY.expectTokenRequest(newAuthToken, tokenLifetime,
                                            self._VALID_CLIENT,
                                            self._VALID_SCOPE)
     result = tokenResource.render_POST(request)
     self._TOKEN_FACTORY.assertAllTokensRequested()
     self.assertValidTokenResponse(request,
                                   result,
                                   newAuthToken,
                                   tokenLifetime,
                                   expectedScope=self._VALID_SCOPE)
Пример #2
0
 def testAuthorizedClientWithoutScope(self):
     """
     Test that of a request without a scope is accepted
     if the token resource has a default scope.
     """
     defaultScope = ['default', 'scope']
     accessToken = 'clientCredentialsAccessTokenWithoutScope'
     tokenResource = TokenResource(self._TOKEN_FACTORY,
                                   self._PERSISTENT_STORAGE,
                                   self._REFRESH_TOKEN_STORAGE,
                                   self._AUTH_TOKEN_STORAGE,
                                   self._CLIENT_STORAGE,
                                   defaultScope=defaultScope,
                                   passwordManager=self._PASSWORD_MANAGER)
     request = self.generateValidTokenRequest(
         arguments={
             'grant_type': 'client_credentials',
         },
         authentication=self._VALID_CLIENT)
     self._TOKEN_FACTORY.expectTokenRequest(accessToken,
                                            tokenResource.authTokenLifeTime,
                                            self._VALID_CLIENT,
                                            defaultScope)
     result = tokenResource.render_POST(request)
     self._TOKEN_FACTORY.assertAllTokensRequested()
     self.assertValidTokenResponse(request,
                                   result,
                                   accessToken,
                                   tokenResource.authTokenLifeTime,
                                   expectedScope=defaultScope)
Пример #3
0
 def testRefreshTokenRenewal(self):
     """ Test that the refresh token is refreshed when expected. """
     oldRefreshToken = 'oldRefreshToken'
     additionalData = 'someAdditionalData'
     newAuthToken = 'newAuthToken'
     newRefreshToken = 'newRefreshToken'
     self._REFRESH_TOKEN_STORAGE.store(
         oldRefreshToken, self._VALID_CLIENT, self._VALID_SCOPE, additionalData)
     tokenResource = TokenResource(
         self._TOKEN_FACTORY, self._PERSISTENT_STORAGE, self._REFRESH_TOKEN_STORAGE,
         self._AUTH_TOKEN_STORAGE, self._CLIENT_STORAGE, minRefreshTokenLifeTime=0,
         passwordManager=self._PASSWORD_MANAGER)
     request = self.generateValidTokenRequest(arguments={
         'grant_type': 'refresh_token',
         'refresh_token': oldRefreshToken
     }, authentication=self._VALID_CLIENT)
     self._TOKEN_FACTORY.expectTokenRequest(
         newAuthToken, tokenResource.authTokenLifeTime,
         self._VALID_CLIENT, self._VALID_SCOPE, additionalData)
     self._TOKEN_FACTORY.expectTokenRequest(
         newRefreshToken, None, self._VALID_CLIENT, self._VALID_SCOPE, additionalData)
     result = tokenResource.render_POST(request)
     self._TOKEN_FACTORY.assertAllTokensRequested()
     self.assertFalse(
         self._REFRESH_TOKEN_STORAGE.contains(oldRefreshToken),
         msg='Expected the token resource to remove an old refresh token from the token storage.'
     )
     self.assertValidTokenResponse(
         request, result, newAuthToken, tokenResource.authTokenLifeTime,
         expectedRefreshToken=newRefreshToken, expectedScope=self._VALID_SCOPE,
         expectedAdditionalData=additionalData)
Пример #4
0
 def setUpClass(cls):
     super(FullExampleTestCase, cls).setUpClass()
     sys.path.append(os.path.abspath(os.path.join(
         os.path.dirname(__file__), '..', '..', 'example')))
     exampleModule = importlib.import_module('main')
     # noinspection PyUnresolvedReferences
     cls._VALID_CLIENT = exampleModule.getTestClient()
     # noinspection PyUnresolvedReferences
     cls._SERVER = MockSite(exampleModule.setupTestServerResource())
     TokenResource.getTokenStorageSingleton().store(
         cls._VALID_TOKEN, cls._VALID_CLIENT, cls._VALID_SCOPE)
Пример #5
0
 def testIsValidToken(self):
     """ Test that the isValidToken method rejects invalid tokens and accepts valid ones. """
     self.assertTrue(TokenResource.isValidToken('aValidToken'),
                     msg='Expected isValidToken to accept a valid token.')
     self.assertTrue(TokenResource.isValidToken(
         TokenResource.VALID_TOKEN_CHARS),
                     msg='Expected isValidToken to accept a valid token.')
     self.assertFalse(
         TokenResource.isValidToken('Token!'),
         msg='Expected isValidToken to accept an invalid token.')
     self.assertFalse(
         TokenResource.isValidToken('an invalid Token'),
         msg='Expected isValidToken to accept an invalid token.')
Пример #6
0
 def testInsecureConnection(self):
     """
     Test the rejection of a request via an insecure transport,
     except if allowInsecureRequestDebug is set to true.
     """
     request = self.generateValidTokenRequest(
         arguments={
             'grant_type': 'refresh_token',
             'refresh_token': self._VALID_REFRESH_TOKEN
         },
         authentication=self._VALID_CLIENT,
         isSecure=False)
     result = self._TOKEN_RESOURCE.render_POST(request)
     self.assertFailedTokenRequest(
         request,
         result,
         InsecureConnectionError(),
         msg=
         'Expected the token resource to reject a request made via an insecure transport'
     )
     debugTokenResource = TokenResource(
         self._TOKEN_FACTORY,
         self._PERSISTENT_STORAGE,
         self._REFRESH_TOKEN_STORAGE,
         self._AUTH_TOKEN_STORAGE,
         self._CLIENT_STORAGE,
         allowInsecureRequestDebug=True,
         passwordManager=self._PASSWORD_MANAGER)
     request = self.generateValidTokenRequest(
         arguments={
             'grant_type': 'refresh_token',
             'refresh_token': self._VALID_REFRESH_TOKEN
         },
         authentication=self._VALID_CLIENT,
         isSecure=False)
     newAuthToken = 'tokenViaInsecureConnection'
     self._TOKEN_FACTORY.expectTokenRequest(
         newAuthToken, debugTokenResource.authTokenLifeTime,
         self._VALID_CLIENT, self._VALID_SCOPE)
     result = debugTokenResource.render_POST(request)
     self._TOKEN_FACTORY.assertAllTokensRequested()
     self.assertValidTokenResponse(
         request,
         result,
         newAuthToken,
         expectedExpireTime=debugTokenResource.authTokenLifeTime,
         expectedScope=self._VALID_SCOPE)
 def testAuthorizedWithoutScope(self):
     """
     Test that a request without a scope is accepted,
     if the token resource has a default scope.
     """
     userName = b'validUserWithoutScope'
     password = b'validPasswordWithoutScope'
     defaultScope = ['default', 'scope']
     authToken = 'resourceOwnerPasswordCredentialsTokenWithoutScope'
     refreshToken = 'resourceOwnerPasswordCredentialsRefreshTokenWithoutScope'
     tokenResource = TokenResource(self._TOKEN_FACTORY,
                                   self._PERSISTENT_STORAGE,
                                   self._REFRESH_TOKEN_STORAGE,
                                   self._AUTH_TOKEN_STORAGE,
                                   self._CLIENT_STORAGE,
                                   defaultScope=defaultScope,
                                   passwordManager=self._PASSWORD_MANAGER)
     request = self.generateValidTokenRequest(
         arguments={
             'grant_type': 'password',
             'username': userName,
             'password': password,
         },
         authentication=self._VALID_CLIENT)
     self._PASSWORD_MANAGER.expectAuthenticateRequest(userName, password)
     self._TOKEN_FACTORY.expectTokenRequest(authToken,
                                            tokenResource.authTokenLifeTime,
                                            self._VALID_CLIENT,
                                            defaultScope)
     self._TOKEN_FACTORY.expectTokenRequest(refreshToken, None,
                                            self._VALID_CLIENT,
                                            defaultScope)
     result = tokenResource.render_POST(request)
     self.assertTrue(
         self._PASSWORD_MANAGER.allPasswordsChecked(),
         msg='Expected the token resource to check if the given '
         'user name and password combination is valid.')
     self._TOKEN_FACTORY.assertAllTokensRequested()
     self.assertValidTokenResponse(request,
                                   result,
                                   authToken,
                                   tokenResource.authTokenLifeTime,
                                   expectedScope=defaultScope,
                                   expectedRefreshToken=refreshToken)
 def testWhenDisabled(self):
     """ Test the rejection of a password request when the grant type is disabled. """
     tokenResource = TokenResource(self._TOKEN_FACTORY,
                                   self._PERSISTENT_STORAGE,
                                   self._REFRESH_TOKEN_STORAGE,
                                   self._AUTH_TOKEN_STORAGE,
                                   self._CLIENT_STORAGE,
                                   grantTypes=[])
     request = self.generateValidTokenRequest(
         arguments={
             'grant_type': 'password',
             'username': b'someUserName',
             'password': b'somePassword',
         },
         authentication=self._VALID_CLIENT)
     result = tokenResource.render_POST(request)
     self.assertFailedTokenRequest(
         request,
         result,
         UnsupportedGrantTypeError('password'),
         msg='Expected the token resource to reject a password '
         'request, if the grant type is disabled')
Пример #9
0
 def testTokenGeneration(self):
     """ Verify that the token factory generates valid tokens. """
     token = self._TOKEN_FACTORY.generateToken(None, self._DUMMY_CLIENT,
                                               self._VALID_SCOPE)
     self.assertIsInstance(
         token,
         str,
         message='Expected the token factory to return a string.')
     self.assertTrue(
         TokenResource.isValidToken(token),
         msg=
         'The generated token is not valid according to the oauth2 specifications.'
     )
Пример #10
0
    def _testTokenLifetime(self, token, lifetime):
        """
        Test that a request made to a token resource with the given default auth token lifetime
        is valid and generates a token with the lifetime.

        :param token: The token that should get generated.
        :param lifetime: The default and expected lifetime of the token.
        """
        tokenResource = TokenResource(
            self._TOKEN_FACTORY, self._PERSISTENT_STORAGE, self._REFRESH_TOKEN_STORAGE,
            self._AUTH_TOKEN_STORAGE, self._CLIENT_STORAGE, authTokenLifeTime=lifetime,
            passwordManager=self._PASSWORD_MANAGER)
        request = self.generateValidTokenRequest(arguments={
            'grant_type': 'refresh_token',
            'refresh_token': self._VALID_REFRESH_TOKEN
        }, authentication=self._VALID_CLIENT)
        self._TOKEN_FACTORY.expectTokenRequest(
            token, lifetime, self._VALID_CLIENT, self._VALID_SCOPE)
        result = tokenResource.render_POST(request)
        self._TOKEN_FACTORY.assertAllTokensRequested()
        self.assertValidTokenResponse(request, result, token, lifetime,
                                      expectedScope=self._VALID_SCOPE)
Пример #11
0
 def setUpClass(cls):
     super(AbstractTokenResourceTest, cls).setUpClass()
     cls._AUTH_TOKEN_STORAGE = DictTokenStorage()
     cls._REFRESH_TOKEN_STORAGE = DictTokenStorage()
     cls._TOKEN_FACTORY = TestTokenFactory()
     cls._PERSISTENT_STORAGE = TestPersistentStorage()
     cls._CLIENT_STORAGE = TestClientStorage()
     cls._REFRESH_TOKEN_STORAGE.store(cls._VALID_REFRESH_TOKEN,
                                      cls._VALID_CLIENT, cls._VALID_SCOPE)
     cls._CLIENT_STORAGE.addClient(cls._VALID_CLIENT)
     cls._PASSWORD_MANAGER = TestPasswordManager()
     cls._TOKEN_RESOURCE = TokenResource(
         cls._TOKEN_FACTORY,
         cls._PERSISTENT_STORAGE,
         cls._REFRESH_TOKEN_STORAGE,
         cls._AUTH_TOKEN_STORAGE,
         cls._CLIENT_STORAGE,
         passwordManager=cls._PASSWORD_MANAGER)
Пример #12
0
def isAuthorized(request, scope, allowInsecureRequestDebug=False):
    """
    Returns True if the token in the request grants access to the given
    scope. The token is validated via the authTokenStorage singleton
    given to the TokenResource instance. If the token is invalid,
    does not grant access to the scope or was not send via a secure
    protocol, False is returned, an error is written to the request
    and the request is closed.
    You can not write to the request if this function returned False!
    :param request: The request.
    :param scope: The scope or list of scopes the token must grant access to.
    :param allowInsecureRequestDebug: Allow requests to originate from
           insecure connections. Only use for local testing!
    :return: True, if the request is authorized, False otherwise.
    """
    error = None
    scope = scope if type(scope) == list else [scope]
    if not (allowInsecureRequestDebug or request.isSecure()):
        error = InsecureConnectionError()
    else:
        try:
            requestToken = _getToken(request)
        except ValueError:
            error = MultipleTokensError(scope)
        else:
            if requestToken is None:
                error = MissingTokenError(scope)
            else:
                try:
                    requestToken = requestToken.decode('utf-8')
                except UnicodeDecodeError:
                    pass
                else:
                    tokenStorage = TokenResource.getTokenStorageSingleton()
                    if tokenStorage.contains(requestToken):
                        if tokenStorage.hasAccess(requestToken, scope):
                            return True
                        else:
                            error = InsufficientScopeRequestError(scope)
            if error is None:
                error = InvalidTokenRequestError(scope)
    request.write(error.generate(request))
    request.finish()
    return False
Пример #13
0
def setupTestServerResource():
    """
    Setup a test server with a protected clock resource and an oauth2 endpoint.
    :return: The root resource of the test server
    """
    clientStorage = setupOAuth2Clients()
    enabledGrantTypes = [GrantTypes.AuthorizationCode, GrantTypes.RefreshToken]
    tokenResource = TokenResource(UUIDTokenFactory(),
                                  PersistentStorageImp(),
                                  DictTokenStorage(),
                                  DictTokenStorage(),
                                  clientStorage,
                                  allowInsecureRequestDebug=True,
                                  grantTypes=enabledGrantTypes)
    root = Resource()
    root.putChild(b'clock', ClockPage())
    root.putChild(
        b'oauth2',
        OAuth2Endpoint.initFromTokenResource(tokenResource,
                                             subPath=b'token',
                                             grantTypes=enabledGrantTypes))
    return root