2017-03-04 56 views
0

我有在這裏一個小疑問就扭曲了前當我在瀏覽通過量的扭曲的例子(這是寫得很好),我看到使用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() 

回答

0

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