Ejemplo n.º 1
0
 def testNotes(self):
     f = HTTPTopLevel('users', 'PUT')
     usage = HTTPUsage('/dummy', 'an example of great profundity')
     f.addUsage(usage)
     note = Note('hey')
     usage.addNote(note)
     note = Note('hey')
     usage.addNote(note)
     self.assertEqual(len(usage.notes), 2)
     self.reg.register(f)
     apis = self.reg.get('users', 'PUT')
     self.assertEqual(apis, [['users', [('PUT', f)]]])
     f = apis[0][1][0][1]
     self.assertEqual(len(f.usages), 1)
     self.assertEqual(len(f.usages[0].notes), 2)
Ejemplo n.º 2
0
    def testFindUsage(self):

        class Dummy1(object):
            pass

        class Dummy2(object):
            pass

        class Dummy3(object):
            pass

        f = HTTPTopLevel('users', 'PUT')
        self.reg.register(f)
        usage1 = HTTPUsage('', "Return a list of all users.")
        usage1.resourceClass = Dummy1
        f.addUsage(usage1)

        f = HTTPTopLevel('dummy', 'GET')
        self.reg.register(f)
        usage2 = HTTPUsage('', "Return a list of all dummies.")
        usage2.resourceClass = Dummy2
        f.addUsage(usage2)

        # Find the usage with class Dummy1.
        u = self.reg.findUsage('users', 'PUT',
                               usageResourceClass=Dummy1)
        self.assertTrue(u.resourceClass is usage1.resourceClass)

        # Find the usage with class Dummy2.
        u = self.reg.findUsage('dummy', 'GET',
                               usageResourceClass=Dummy2)
        self.assertTrue(u.resourceClass is usage2.resourceClass)

        # Ask for a non-existent usage class.
        self.assertRaises(error.NoSuchUsage,
                          self.reg.findUsage, 'dummy', 'GET',
                          usageResourceClass=Dummy3)

        # Ask for a non-existent toplevel.
        self.assertRaises(error.NoSuchToplevel,
                          self.reg.findUsage, 'sunny', 'PUT',
                          usageResourceClass=Dummy2)

        # Ask for a non-existent verb.
        self.assertRaises(error.NoSuchVerb,
                          self.reg.findUsage, 'dummy', 'PUT',
                          usageResourceClass=Dummy2)
Ejemplo n.º 3
0
    def testGetWildcards(self):
        f1 = HTTPTopLevel('objects', 'GET')
        self.reg.register(f1)
        f2 = HTTPTopLevel('objects', 'PUT')
        self.reg.register(f2)
        f3 = HTTPTopLevel('users', 'GET')
        self.reg.register(f3)

        apis = self.reg.get('objects', 'GET')
        self.assertEqual(apis, [['objects', [('GET', f1)]]])

        apis = self.reg.get('objects', '*')
        self.assertEqual(apis, [['objects', [('GET', f1), ('PUT', f2)]]])

        apis = self.reg.get('*', 'GET')
        self.assertEqual(apis, [['objects', [('GET', f1)]],
                                ['users', [('GET', f3)]]])

        apis = self.reg.get('*', 'PUT')
        self.assertEqual(apis, [['objects', [('PUT', f2)]]])

        apis = self.reg.get('*', '*')
        self.assertEqual(apis, [['objects', [('GET', f1), ('PUT', f2)]],
                                ['users', [('GET', f3)]]])
Ejemplo n.º 4
0
                                                description.encode('utf-8'))

        request.setResponseCode(usage.successCode)

    @defer.inlineCallbacks
    def deferred_render_DELETE(self, request):
        usage = registry.findUsage(httpNamespaceCategoryName, 'DELETE',
                                   NamespacesResource)
        registry.checkRequest(usage, request)
        yield self.facadeClient.deleteNamespace(self.session,
                                                sep.join(request.postpath))
        request.setResponseCode(usage.successCode)


# ------------------------------ Namespaces POST --------------------------
topLevel = HTTPTopLevel(httpNamespaceCategoryName, 'POST')
registry.register(topLevel)

# --- POST /namespaces/NAMESPACE1/NAMESPACE2 ------------------------------

usage = HTTPUsage(
    apiDoc.NS_NS, 'Create a new namespace.  Intermediate '
    "namespaces are created automatically if they don't already "
    'exist.')
topLevel.addUsage(usage)
usage.resourceClass = NamespacesResource
usage.successCode = http.CREATED

usage.addNote(
    Note("""The new namespace will have permissions set
according to the user's defaults. There is no permission inheritance
Ejemplo n.º 5
0
 def testRegisterAndGetNonExistentVerb(self):
     f = HTTPTopLevel('users', 'PUT')
     self.reg.register(f)
     self.assertRaises(error.NoSuchVerb, self.reg.get, 'users', '')
Ejemplo n.º 6
0
 def testRegisterAndGetNonExistentToplevel(self):
     f = HTTPTopLevel('users', 'PUT')
     self.reg.register(f)
     self.assertRaises(error.NoSuchToplevel, self.reg.get, 'fred', '')
Ejemplo n.º 7
0
 def testRegisterAndGet(self):
     f = HTTPTopLevel('users', 'PUT')
     self.reg.register(f)
     apis = self.reg.get('users', 'PUT')
     self.assertEqual(apis, [['users', [('PUT', f)]]])
Ejemplo n.º 8
0
        @return: A C{deferred} which fires with a JSON payload with the
            information about recent activity for the given user.
        """
        recentActivity = yield self.facadeClient.getRecentUserActivity(
            self.session, self.username)

        body = buildPayload('application/json', recentActivity)
        request.setHeader('Content-length', str(len(body)))
        request.setHeader('Content-type', 'application/json')
        request.setResponseCode(http.OK)
        returnValue(body)

# API DOCUMENTATION

# GET on  /recent
topLevel = HTTPTopLevel('recent', 'GET')
topLevel.description = dedent("""
    The GET method on recent is used to retrieve information about the latest
    updated tag values on a given object or user.""")
registry.register(topLevel)

# GET on /recent/objects
usage = HTTPUsage('/objects', dedent("""
    To request information on the latest tag values on the objects returned by
    a given query"""))
usage.resourceClass = RecentObjectsActivityResource
usage.addArgument(Argument(
    'query',
    dedent("""
    A query string specifying what sorts of objects to get recent activity for.
    The query language is described <a
Ejemplo n.º 9
0
                                   ObjectsResource)
        registry.checkRequest(usage, request)
        responseType = usage.getResponsePayloadTypeFromAcceptHeader(request)
        query = request.args['query'][0]
        results = yield self.facadeClient.resolveQuery(self.session, query)
        responseDict = {'ids': list(results)}
        registry.checkResponse(responseType, responseDict, usage, request)
        body = payloads.buildPayload(responseType, responseDict)
        request.setHeader('Content-length', str(len(body)))
        request.setHeader('Content-type', responseType)
        request.setResponseCode(usage.successCode)
        defer.returnValue(body)


# ------------------------------ Objects POST -----------------------------
topLevel = HTTPTopLevel(httpObjectCategoryName, 'POST')
topLevel.description = "Create a new Fluidinfo object."
registry.register(topLevel)

# --- POST /objects -------------------------------------------------------

usage = HTTPUsage('', 'Create a new object. You must provide credentials for '
                      'this call to succeed.')
topLevel.addUsage(usage)
usage.resourceClass = ObjectsResource
usage.successCode = http.CREATED

apiDoc.addBadRequestPayload(usage)

apiDoc.addCannotRespondWithPayload(usage)
Ejemplo n.º 10
0
            or a tag that the caller does not have DELETE permission for.
        """
        usage = registry.findUsage(httpValueCategoryName, 'DELETE',
                                   ValuesResource)
        registry.checkRequest(usage, request)
        query = request.args[queryArg][0]
        tags = request.args[tagArg]
        if tags == ['*']:
            tags = None
        yield self.facadeClient.deleteValuesForQuery(self.session, query, tags)
        request.setResponseCode(usage.successCode)
        defer.returnValue(None)


# ------------------------------ Values GET -----------------------------
topLevel = HTTPTopLevel(httpValueCategoryName, 'GET')

topLevel.description = """The GET method on values is used to retrieve
    tag values from objects matching a query."""

# We could here mention
# href="http://doc.fluidinfo.com/fluidDB/api/draft-values-spec.html">
# /values draft spec</a>.

registry.register(topLevel)

# --- GET /values --------------------------------------------------------

usage = HTTPUsage(
    '', """Search for objects matching a Fluidinfo query, and return the
           value of the requested tags on the matching objects.""")
Ejemplo n.º 11
0
                                   ObjectsResource)
        registry.checkRequest(usage, request)
        responseType = usage.getResponsePayloadTypeFromAcceptHeader(request)
        query = request.args['query'][0]
        results = yield self.facadeClient.resolveQuery(self.session, query)
        responseDict = {'ids': list(results)}
        registry.checkResponse(responseType, responseDict, usage, request)
        body = payloads.buildPayload(responseType, responseDict)
        request.setHeader('Content-length', str(len(body)))
        request.setHeader('Content-type', responseType)
        request.setResponseCode(usage.successCode)
        defer.returnValue(body)


# ------------------------------ Objects POST -----------------------------
topLevel = HTTPTopLevel(httpObjectCategoryName, 'POST')
topLevel.description = "Create a new Fluidinfo object."
registry.register(topLevel)

# --- POST /objects -------------------------------------------------------

usage = HTTPUsage(
    '', 'Create a new object. You must provide credentials for '
    'this call to succeed.')
topLevel.addUsage(usage)
usage.resourceClass = ObjectsResource
usage.successCode = http.CREATED

apiDoc.addBadRequestPayload(usage)

apiDoc.addCannotRespondWithPayload(usage)
Ejemplo n.º 12
0
            return self
        else:
            try:
                # Make sure we have valid UTF-8 in the about value.
                about.decode('utf-8')
            except UnicodeDecodeError:
                return ErrorResource(
                    http.BAD_REQUEST, error.BadArgument,
                    {'Error-Message': 'About value in URI was not UTF-8'})
            else:
                return AboutObjectResource(self.facadeClient, self.session,
                                           about)


# ------------------------------ About POST -----------------------------
topLevel = HTTPTopLevel(httpAboutCategoryName, 'POST')
topLevel.description = "Create a new object."
registry.register(topLevel)

# --- POST /about -------------------------------------------------------

usage = HTTPUsage('/' + apiDoc.ABOUTSTR, ('''Create a new object with the
    given about value. If there is already a Fluidinfo object whose
    ''' + apiDoc.ABOUT_TAG + ''' tag has the given value, the returned
    object id will be that of the pre-existing object. In this call, and
    all others with an about value in the URI, you must convert
    your about value to UTF-8 and then
    <a href="http://en.wikipedia.org/wiki/Percent-encoding">
    percent-encode</a> it before adding it to the request URI. You must
    provide valid credentials for this call to succeed.
    For an example see the PUT request, below.'''))
Ejemplo n.º 13
0
            return self
        else:
            try:
                # Make sure we have valid UTF-8 in the about value.
                about.decode('utf-8')
            except UnicodeDecodeError:
                return ErrorResource(
                    http.BAD_REQUEST, error.BadArgument,
                    {'Error-Message': 'About value in URI was not UTF-8'})
            else:
                return AboutObjectResource(
                    self.facadeClient, self.session, about)


# ------------------------------ About POST -----------------------------
topLevel = HTTPTopLevel(httpAboutCategoryName, 'POST')
topLevel.description = "Create a new object."
registry.register(topLevel)

# --- POST /about -------------------------------------------------------

usage = HTTPUsage('/' + apiDoc.ABOUTSTR, ('''Create a new object with the
    given about value. If there is already a Fluidinfo object whose
    ''' + apiDoc.ABOUT_TAG + ''' tag has the given value, the returned
    object id will be that of the pre-existing object. In this call, and
    all others with an about value in the URI, you must convert
    your about value to UTF-8 and then
    <a href="http://en.wikipedia.org/wiki/Percent-encoding">
    percent-encode</a> it before adding it to the request URI. You must
    provide valid credentials for this call to succeed.
    For an example see the PUT request, below.'''))
Ejemplo n.º 14
0
            information about recent activity for the given user.
        """
        recentActivity = yield self.facadeClient.getRecentUserActivity(
            self.session, self.username)

        body = buildPayload('application/json', recentActivity)
        request.setHeader('Content-length', str(len(body)))
        request.setHeader('Content-type', 'application/json')
        request.setResponseCode(http.OK)
        returnValue(body)


# API DOCUMENTATION

# GET on  /recent
topLevel = HTTPTopLevel('recent', 'GET')
topLevel.description = dedent("""
    The GET method on recent is used to retrieve information about the latest
    updated tag values on a given object or user.""")
registry.register(topLevel)

# GET on /recent/objects
usage = HTTPUsage(
    '/objects',
    dedent("""
    To request information on the latest tag values on the objects returned by
    a given query"""))
usage.resourceClass = RecentObjectsActivityResource
usage.addArgument(
    Argument('query',
             dedent("""
Ejemplo n.º 15
0
}


class PermissionsResource(WSFEResource):

    def getChild(self, name, request):
        try:
            klass = _classForCategory[name]
        except KeyError:
            return NoResource()
        else:
            return klass(self.facadeClient, self.session)


# ------------------------------ Permissions POST -------------------------
topLevel = HTTPTopLevel(httpPermissionCategoryName, 'POST')
topLevel.description = """
    POST is not supported on permissions, because permissions are
    automatically set from a user's default permissions when a namespace or
    tag is first created. Use PUT to adjust the permissions on a given
    namespace or tag.  """
    # TODO: Finish this sentence and add it to the description:
    # To change a user's defaults, do a PUT on.... what exactly?
registry.register(topLevel)


# ------------------------------ Permissions GET --------------------------
topLevel = HTTPTopLevel('permissions', 'GET')
registry.register(topLevel)

Ejemplo n.º 16
0
            or a tag that the caller does not have DELETE permission for.
        """
        usage = registry.findUsage(httpValueCategoryName, 'DELETE',
                                   ValuesResource)
        registry.checkRequest(usage, request)
        query = request.args[queryArg][0]
        tags = request.args[tagArg]
        if tags == ['*']:
            tags = None
        yield self.facadeClient.deleteValuesForQuery(self.session, query, tags)
        request.setResponseCode(usage.successCode)
        defer.returnValue(None)


# ------------------------------ Values GET -----------------------------
topLevel = HTTPTopLevel(httpValueCategoryName, 'GET')

topLevel.description = """The GET method on values is used to retrieve
    tag values from objects matching a query."""

# We could here mention
# href="http://doc.fluidinfo.com/fluidDB/api/draft-values-spec.html">
# /values draft spec</a>.

registry.register(topLevel)


# --- GET /values --------------------------------------------------------

usage = HTTPUsage(
    '', """Search for objects matching a Fluidinfo query, and return the
Ejemplo n.º 17
0
        responseDict = {
            'id': objectId,
            'URI': location,
        }
        registry.checkResponse(responseType, responseDict, usage, request)
        body = payloads.buildPayload(responseType, responseDict)
        request.setHeader('Content-length', str(len(body)))
        request.setHeader('Content-type', responseType)
        request.setHeader('Location', location)
        request.setResponseCode(usage.successCode)
        defer.returnValue(body)


# ------------------------------ Users POST -------------------------------
topLevel = HTTPTopLevel(httpUserCategoryName, 'POST')
topLevel.adminOnly = True
registry.register(topLevel)

# --- POST /users ---------------------------------------------------------

usage = HTTPUsage('', 'Create a new user.')
usage.adminOnly = True
usage.resourceClass = UsersResource
usage.successCode = http.CREATED
topLevel.addUsage(usage)

apiDoc.addNeedAdmin(usage, apiDoc.CREATE)

usage.addReturn(Return(
    apiDoc.PRECONDITION_FAILED,
Ejemplo n.º 18
0
                                                description.encode('utf-8'))

        request.setResponseCode(usage.successCode)

    @defer.inlineCallbacks
    def deferred_render_DELETE(self, request):
        usage = registry.findUsage(httpNamespaceCategoryName, 'DELETE',
                                   NamespacesResource)
        registry.checkRequest(usage, request)
        yield self.facadeClient.deleteNamespace(self.session,
                                                sep.join(request.postpath))
        request.setResponseCode(usage.successCode)


# ------------------------------ Namespaces POST --------------------------
topLevel = HTTPTopLevel(httpNamespaceCategoryName, 'POST')
registry.register(topLevel)


# --- POST /namespaces/NAMESPACE1/NAMESPACE2 ------------------------------

usage = HTTPUsage(apiDoc.NS_NS, 'Create a new namespace.  Intermediate '
                  "namespaces are created automatically if they don't already "
                  'exist.')
topLevel.addUsage(usage)
usage.resourceClass = NamespacesResource
usage.successCode = http.CREATED

usage.addNote(Note("""The new namespace will have permissions set
according to the user's defaults. There is no permission inheritance
in Fluidinfo."""))
Ejemplo n.º 19
0
    tagInstanceSetCategoryName: ConcreteTagInstancesPermissionResource,
}


class PermissionsResource(WSFEResource):
    def getChild(self, name, request):
        try:
            klass = _classForCategory[name]
        except KeyError:
            return NoResource()
        else:
            return klass(self.facadeClient, self.session)


# ------------------------------ Permissions POST -------------------------
topLevel = HTTPTopLevel(httpPermissionCategoryName, 'POST')
topLevel.description = """
    POST is not supported on permissions, because permissions are
    automatically set from a user's default permissions when a namespace or
    tag is first created. Use PUT to adjust the permissions on a given
    namespace or tag.  """
# TODO: Finish this sentence and add it to the description:
# To change a user's defaults, do a PUT on.... what exactly?
registry.register(topLevel)

# ------------------------------ Permissions GET --------------------------
topLevel = HTTPTopLevel('permissions', 'GET')
registry.register(topLevel)

# --- GET /permissions/namespaces/NAMESPACE1/NAMESPACE2 ------------