Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

started expansion of REST environment

  • Loading branch information...
commit 811a56ae52d21af7b37cf8118e362e7f6d6d8cdc 1 parent 5858f01
@vecna vecna authored
View
2  REST-spec.md
@@ -273,7 +273,7 @@ of the datatype-name, the list and the detailed meaning would be found in:
'description': 'string',
'admin_options': '$formFieldsDict',
'user_options': '$formFieldsDict',
- 'service-message': 'string'
+ 'service_message': 'string'
}
* **groupDescriptionDict**, is an object used to describe a group of receivers, more than
View
2  globaleaks/rest/__init__.py
@@ -1 +1 @@
-__all__ = [ 'api', 'handlers', 'utils' ]
+__all__ = [ 'api', 'handlers', 'utils', 'external_loader' ]
View
109 globaleaks/rest/api.py
@@ -1,45 +1,118 @@
import json
from twisted.web import resource
-
from globaleaks.rest.handlers import *
from globaleaks.rest.utils import processChildren
-import pdb
+__all__ = ['RESTful', 'attach_rest' ]
+
+"""
+This file contains:
+
+ class RESTful(resource.Resource)
+ getChild
+"""
+
+"""
+http://twistedmatrix.com/documents/12.1.0/api/twisted.web.resource.IResource.html
+"""
class RESTful(resource.Resource):
- APImap = {
- 'node': nodeHandler,
- 'submission': submissionHandlers, # wildcard handling (WC)
- 'tip': tipHandlers, # WC
- 'admin': {
- 'contexts': adminContextHandler,
- 'node': adminNodeHandler,
- 'group' : adminGroupHandlers, # WC
- 'receivers': adminReceiversHandlers, # WC
- 'modules': adminModulesHandlers # WC
- }
- }
- def __init__(self):
+ def __init__(self, APImap):
"""
Create the root of the restful interface and create the children
handlers for handlers that don't take a parameter.
+
+ APImap is a dict collected by all the modules that want
+ expose a REST interface
"""
resource.Resource.__init__(self)
- processChildren(self, self.APImap)
+
+ # this function is in utils.py, and is a recursive function
+ processChildren(self, APImap)
+
+ # call the module(s) that load REST interface
+ from globaleaks.rest.external_loader import simulation_of_module_loading_rest
+ simulation_of_module_loading_rest()
def getChild(self, path, request):
"""
When trying to access a child that does not exist return an empty
resource.
+ This method is overriden when you need to handle 'stuff/$random/child'
"""
- print "getChild ", path, request
+ print "(default error ?) getChild ", path, request
return resource.Resource()
+
+"""
+The follwing part of code is intended to be moved in the
+backend/core logic, and implemented here just for
+"""
+
if __name__ == "__main__":
from twisted.internet import reactor
from twisted.web import server
- reactor.listenTCP(8082, server.Site(RESTful()))
+
+ # not all APIs are know at the start of the software,
+ # modules can implement their own REST
+
+ tipAPImap = {
+ 'download_material': downloadMaterialHandler,
+ 'add_comment': addCommentHandler,
+ 'pertinence': pertinenceHandler,
+ 'add_description': addDescriptionHandler
+ }
+
+ adminAPImap = {
+ 'contexts': ContextHandler,
+ 'node': NodeHandler,
+ 'group' : GroupHandlers, # WC
+ 'receivers': ReceiversHandlers, # WC
+ 'modules': ModulesHandlers # WC
+ }
+
+ APImap = {
+ 'node': nodeHandler,
+ 'submission': submissionHandlers, # wildcard handling
+ 'tip': tipAPImap, # tipHandlers, # handle the default path
+ 'admin': adminAPImap, # adminHandlers, # too
+ 'receiver' : receiverHandlers # too!
+ }
+
+ print "\n"
+ print "adminAPImap", len(adminAPImap)
+ print "APImap", len(APImap)
+ print "tipAPImap", len(tipAPImap)
+ #APImap.update(tipAPImap)
+ #APImap.update(adminAPImap)
+ print "sum:", len(APImap)
+
+ for k, v in APImap.items():
+ if isinstance(v, dict):
+ print k
+ for sk, sv in v.items():
+ print "\t",sk," => ", str(sv)
+ else:
+ print k," => ", str(v)
+
+ reactor.listenTCP(8082, server.Site(RESTful(APImap)))
reactor.run()
+
+
+# ORIGINAL API MAP
+# APImap = {
+# 'node': nodeHandler,
+# 'submission': submissionHandlers, # wildcard handling (WC)
+# 'tip': tipHandlers, # WC
+# 'admin': {
+# 'contexts': adminContextHandler,
+# 'node': adminNodeHandler,
+# 'group' : adminGroupHandlers, # WC
+# 'receivers': adminReceiversHandlers, # WC
+# 'modules': adminModulesHandlers # WC
+# }
+# }
+
View
29 globaleaks/rest/external_loader.py
@@ -0,0 +1,29 @@
+from twisted.web import resource
+
+"""
+This file is a test,
+emulate an external module, when need to load a dedicated REST interface
+"""
+
+__all__ = [ 'simulation_of_module_loading_rest' ]
+
+def simulation_of_module_loading_rest():
+
+ class internalHandler(resource.Resource):
+
+ def __init__(self, name="module_exteral_test"):
+ self.name = name
+ resource.Resource.__init__(self)
+
+ def render_GET(self, request):
+ print name + "GET" + str(request)
+ return name + "GET" + str(request)
+
+ def render_POST(self, request):
+ print name + "POST" + str(request)
+ return name + "POST" + str(request)
+
+ modular_rest = internalHandler()
+ print "putChild di external_test", str(internalHandler)
+ modular_rest.putChild("/external_test/", internalHandler() )
+
View
172 globaleaks/rest/handlers.py
@@ -5,113 +5,145 @@
This contains all of the handlers for the REST interface.
Should not contain any logic that is specific to the operations to be done
by the particular REST interface.
+
+ It's simply implement the inteface
"""
import json
from twisted.web import resource
-from globaleaks.rest.utils import processChildren
-
-__all__ = [ 'nodeHandler', 'submissionHandlers', 'tipHandlers',
- 'adminContextHandler', 'adminNodeHandler', 'adminGroupHandlers',
- 'adminReceiversHandlers', 'adminModulesHandlers' ]
+from globaleaks.rest.utils import processChildren, parameterHandler
+
+__all__ = [ 'nodeHandler', 'submissionHandlers', 'receiverHandlers',
+ # follow "admin" block of handlers
+ 'adminHandlers',
+ 'ContextHandler', 'NodeHandler', 'GroupHandlers',
+ 'ReceiversHandlers', 'ModulesHandlers',
+ # follow "tip" block of handlers
+ 'tipHandlers',
+ 'downloadMaterialHandler', 'addCommentHandler',
+ 'pertinenceHandler', 'addDescriptionHandler' ]
class nodeHandler(resource.Resource):
- def __init__(self, name="default"):
- self.name = name
- resource.Resource.__init__(self)
+
+# def __init__(self, name="default"):
+# self.name = name
+# resource.Resource.__init__(self)
def render_GET(self, request):
- print "infoHandler " + "GET"
- return json.dumps(API.keys())
+ print "infoHandler GET", str(request)
+ return "infoHandler GET" + str(request)
def render_POST(self, request):
- print "infoHandler " + "POST"
- pass
-
-class nodeHandler(resource.Resource):
- def render_GET(self, request):
- return str(self.__class__)
+ print "infoHandler POST", str(request)
+ return "infoHandler POST" + str(request)
class submissionHandlers(resource.Resource):
def render_GET(self, request):
- return str(self.__class__)
+ return str(self.__class__.__name__ )
-class adminContextHandler(resource.Resource):
+class receiverHandlers(resource.Resource):
def render_GET(self, request):
- return str(self.__class__)
+ return str(self.__class__.__name__ )
-class adminNodeHandler(resource.Resource):
- def render_GET(self, request):
- return str(self.__class__)
+# Follow the Admin Handlers
+class adminHandlers(resource.Resource):
+ path = 'default'
-class adminGroupHandlers(resource.Resource):
- def render_GET(self, request):
- print "admin group hahaha"
- import pdb
- #pdb.set_trace()
- return str(self.__class__)
+ def __init__(self):
+ print "init of adminHandlers"
+ resource.Resource.__init__(self)
-class adminReceiversHandlers(resource.Resource):
- def render_GET(self, request):
- return str(self.__class__)
+ def getChild(self, path, request):
+ print self.__class__.name, "Got child request!", path, request
+ return adminHandlers()
+
+class ContextHandler(parameterHandler):
+ def render_GET(self, request, parameter):
+ return str(self.__class__.__name__) + request + parameter
+
+class NodeHandler(parameterHandler):
+ def render_GET(self, request, parameter):
+ return str(self.__class__.__name__) + request + parameter
+
+class GroupHandlers(parameterHandler):
+ def render_GET(self, request, parameter):
+ print "GET", request.path
+ print type(parameter)
+ print parameter
+ return "test GET & parm" + request.path + ", " + parameter
+
+ def render_POST(self, request, parameter):
+ print "POST", request.path
+ print type(parameter)
+ print parameter
+ return "test POST & parm" + request.path + ", " + parameter
+
+class ReceiversHandlers(parameterHandler):
+ def render_GET(self, request, parameter):
+ return str(self.__class__.__name__) + request + parameter
+
+class ModulesHandlers(parameterHandler):
+ def render_GET(self, request, parameter):
+ return str(self.__class__.__name__) + request + parameter
+#############################################
-class adminModulesHandlers(resource.Resource):
- def render_GET(self, request):
- return str(self.__class__)
# Follow the Tip Handlers,
+class tipHandlers(resource.Resource):
+ path = 'default'
+
+ def __init__(self):
+ resource.Resource.__init__(self)
-class parameterHandler(resource.Resource):
- regexp = ''
- isLeaf = True
+ # Tip can be expanded by a module, then in this
+ # point, the module list need to be already loaded,
+ # because here is request if other REST would be exposed.
- print self.__class__ + str(request)
+ """
+ tipAPImap = {
+ 'download_material': downloadMaterialHandler,
+ 'add_comment': addCommentHandler,
+ 'pertinence': pertinenceHandler,
+ 'add_description': addDescriptionHandler
+ }
- def render(self, request):
- m = getattr(self, 'render_' + request.method, None)
+ processChildren(self, self.tipAPImap)
+ """
- print self.__class__ + str(m)
+ def getChild(self, path, request):
+ print self.__class__.name, "Got child request!", path, request
+ return tipHandlers()
- if not m:
- # This needs to be here until the deprecated subclasses of the
- # below three error resources in twisted.web.error are removed.
- from twisted.web.error import UnsupportedMethod
- allowedMethods = (getattr(self, 'allowedMethods', 0) or
- _computeAllowedMethods(self))
- raise UnsupportedMethod(allowedMethods)
- parameter = request.path.split('/')[2]
- return m(request, parameter)
class addCommentHandler(parameterHandler):
+
def render_GET(self, request, parameter):
- return str(self.__class__) + "<br>" + parameter
+ return "GET " + str(self.__class__) + "<br>" + parameter
+
+ def render_POST(self, request, parameter):
+ return "POST " + str(self.__class__) + "<br>" + parameter
class pertinenceHandler(parameterHandler):
+
def render_GET(self, request, parameter):
- return str(self.__class__) + "<br>" + parameter
+ return "GET " + str(self.__class__) + "<br>" + parameter
+
+ def render_POST(self, request, parameter):
+ return "POST " + str(self.__class__) + "<br>" + parameter
class downloadMaterialHandler(parameterHandler):
- def render_GET(self, request, parameter):
- return str(self.__class__) + "<br>" + parameter
-class addDescriptionHandler(parameterHandler):
def render_GET(self, request, parameter):
- return str(self.__class__)
+ return "GET " + str(self.__class__) + "<br>" + parameter
+ def render_POST(self, request, parameter):
+ return "POST " + str(self.__class__) + "<br>" + parameter
-# XXX Tip Factory would dispatch those APIs, only if needed.
-class tipHandlers(resource.Resource):
- path = 'default'
+class addDescriptionHandler(parameterHandler):
- tipAPImap = { 'download_material': downloadMaterialHandler,
- 'add_comment': addCommentHandler,
- 'pertinence': pertinenceHandler,
- 'add_description': addDescriptionHandler}
+ def render_GET(self, request, parameter):
+ return "GET " + str(self.__class__) + "<br>" + parameter
- def __init__(self):
- print self.__class__
- resource.Resource.__init__(self)
- processChildren(self, self.tipAPImap)
+ def render_POST(self, request, parameter):
+ return "POST " + str(self.__class__) + "<br>" + parameter
- def getChild(self, path, request):
- print "Got child request!"
- return tipHandlers()
+#############################################
View
50 globaleaks/rest/jsoncurl.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+
+url="node"
+payload="{'fuffa': 'xxx'}"
+echo "\n\nNEXT: $url"
+echo $payload
+read y
+curl http://127.0.0.1:8082/$url --data-urlencode $payload@my.json
+
+url="nodwRONGe"
+payload="{'fuffa': 'xxx'}"
+echo "\n\nNEXT: $url"
+read y
+curl http://127.0.0.1:8082/$url --data-urlencode $payload@my.json
+
+url="admin/group/GR0UP1D/"
+payload="{'xxx': 'yyy'}"
+echo "\n\nNEXT: $url"
+read y
+curl http://127.0.0.1:8082/$url --data-urlencode $payload@my.json
+
+url="admin/group/GR0UP1D/"
+echo "\n\nNEXT: GET $url"
+read y
+curl -G http://127.0.0.1:8082/$url
+
+url="submission/48329049032840923/status"
+payload="{'xxx': 'yyy'}"
+echo "\n\nNEXT: $url"
+read y
+curl http://127.0.0.1:8082/$url --data-urlencode $payload@my.json
+
+url="external_test/4832"
+payload="{'xxx': 'yyy'}"
+echo "\n\nNEXT: $url"
+read y
+curl http://127.0.0.1:8082/$url --data-urlencode $payload@my.json
+
+url="tip/4u3242309/download_material"
+payload="{'xxx': 'yyy'}"
+echo "\n\nNEXT: $url"
+read y
+curl http://127.0.0.1:8082/$url --data-urlencode $payload@my.json
+
+url="tip/pertinence"
+payload="{'xxx': 'yyy'}"
+echo "\n\nNEXT: $url"
+read y
+curl http://127.0.0.1:8082/$url --data-urlencode $payload@my.json
View
51 globaleaks/rest/utils.py
@@ -1,5 +1,14 @@
from twisted.web import resource
-import pdb
+
+"""
+This file contains:
+
+ processChildren
+ class parameterHandler(resource.Resource)
+ render
+"""
+
+__all__ = [ 'processChildren', 'parameterHandler' ]
def processChildren(res, api):
"""
@@ -10,15 +19,11 @@ def processChildren(res, api):
"""
for i, a in enumerate(api.items()):
path, handler = a
- print i
+
if isinstance(handler, dict):
# If I am dealing with a dict then I need to pass it through
# processChildren again (it has children).
- print "Got the dict :("
- print "Res: %s" % res
- print "Path: %s" % path
- print "Handler: %s" % handler
new_res = resource.Resource()
if hasattr(res, 'path'):
new_res.path = res.path
@@ -28,13 +33,39 @@ def processChildren(res, api):
# If I am not dealing with a dict then I just need to add the child
# handler to this particular path.
- print "Got the handler ;)"
- print "Res: %s" % res
- print "Path: %s" % path
- print "Handler: %s" % handler
+ # here is instanced the handler object, and then
+ # a recurson with processChildern would be started
res.putChild(path, handler())
+
if (len(api) - 1) == i:
# If I am inside of the leaf of the tree then I need to return
# (this is needed to make recursion work)
return res
+
+class parameterHandler(resource.Resource):
+ regexp = ''
+ isLeaf = True
+
+ def render(self, request):
+
+ print "X: called render in", self.__class__.__name__, request.method, request
+
+ m = getattr(self, 'render_' + request.method, None)
+
+ print self.__class__.__name__ + str(m)
+
+ if not m:
+ # This needs to be here until the deprecated subclasses of the
+ # below three error resources in twisted.web.error are removed.
+ from twisted.web.error import UnsupportedMethod
+ allowedMethods = (getattr(self, 'allowedMethods', 0) or _computeAllowedMethods(self))
+ raise UnsupportedMethod(allowedMethods)
+
+ parameter = request.path.split('/')[2]
+
+ print "render: method right:", str(m), request, parameter
+
+ return m(request, parameter)
+
+
View
62 globaleaks/utils/JSONhelper.py
@@ -282,9 +282,69 @@ def printJSON(self):
print "\n"
"""
-FormField is the field description for every FORM
+formFieldDict is the field description for every FORM
"""
+"""
+nodePropertiesDict, actually is defined to be
+simply the "Configurable Boolean Parameters"
+but need to be review in the next days -- 08/12
+"""
+class nodePropertiesDict(RestJSONwrapper):
+
+ def __init__(self, CBP):
+ self._values = ({})
+ RestJSONwrapper.__init__(self)
+
+
+"""
+nodeStatisticsDict, need to be defined
+"""
+class nodeStatisticsDict(RestJSONwrapper):
+
+ def __init__(self):
+ print self.__class__, "not yet defined"
+ pass
+
+
+"""
+moduleDataDict
+"""
+class moduleDataDict(RestJSONwrapper):
+
+ def __init__(self, mID):
+ self._values = ({
+ 'ID' : '', 'active' : None, 'module_type' : '',
+ 'module_name' : '', 'description' : '',
+ 'admin_options' : {}, 'user_options' : {},
+ 'service_message' : '' })
+
+ self._values['ID'] = rID
+ RestJSONwrapper.__init__(self)
+
+
+
+
+
+"""
+groupDescriptionDict
+"""
+class groupDescriptionDict(RestJSONwrapper):
+
+"""
+contextDescriptionDict
+"""
+class contextDescriptionDict(RestJSONwrapper):
+"""
+tipIndexDict
+"""
+class tipIndexDict(RestJSONwrapper):
+"""
+tipStatistics
+"""
+class tipStatistics(RestJSONwrapper):
+
+
################################################################
################################################################
Please sign in to comment.
Something went wrong with that request. Please try again.