2017-03-04 5 views
0

私はここで撚り糸の例をブラウズしていたときに撚りがかかっていると疑問を呈しています(これは非常によく書かれています)。credの例を見ました。私はこの好奇心がより多くの私はそれを好きであり、その周りに私の頭を包み込み、その機能を詳細に理解しようとしているので、よりねじれを使用するためです。今私の質問なぜ私はcredを使用する最初の場所ですか?単純なユーザーのパススルー証明書の場合、データベースへの単純なチェックは、ほとんどのWebアプリケーションで行われたように使用できますか? asyncを作成する場合は、dbクライアントのcouldnt asyncバージョンを使用して同じ結果を得ることができますか?relam,avatarsおよびportalsを使用するとどのような利点がありますか?私はこれらの事柄がどのようなシナリオで使用できるのかを意味します。私はそれがねじれたクレジットの私のundersatndingと関係があることを知っているので、助けてください。以下、私はおよそpython twisted cred use

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を話しているexは、アプリケーションが、検証の具体的な手段いくつかの資格情報とは独立して開発することを可能にすると、資格情報データベースがアプリケーションとは独立して開発することができます抽象化を提供しています。

例では、アプリケーションコード(Protocol)が資格情報が純粋にメモリに格納されているという事実を認識していないことに注意してください。 InMemoryUsernamePasswordDatabaseDontUseをPAMバックエンド、/etc-passwdスタイルのデータベース、またはPostgreSQLを使用したものに置き換えた場合も同様です。

これらのユーザー名/パスワードバックエンドはすべて、アプリケーションロジックとは独立して開発することができます。つまり、自分の仕事や他の誰かがあなたと共有しているものであれ、アプリケーションの再利用が可能です。

+0

返信ありがとうございますが、それでも私にはわかりません。つまり、ユーザーの検証をチェックするクラスを使用して、そのような抽象化を得ることができます(私はWebアプリケーションを作っています)。これは、Webアプリケーションのための適切なものではありませんか? – anekix

+0

私は本当に理解していません。 twisted.credと全く同じものをゼロから実装できますか?もちろん可能です。 twisted.credはPythonコードの山です。独自のHTTPサーバーと独自のファイルシステムと独自のTCP/IPスタックを実装することもできます。それはまさにソフトウェアです。図書館のポイントは、誰もがすべてのプログラムのためにすべてのものを再実装する必要がないようにすることです。 –

+0

私はそれを意味しませんでした。私はライブラリが何らかの理由で存在することを知っています。それはなぜ私の質問で私は '私はそれがねじれたクレジットの私のundersatndingと関係があることを知っていることを言った。可能であれば、あなたが私が 'twisted.cred'についてのより多くの情報をどこから探すことができるかを私に指示してください。 – anekix