def setUp(self):
self.s = MyClient()
self.s.startService()
- s = webish.WebishServer("0")
+ self.ws = s = webish.WebishServer("0")
+ s.allow_local_access(True)
s.setServiceParent(self.s)
port = s.listener._port.getHost().port
self.webish_url = "http://localhost:%d" % port
d.addBoth(self.should404, "test_GET_FILEURL_json_missing")
return d
+ def disable_local_access(self, res=None):
+ self.ws.allow_local_access(False)
+ return res
+
def test_GET_FILEURL_localfile(self):
localfile = os.path.abspath("web/GET_FILEURL_localfile")
+ url = "/vdrive/global/foo/bar.txt?t=download&localfile=%s" % localfile
fileutil.make_dirs("web")
- d = self.GET("/vdrive/global/foo/bar.txt?t=download&localfile=%s"
- % localfile)
+ d = self.GET(url)
def _done(res):
self.failUnless(os.path.exists(localfile))
data = open(localfile, "rb").read()
d.addCallback(_done)
return d
+ def test_GET_FILEURL_localfile_disabled(self):
+ localfile = os.path.abspath("web/GET_FILEURL_localfile_disabled")
+ url = "/vdrive/global/foo/bar.txt?t=download&localfile=%s" % localfile
+ fileutil.make_dirs("web")
+ self.disable_local_access()
+ d = self.GET(url)
+ d.addBoth(self.shouldFail, error.Error, "localfile disabled",
+ "403 Forbidden",
+ "local file access is disabled")
+ return d
+
def test_GET_FILEURL_localfile_nonlocal(self):
# TODO: somehow pretend that we aren't local, and verify that the
# server refuses to write to local files, probably by changing the
def test_PUT_NEWFILEURL_localfile(self):
localfile = os.path.abspath("web/PUT_NEWFILEURL_localfile")
+ url = "/vdrive/global/foo/new.txt?t=upload&localfile=%s" % localfile
fileutil.make_dirs("web")
f = open(localfile, "wb")
f.write(self.NEWFILE_CONTENTS)
f.close()
- d = self.PUT("/vdrive/global/foo/new.txt?t=upload&localfile=%s" %
- localfile, "")
+ d = self.PUT(url, "")
def _check(res):
self.failUnless("new.txt" in self._foo_node.children)
new_uri = self._foo_node.children["new.txt"]
d.addCallback(_check)
return d
+ def test_PUT_NEWFILEURL_localfile_disabled(self):
+ localfile = os.path.abspath("web/PUT_NEWFILEURL_localfile_disabled")
+ url = "/vdrive/global/foo/new.txt?t=upload&localfile=%s" % localfile
+ fileutil.make_dirs("web")
+ f = open(localfile, "wb")
+ f.write(self.NEWFILE_CONTENTS)
+ f.close()
+ self.disable_local_access()
+ d = self.PUT(url, "")
+ d.addBoth(self.shouldFail, error.Error, "put localfile disabled",
+ "403 Forbidden",
+ "local file access is disabled")
+ return d
+
def test_PUT_NEWFILEURL_localfile_mkdirs(self):
localfile = os.path.abspath("web/PUT_NEWFILEURL_localfile_mkdirs")
fileutil.make_dirs("web")
d.addCallback(_check)
return d
+ def test_GET_DIRURL_localdir_disabled(self):
+ localdir = os.path.abspath("web/GET_DIRURL_localdir_disabled")
+ fileutil.make_dirs("web")
+ self.disable_local_access()
+ d = self.GET("/vdrive/global/foo?t=download&localdir=%s" % localdir)
+ d.addBoth(self.shouldFail, error.Error, "localfile disabled",
+ "403 Forbidden",
+ "local file access is disabled")
+ return d
+
def test_GET_DIRURL_localdir_nonabsolute(self):
localdir = "web/nonabsolute/dirpath"
fileutil.make_dirs("web/nonabsolute")
d.addCallback(_check)
return d
+ def test_PUT_NEWDIRURL_localdir_disabled(self):
+ localdir = os.path.abspath("web/PUT_NEWDIRURL_localdir_disabled")
+ # create some files there
+ fileutil.make_dirs(os.path.join(localdir, "one"))
+ fileutil.make_dirs(os.path.join(localdir, "one/sub"))
+ fileutil.make_dirs(os.path.join(localdir, "two"))
+ fileutil.make_dirs(os.path.join(localdir, "three"))
+ self.touch(localdir, "three/foo.txt")
+ self.touch(localdir, "three/bar.txt")
+ self.touch(localdir, "zap.zip")
+
+ self.disable_local_access()
+ d = self.PUT("/vdrive/global/newdir?t=upload&localdir=%s"
+ % localdir, "")
+ d.addBoth(self.shouldFail, error.Error, "localfile disabled",
+ "403 Forbidden",
+ "local file access is disabled")
+ return d
+
def test_PUT_NEWDIRURL_localdir_mkdirs(self):
localdir = os.path.abspath("web/PUT_NEWDIRURL_localdir_mkdirs")
# create some files there
class IClient(Interface):
pass
+class ILocalAccess(Interface):
+ def allow_local_access():
+ pass
# we must override twisted.web.http.Request.requestReceived with a version
req.setHeader("content-type", "text/plain")
return "localfile= or localdir= requires an absolute path"
-
+class LocalAccessDisabledError:
+ implements(inevow.IResource)
+
+ def renderHTTP(self, ctx):
+ req = inevow.IRequest(ctx)
+ req.setResponseCode(http.FORBIDDEN)
+ req.setHeader("content-type", "text/plain")
+ return "local file access is disabled"
+
class LocalFileDownloader(resource.Resource):
def __init__(self, filenode, local_filename):
if localdir != os.path.abspath(localdir):
return NeedAbsolutePathError(), ()
if localfile or localdir:
+ if not ILocalAccess(ctx).allow_local_access():
+ return LocalAccessDisabledError(), ()
if req.getHost().host != LOCALHOST:
return NeedLocalhostError(), ()
# TODO: think about clobbering/revealing config files and node secrets
return T.div[form]
+class LocalAccess:
+ implements(ILocalAccess)
+ def __init__(self):
+ self.local_access = False
+ def allow_local_access(self):
+ return self.local_access
+
class WebishServer(service.MultiService):
name = "webish"
- def __init__(self, webport):
+ def __init__(self, webport, local_access=False):
service.MultiService.__init__(self)
self.root = Root()
self.site = site = appserver.NevowSite(self.root)
self.site.requestFactory = MyRequest
+ self.allow_local = LocalAccess()
+ self.site.remember(self.allow_local, ILocalAccess)
s = strports.service(webport, site)
s.setServiceParent(self)
self.listener = s # stash it so the tests can query for the portnum
+ def allow_local_access(self, enable=True):
+ self.allow_local.local_access = enable
+
def startService(self):
service.MultiService.startService(self)
# to make various services available to render_* methods, we stash a