예제 #1
0
    def testRenderWithUserConflict(self):
        """
        A C{CONFLICT} HTTP status code is returned if the authorization is
        successfully verified by the service provider, but the username
        clashes with an existing L{User} that isn't linked to the Twitter UID.
        The offending username is returned UTF-8 and base64 encoded.
        """
        username = u'john\N{HIRAGANA LETTER A}'
        UserAPI().create([(username, 'secret', u'John', u'*****@*****.**')])
        self.store.commit()

        self.agent._connect = self._connect
        headers = {'X-Verify-Credentials-Authorization': ['OAuth ...'],
                   'X-Auth-Service-Provider': [TWITTER_URL]}
        request = FakeRequest(headers=Headers(headers))
        with login(u'anon', self.anonymous.objectID, self.transact) as session:
            resource = OAuthEchoResource(session, self.agent)
            self.assertEqual(NOT_DONE_YET, resource.render_GET(request))

            [(_, responseDeferred)] = self.protocol.requests
            data = {'id': 1984245, 'screen_name': username, 'name': u'John'}
            response = FakeResponse(ResponseDone(), dumps(data))
            responseDeferred.callback(response)
            yield resource.deferred
            self.assertEqual(CONFLICT, request.code)
            headers = dict(request.responseHeaders.getAllRawHeaders())
            encodedUsername = b64encode(username.encode('utf-8'))
            self.assertEqual(
                {'X-Fluiddb-Error-Class': ['UsernameConflict'],
                 'X-Fluiddb-Username': [encodedUsername],
                 'X-Fluiddb-Request-Id': [session.id]},
                headers)
예제 #2
0
    def testRenderWithUserConflict(self):
        """
        A C{CONFLICT} HTTP status code is returned if the authorization is
        successfully verified by the service provider, but the username
        clashes with an existing L{User} that isn't linked to the Twitter UID.
        The offending username is returned UTF-8 and base64 encoded.
        """
        username = u'john\N{HIRAGANA LETTER A}'
        UserAPI().create([(username, 'secret', u'John', u'*****@*****.**')])
        self.store.commit()

        self.agent._connect = self._connect
        headers = {
            'X-Verify-Credentials-Authorization': ['OAuth ...'],
            'X-Auth-Service-Provider': [TWITTER_URL]
        }
        request = FakeRequest(headers=Headers(headers))
        with login(u'anon', self.anonymous.objectID, self.transact) as session:
            resource = OAuthEchoResource(session, self.agent)
            self.assertEqual(NOT_DONE_YET, resource.render_GET(request))

            [(_, responseDeferred)] = self.protocol.requests
            data = {'id': 1984245, 'screen_name': username, 'name': u'John'}
            response = FakeResponse(ResponseDone(), dumps(data))
            responseDeferred.callback(response)
            yield resource.deferred
            self.assertEqual(CONFLICT, request.code)
            headers = dict(request.responseHeaders.getAllRawHeaders())
            encodedUsername = b64encode(username.encode('utf-8'))
            self.assertEqual(
                {
                    'X-Fluiddb-Error-Class': ['UsernameConflict'],
                    'X-Fluiddb-Username': [encodedUsername],
                    'X-Fluiddb-Request-Id': [session.id]
                }, headers)
예제 #3
0
    def testRenderWithNewUser(self):
        """
        Missing L{User}s are created automatically and linked to
        L{TwitterUser}s for authorized UIDs.
        """
        self.assertNotIn(u'john', UserAPI().get([u'john']))
        self.store.commit()

        self.agent._connect = self._connect
        headers = {
            'X-Verify-Credentials-Authorization': ['OAuth ...'],
            'X-Auth-Service-Provider': [TWITTER_URL]
        }
        request = FakeRequest(headers=Headers(headers))
        with login(u'anon', self.anonymous.objectID, self.transact) as session:
            resource = OAuthEchoResource(session, self.agent)
            self.assertEqual(NOT_DONE_YET, resource.render_GET(request))

            [(_, responseDeferred)] = self.protocol.requests
            data = {'id': 1984245, 'screen_name': u'john', 'name': u'John'}
            response = FakeResponse(ResponseDone(), dumps(data))
            responseDeferred.callback(response)
            result = yield resource.deferred
            self.assertTrue(result['access-token'])
            self.assertTrue(result['renewal-token'])
            del result['access-token']
            del result['renewal-token']
            self.assertEqual(
                {
                    'username': u'john',
                    'new-user': True,
                    'missing-password': True,
                    'data': data,
                    'uid': 1984245
                }, result)
            self.assertEqual(OK, request.code)
            self.assertEqual(data, loads(request.written.getvalue()))
            headers = dict(request.responseHeaders.getAllRawHeaders())
            self.assertTrue(headers['X-Fluiddb-Access-Token'])
            self.assertTrue(headers['X-Fluiddb-Renewal-Token'])
            del headers['X-Fluiddb-Access-Token']
            del headers['X-Fluiddb-Renewal-Token']
            self.assertEqual(
                {
                    'X-Fluiddb-New-User': ['true'],
                    'X-Fluiddb-Missing-Password': ['true'],
                    'X-Fluiddb-Username': ['am9obg==']
                },  # username is in base64.
                headers)

            self.store.rollback()
            self.assertIn(u'john', UserAPI().get([u'john']))
예제 #4
0
    def getChild(self, path, request):
        if isinstance(self.session, UnauthorizedLogin):
            factories = [
                BasicCredentialFactory('fluidinfo.com'),
                OAuthCredentialFactory('fluidinfo.com'),
                OAuth2CredentialFactory('fluidinfo.com')
            ]
            return WSFEUnauthorizedResource(factories)

        # Add a unique id to the request so we can more easily trace its
        # progress in our log files. Note that we need to put an id on the
        # request even in the case that we're going to return NoResource,
        # as it's all logged.
        request._fluidDB_reqid = self.session.id
        self.session.http.trace(request)
        if path == 'oauthecho':
            return OAuthEchoResource(self.session)
        elif path == 'renew-oauth-token':
            return RenewOAuthTokenResource(self.session)
        try:
            resource = self._resources[path]
        except KeyError:
            return NoResource()
        else:
            return resource(self.facadeClient, self.session)
예제 #5
0
 def testRenderWithUnknownServiceProvider(self):
     """
     A C{BAD_REQUEST} HTTP status code is returned if the
     C{X-Auth-Service-Provider} in the header is not supported.
     """
     headers = {'X-Verify-Credentials-Authorization': ['OAuth ...'],
                'X-Auth-Service-Provider': ['https://example.com/1/verify']}
     request = FakeRequest(headers=Headers(headers))
     with login(u'anon', self.anonymous.objectID, self.transact) as session:
         resource = OAuthEchoResource(session)
         self.assertEqual('', resource.render_GET(request))
         headers = dict(request.responseHeaders.getAllRawHeaders())
         yield resource.deferred
         self.assertEqual(
             {'X-Fluiddb-Error-Class': ['UnknownServiceProvider'],
              'X-Fluiddb-Request-Id': [session.id]},
             headers)
예제 #6
0
    def testRenderWithNewUser(self):
        """
        Missing L{User}s are created automatically and linked to
        L{TwitterUser}s for authorized UIDs.
        """
        self.assertNotIn(u'john', UserAPI().get([u'john']))
        self.store.commit()

        self.agent._connect = self._connect
        headers = {'X-Verify-Credentials-Authorization': ['OAuth ...'],
                   'X-Auth-Service-Provider': [TWITTER_URL]}
        request = FakeRequest(headers=Headers(headers))
        with login(u'anon', self.anonymous.objectID, self.transact) as session:
            resource = OAuthEchoResource(session, self.agent)
            self.assertEqual(NOT_DONE_YET, resource.render_GET(request))

            [(_, responseDeferred)] = self.protocol.requests
            data = {'id': 1984245, 'screen_name': u'john', 'name': u'John'}
            response = FakeResponse(ResponseDone(), dumps(data))
            responseDeferred.callback(response)
            result = yield resource.deferred
            self.assertTrue(result['access-token'])
            self.assertTrue(result['renewal-token'])
            del result['access-token']
            del result['renewal-token']
            self.assertEqual({'username': u'john',
                              'new-user': True,
                              'missing-password': True,
                              'data': data,
                              'uid': 1984245},
                             result)
            self.assertEqual(OK, request.code)
            self.assertEqual(data, loads(request.written.getvalue()))
            headers = dict(request.responseHeaders.getAllRawHeaders())
            self.assertTrue(headers['X-Fluiddb-Access-Token'])
            self.assertTrue(headers['X-Fluiddb-Renewal-Token'])
            del headers['X-Fluiddb-Access-Token']
            del headers['X-Fluiddb-Renewal-Token']
            self.assertEqual(
                {'X-Fluiddb-New-User': ['true'],
                 'X-Fluiddb-Missing-Password': ['true'],
                 'X-Fluiddb-Username': ['am9obg==']},  # username is in base64.
                headers)

            self.store.rollback()
            self.assertIn(u'john', UserAPI().get([u'john']))
예제 #7
0
 def testRenderWithMissingServiceProviderHeader(self):
     """
     A C{BAD_REQUEST} HTTP status code is returned if the
     C{X-Auth-Service-Provider} header is not in the request, and the
     C{X-Fluiddb-*} response headers indicate that the header is missing.
     """
     headers = {'X-Verify-Credentials-Authorization': ['OAuth ...']}
     request = FakeRequest(headers=Headers(headers))
     with login(u'anon', self.anonymous.objectID, self.transact) as session:
         resource = OAuthEchoResource(session)
         self.assertEqual('', resource.render_GET(request))
         headers = dict(request.responseHeaders.getAllRawHeaders())
         yield resource.deferred
         self.assertEqual(
             {'X-Fluiddb-Error-Class': ['MissingHeader'],
              'X-Fluiddb-Header': ['X-Auth-Service-Provider'],
              'X-Fluiddb-Request-Id': [session.id]},
             headers)
예제 #8
0
 def testRenderWithMissingServiceProviderHeader(self):
     """
     A C{BAD_REQUEST} HTTP status code is returned if the
     C{X-Auth-Service-Provider} header is not in the request, and the
     C{X-Fluiddb-*} response headers indicate that the header is missing.
     """
     headers = {'X-Verify-Credentials-Authorization': ['OAuth ...']}
     request = FakeRequest(headers=Headers(headers))
     with login(u'anon', self.anonymous.objectID, self.transact) as session:
         resource = OAuthEchoResource(session)
         self.assertEqual('', resource.render_GET(request))
         headers = dict(request.responseHeaders.getAllRawHeaders())
         yield resource.deferred
         self.assertEqual(
             {
                 'X-Fluiddb-Error-Class': ['MissingHeader'],
                 'X-Fluiddb-Header': ['X-Auth-Service-Provider'],
                 'X-Fluiddb-Request-Id': [session.id]
             }, headers)
예제 #9
0
 def testRenderWithUnsupportedAuthorizationHeader(self):
     """
     A C{BAD_REQUEST} HTTP status code is returned if the
     C{X-Verify-Credentials-Authorization} in the header doesn't use the
     C{OAuth} scheme.
     """
     headers = {'X-Verify-Credentials-Authorization': ['Basic ...'],
                'X-Auth-Service-Provider': [TWITTER_URL]}
     request = FakeRequest(headers=Headers(headers))
     with login(u'anon', self.anonymous.objectID, self.transact) as session:
         resource = OAuthEchoResource(session)
         self.assertEqual('', resource.render_GET(request))
         headers = dict(request.responseHeaders.getAllRawHeaders())
         yield resource.deferred
         self.assertEqual(
             {'X-Fluiddb-Error-Class': ['BadHeader'],
              'X-Fluiddb-Header': ['X-Verify-Credentials-Authorization'],
              'X-Fluiddb-Request-Id': [session.id]},
             headers)
예제 #10
0
 def testRenderWithUnknownServiceProvider(self):
     """
     A C{BAD_REQUEST} HTTP status code is returned if the
     C{X-Auth-Service-Provider} in the header is not supported.
     """
     headers = {
         'X-Verify-Credentials-Authorization': ['OAuth ...'],
         'X-Auth-Service-Provider': ['https://example.com/1/verify']
     }
     request = FakeRequest(headers=Headers(headers))
     with login(u'anon', self.anonymous.objectID, self.transact) as session:
         resource = OAuthEchoResource(session)
         self.assertEqual('', resource.render_GET(request))
         headers = dict(request.responseHeaders.getAllRawHeaders())
         yield resource.deferred
         self.assertEqual(
             {
                 'X-Fluiddb-Error-Class': ['UnknownServiceProvider'],
                 'X-Fluiddb-Request-Id': [session.id]
             }, headers)
예제 #11
0
    def testRenderWithSuccessfulVerification(self):
        """
        An C{OK} HTTP status code is returned if the authorization is
        successfully verified by the service provider.  The results of the
        call to the service provider to verify credentials are returned to the
        user.
        """
        UserAPI().create([(u'john', 'secret', u'John', u'*****@*****.**')])
        TwitterUserAPI().create(u'john', 1984245)
        self.store.commit()

        self.agent._connect = self._connect
        headers = {
            'X-Verify-Credentials-Authorization': ['OAuth ...'],
            'X-Auth-Service-Provider': [TWITTER_URL]
        }
        request = FakeRequest(headers=Headers(headers))
        with login(u'anon', self.anonymous.objectID, self.transact) as session:
            resource = OAuthEchoResource(session, self.agent)
            self.assertEqual(NOT_DONE_YET, resource.render_GET(request))

            [(_, responseDeferred)] = self.protocol.requests
            data = {'id': 1984245, 'screen_name': u'john', 'name': u'John'}
            response = FakeResponse(ResponseDone(), dumps(data))
            responseDeferred.callback(response)
            result = yield resource.deferred
            self.assertTrue(result['access-token'])
            self.assertTrue(result['renewal-token'])
            del result['access-token']
            del result['renewal-token']
            self.assertEqual(
                {
                    'username': u'john',
                    'new-user': False,
                    'missing-password': False,
                    'data': data,
                    'uid': 1984245
                }, result)
            self.assertEqual(OK, request.code)
            self.assertEqual(data, loads(request.written.getvalue()))
예제 #12
0
 def testRenderWithUnsupportedAuthorizationHeader(self):
     """
     A C{BAD_REQUEST} HTTP status code is returned if the
     C{X-Verify-Credentials-Authorization} in the header doesn't use the
     C{OAuth} scheme.
     """
     headers = {
         'X-Verify-Credentials-Authorization': ['Basic ...'],
         'X-Auth-Service-Provider': [TWITTER_URL]
     }
     request = FakeRequest(headers=Headers(headers))
     with login(u'anon', self.anonymous.objectID, self.transact) as session:
         resource = OAuthEchoResource(session)
         self.assertEqual('', resource.render_GET(request))
         headers = dict(request.responseHeaders.getAllRawHeaders())
         yield resource.deferred
         self.assertEqual(
             {
                 'X-Fluiddb-Error-Class': ['BadHeader'],
                 'X-Fluiddb-Header': ['X-Verify-Credentials-Authorization'],
                 'X-Fluiddb-Request-Id': [session.id]
             }, headers)
예제 #13
0
    def testRenderWithFailingServiceProviderCall(self):
        """
        A C{SERVICE_UNAVAILABLE} HTTP status code is returned if an error
        occurs while communicating with the L{ServiceProvider}.
        """
        UserAPI().create([(u'user', 'secret', u'User', u'*****@*****.**')])
        TwitterUserAPI().create(u'user', 1984245)
        self.store.commit()

        self.agent._connect = self._connect
        headers = {'X-Verify-Credentials-Authorization': ['OAuth ...'],
                   'X-Auth-Service-Provider': [TWITTER_URL]}
        request = FakeRequest(headers=Headers(headers))
        with login(u'anon', self.anonymous.objectID, self.transact) as session:
            resource = OAuthEchoResource(session, self.agent)
            self.assertEqual(NOT_DONE_YET, resource.render_GET(request))

            [(_, responseDeferred)] = self.protocol.requests
            response = FakeResponse(RuntimeError(), None)
            responseDeferred.callback(response)
            yield resource.deferred
            self.assertEqual(SERVICE_UNAVAILABLE, request.code)
예제 #14
0
    def testRenderWithFailingServiceProviderCall(self):
        """
        A C{SERVICE_UNAVAILABLE} HTTP status code is returned if an error
        occurs while communicating with the L{ServiceProvider}.
        """
        UserAPI().create([(u'user', 'secret', u'User', u'*****@*****.**')])
        TwitterUserAPI().create(u'user', 1984245)
        self.store.commit()

        self.agent._connect = self._connect
        headers = {
            'X-Verify-Credentials-Authorization': ['OAuth ...'],
            'X-Auth-Service-Provider': [TWITTER_URL]
        }
        request = FakeRequest(headers=Headers(headers))
        with login(u'anon', self.anonymous.objectID, self.transact) as session:
            resource = OAuthEchoResource(session, self.agent)
            self.assertEqual(NOT_DONE_YET, resource.render_GET(request))

            [(_, responseDeferred)] = self.protocol.requests
            response = FakeResponse(RuntimeError(), None)
            responseDeferred.callback(response)
            yield resource.deferred
            self.assertEqual(SERVICE_UNAVAILABLE, request.code)
예제 #15
0
    def testRenderWithSuccessfulVerification(self):
        """
        An C{OK} HTTP status code is returned if the authorization is
        successfully verified by the service provider.  The results of the
        call to the service provider to verify credentials are returned to the
        user.
        """
        UserAPI().create([(u'john', 'secret', u'John', u'*****@*****.**')])
        TwitterUserAPI().create(u'john', 1984245)
        self.store.commit()

        self.agent._connect = self._connect
        headers = {'X-Verify-Credentials-Authorization': ['OAuth ...'],
                   'X-Auth-Service-Provider': [TWITTER_URL]}
        request = FakeRequest(headers=Headers(headers))
        with login(u'anon', self.anonymous.objectID, self.transact) as session:
            resource = OAuthEchoResource(session, self.agent)
            self.assertEqual(NOT_DONE_YET, resource.render_GET(request))

            [(_, responseDeferred)] = self.protocol.requests
            data = {'id': 1984245, 'screen_name': u'john', 'name': u'John'}
            response = FakeResponse(ResponseDone(), dumps(data))
            responseDeferred.callback(response)
            result = yield resource.deferred
            self.assertTrue(result['access-token'])
            self.assertTrue(result['renewal-token'])
            del result['access-token']
            del result['renewal-token']
            self.assertEqual({'username': u'john',
                              'new-user': False,
                              'missing-password': False,
                              'data': data,
                              'uid': 1984245},
                             result)
            self.assertEqual(OK, request.code)
            self.assertEqual(data, loads(request.written.getvalue()))