def test_get_path_parents(self):
     for path, parents in [
         ("", [""]),
         ("one", ["", "one"]),
         ("one/two", ["", "one", "one/two"]),
         ("one/two/", ["", "one", "one/two"]),
         ("one/two/three", ["", "one", "one/two", "one/two/three"]),
     ]:
         self.assertEqual(parents, PermissionsManager.get_path_parents(path))
 def test_get_path_parents(self):
     for path, parents in [
         ('', ['']),
         ('one', ['', 'one']),
         ('one/two', ['', 'one', 'one/two']),
         ('one/two/', ['', 'one', 'one/two']),
         ('one/two/three', ['', 'one', 'one/two', 'one/two/three']),
     ]:
         self.assertEqual(parents,
                          PermissionsManager.get_path_parents(path))
class TestDirectoryPermissions(unittest.TestCase):

    permissions = {
        'dir_1': set(['group_1']),
        'dir_1/subdir_2': set(['group_2']),
        'dir_2': set(['group_2']),
        'shared': set(['group_1', 'group_2']),
    }

    users = {
        'no_privs': ['no_priv_group'],
        'min_privs': ['staff'],
        'user_1': ['staff', 'group_1'],
        'user_2': ['staff', 'group_2'],
        'admin': ['staff', 'group_1', 'group_2']
    }

    def authenticate(self, username, password):
        try:
            return self.users[username]
        except KeyError:
            return None

    def setUp(self):
        self.manager = PermissionsManager(self.permissions,
                                          required_group='staff',
                                          authenticate=self.authenticate)

    def test_get_path_parents(self):
        for path, parents in [
            ('', ['']),
            ('one', ['', 'one']),
            ('one/two', ['', 'one', 'one/two']),
            ('one/two/', ['', 'one', 'one/two']),
            ('one/two/three', ['', 'one', 'one/two', 'one/two/three']),
        ]:
            self.assertEqual(parents,
                             PermissionsManager.get_path_parents(path))

    def test_unknown_user_returns_falsey(self):
        self.assertFalse(self.manager.get_user('unknown', 'nopass'))

    def test_user_to_string_contains_id(self):
        user = self.manager.get_user('min_privs', 'password')
        self.assertIn('min_privs', '%s' % user)

    def test_non_staff_user_rejected(self):
        self.assertFalse(self.manager.get_user('no_privs', 'password'))

    def test_staff_users_have_read_access_to_all(self):
        for username in self.users.keys():
            if username == 'no_privs':
                continue
            user = self.manager.get_user(username, 'password')
            for path in self.permissions.keys():
                self.assertTrue(user.has_read_access(path))

    def test_correct_users_have_write_access(self):
        write_access = {
            'dir_1': set(['user_1', 'admin']),
            'dir_1/subdir_2': set(['user_1', 'user_2', 'admin']),
            'dir_2': set(['user_2', 'admin']),
            'shared': set(['user_1', 'user_2', 'admin']),
        }
        for path, users_with_write_access in write_access.items():
            for username in self.users.keys():
                user = self.manager.get_user(username, 'password')
                has_write = (user and user.has_write_access(path))
                if username in users_with_write_access:
                    self.assertTrue(has_write,
                                    msg='%s should have write access to %s' %
                                    (username, path))
                else:
                    self.assertFalse(
                        has_write,
                        msg='%s should not have write access to %s' %
                        (username, path))
 def setUp(self):
     self.manager = PermissionsManager(self.permissions,
                                       required_group='staff',
                                       authenticate=self.authenticate)
class TestDirectoryPermissions(unittest.TestCase):

    permissions = {
        "dir_1": set(["group_1"]),
        "dir_1/subdir_2": set(["group_2"]),
        "dir_2": set(["group_2"]),
        "shared": set(["group_1", "group_2"]),
    }

    users = {
        "no_privs": ["no_priv_group"],
        "min_privs": ["staff"],
        "user_1": ["staff", "group_1"],
        "user_2": ["staff", "group_2"],
        "admin": ["staff", "group_1", "group_2"],
    }

    def authenticate(self, username, password):
        try:
            return self.users[username]
        except KeyError:
            return None

    def setUp(self):
        self.manager = PermissionsManager(self.permissions, required_group="staff", authenticate=self.authenticate)

    def test_get_path_parents(self):
        for path, parents in [
            ("", [""]),
            ("one", ["", "one"]),
            ("one/two", ["", "one", "one/two"]),
            ("one/two/", ["", "one", "one/two"]),
            ("one/two/three", ["", "one", "one/two", "one/two/three"]),
        ]:
            self.assertEqual(parents, PermissionsManager.get_path_parents(path))

    def test_unknown_user_returns_falsey(self):
        self.assertFalse(self.manager.get_user("unknown", "nopass"))

    def test_user_to_string_contains_id(self):
        user = self.manager.get_user("min_privs", "password")
        self.assertIn("min_privs", "%s" % user)

    def test_non_staff_user_rejected(self):
        self.assertFalse(self.manager.get_user("no_privs", "password"))

    def test_staff_users_have_read_access_to_all(self):
        for username in self.users.keys():
            if username == "no_privs":
                continue
            user = self.manager.get_user(username, "password")
            for path in self.permissions.keys():
                self.assertTrue(user.has_read_access(path))

    def test_correct_users_have_write_access(self):
        write_access = {
            "dir_1": set(["user_1", "admin"]),
            "dir_1/subdir_2": set(["user_1", "user_2", "admin"]),
            "dir_2": set(["user_2", "admin"]),
            "shared": set(["user_1", "user_2", "admin"]),
        }
        for path, users_with_write_access in write_access.items():
            for username in self.users.keys():
                user = self.manager.get_user(username, "password")
                has_write = user and user.has_write_access(path)
                if username in users_with_write_access:
                    self.assertTrue(has_write, msg="%s should have write access to %s" % (username, path))
                else:
                    self.assertFalse(has_write, msg="%s should not have write access to %s" % (username, path))
 def setUp(self):
     self.manager = PermissionsManager(self.permissions, required_group="staff", authenticate=self.authenticate)
development_root = os.path.join(os.path.dirname(__file__), 'tmp')
FILE_ROOT = os.path.realpath(
    os.environ.get('FILESERVER_ROOT', development_root))
# Note, you can generate a new host key like this:
# ssh-keygen -t rsa -N '' -f host_key
HOST_KEY = os.path.join(os.path.dirname(__file__), 'config/host_key')
PERMISSIONS_FILE = os.path.join(os.path.dirname(__file__),
                                'config/permissions.ini')

AUTH_LDAP_SERVER_URI = "ldap://ldap-server.example.com"
AUTH_LDAP_BIND_DN = "cn=Directory Manager"
AUTH_LDAP_BIND_PASSWORD = "******"
LDAP_ROOT_DN = 'dc=timetric,dc=com'
LDAP_GROUP_ROOT_DN = 'ou=timetric,ou=groups,%s' % LDAP_ROOT_DN
REQUIRED_GROUP = 'staff'

if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO)
    permissions = read_permissions_file(PERMISSIONS_FILE)
    ldap_auth = LDAPAuth(AUTH_LDAP_SERVER_URI,
                         bind_dn=AUTH_LDAP_BIND_DN,
                         bind_password=AUTH_LDAP_BIND_PASSWORD,
                         base_dn=LDAP_ROOT_DN,
                         group_dn=LDAP_GROUP_ROOT_DN)
    manager = PermissionsManager(permissions,
                                 required_group=REQUIRED_GROUP,
                                 authenticate=ldap_auth)
    server = SFTPServer(FILE_ROOT, HOST_KEY, get_user=manager.get_user)
    server.serve_forever('0.0.0.0', SSH_PORT)