Fix magic-folder 'status' command

This commit is contained in:
meejah 2016-05-23 14:48:07 -06:00 committed by Brian Warner
parent db40417886
commit 4509c7dafd
4 changed files with 31 additions and 36 deletions

View File

@ -224,6 +224,7 @@ class QueueMixin(HookMixin):
self._log("%d items to process" % len(to_process), )
for item in to_process:
self._process_history.appendleft(item)
try:
self._log(" processing '%r'" % (item,))
proc = yield self._process(item)

View File

@ -218,13 +218,21 @@ class StatusOptions(BasedirOptions):
self['node-url'] = f.read().strip()
def _get_json_for_fragment(options, fragment, method='GET'):
def _get_json_for_fragment(options, fragment, method='GET', post_args=None):
nodeurl = options['node-url']
if nodeurl.endswith('/'):
nodeurl = nodeurl[:-1]
url = u'%s/%s' % (nodeurl, fragment)
resp = do_http(method, url)
if method == 'POST':
if post_args is None:
raise ValueError("Must pass post_args= for POST method")
body = urllib.urlencode(post_args)
else:
body = ''
if post_args is not None:
raise ValueError("post_args= only valid for POST method")
resp = do_http(method, url, body=body)
if isinstance(resp, BadResponse):
# specifically NOT using format_http_error() here because the
# URL is pretty sensitive (we're doing /uri/<key>).
@ -233,8 +241,12 @@ def _get_json_for_fragment(options, fragment, method='GET'):
)
data = resp.read()
parsed = simplejson.loads(data)
if not parsed:
try:
parsed = simplejson.loads(data)
except Exception as e:
print "Failed to parse reply:\n%s" % (data,)
return []
if parsed is None:
raise RuntimeError("No data from '%s'" % (nodeurl,))
return parsed
@ -339,8 +351,12 @@ def status(options):
token = f.read()
magicdata = _get_json_for_fragment(
options,
'magic_folder?t=json&token=' + token,
'magic_folder?t=json',
method='POST',
post_args=dict(
t='json',
token=token,
)
)
if len(magicdata):
uploads = [item for item in magicdata if item['kind'] == 'upload']

View File

@ -395,10 +395,10 @@ class TokenOnlyWebApi(resource.Resource):
provide the "t=" argument to indicate the return-value (the only
valid value for this is "json")
Subclasses should override '_render_json' which should process the
API call and return a valid JSON object. This will only be called
if the correct token is present and valid (during renderHTTP
processing).
Subclasses should override 'post_json' which should process the
API call and return a string which encodes a valid JSON
object. This will only be called if the correct token is present
and valid (during renderHTTP processing).
"""
def __init__(self, client):
@ -416,7 +416,7 @@ class TokenOnlyWebApi(resource.Resource):
# argument to work if you passed it as a GET-style argument
token = None
if req.fields and 'token' in req.fields:
token = req.fields['token'].value[0]
token = req.fields['token'].value.strip()
if not token:
raise WebError("Missing token", http.UNAUTHORIZED)
if not timing_safe_compare(token, self.client.get_auth_token()):

View File

@ -5,19 +5,19 @@ from twisted.web.server import UnsupportedMethod
from nevow import rend
from nevow.inevow import IRequest
from allmydata.web.common import get_arg, WebError
from allmydata.web.common import WebError, TokenOnlyWebApi
class MagicFolderWebApi(rend.Page):
class MagicFolderWebApi(TokenOnlyWebApi):
"""
I provide the web-based API for Magic Folder status etc.
"""
def __init__(self, client):
super(MagicFolderWebApi, self).__init__(client)
TokenOnlyWebApi.__init__(self, client)
self.client = client
def _render_json(self, req):
def post_json(self, req):
req.setHeader("content-type", "application/json")
data = []
@ -44,25 +44,3 @@ class MagicFolderWebApi(rend.Page):
data.append(d)
return simplejson.dumps(data)
def renderHTTP(self, ctx):
req = IRequest(ctx)
t = get_arg(req, "t", None)
if req.method != 'POST':
raise UnsupportedMethod(('POST',))
token = get_arg(req, "token", None)
# XXX need constant-time comparison?
if token is None or token != self.client.get_auth_token():
raise WebError("Missing or invalid token.", 400)
if t is None:
return rend.Page.renderHTTP(self, ctx)
t = t.strip()
if t == 'json':
return self._render_json(req)
raise WebError("'%s' invalid type for 't' arg" % (t,), 400)