Package flumotion :: Package twisted :: Module checkers
[hide private]

Source Code for Module flumotion.twisted.checkers

  1  # -*- Mode: Python; test-case-name: flumotion.test.test_checkers -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3   
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007,2008,2009 Fluendo, S.L. 
  6  # Copyright (C) 2010,2011 Flumotion Services, S.A. 
  7  # All rights reserved. 
  8  # 
  9  # This file may be distributed and/or modified under the terms of 
 10  # the GNU Lesser General Public License version 2.1 as published by 
 11  # the Free Software Foundation. 
 12  # This file is distributed without any warranty; without even the implied 
 13  # warranty of merchantability or fitness for a particular purpose. 
 14  # See "LICENSE.LGPL" in the source distribution for more information. 
 15  # 
 16  # Headers in this file shall remain intact. 
 17   
 18  """ 
 19  Flumotion Twisted credential checkers 
 20  """ 
 21   
 22  from twisted.cred import checkers 
 23  from twisted.internet import defer 
 24  from twisted.python import failure 
 25  from zope.interface import implements 
 26   
 27  from flumotion.common import log, errors 
 28  from flumotion.twisted import credentials 
 29   
 30  __version__ = "$Rev$" 
 31   
 32   
 33  # FIXME: give the manager's bouncer's checker to the flexcredchecker, 
 34  # and forward to it 
 35   
 36   
37 -class FlexibleCredentialsChecker(log.Loggable):
38 """ 39 I am an in-memory username/password credentials checker that also 40 allows anonymous logins if instructed to do so. 41 """ 42 logCategory = 'credchecker' 43 implements(checkers.ICredentialsChecker) 44 45 credentialInterfaces = (credentials.IUsernamePassword, 46 credentials.IUsernameHashedPassword) 47
48 - def __init__(self, **users):
49 self.users = users 50 self._passwordless = False # do we allow passwordless logins ?
51
52 - def allowPasswordless(self, wellDoWeQuestionMark):
53 self._passwordless = wellDoWeQuestionMark
54
55 - def addUser(self, username, password):
56 self.users[username] = password
57
58 - def _cbPasswordMatch(self, matched, username, avatarId):
59 if matched: 60 return avatarId or username 61 else: 62 return failure.Failure(errors.NotAuthenticatedError())
63 64 ### ICredentialsChecker interface methods 65
66 - def requestAvatarId(self, credentials):
67 avatarId = getattr(credentials, 'avatarId', None) 68 69 if self._passwordless: 70 self.debug('allowing passwordless login for user %s', 71 credentials.username) 72 return defer.succeed(avatarId or credentials.username) 73 elif credentials.username in self.users: 74 self.debug('authenticating user %s' % credentials.username) 75 return defer.maybeDeferred( 76 credentials.checkPassword, 77 self.users[credentials.username]).addCallback( 78 self._cbPasswordMatch, str(credentials.username), 79 avatarId) 80 else: 81 return defer.fail(errors.NotAuthenticatedError())
82 83
84 -class CryptChecker(log.Loggable):
85 """ 86 I check credentials using a crypt-based backend. 87 """ 88 implements(checkers.ICredentialsChecker) 89 credentialInterfaces = (credentials.IUsernameCryptPassword, ) 90 91 logCategory = 'cryptchecker' 92
93 - def __init__(self, **users):
94 self.users = users
95
96 - def addUser(self, username, cryptPassword):
97 """ 98 Add the given username and password. 99 100 @param username: name of the user to add 101 @type username: string 102 @param cryptPassword: the crypted password for this user 103 @type cryptPassword: string 104 """ 105 self.debug('added user %s' % username) 106 self.users[username] = cryptPassword
107
108 - def _cbCryptPasswordMatch(self, matched, username):
109 if matched: 110 self.debug('user %s authenticated' % username) 111 return username 112 else: 113 self.debug('user %s refused, password not matched' % username) 114 return failure.Failure(errors.NotAuthenticatedError())
115 116 ### ICredentialsChecker methods 117
118 - def requestAvatarId(self, credentials):
119 if credentials.username in self.users: 120 return defer.maybeDeferred( 121 credentials.checkCryptPassword, 122 self.users[credentials.username]).addCallback( 123 self._cbCryptPasswordMatch, credentials.username) 124 else: 125 self.debug("user '%s' refused, not in storage backend" % 126 credentials.username) 127 return defer.fail(errors.NotAuthenticatedError())
128 129
130 -class Sha256Checker(log.Loggable):
131 """ 132 I check credentials using a SHA-256-based backend. 133 """ 134 implements(checkers.ICredentialsChecker) 135 credentialInterfaces = (credentials.IUsernameSha256Password, ) 136 137 logCategory = 'sha256checker' 138
139 - def __init__(self, **users):
140 self.users = users
141
142 - def addUser(self, username, salt, sha256Data):
143 """ 144 Add the given username and password. 145 146 @param username: name of the user to add 147 @type username: str 148 @param salt: the salt for this user 149 @type salt: str 150 @param sha256Data: the sha256 data for this user 151 @type sha256Data: str 152 """ 153 self.debug('added user %s' % username) 154 self.users[username] = (salt, sha256Data)
155
156 - def _cbSha256PasswordMatch(self, matched, username):
157 if matched: 158 self.debug('user %s authenticated' % username) 159 return username 160 else: 161 self.debug('user %s refused, password not matched' % username) 162 return failure.Failure(errors.NotAuthenticatedError())
163 164 ### ICredentialsChecker methods 165
166 - def requestAvatarId(self, credentials):
167 if credentials.username in self.users: 168 salt, data = self.users[credentials.username] 169 password = salt + data 170 return defer.maybeDeferred( 171 credentials.checkSha256Password, 172 password).addCallback( 173 self._cbSha256PasswordMatch, credentials.username) 174 else: 175 self.debug('user %s refused, not in database' % 176 credentials.username) 177 return defer.fail(errors.NotAuthenticatedError())
178