twisted的FTPRealm解读

首先看下我的测试代码

from twisted.protocols.ftp import FTPFactory, FTPRealm
from twisted.cred.portal import Portal
from twisted.cred.checkers import AllowAnonymousAccess, FilePasswordDB
from twisted.internet import reactor
from twisted.internet import endpoints

#pass.dat the same directory with ftp01.py
# =====================
# jeff:bozo
# grimmtooth:bozo2
# =====================
#
p = Portal(FTPRealm(anonymousRoot='E:/', userHome='E:/'),
           [AllowAnonymousAccess(), FilePasswordDB("pass.dat")])
f = FTPFactory(p)
endpoints.serverFromString(reactor,'tcp:21').listen(f)
reactor.run()


Portal类是cred的认证类,是用户登陆认证入口,通过Portal来构造一个FTPFactory提供TCP的服务(FTP,FTP是建立在TCP基础上的)。

FTPRealm是从BaseFTPRealm派生,BaseFTPRealm实现了portal.IRealm的接口。

class BaseFTPRealm:
    """
    Base class for simple FTP realms which provides an easy hook for specifying
    the home directory for each user.
    """
    implements(portal.IRealm)

    def __init__(self, anonymousRoot):
        self.anonymousRoot = filepath.FilePath(anonymousRoot)


    def getHomeDirectory(self, avatarId):
        """
        Return a L{FilePath} representing the home directory of the given
        avatar.  Override this in a subclass.

        @param avatarId: A user identifier returned from a credentials checker.
        @type avatarId: C{str}

        @rtype: L{FilePath}
        """
        raise NotImplementedError(
            "%r did not override getHomeDirectory" % (self.__class__,))


    def requestAvatar(self, avatarId, mind, *interfaces):
        for iface in interfaces:
            if iface is IFTPShell:
                if avatarId is checkers.ANONYMOUS:
                    avatar = FTPAnonymousShell(self.anonymousRoot)
                else:
                    avatar = FTPShell(self.getHomeDirectory(avatarId))
                return (IFTPShell, avatar,
                        getattr(avatar, 'logout', lambda: None))
        raise NotImplementedError(
            "Only IFTPShell interface is supported by this realm")

如果是匿名用户请求登陆则返回FTPAnonymousShell,否则返回FTPShell。这里FTPBaseRealm在用户登陆的时候直接以getHomeDirectory()作为FTP用户访问的根目录。

在看看FTPRealm,重写了getHomeDirectory,根据avatarId来返回一个子目录,这里特别要注意的是avatarId也就是FTP账号登陆的用户名。所以如果指定了userHome路径以后,还需要以用户名称来组织一个目录,这样才能让该用户正确访问到。

class FTPRealm(BaseFTPRealm):
    """
    @type anonymousRoot: L{twisted.python.filepath.FilePath}
    @ivar anonymousRoot: Root of the filesystem to which anonymous
        users will be granted access.

    @type userHome: L{filepath.FilePath}
    @ivar userHome: Root of the filesystem containing user home directories.
    """
    def __init__(self, anonymousRoot, userHome='/home'):
        BaseFTPRealm.__init__(self, anonymousRoot)
        self.userHome = filepath.FilePath(userHome)


    def getHomeDirectory(self, avatarId):
        """
        Use C{avatarId} as a single path segment to construct a child of
        C{self.userHome} and return that child.
        """
        return self.userHome.child(avatarId)

现在在反过来看看我例子里面的文件系统目录,匿名用户目录和用户目录都是E:盘,如果是匿名用户访问则直接访问E盘,否则如果是其他用户访问则访问的是E:\{用户名}目录。Portal的第二个参数指定了,用户的访问权限,可以匿名访问,而且可以通过文件密码的形式来访问,文件密码的格式(按照行),用户名:密码

[AllowAnonymousAccess(), FilePasswordDB("pass.dat")

这样通过几行代码就实现了一个简单的文件服务器了。也可以通过实现portal.IRealm接口来自定制访问权限。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值