蟒蛇绞名气使用

问题描述:

我有在这里一个小疑问就扭曲了前当我在浏览通过量的扭曲的例子(这是写得很好),我看到使用cred的例子。我不得不提到,这种好奇心是因为我使用的扭曲越多,我越喜欢它,试图围绕它来理解它的功能。现在我的问题是为什么首先我会用cred?如果它是简单的用户通行证凭证,那么可以像对待大多数Web应用程序一样使用对数据库的简单检查吗?如果制作异步然后想不出DB客户端的异步版本来达到同样的?我可以得到什么好处通过relamavatarsportals?我的意思是在这种情况下可以使用这些东西。我知道这与我扭曲的信用证欠款有关,所以请帮忙。下面是我说的前约蟒蛇绞名气使用

from __future__ import print_function 

import sys 
from zope.interface import implementer, Interface 

from twisted.protocols import basic 
from twisted.internet import protocol 
from twisted.python import log 

from twisted.cred import error 
from twisted.cred import portal 
from twisted.cred import checkers 
from twisted.cred import credentials 

class IProtocolUser(Interface): 
    def getPrivileges(): 
     """Return a list of privileges this user has.""" 

    def logout(): 
     """Cleanup per-login resources allocated to this avatar""" 

@implementer(IProtocolUser) 
class AnonymousUser: 
    def getPrivileges(self): 
     return [1, 2, 3] 

    def logout(self): 
     print("Cleaning up anonymous user resources") 

@implementer(IProtocolUser) 
class RegularUser: 
    def getPrivileges(self): 
     return [1, 2, 3, 5, 6] 

    def logout(self): 
     print("Cleaning up regular user resources") 

@implementer(IProtocolUser) 
class Administrator: 
    def getPrivileges(self): 
     return range(50) 

    def logout(self): 
     print("Cleaning up administrator resources") 

class Protocol(basic.LineReceiver): 
    user = None 
    portal = None 
    avatar = None 
    logout = None 

    def connectionMade(self): 
     self.sendLine("Login with USER <name> followed by PASS <password> or ANON") 
     self.sendLine("Check privileges with PRIVS") 

    def connectionLost(self, reason): 
     if self.logout: 
      self.logout() 
      self.avatar = None 
      self.logout = None 

    def lineReceived(self, line): 
     f = getattr(self, 'cmd_' + line.upper().split()[0]) 
     if f: 
      try: 
       f(*line.split()[1:]) 
      except TypeError: 
       self.sendLine("Wrong number of arguments.") 
      except: 
       self.sendLine("Server error (probably your fault)") 

    def cmd_ANON(self): 
     if self.portal: 
      self.portal.login(credentials.Anonymous(), None, IProtocolUser 
       ).addCallbacks(self._cbLogin, self._ebLogin 
       ) 
     else: 
      self.sendLine("DENIED") 

    def cmd_USER(self, name): 
     self.user = name 
     self.sendLine("Alright. Now PASS?") 

    def cmd_PASS(self, password): 
     if not self.user: 
      self.sendLine("USER required before PASS") 
     else: 
      if self.portal: 
       self.portal.login(
        credentials.UsernamePassword(self.user, password), 
        None, 
        IProtocolUser 
       ).addCallbacks(self._cbLogin, self._ebLogin 
       ) 
      else: 
       self.sendLine("DENIED") 

    def cmd_PRIVS(self): 
     self.sendLine("You have the following privileges: ") 
     self.sendLine(" ".join(map(str, self.avatar.getPrivileges()))) 

    def _cbLogin(self, result): 
     (interface, avatar, logout) = result 
     assert interface is IProtocolUser 
     self.avatar = avatar 
     self.logout = logout 
     self.sendLine("Login successful. Available commands: PRIVS") 

    def _ebLogin(self, failure): 
     failure.trap(error.UnauthorizedLogin) 
     self.sendLine("Login denied! Go away.") 

class ServerFactory(protocol.ServerFactory): 
    protocol = Protocol 

    def __init__(self, portal): 
     self.portal = portal 

    def buildProtocol(self, addr): 
     p = protocol.ServerFactory.buildProtocol(self, addr) 
     p.portal = self.portal 
     return p 

@implementer(portal.IRealm) 
class Realm: 
    def requestAvatar(self, avatarId, mind, *interfaces): 
     if IProtocolUser in interfaces: 
      if avatarId == checkers.ANONYMOUS: 
       av = AnonymousUser() 
      elif avatarId.isupper(): 
       # Capitalized usernames are administrators. 
       av = Administrator() 
      else: 
       av = RegularUser() 
      return IProtocolUser, av, av.logout 
     raise NotImplementedError("Only IProtocolUser interface is supported by this realm") 

def main(): 
    r = Realm() 
    p = portal.Portal(r) 
    c = checkers.InMemoryUsernamePasswordDatabaseDontUse() 
    c.addUser("auser", "thepass") 
    c.addUser("SECONDUSER", "secret") 
    p.registerChecker(c) 
    p.registerChecker(checkers.AllowAnonymousAccess()) 

    f = ServerFactory(p) 

    log.startLogging(sys.stdout) 

    from twisted.internet import reactor 
    reactor.listenTCP(4738, f) 
    reactor.run() 

if __name__ == '__main__': 
    main() 

twisted.cred提供了一个抽象,它允许您的应用程序开发独立的验证凭证一些的具体方法,并让你的证书数据库独立开发应用程序。

在您的例子,请注意您的应用程序代码(Protocol)是怎么知道的凭据纯粹是存储在内存中的事实。如果你将InMemoryUsernamePasswordDatabaseDontUse替换为PAM后端,/etc-passwd风格的数据库或使用PostgreSQL的东西,它同样不会意识到。

此外,这些用户名/密码后端都可以独立开发应用程序逻辑的 - 允许每个应用程序的重新使用它们,无论他们是你的工作或工作的其他人与你分享。

+0

感谢回答,但它仍然不是很清楚,我我的意思是,我可以使用类检查用户验证得到那种抽象的(假设我想提出一个web应用程序)。这是不是一个Web应用程序适合的东西? – anekix

+0

我不太明白。你能从头开始实现一个相当于twisted.cred的东西吗?当然可以。 twisted.cred只是一堆Python代码。你也可以实现你自己的HTTP服务器,你自己的文件系统和你自己的TCP/IP协议栈。这只是更多的软件。图书馆的重点在于,不是每个人都必须为每个程序重新实现每一件事情。 –

+0

我不是那个意思。我知道图书馆存在某些原因,这就是为什么在我上面的问题中,我提到'我知道这与我对扭曲的信誉的欠缺有关。如果可能的话,请你给我提供一些方向,以便我可以在'twisted.cred'上找到更多信息。也许我会得到它 – anekix