码迷,mamicode.com
首页 > 其他好文 > 详细

twisted的FTPRealm解读

时间:2015-08-04 09:29:37      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:twisted   ftp   

首先看下我的测试代码

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接口来自定制访问权限。

版权声明:本文为博主原创文章,未经博主允许不得转载。

twisted的FTPRealm解读

标签:twisted   ftp   

原文地址:http://blog.csdn.net/davidsu33/article/details/47271275

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!