Exemple #1
0
    def testRenderWithUnknownConsumer(self):
        """
        A C{BAD_REQUEST} HTTP status code is returned if an
        L{OAuthRenewalToken} for an unknown L{OAuthConsumer} is used in a
        renewal request.
        """
        UserAPI().create(
            [(u'consumer', 'secret', u'Consumer', u'*****@*****.**'),
             (u'user', 'secret', u'User', u'*****@*****.**')])
        consumer = getUser(u'consumer')
        user = getUser(u'consumer')
        api = OAuthConsumerAPI()
        api.register(consumer)
        token = api.getRenewalToken(consumer, user)
        headers = {'X-FluidDB-Renewal-Token': [token.encrypt()]}
        self.store.find(OAuthConsumer).remove()
        self.store.commit()

        request = FakeRequest(headers=Headers(headers))
        with login(u'consumer', consumer.objectID, self.transact) as session:
            resource = RenewOAuthTokenResource(session)
            self.assertEqual(NOT_DONE_YET, resource.render_GET(request))
            yield resource.deferred
            headers = dict(request.responseHeaders.getAllRawHeaders())
            self.assertEqual(
                {'X-Fluiddb-Error-Class': ['UnknownConsumer'],
                 'X-Fluiddb-Username': ['consumer'],
                 'X-Fluiddb-Request-Id': [session.id]},
                headers)
            self.assertEqual(BAD_REQUEST, request.code)
Exemple #2
0
    def testRenewToken(self):
        """
        L{SecureOAuthConsumerAPI.renewToken} generates a new
        L{OAuthRenewalToken} and L{OAuthAccessToken}, given a valid
        L{OAuthRenewalToken}.
        """
        UserAPI().create([
            (u'consumer', u'secret', u'Consumer', u'*****@*****.**'),
            (u'user', u'secret', u'User', u'*****@*****.**')])
        consumer = getUser(u'consumer')
        user = getUser(u'user')

        api = OAuthConsumerAPI()
        api.register(consumer)
        token = api.getRenewalToken(consumer, user).encrypt()
        encryptedRenewalToken, encryptedAccessToken = (
            SecureOAuthConsumerAPI().renewToken(u'consumer', token))
        renewalToken = OAuthRenewalToken.decrypt(consumer,
                                                 encryptedRenewalToken)
        accessToken = OAuthAccessToken.decrypt(consumer, encryptedAccessToken)
        self.assertTrue(isinstance(renewalToken, OAuthRenewalToken))
        self.assertIdentical(consumer, renewalToken.consumer)
        self.assertIdentical(user, renewalToken.user)
        self.assertTrue(isinstance(accessToken, OAuthAccessToken))
        self.assertIdentical(consumer, accessToken.consumer)
        self.assertIdentical(user, accessToken.user)
Exemple #3
0
    def testRenderWithExpiredRenewalToken(self):
        """
        An C{UNAUTHORIZED} HTTP status code is returned if an expired
        L{OAuthRenewalToken} is used in a renewal request.
        """
        UserAPI().create(
            [(u'consumer', 'secret', u'Consumer', u'*****@*****.**'),
             (u'user', 'secret', u'User', u'*****@*****.**')])
        consumer = getUser(u'consumer')
        user = getUser(u'consumer')
        api = OAuthConsumerAPI()
        api.register(consumer)
        creationTime = datetime.utcnow() - timedelta(hours=200)
        token = api.getRenewalToken(consumer, user, now=lambda: creationTime)
        self.store.commit()

        headers = {'X-FluidDB-Renewal-Token': [token.encrypt()]}
        request = FakeRequest(headers=Headers(headers))
        with login(u'consumer', consumer.objectID, self.transact) as session:
            resource = RenewOAuthTokenResource(session)
            self.assertEqual(NOT_DONE_YET, resource.render_GET(request))
            yield resource.deferred
            headers = dict(request.responseHeaders.getAllRawHeaders())
            self.assertEqual(
                {'X-Fluiddb-Error-Class': ['ExpiredOAuth2RenewalToken'],
                 'X-Fluiddb-Username': ['consumer'],
                 'X-Fluiddb-Request-Id': [session.id]},
                headers)
            self.assertEqual(UNAUTHORIZED, request.code)
Exemple #4
0
    def testAuthenticateOAuthWithIncorrectSignature(self):
        """
        L{OAuthConsumerAPI.authenticate} raises an L{AuthenticationError}
        exception if the signature in the L{OAuthCredentials} is incorrect.
        """
        UserAPI().create([
            (u'consumer', u'secret', u'Consumer', u'*****@*****.**'),
            (u'user', u'secret', u'User', u'*****@*****.**')])
        consumerUser = getUser(u'consumer')
        user = getUser(u'user')

        api = OAuthConsumerAPI()
        consumer = api.register(consumerUser, secret='abyOTsAfo9MVN0qz')
        timestamp = 1314976811
        headers = {'header1': 'foo'}
        arguments = 'argument1=bar'
        oauthEchoSecret = getConfig().get('oauth', 'access-secret')
        token = dataToToken(oauthEchoSecret + consumer.secret,
                            {'username': user.username,
                             'creationTime': '2012-12-28 16:18:23'})
        signature = 'wrong'
        nonce = 'nonce'
        credentials = OAuthCredentials(
            'fluidinfo.com', consumerUser.username, token, 'HMAC-SHA1',
            signature, timestamp, nonce, 'GET', u'https://fluidinfo.com/foo',
            headers, arguments)
        self.assertRaises(AuthenticationError, api.authenticate, credentials)
Exemple #5
0
    def testAuthenticateOAuth(self):
        """
        L{OAuthConsumerAPI.authenticate} returns the L{User} when passed valid
        L{OAuthCredentials}.  In the case of OAuth Echo, and in the case of
        this test, a consumer makes a request using a token that grants it
        access to act on behalf of a particular user.
        """
        UserAPI().create([(u'consumer', u'password', u'Consumer',
                           u'*****@*****.**')])
        UserAPI().create([(u'user', u'secret', u'User', u'*****@*****.**')])
        consumer = getUser(u'consumer')
        user = getUser(u'user')

        api = OAuthConsumerAPI()
        api.register(consumer, secret='abyOTsAfo9MVN0qz')
        token = api.getAccessToken(consumer, user)
        timestamp = 1314976811
        headers = {'header1': 'foo'}
        arguments = 'argument1=bar'
        signature = 'Sno1ocDhYv9vwJnEJATE3cmUvSo='
        nonce = 'nonce'
        credentials = OAuthCredentials(
            'fluidinfo.com', consumer.username, token.encrypt(), 'HMAC-SHA1',
            signature, timestamp, nonce, 'GET', u'https://fluidinfo.com/foo',
            headers, arguments)
        self.assertIdentical(user, api.authenticate(credentials))
Exemple #6
0
    def testRequestAvatarId(self):
        """
        L{FacadeOAuthChecker.requestAvatarId} creates a
        L{FluidinfoSession} for the authenticated user only if credentials are
        correct.
        """
        UserAPI().create([(u'consumer', u'secret', u'Consumer',
                           u'*****@*****.**'),
                          (u'user', u'secret', u'User', u'*****@*****.**')])
        consumerUser = getUser(u'consumer')
        user = getUser(u'user')
        api = OAuthConsumerAPI()
        consumer = api.register(consumerUser)
        token = api.getAccessToken(consumerUser, user)
        self.store.commit()

        timestamp = 1314976811
        headers = {'header1': 'foo'}
        arguments = 'argument1=bar'
        # FIXME This isn't ideal.  It'd be better to use a hard-coded
        # signature, because then we'd know when something changed.  It's hard
        # to do that, though, because the encrypted token generated by
        # fluiddb.util.minitoken is always different. -jkakar
        request = Request.from_request('GET', u'https://fluidinfo.com/foo',
                                       headers, {'argument1': 'bar'})
        signature = SignatureMethod_HMAC_SHA1().sign(request, consumer, None)
        nonce = 'nonce'
        credentials = OAuthCredentials('fluidinfo.com', consumerUser.username,
                                       token.encrypt(), 'HMAC-SHA1', signature,
                                       timestamp, nonce, 'GET',
                                       u'https://fluidinfo.com/foo', headers,
                                       arguments)
        session = yield self.checker.requestAvatarId(credentials)
        self.assertEqual(user.username, session.auth.username)
        self.assertEqual(user.objectID, session.auth.objectID)
Exemple #7
0
    def testAuthenticateUserWithOAuthIncorrectSignature(self):
        """
        L{FacadeAuthMixin.authenticateUserWithOAuth} raises a
        L{TPasswordIncorrect} exception if the signature in the OAuth
        credentials is incorrect.
        """
        UserAPI().create([
            (u'consumer', u'secret', u'Consumer', u'*****@*****.**'),
            (u'user', u'secret', u'User', u'*****@*****.**')])
        consumerUser = getUser(u'consumer')
        user = getUser(u'user')
        api = OAuthConsumerAPI()
        api.register(consumerUser)
        token = api.getAccessToken(consumerUser, user)

        self.store.commit()
        timestamp = 1314976811
        headers = {'header1': 'foo'}
        arguments = 'argument1=bar'
        signature = 'wrong'
        nonce = 'nonce'
        credentials = OAuthCredentials(
            'fluidinfo.com', user.username, token.encrypt(), u'HMAC-SHA1',
            signature, timestamp, nonce, 'GET', 'https://fluidinfo.com/foo',
            headers, arguments)
        deferred = self.facade.authenticateUserWithOAuth(credentials)
        return self.assertFailure(deferred, TPasswordIncorrect)
Exemple #8
0
    def testAuthenticateUserWithOAuthWithMixedCaseInToken(self):
        """
        L{FacadeAuthMixin.authenticateUserWithOAuth} ignores the case in the
        username in the token.
        """
        UserAPI().create([
            (u'consumer', u'secret', u'Consumer', u'*****@*****.**'),
            (u'user', u'secret', u'User', u'*****@*****.**')])
        consumerUser = getUser(u'consumer')
        user = getUser(u'user')
        api = OAuthConsumerAPI()
        consumer = api.register(consumerUser)
        token = dataToToken(consumer.secret,
                            {'username': u'UseR',
                             'creationTime': '20121228-161823'})

        self.store.commit()
        timestamp = 1314976811
        headers = {'header1': 'foo'}
        arguments = 'argument1=bar'
        request = Request.from_request('GET', u'https://fluidinfo.com/foo',
                                       headers, {'argument1': 'bar'})
        signature = SignatureMethod_HMAC_SHA1().sign(request,
                                                     consumer, None)
        nonce = 'nonce'
        credentials = OAuthCredentials(
            'fluidinfo.com', consumerUser.username, token,
            'HMAC-SHA1', signature, timestamp, nonce, 'GET',
            u'https://fluidinfo.com/foo', headers, arguments)
        session = yield self.facade.authenticateUserWithOAuth(credentials)
        self.assertEqual(user.username, session.auth.username)
        self.assertEqual(user.objectID, session.auth.objectID)
Exemple #9
0
    def testAuthenticateUserWithOAuth(self):
        """
        L{FacadeAuthMixin.authenticateUserWithOAuth} creates a
        L{FluidinfoSession} for the authenticated user only if credentials are
        correct.
        """
        UserAPI().create([
            (u'consumer', u'secret', u'Consumer', u'*****@*****.**'),
            (u'user', u'secret', u'User', u'*****@*****.**')])
        consumerUser = getUser(u'consumer')
        user = getUser(u'user')
        api = OAuthConsumerAPI()
        consumer = api.register(consumerUser)
        token = api.getAccessToken(consumerUser, user)

        self.store.commit()
        timestamp = 1314976811
        headers = {'header1': 'foo'}
        arguments = 'argument1=bar'
        request = Request.from_request('GET', u'https://fluidinfo.com/foo',
                                       headers, {'argument1': 'bar'})
        signature = SignatureMethod_HMAC_SHA1().sign(request,
                                                     consumer, None)
        nonce = 'nonce'
        credentials = OAuthCredentials(
            'fluidinfo.com', consumerUser.username, token.encrypt(),
            'HMAC-SHA1', signature, timestamp, nonce, 'GET',
            u'https://fluidinfo.com/foo', headers, arguments)
        session = yield self.facade.authenticateUserWithOAuth(credentials)
        self.assertEqual(user.username, session.auth.username)
        self.assertEqual(user.objectID, session.auth.objectID)
Exemple #10
0
    def testRenderWithSuccessfulVerification(self):
        """
        An C{OK} HTTP status code is returned, along with new access and
        renewal tokens, if a renewal request is successful.
        """
        UserAPI().create(
            [(u'consumer', 'secret', u'Consumer', u'*****@*****.**'),
             (u'user', 'secret', u'User', u'*****@*****.**')])
        consumer = getUser(u'consumer')
        user = getUser(u'consumer')
        api = OAuthConsumerAPI()
        api.register(consumer)
        token = api.getRenewalToken(consumer, user)
        self.store.commit()

        headers = {'X-FluidDB-Renewal-Token': [token.encrypt()]}
        request = FakeRequest(headers=Headers(headers))
        with login(u'consumer', consumer.objectID, self.transact) as session:
            resource = RenewOAuthTokenResource(session)
            self.assertEqual(NOT_DONE_YET, resource.render_GET(request))

            yield resource.deferred
            headers = dict(request.responseHeaders.getAllRawHeaders())
            self.assertTrue(headers['X-Fluiddb-Access-Token'])
            self.assertTrue(headers['X-Fluiddb-Renewal-Token'])
            self.assertEqual(OK, request.code)
Exemple #11
0
    def testGetRecentUserActivity(self):
        """
        L{FacadeRecentActivityMixin.getRecentUserActivity} returns a C{dict}
        with information about the recent tag values on the given user.
        """
        tagValues = TagValueAPI(self.user)
        objectID1 = ObjectAPI(self.user).create(u'object1')
        objectID2 = uuid4()

        # Use commit() frequently to have different timestamps on each value.
        self.store.commit()
        tagValues.set({objectID1: {u'user/tag1': u'A'}})
        self.store.commit()
        tagValues.set({objectID1: {u'user/tag2': u'B'}})
        self.store.commit()

        UserAPI().create([(u'user2', u'secret', u'User', u'*****@*****.**')])
        tagValues = TagValueAPI(getUser(u'user2'))

        tagValues.set({objectID1: {u'user2/tag1': u'C'}})
        self.store.commit()
        tagValues.set({objectID2: {u'user2/tag2': u'D'}})
        self.store.commit()

        UserAPI().create([(u'user3', u'secret', u'User', u'*****@*****.**')])
        tagValues = TagValueAPI(getUser(u'user3'))

        tagValues.set({objectID1: {u'user3/tag1': u'C'}})
        self.store.commit()
        tagValues.set({objectID2: {u'user3/tag2': u'D'}})
        self.store.commit()

        expected = [
            {'tag': u'user/tag2',
             'id': str(objectID1),
             'about': u'object1',
             'value': u'B',
             'username': u'username'},

            {'tag': u'user/tag1',
             'id': str(objectID1),
             'about': u'object1',
             'value': u'A',
             'username': u'username'}]

        with login(self.user.username, uuid4(), self.transact) as session:
            result = yield self.facade.getRecentUserActivity(
                session, self.user.username.encode('utf-8'))
            # Remove the creation times from the result.
            for item in result:
                del item['updated-at']
            self.assertEqual(expected, result)
Exemple #12
0
    def testInstantiate(self):
        """An OAuth token contains a consumer, user and creation time."""
        UserAPI().create([
            (u'consumer', u'secret', u'Consumer', u'*****@*****.**'),
            (u'user', u'secret', u'User', u'*****@*****.**')])
        consumer = getUser(u'consumer')
        user = getUser(u'user')
        now = datetime.utcnow()

        token = self.cls(consumer, user, lambda: now)
        self.assertEqual(consumer, token.consumer)
        self.assertEqual(user, token.user)
        self.assertEqual(now, token.creationTime)
Exemple #13
0
    def testEncryptTokenWithUnknownConsumer(self):
        """
        L{OAuthTokenBase.encrypt} raises an L{UnknownConsumerError} if the
        consumer specified in the token doesn't have a matching
        L{OAuthConsumer} object.
        """
        UserAPI().create([
            (u'consumer', u'secret', u'Consumer', u'*****@*****.**'),
            (u'user', u'secret', u'User', u'*****@*****.**')])
        consumer = getUser(u'consumer')
        user = getUser(u'user')

        token = self.cls(consumer, user)
        self.assertRaises(UnknownConsumerError, token.encrypt)
    def testGetForUsersReturnsOnlyAllowedTags(self):
        """
        L{SecureRecentActivityAPI.getForUser} returns all the tags for the
        superuser.
        """
        tagValues = TagValueAPI(self.user)
        objectID1 = ObjectAPI(self.user).create(u'object1')
        objectID2 = uuid4()

        # Use commit() frequently to have different timestamps on each value.
        self.store.commit()
        tagValues.set({objectID1: {u'user/tag1': u'A'}})
        self.store.commit()
        tagValues.set({objectID1: {u'user/tag2': u'B'}})
        self.store.commit()

        UserAPI().create([(u'user2', u'secret', u'User', u'*****@*****.**')])
        tagValues = TagValueAPI(getUser(u'user2'))

        tagValues.set({objectID1: {u'user2/tag1': u'C'}})
        self.store.commit()
        tagValues.set({objectID2: {u'user2/tag2': u'D'}})
        self.store.commit()

        UserAPI().create([(u'user3', u'secret', u'User', u'*****@*****.**')])
        tagValues = TagValueAPI(getUser(u'user3'))

        tagValues.set({objectID1: {u'user3/tag1': u'C'}})
        self.store.commit()
        tagValues.set({objectID2: {u'user3/tag2': u'D'}})
        self.store.commit()

        self.permissions.set([(u'user/tag2', Operation.READ_TAG_VALUE,
                               Policy.OPEN, [u'user']),
                              (u'user2/tag2', Operation.READ_TAG_VALUE,
                               Policy.CLOSED, [])])

        expected = [
            (u'user2/tag2', objectID2, None, u'D', u'user2'),
            (u'user2/tag1', objectID1, u'object1', u'C', u'user2'),
            (u'user/tag2', objectID1, u'object1', u'B', u'user'),
            (u'user/tag1', objectID1, u'object1', u'A', u'user')]

        result = self.recentActivity.getForUsers([u'user', u'user2'])
        # Remove the creation times from the result, with the order is enough.
        result = [(path, objectID, about, value, username)
                  for path, objectID, about, value, username, time in result]
        self.assertEqual(expected, result)
Exemple #15
0
    def testCreatePrivateChildTagWithDelegatedCreator(self):
        """
        L{TagAPI.create} always ensures that a new L{Tag} is usable by the
        L{User} that created it.  If the L{Operation.READ_TAG_VALUE}
        permission is L{Policy.CLOSED} the creator is added to the exceptions
        list.
        """
        UserAPI().create([(u'friend', u'secret', u'name', u'*****@*****.**')
                          ])
        PermissionAPI(self.user).set([(u'username', Operation.CREATE_NAMESPACE,
                                       Policy.CLOSED, [u'username',
                                                       u'friend']),
                                      (u'username', Operation.LIST_NAMESPACE,
                                       Policy.CLOSED, [u'username',
                                                       u'friend'])])

        friend = getUser(u'friend')
        TagAPI(friend).create([(u'username/tag', u'A shared tag')])
        result = getTagPermissions([u'username/tag'])
        tag, permission = result.one()
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.UPDATE_TAG))
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.DELETE_TAG))
        self.assertEqual((Policy.CLOSED, [self.user.id]),
                         permission.get(Operation.CONTROL_TAG))
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.WRITE_TAG_VALUE))
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.READ_TAG_VALUE))
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.DELETE_TAG_VALUE))
        self.assertEqual((Policy.CLOSED, [self.user.id]),
                         permission.get(Operation.CONTROL_TAG_VALUE))
Exemple #16
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))
Exemple #17
0
    def create(self, values):
        """Create new L{Namespace}s.

        Missing parent L{Namespace}s are created automatically.  For example,
        if C{foo/bar/baz} is requested, and C{foo/bar} doesn't already exist,
        it will be created before C{foo/bar/baz} is created.  Associated
        L{NamespacePermission}s are created automatically with the system-wide
        default permissions.

        @param values: A sequence of C{(path, description)} 2-tuples.
        @raises DuplicatePathError: Raised if the path for a new L{Namespace}
            collides with an existing one.
        @raise MalformedPathError: Raised if one of the given paths is empty
            or has unacceptable characters.
        @return: A C{list} of C{(objectID, path)} 2-tuples for the new
            L{Namespace}s.
        """
        from fluiddb.model.user import getUser

        if not values:
            return []

        paths = [path for path, description in values]
        descriptions = dict(values)

        self._checkForDuplicates(paths)

        admin = getUser(u'fluiddb')
        objects = self._factory.objects(admin)
        systemValues = {}

        paths = getPathHierarchy(paths)
        existingNamespaces = dict((namespace.path, namespace)
                                  for namespace in getNamespaces(paths=paths))
        newNamespaces = []

        for path in sorted(paths):
            if path in existingNamespaces:
                continue

            parentPath = getParentPath(path)
            parentID = (existingNamespaces[parentPath].id
                        if parentPath is not None
                        else None)
            namespace = createNamespace(self._user, path, parentID)
            aboutValue = u'Object for the namespace %s' % path
            description = descriptions.get(path, aboutValue)
            namespace.objectID = objects.create(aboutValue)
            systemValues[namespace.objectID] = {
                u'fluiddb/namespaces/description': description,
                u'fluiddb/namespaces/path': path,
                u'fluiddb/about': aboutValue}
            existingNamespaces[path] = namespace
            newNamespaces.append(namespace)

        self._createPermissions(newNamespaces)
        self._factory.tagValues(admin).set(systemValues)
        values = [(namespace.objectID, namespace.path)
                  for namespace in newNamespaces]
        return values
Exemple #18
0
 def setUp(self):
     super(CachingPermissionCheckerAPITest, self).setUp()
     self.system = createSystemData()
     UserAPI().create([(u'username', u'password', u'User',
                        u'*****@*****.**')])
     self.user = getUser(u'username')
     self.api = CachingPermissionCheckerAPI()
Exemple #19
0
 def setUp(self):
     super(CachingPermissionCheckerAPITest, self).setUp()
     self.system = createSystemData()
     UserAPI().create([(u'username', u'password', u'User',
                        u'*****@*****.**')])
     self.user = getUser(u'username')
     self.api = CachingPermissionCheckerAPI()
Exemple #20
0
def setVersionTag(version):
    """Updates the fluiddb/version tag.

    @param version: The new version string.
    """
    user = getUser(u'fluiddb')
    objectID = ObjectAPI(user).create(u'fluidinfo')
    releaseDate = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
    values = {objectID: {
        u'fluiddb/api-version': {
            'mime-type': 'text/plain',
            'contents': version},
        u'fluiddb/release-date': {
            'mime-type': 'text/plain',
            'contents': releaseDate + '\n'}}}
    TagValueAPI(user).set(values)
    PermissionAPI(user).set([
        (u'fluiddb/api-version', Operation.READ_TAG_VALUE, Policy.OPEN, []),
        (u'fluiddb/release-date', Operation.READ_TAG_VALUE, Policy.OPEN, [])])

    try:
        transaction.commit()
    except:
        transaction.abort()
        raise
Exemple #21
0
 def setUp(self):
     super(SuperuserPermissionCheckerTest, self).setUp()
     self.system = createSystemData()
     UserAPI().create([(u'username', u'password', u'User',
                        u'*****@*****.**')])
     self.user = getUser(u'username')
     self.permissions = PermissionAPI(self.user)
Exemple #22
0
    def testAuthenticateOAuthWithUnknownConsumer(self):
        """
        L{OAuthConsumerAPI.authenticate} raises an L{AuthenticationError}
        exception if the consumer is not registered.
        """
        UserAPI().create([(u'user1', u'secret1', u'User1',
                           u'*****@*****.**')])
        user1 = getUser(u'user1')

        secret = 'a' * 16
        timestamp = 1314976811
        headers = {'header1': 'foo'}
        arguments = 'argument1=bar'

        oauthEchoSecret = getConfig().get('oauth', 'access-secret')
        token = dataToToken(oauthEchoSecret + secret, {'user1': 'secret1'})
        signature = 'Sno1ocDhYv9vwJnEJATE3cmUvSo='
        nonce = 'nonce'

        oauthConsumerAPI = OAuthConsumerAPI()
        credentials = OAuthCredentials(
            'fluidinfo.com', user1.username, token, 'HMAC-SHA1', signature,
            timestamp, nonce, 'GET', u'https://fluidinfo.com/foo', headers,
            arguments)

        self.assertRaises(AuthenticationError, oauthConsumerAPI.authenticate,
                          credentials)
Exemple #23
0
    def decrypt(cls, consumerUser, encryptedToken):
        """Decrypt a token and convert it into a stateful object.

        @param cls: The class representing the token.
        @param consumerUser: The L{User} instance of the consumer that holds
            the token.
        @param: The encrypted token as a C{str}.
        @raise UnknownConsumerError: Raised if C{consumerUser} doesn't have a
            matching L{OAuthConsumer} in the system.
        @raise UnknownUserError: Raised if the L{User} the token provides
            access on behalf of doesn't exist.
        @return: An instance of C{cls}.
        """
        result = getOAuthConsumers(userIDs=[consumerUser.id]).one()
        if result is None:
            raise UnknownConsumerError("'%s' is not a consumer." %
                                       consumerUser.username)
        _, consumer = result
        salt = getConfig().get('oauth', cls.configName)
        secret = salt + consumer.secret
        data = tokenToData(secret, encryptedToken)
        username = data['username'].lower()
        user = getUser(username)
        if user is None:
            raise UnknownUserError([username])
        token = cls(consumerUser, user)
        try:
            token.creationTime = datetime.strptime(data['creationTime'],
                                                   '%Y%m%d-%H%M%S')
        except KeyError:
            token.creationTime = None
        return token
Exemple #24
0
 def setUp(self):
     super(SecurePermissionAPIWithBrokenCacheTest, self).setUp()
     self.system = createSystemData()
     UserAPI().create([(u'username', u'password', u'User',
                        u'*****@*****.**')])
     self.user = getUser(u'username')
     self.permissions = SecurePermissionAPI(self.user)
Exemple #25
0
    def authenticate(self, oauthCredentials):
        """Verify the given OAuth credentials.

        @param oauthCredentials: The L{OAuthCredentials} that contains the
            OAuth authentication fields.
        @raise UnknownUserError: Raised if the user in the consumer key or in
            the token doesn't exist.
        @raise AuthenticationError: Raised if passed an invalid token or if
            the OAuth credentials can't be verified.
        @return: The L{User} for the OAuth credentials.
        """
        consumerUser = getUser(oauthCredentials.consumerKey)
        if not consumerUser:
            raise UnknownUserError([oauthCredentials.consumerKey])
        oauthConsumer = self.get(consumerUser)

        # Make sure the consumer has been registered.  If so, the
        # oauthConsumer will have a 'secret' attribute.
        try:
            secret = oauthConsumer.secret
        except AttributeError:
            # XXX We should probably log this.
            raise AuthenticationError(oauthCredentials.consumerKey)

        try:
            token = OAuthAccessToken.decrypt(consumerUser,
                                             oauthCredentials.token)
        except ValueError:
            raise AuthenticationError(oauthCredentials.consumerKey)
        if oauthCredentials.verifySignature(secret):
            return token.user
        else:
            raise AuthenticationError(token.user.username)
Exemple #26
0
 def setUp(self):
     super(SecureObjectAPIWithBrokenCacheTest, self).setUp()
     self.system = createSystemData()
     UserAPI().create([(u'user', u'password', u'User',
                        u'*****@*****.**')])
     self.user = getUser(u'user')
     self.objects = SecureObjectAPI(self.user)
 def setUp(self):
     super(SecureRecentActivityAPIWithUserRoleTest, self).setUp()
     createSystemData()
     UserAPI().create([(u'user', u'secret', u'User', u'*****@*****.**')])
     self.user = getUser(u'user')
     self.recentActivity = SecureRecentActivityAPI(self.user)
     self.permissions = CachingPermissionAPI(self.user)
Exemple #28
0
    def testAuthenticateOAuthWithUnknownUser(self):
        """
        L{OAuthConsumerAPI.authenticate} raises a L{UnknownUserError} exception
        if the user in the L{OAuthCredentials} token doesn't exist.
        """
        UserAPI().create([(u'user1', u'secret1', u'User1',
                           u'*****@*****.**')])
        user1 = getUser(u'user1')

        oauthConsumerAPI = OAuthConsumerAPI()
        consumer = oauthConsumerAPI.register(user1, secret='abyOTsAfo9MVN0qz')

        timestamp = 1314976811
        headers = {'header1': 'foo'}
        arguments = 'argument1=bar'
        oauthEchoSecret = getConfig().get('oauth', 'access-secret')
        token = dataToToken(oauthEchoSecret + consumer.secret,
                            {'username': '******'})
        signature = 'Sno1ocDhYv9vwJnEJATE3cmUvSo='
        nonce = 'nonce'
        credentials = OAuthCredentials(
            'fluidinfo.com', user1.username, token, 'HMAC-SHA1', signature,
            timestamp, nonce, 'GET', u'https://fluidinfo.com/foo', headers,
            arguments)
        self.assertRaises(UnknownUserError, oauthConsumerAPI.authenticate,
                          credentials)
Exemple #29
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)
Exemple #30
0
    def testAuthenticateOAuthWithInvalidToken(self):
        """
        L{OAuthConsumerAPI.authenticate} raises an L{AuthenticationError}
        exception if the token in the L{OAuthCredentials} is invalid.
        """
        UserAPI().create([(u'user1', u'secret1', u'User1',
                           u'*****@*****.**')])
        user1 = getUser(u'user1')

        # NOTE This second user is not used, but it's created anyway to make
        # sure that the environment is the same as the other tests, but this
        # time the test will only fail because of an invalid token.
        # This is here to avoid regressions.
        UserAPI().create([(u'user2', u'secret2', u'User2',
                           u'*****@*****.**')])

        oauthConsumerAPI = OAuthConsumerAPI()
        oauthConsumerAPI.register(user1, secret='abyOTsAfo9MVN0qz')
        timestamp = 1314976811
        headers = {'header1': 'foo'}
        arguments = 'argument1=bar'
        token = 'invalid'
        signature = 'wrong'
        nonce = 'nonce'
        credentials = OAuthCredentials(
            'fluidinfo.com', user1.username, token, 'HMAC-SHA1', signature,
            timestamp, nonce, 'GET', u'https://fluidinfo.com/foo', headers,
            arguments)
        self.assertRaises(AuthenticationError, oauthConsumerAPI.authenticate,
                          credentials)
Exemple #31
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)
Exemple #32
0
def removeTestingData():
    """
    Delete L{User}s, L{Namespace}s and L{Tag}s used for testing purposes.
    """
    admin = getUser(u'fluiddb')
    logging.info('Deleting testing tags.')
    result = TagAPI(admin).get(TESTING_DATA[u'tags'])
    if result:
        TagAPI(admin).delete(result.keys())

    logging.info('Deleting testing namespaces.')
    result = NamespaceAPI(admin).get(TESTING_DATA[u'namespaces'])
    # we must delete namespaces one by one, otherwise we'll get NotEmptyError.
    for path in sorted(result.keys(), reverse=True):
        NamespaceAPI(admin).delete([path])

    logging.info('Deleting testing users.')
    result = UserAPI().get(TESTING_DATA[u'users'])
    if result:
        for username in result:
            path = '%s/private' % username
            try:
                NamespaceAPI(admin).delete([path])
            except FeatureError:
                # FIXME This is a bit crap, but it's faster than checking to
                # see if the namespace exists before attempting to delete it.
                continue
    if result:
        UserAPI().delete(result.keys())
    getMainStore().commit()
Exemple #33
0
    def testCreateChildNamespaceInheritsParentNamespacePermissions(self):
        """
        L{NamespaceAPI.create} creates new L{Namespace}s with
        L{Operation.CREATE_NAMESPACE} permissions inherited from the parent
        L{Namespace}'s permissions.
        """
        UserAPI().create([(u'user', u'secret', u'name', u'*****@*****.**')])
        user = getUser(u'user')
        PermissionAPI(self.user).set([
            (u'user', Operation.CREATE_NAMESPACE, Policy.OPEN, []),
            (u'user', Operation.UPDATE_NAMESPACE, Policy.OPEN, []),
            (u'user', Operation.DELETE_NAMESPACE, Policy.OPEN, []),
            (u'user', Operation.LIST_NAMESPACE, Policy.CLOSED, [u'user']),
            (u'user', Operation.CONTROL_NAMESPACE, Policy.OPEN, [])])

        self.namespaces.create([(u'user/child', u'A child namespace')])
        result = getNamespacePermissions([u'user/child'])
        namespace, permission = result.one()
        self.assertEqual((Policy.OPEN, []),
                         permission.get(Operation.CREATE_NAMESPACE))
        self.assertEqual((Policy.OPEN, []),
                         permission.get(Operation.UPDATE_NAMESPACE))
        self.assertEqual((Policy.OPEN, []),
                         permission.get(Operation.DELETE_NAMESPACE))
        self.assertEqual((Policy.CLOSED, [user.id]),
                         permission.get(Operation.LIST_NAMESPACE))
        self.assertEqual((Policy.OPEN, []),
                         permission.get(Operation.CONTROL_NAMESPACE))
Exemple #34
0
    def create(self, value=None):
        """Create a new object.

        If the about C{value} already exists, the matching object ID will be
        returned.  Otherwise, a new one is created.  An L{AboutTagValue} is
        not created if C{value} is not provided.

        @param value: Optionally, an L{AboutTagValue.value} to associate with
            the new object.
        @return: A L{UUID} representing the object ID for the exsiting object,
            if one matching the value already exists, or a new object ID.
        """
        if not value:
            return uuid4()

        from fluiddb.model.user import getUser

        existingValue = getAboutTagValues(values=[value]).one()
        if existingValue:
            return existingValue.objectID
        else:
            objectID = uuid4()
            updates = {objectID: {u'fluiddb/about': value}}
            self._factory.tagValues(getUser(u'fluiddb')).set(updates)
            createAboutTagValue(objectID, value)
            return objectID
Exemple #35
0
    def _createTags(self, values, parentNamespaces):
        """Create new tags.

        @param values: A sequence of C{(Tag.path, description)} 2-tuples.
        @param parentNamespaces: A C{dict} mapping L{Namespace.path}s to
            L{Namespace} instances, the parents of the new L{Tag}s.
        @return: A C{list} of C{(objectID, Tag.path)} 2-tuples.
        """
        admin = getUser(u'fluiddb')
        objects = self._factory.objects(admin)
        systemValues = {}
        result = []
        tags = []
        for path, description in values:
            parentPath = getParentPath(path)
            name = getPathName(path)
            parentNamespace = parentNamespaces.get(parentPath)
            tag = createTag(self._user, parentNamespace, name)
            tag.objectID = objects.create(
                u'Object for the attribute %s' % path)
            result.append((tag.objectID, path))
            systemValues[tag.objectID] = {
                u'fluiddb/tags/description': description,
                u'fluiddb/tags/path': path
            }
            tags.append(tag)
        self._createPermissions(tags)

        if systemValues:
            self._factory.tagValues(admin).set(systemValues)

        return result
Exemple #36
0
        def run(userData):
            """
            Handle user data sent by the L{ServiceProvider} when credentials
            are successfully verified.
            """
            uid = userData['id']
            user = TwitterUserAPI().get(uid)
            if user is None:
                newUser = True
                username = userData['screen_name'].lower()
                fullname = userData['name']
                UserAPI().create([(username, None, fullname, None)])
                TwitterUserAPI().create(username, uid)
                user = TwitterUserAPI().get(uid)
            else:
                newUser = False

            # FIXME The calls to encrypt the tokens below aren't tested very
            # well.
            consumer = getUser(consumerUsername)
            accessToken = OAuthConsumerAPI().getAccessToken(consumer, user)
            renewalToken = OAuthConsumerAPI().getRenewalToken(consumer, user)
            return {'username': user.username,
                    'new-user': newUser,
                    'missing-password': (user.passwordHash == '!'),
                    'access-token': accessToken.encrypt(),
                    'renewal-token': renewalToken.encrypt(),
                    'uid': uid,
                    'data': userData}
Exemple #37
0
    def decrypt(cls, consumerUser, encryptedToken):
        """Decrypt a token and convert it into a stateful object.

        @param cls: The class representing the token.
        @param consumerUser: The L{User} instance of the consumer that holds
            the token.
        @param: The encrypted token as a C{str}.
        @raise UnknownConsumerError: Raised if C{consumerUser} doesn't have a
            matching L{OAuthConsumer} in the system.
        @raise UnknownUserError: Raised if the L{User} the token provides
            access on behalf of doesn't exist.
        @return: An instance of C{cls}.
        """
        result = getOAuthConsumers(userIDs=[consumerUser.id]).one()
        if result is None:
            raise UnknownConsumerError("'%s' is not a consumer."
                                       % consumerUser.username)
        _, consumer = result
        salt = getConfig().get('oauth', cls.configName)
        secret = salt + consumer.secret
        data = tokenToData(secret, encryptedToken)
        username = data['username'].lower()
        user = getUser(username)
        if user is None:
            raise UnknownUserError([username])
        token = cls(consumerUser, user)
        try:
            token.creationTime = datetime.strptime(data['creationTime'],
                                                   '%Y%m%d-%H%M%S')
        except KeyError:
            token.creationTime = None
        return token
Exemple #38
0
 def setUp(self):
     super(CachingPermissionAPIWithBrokenCacheTest, self).setUp()
     self.system = createSystemData()
     UserAPI().create([(u'username', u'password', u'User',
                        u'*****@*****.**')])
     self.user = getUser(u'username')
     self.permissions = CachingPermissionAPI(self.user)
 def setUp(self):
     super(SecureRecentActivityAPIWithUserRoleTest, self).setUp()
     createSystemData()
     UserAPI().create([(u'user', u'secret', u'User', u'*****@*****.**')])
     self.user = getUser(u'user')
     self.recentActivity = SecureRecentActivityAPI(self.user)
     self.permissions = CachingPermissionAPI(self.user)
Exemple #40
0
    def authenticate(self, oauthCredentials):
        """Verify the given OAuth credentials.

        @param oauthCredentials: The L{OAuthCredentials} that contains the
            OAuth authentication fields.
        @raise UnknownUserError: Raised if the user in the consumer key or in
            the token doesn't exist.
        @raise AuthenticationError: Raised if passed an invalid token or if
            the OAuth credentials can't be verified.
        @return: The L{User} for the OAuth credentials.
        """
        consumerUser = getUser(oauthCredentials.consumerKey)
        if not consumerUser:
            raise UnknownUserError([oauthCredentials.consumerKey])
        oauthConsumer = self.get(consumerUser)

        # Make sure the consumer has been registered.  If so, the
        # oauthConsumer will have a 'secret' attribute.
        try:
            secret = oauthConsumer.secret
        except AttributeError:
            # XXX We should probably log this.
            raise AuthenticationError(oauthCredentials.consumerKey)

        try:
            token = OAuthAccessToken.decrypt(consumerUser,
                                             oauthCredentials.token)
        except ValueError:
            raise AuthenticationError(oauthCredentials.consumerKey)
        if oauthCredentials.verifySignature(secret):
            return token.user
        else:
            raise AuthenticationError(token.user.username)
Exemple #41
0
    def testCreateChildTagWithDelegatedCreator(self):
        """
        L{TagAPI.create} always ensures that a new L{Tag} is usable by the
        L{User} that created it.  In the case of default permissions, the user
        creating the new L{Tag} is granted L{Operation.UPDATE_TAG},
        L{Operation.DELETE_TAG}, L{Operation.WRITE_TAG_VALUE} and
        L{Operation.DELETE_TAG_VALUE}.
        """
        UserAPI().create([(u'friend', u'secret', u'name', u'*****@*****.**')
                          ])
        PermissionAPI(self.user).set([(u'username', Operation.CREATE_NAMESPACE,
                                       Policy.CLOSED, [u'username',
                                                       u'friend'])])

        friend = getUser(u'friend')
        TagAPI(friend).create([(u'username/tag', u'A shared tag')])
        result = getTagPermissions([u'username/tag'])
        tag, permission = result.one()
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.UPDATE_TAG))
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.DELETE_TAG))
        self.assertEqual((Policy.CLOSED, [self.user.id]),
                         permission.get(Operation.CONTROL_TAG))
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.WRITE_TAG_VALUE))
        self.assertEqual((Policy.OPEN, []),
                         permission.get(Operation.READ_TAG_VALUE))
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.DELETE_TAG_VALUE))
        self.assertEqual((Policy.CLOSED, [self.user.id]),
                         permission.get(Operation.CONTROL_TAG_VALUE))
Exemple #42
0
 def setUp(self):
     super(DatasetImporterTest, self).setUp()
     self.system = createSystemData()
     UserAPI().create([(u'user', u'secret', u'User', u'*****@*****.**')])
     user = getUser(u'user')
     self.objects = SecureObjectAPI(user)
     self.values = SecureTagValueAPI(user)
Exemple #43
0
    def testGetRenewalTokenWithoutConsumer(self):
        """
        L{OAuthConsumerAPI.getRenewalToken} raised an L{UnknownConsumerError}
        if an L{OAuthConsumer} is not available for the specified L{User}
        consumer.
        """
        UserAPI().create([
            (u'consumer', u'secret', u'Consumer', u'*****@*****.**'),
            (u'user', u'secret', u'User', u'*****@*****.**')])
        consumerUser = getUser(u'consumer')
        user = getUser(u'user')

        now = datetime.utcnow()
        api = OAuthConsumerAPI()
        self.assertRaises(UnknownConsumerError, api.getRenewalToken,
                          consumerUser, user, now=lambda: now)
Exemple #44
0
 def setUp(self):
     super(DatasetImporterTest, self).setUp()
     self.system = createSystemData()
     UserAPI().create([(u'user', u'secret', u'User', u'*****@*****.**')])
     user = getUser(u'user')
     self.objects = SecureObjectAPI(user)
     self.values = SecureTagValueAPI(user)
Exemple #45
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)