ftpd/sftpd: stop using RuntimeError, for #639
authorBrian Warner <warner@lothar.com>
Mon, 23 Feb 2009 00:24:26 +0000 (17:24 -0700)
committerBrian Warner <warner@lothar.com>
Mon, 23 Feb 2009 00:24:26 +0000 (17:24 -0700)
src/allmydata/frontends/auth.py
src/allmydata/frontends/ftpd.py
src/allmydata/frontends/sftpd.py

index 6adbebb2a14aabbfd150ca66973101083ab01af3..82ef1c658a54a1485db94451566d4f793c65d124 100644 (file)
@@ -5,6 +5,11 @@ from twisted.internet import defer
 from twisted.cred import error, checkers, credentials
 from allmydata.util import base32
 
+class NeedRootcapLookupScheme(Exception):
+    """Accountname+Password-based access schemes require some kind of
+    mechanism to translate name+passwd pairs into a rootcap, either a file of
+    name/passwd/rootcap tuples, or a server to do the translation."""
+
 class FTPAvatarID:
     def __init__(self, username, rootcap):
         self.username = username
index 598c8db04798ffc3207f75e75c5b36d7c7f5bfab..c187d86aa92f061886e25e216f91d90bc3ae4792 100644 (file)
@@ -267,7 +267,7 @@ class Handler:
         d.addCallback(_got_parent)
         return d
 
-from auth import AccountURLChecker, AccountFileChecker
+from auth import AccountURLChecker, AccountFileChecker, NeedRootcapLookupScheme
 
 
 class Dispatcher:
@@ -303,7 +303,7 @@ class FTPServer(service.MultiService):
             p.registerChecker(c)
         if not accountfile and not accounturl:
             # we could leave this anonymous, with just the /uri/CAP form
-            raise RuntimeError("must provide some translation")
+            raise NeedRootcapLookupScheme("must provide some translation")
 
         f = ftp.FTPFactory(p)
         s = strports.service(ftp_portstr, f)
index d29aa8a6305f853232e3359591c672cfb128ebac..aa15bbba7db5f1f66974a0fdbd7155d769a8600f 100644 (file)
@@ -116,6 +116,9 @@ class StoppableList:
 class FakeStat:
     pass
 
+class BadRemoveRequest(Exception):
+    pass
+
 class SFTPHandler:
     implements(ISFTPServer)
     def __init__(self, user):
@@ -259,9 +262,9 @@ class SFTPHandler:
             d = parent.get(childname)
             def _got_child(child):
                 if must_be_directory and not IDirectoryNode.providedBy(child):
-                    raise RuntimeError("rmdir called on a file")
+                    raise BadRemoveRequest("rmdir called on a file")
                 if must_be_file and IDirectoryNode.providedBy(child):
-                    raise RuntimeError("rmfile called on a directory")
+                    raise BadRemoveRequest("rmfile called on a directory")
                 return parent.delete(childname)
             d.addCallback(_got_child)
             d.addErrback(self._convert_error)
@@ -421,7 +424,7 @@ class SFTPHandler:
 # then you get SFTPHandler(user)
 components.registerAdapter(SFTPHandler, SFTPUser, ISFTPServer)
 
-from auth import AccountURLChecker, AccountFileChecker
+from auth import AccountURLChecker, AccountFileChecker, NeedRootcapLookupScheme
 
 class Dispatcher:
     implements(portal.IRealm)
@@ -452,7 +455,7 @@ class SFTPServer(service.MultiService):
             p.registerChecker(c)
         if not accountfile and not accounturl:
             # we could leave this anonymous, with just the /uri/CAP form
-            raise RuntimeError("must provide some translation")
+            raise NeedRootcapLookupScheme("must provide some translation")
 
         pubkey = keys.Key.fromFile(pubkey_file)
         privkey = keys.Key.fromFile(privkey_file)