Esempio n. 1
0
    def testGetUserWithNewUserAndMixedCaseTwitterScreenName(self):
        """
        A new L{User} is created if L{Delegator.getUser} verifies the
        L{TwitterUser} but can't find a user matching the Twitter screen name.
        The Twitter user's screen name should be lowercased to make the
        new Fluidinfo username.
        """
        UserAPI().create([
            (u'consumer', 'secret', u'Consumer', u'*****@*****.**')])
        consumer = getUser(u'consumer')
        OAuthConsumerAPI().register(consumer)
        self.store.commit()

        self.agent._connect = self._connect
        authentication = 'OAuth oauth_consumer_key="...", ...'
        provider = ServiceProvider(self.agent, 'https://example.com/verify')
        delegator = Delegator(self.transact)
        deferred = delegator.getUser(u'consumer', provider, authentication)

        [(request, responseDeferred)] = self.protocol.requests
        response = FakeResponse(ResponseDone(),
                                dumps({'id': 1984245,
                                       'screen_name': u'MixedCaseName',
                                       'name': u'John Doe'}))
        responseDeferred.callback(response)
        result = yield deferred
        self.assertTrue(result['new-user'])
        user = TwitterUserAPI().get(1984245)
        self.assertEqual(u'mixedcasename', user.username)
Esempio n. 2
0
    def testGetUserWithNoPassword(self):
        """
        If a L{User} returned by L{Delegator.getUser} doesn't have a password,
        a C{missing-password} value is added to the result.
        """
        UserAPI().create([
            (u'consumer', 'secret', u'Consumer', u'*****@*****.**'),
            (u'user', None, u'User', u'*****@*****.**')])
        TwitterUserAPI().create(u'user', 1984245)
        consumer = getUser(u'consumer')
        OAuthConsumerAPI().register(consumer)
        self.store.commit()

        self.agent._connect = self._connect
        authentication = 'OAuth oauth_consumer_key="...", ...'
        provider = ServiceProvider(self.agent, 'https://example.com/verify')
        delegator = Delegator(self.transact)
        deferred = delegator.getUser(u'consumer', provider, authentication)

        [(request, responseDeferred)] = self.protocol.requests
        response = FakeResponse(ResponseDone(), dumps({'id': 1984245}))
        responseDeferred.callback(response)
        result = yield deferred
        self.assertTrue(result['access-token'])
        self.assertTrue(result['renewal-token'])
        del result['access-token']
        del result['renewal-token']
        self.assertEqual({'username': u'user',
                          'new-user': False,
                          'missing-password': True,
                          'uid': 1984245,
                          'data': {u'id': 1984245}},
                         result)
Esempio n. 3
0
    def testGetUserWithUserConflict(self):
        """
        A L{DuplicateUserError} exception is raised if a L{User} with the same
        username as the Twitter user's screen name already exists, but is not
        associated with the Twitter UID.
        """
        UserAPI().create([
            (u'consumer', 'secret', u'Consumer', u'*****@*****.**'),
            (u'john', 'secret', u'John', u'*****@*****.**')])
        self.store.commit()

        self.agent._connect = self._connect
        authentication = 'OAuth oauth_consumer_key="...", ...'
        consumer = getUser(u'consumer')
        provider = ServiceProvider(self.agent, 'https://example.com/verify')
        delegator = Delegator(self.transact)
        deferred = delegator.getUser(consumer, provider, authentication)

        [(request, responseDeferred)] = self.protocol.requests
        response = FakeResponse(ResponseDone(), dumps({'id': 1984245,
                                                       'screen_name': u'john',
                                                       'name': u'John Doe'}))
        responseDeferred.callback(response)
        error = yield self.assertFailure(deferred, DuplicateUserError)
        self.assertEqual([u'john'], list(error.usernames))
Esempio n. 4
0
    def testGetUser(self):
        """
        L{Delegator.getUser} returns a C{(User, data)} 2-tuple when the
        service provider successfully verifies credentials and a mapping
        between a Fluidinfo L{User} and the L{TwitterUser} being verified
        exists.
        """
        UserAPI().create([
            (u'consumer', 'secret', u'Consumer', u'*****@*****.**'),
            (u'user', 'secret', u'User', u'*****@*****.**')])
        TwitterUserAPI().create(u'user', 1984245)
        consumer = getUser(u'consumer')
        OAuthConsumerAPI().register(consumer)
        self.store.commit()

        self.agent._connect = self._connect
        authentication = 'OAuth oauth_consumer_key="...", ...'
        provider = ServiceProvider(self.agent, 'https://example.com/verify')
        delegator = Delegator(self.transact)
        deferred = delegator.getUser(u'consumer', provider, authentication)

        [(request, responseDeferred)] = self.protocol.requests
        response = FakeResponse(ResponseDone(), dumps({'id': 1984245}))
        responseDeferred.callback(response)
        result = yield deferred
        self.assertTrue(result['access-token'])
        self.assertTrue(result['renewal-token'])
        del result['access-token']
        del result['renewal-token']
        self.assertEqual({'username': u'user',
                          'new-user': False,
                          'missing-password': False,
                          'uid': 1984245,
                          'data': {u'id': 1984245}},
                         result)
Esempio n. 5
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)
Esempio n. 6
0
    def test_json_content(self):
        d = json_content(self.response)

        self.protocol.dataReceived('{"msg":"hello!"}')
        self.protocol.connectionLost(Failure(ResponseDone()))

        self.assertEqual(self.successResultOf(d), {"msg": "hello!"})
Esempio n. 7
0
    def test_connectionLostDoneAfterError(self):
        """
        Reconnect with initial interval after succesful reconnect.
        """
        self.setUpState('connecting')

        # First connect fails.
        self.api.connectFail(ConnectError())
        self.flushLoggedErrors(ConnectError)

        # A reconnect is attempted
        self.clock.advance(0.25)
        self.assertEqual(2, len(self.api.filterCalls))

        # Reconnect succeeds.
        self.api.connected()

        # Connection closed by other party.
        self.api.protocol.connectionLost(failure.Failure(ResponseDone()))
        self.clock.advance(0)

        # A reconnect is attempted, but not before the back off delay.
        self.assertEqual(2, len(self.api.filterCalls))
        self.clock.advance(DELAY_INITIAL)
        self.assertEqual(3, len(self.api.filterCalls))

        # Second reconnect fails.
        self.api.connectFail(ConnectError())
        self.flushLoggedErrors(ConnectError)

        # A reconnect is attempted, but not before the same back off delay.
        self.assertEqual(3, len(self.api.filterCalls))
        self.clock.advance(0.25)
        self.assertEqual(4, len(self.api.filterCalls))
Esempio n. 8
0
 def deliverBody(self, protocol):
     """
     Immediately deliver the entire response body to C{protocol}.
     """
     protocol.makeConnection(_StubProducer())
     protocol.dataReceived(self._responseBody)
     protocol.connectionLost(Failure(ResponseDone()))
Esempio n. 9
0
    def test_connectConnectingReconnect(self):
        """
        Don't connect while connecting.
        """
        self.setUpState('connecting')

        # Try to connect.
        self.monitor.connect(forceReconnect=True)

        # As we haven't connected yet, we cannot drop the connection yet,
        # and no reconnect should have taken place.
        self.clock.advance(DELAY_INITIAL)
        self.assertEqual(1, len(self.api.filterCalls))

        # The initial connection is now established.
        self.api.connected()

        # A disconnect occurs right away.
        self.clock.advance(0)
        self.assertTrue(self.api.protocol.stopCalled)
        self.api.protocol.connectionLost(failure.Failure(ResponseDone()))
        self.clock.advance(0)

        # Now the reconnect occurs, wait for delayed calls.
        self.clock.advance(DELAY_INITIAL)
        self.assertEqual(2, len(self.api.filterCalls))
Esempio n. 10
0
 def test_closedNoTimeout(self):
     """
     When the connection is done, there is no timeout.
     """
     self.protocol.connectionLost(failure.Failure(ResponseDone()))
     self.assertEquals(None, self.protocol.timeOut)
     return self.protocol.deferred
Esempio n. 11
0
 def connection_lost(self, reason):
     self._stream_response = None
     self._stream_protocol = None
     if reason.check(PotentialDataLoss):
         reason = Failure(ResponseDone())
     if self.disconnect_callback is not None:
         self.disconnect_callback(self, reason)
     self._reconnect()
Esempio n. 12
0
    def test_content(self):
        d = content(self.response)

        self.protocol.dataReceived(b'foo')
        self.protocol.dataReceived(b'bar')
        self.protocol.connectionLost(Failure(ResponseDone()))

        self.assertEqual(self.successResultOf(d), b'foobar')
Esempio n. 13
0
    def test_text_content_default_encoding_no_param(self):
        self.response.headers = Headers({'Content-Type': ['text/plain']})

        d = text_content(self.response)

        self.protocol.dataReceived('\xa1')
        self.protocol.connectionLost(Failure(ResponseDone()))

        self.assertEqual(self.successResultOf(d), u'\xa1')
Esempio n. 14
0
    def test_text_content_default_encoding_no_header(self):
        self.response.headers = Headers()

        d = text_content(self.response)

        self.protocol.dataReceived(b'\xa1')
        self.protocol.connectionLost(Failure(ResponseDone()))

        self.assertEqual(self.successResultOf(d), u'\xa1')
Esempio n. 15
0
 def feed_response(protocol):
     config = {
         "relays": [
             {
                 "fingerprint": "boom",
             },
         ]
     }
     protocol.dataReceived(json.dumps(config).encode())
     protocol.connectionLost(Failure(ResponseDone()))
Esempio n. 16
0
 def feed_response(protocol):
     config = {
         "relays": [
             {
                 "fingerprint": "00786E43CCC5409753F25E36031C5CEA6EA43702",
             },
         ]
     }
     protocol.dataReceived(json.dumps(config).encode())
     protocol.connectionLost(Failure(ResponseDone()))
Esempio n. 17
0
    def test_no_error(self):
        """A response that is NOT too large."""

        # Start sending data.
        self.protocol.dataReceived(b"12345")
        # Close the connection.
        self.protocol.connectionLost(Failure(ResponseDone()))

        self.assertEqual(self.result.getvalue(), b"12345")
        self.assertEqual(self.deferred.result, 5)
Esempio n. 18
0
    def test_content_application_json_default_encoding(self):
        self.response.headers = Headers(
            {b'Content-Type': [b'application/json']})

        d = text_content(self.response)

        self.protocol.dataReceived(b'gr\xc3\xbcn')
        self.protocol.connectionLost(Failure(ResponseDone()))

        self.assertEqual(self.successResultOf(d), u'grün')
Esempio n. 19
0
    def test_text_content(self):
        self.response.headers = Headers(
            {b'Content-Type': [b'text/plain; charset=utf-8']})

        d = text_content(self.response)

        self.protocol.dataReceived(b'\xe2\x98\x83')
        self.protocol.connectionLost(Failure(ResponseDone()))

        self.assertEqual(self.successResultOf(d), u'\u2603')
Esempio n. 20
0
    def test_content_multiple_waiters(self):
        d1 = content(self.response)
        d2 = content(self.response)

        self.protocol.dataReceived(b'foo')
        self.protocol.connectionLost(Failure(ResponseDone()))

        self.assertEqual(self.successResultOf(d1), b'foo')
        self.assertEqual(self.successResultOf(d2), b'foo')

        self.assertNotIdentical(d1, d2)
Esempio n. 21
0
    def test_multiple_packets(self):
        """Data should be accummulated through mutliple packets."""

        # Start sending data.
        self.protocol.dataReceived(b"12")
        self.protocol.dataReceived(b"34")
        # Close the connection.
        self.protocol.connectionLost(Failure(ResponseDone()))

        self.assertEqual(self.result.getvalue(), b"1234")
        self.assertEqual(self.deferred.result, 4)
Esempio n. 22
0
    def test_too_large(self):
        """A response which is too large raises an exception."""

        # Start sending data.
        self.protocol.dataReceived(b"1234567890")
        # Close the connection.
        self.protocol.connectionLost(Failure(ResponseDone()))

        self.assertEqual(self.result.getvalue(), b"1234567890")
        self.assertIsInstance(self.deferred.result, Failure)
        self.assertIsInstance(self.deferred.result.value, BodyExceededMaxSize)
        self._cleanup_error()
Esempio n. 23
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']))
Esempio n. 24
0
    def test_collect(self):
        data = []

        d = collect(self.response, data.append)

        self.protocol.dataReceived(b'{')
        self.protocol.dataReceived(b'"msg": "hell')
        self.protocol.dataReceived(b'o"}')

        self.protocol.connectionLost(Failure(ResponseDone()))

        self.assertEqual(self.successResultOf(d), None)

        self.assertEqual(data, [b'{', b'"msg": "hell', b'o"}'])
Esempio n. 25
0
    def test_json_content_utf16(self):
        """
        JSON received is decoded according to the charset given in the
        Content-Type header.
        """
        self.response.headers = Headers({
            b'Content-Type': [b"application/json; charset='UTF-16LE'"],
        })
        d = json_content(self.response)

        self.protocol.dataReceived(u'{"msg":"hëlló!"}'.encode('UTF-16LE'))
        self.protocol.connectionLost(Failure(ResponseDone()))

        self.assertEqual(self.successResultOf(d), {u'msg': u'hëlló!'})
Esempio n. 26
0
    def test_json_content_unicode(self):
        """
        When Unicode JSON content is received, the JSON text should be
        correctly decoded.
        RFC7159 (8.1): "JSON text SHALL be encoded in UTF-8, UTF-16, or UTF-32.
        The default encoding is UTF-8"
        """
        self.response.headers = Headers()
        d = json_content(self.response)

        self.protocol.dataReceived(u'{"msg":"hëlló!"}'.encode('utf-8'))
        self.protocol.connectionLost(Failure(ResponseDone()))

        self.assertEqual(self.successResultOf(d), {u'msg': u'hëlló!'})
Esempio n. 27
0
    def test_stopServiceConnected(self):
        """
        Stopping the service while waiting to reconnect should abort.
        """
        self.setUpState('connected')

        # Stop the service.
        self.monitor.stopService()

        # Actually lose the connection
        self.api.protocol.connectionLost(failure.Failure(ResponseDone()))

        # No reconnect should be attempted.
        self.clock.advance(DELAY_INITIAL)
        self.assertEqual(1, len(self.api.filterCalls))
Esempio n. 28
0
    def testVerifyCredentialsUnpacksSuccessfulResponse(self):
        """
        L{ServiceProvider.verifyCredentials} returns a C{Deferred} that
        fires with the user object returned by Twitter, as a C{dict}, when
        credentials are successfully verified.
        """
        self.agent._connect = self._connect
        authentication = 'OAuth oauth_consumer_key="...", ...'
        provider = ServiceProvider(self.agent, 'https://example.com/verify')
        deferred = provider.verifyCredentials(authentication)

        [(request, responseDeferred)] = self.protocol.requests
        response = FakeResponse(ResponseDone(), dumps({'id': 1984245}))
        responseDeferred.callback(response)
        user = yield deferred
        self.assertEqual(1984245, user['id'])
Esempio n. 29
0
    def test_connectionLostDone(self):
        """
        When the connection is closed while connected, attempt reconnect.
        """
        self.setUpState('connected')

        # Connection closed by other party.
        self.api.protocol.connectionLost(failure.Failure(ResponseDone()))
        self.clock.advance(0)

        # A reconnect is attempted, but not before the back off delay.
        self.assertEqual(1, len(self.api.filterCalls))
        self.clock.advance(1)
        self.assertEqual(1, len(self.api.filterCalls))
        self.clock.advance(DELAY_INITIAL - 1)
        self.assertEqual(2, len(self.api.filterCalls))
Esempio n. 30
0
    def test_text_content_unicode_headers(self):
        """
        Header parsing is robust against unicode header names and values.
        """
        self.response.headers = Headers({
            b'Content-Type':
            [u'text/plain; charset="UTF-16BE"; u=ᛃ'.encode('utf-8')],
            u'Coördination'.encode('iso-8859-1'):
            [u'koʊˌɔrdɪˈneɪʃən'.encode('utf-8')],
        })

        d = text_content(self.response)

        self.protocol.dataReceived(u'ᚠᚡ'.encode('UTF-16BE'))
        self.protocol.connectionLost(Failure(ResponseDone()))

        self.assertEqual(self.successResultOf(d), u'ᚠᚡ')