Package turbogears :: Package identity :: Module base

Source Code for Module turbogears.identity.base

  1  """The TurboGears identity management package.""" 
  2   
  3  # declare what should be exported 
  4  __all__ = [ 
  5      '_encrypt_password', 
  6      'create_default_provider', 
  7      'current', 
  8      'current_provider', 
  9      'encrypt_password', 
 10      'encrypt_pw_with_algorithm', 
 11      'get_identity_errors', 
 12      'get_failure_url', 
 13      'set_current_identity', 
 14      'set_current_provider', 
 15      'set_identity_errors', 
 16      'set_login_attempted', 
 17      'was_login_attempted', 
 18  ] 
 19   
 20   
 21  import logging 
 22  try: 
 23      from hashlib import md5, sha1 
 24  except ImportError: 
 25      from sha import new as sha1 
 26      from md5 import new as md5 
 27   
 28  import cherrypy 
 29  import pkg_resources 
 30  import turbogears 
 31   
 32  from turbogears.util import deprecated, request_available, load_class 
 33  from turbogears.identity.exceptions import * 
 34   
 35   
 36  log = logging.getLogger('turbogears.identity') 
 37   
 38   
39 -def create_default_provider():
40 """Create default identity provider. 41 42 Creates an identity provider according to what is found in 43 the configuration file for the current TurboGears application 44 45 Returns an identity provider instance or 46 raises an IdentityConfigurationException. 47 48 """ 49 provider_plugin = turbogears.config.get('identity.provider', 'sqlobject') 50 plugins = pkg_resources.iter_entry_points( 51 'turbogears.identity.provider', provider_plugin) 52 53 log.debug("Loading provider from plugin: %s", provider_plugin) 54 55 for entrypoint in plugins: 56 try: 57 provider_class = entrypoint.load() 58 except Exception: 59 raise IdentityConfigurationException( 60 "IdentityProvider plugin can't be loaded: %s\n%s" 61 % (provider_plugin, load_error)) 62 break 63 else: 64 provider_class = load_class(provider_plugin) 65 66 if not provider_class: 67 raise IdentityConfigurationException( 68 "IdentityProvider plugin missing: %s" % provider_plugin) 69 70 return provider_class()
71 72
73 -def was_login_attempted():
74 try: 75 return cherrypy.request.identity_login_attempted 76 except AttributeError: 77 return False
78 79
80 -def set_login_attempted(flag):
81 cherrypy.request.identity_login_attempted = flag
82 83
84 -def set_current_identity(identity):
85 cherrypy.request.identity = identity 86 87 try: 88 cherrypy.request.user_name = identity.user_name 89 90 except AttributeError: 91 cherrypy.request.user_name = None
92 93
94 -def set_current_provider(provider):
95 cherrypy.request.identityProvider = provider
96 97
98 -def encrypt_pw_with_algorithm(algorithm, password):
99 """Hash the given password with the specified algorithm. 100 101 Valid values for algorithm are 'md5' and 'sha1' or 'custom'. If the 102 algorithm is 'custom', the config setting 'identity.custom_encryption' 103 needs to be set to a dotted-notation path to a callable that takes 104 an unencrypted password and gives back the password hash. 105 106 All other algorithms values will be essentially a no-op. 107 108 """ 109 hashed_password = password 110 # The algorithms don't work with unicode objects, so decode first. 111 if isinstance(password, unicode): 112 password_8bit = password.encode('utf-8') 113 else: 114 password_8bit = password 115 if algorithm == 'md5': 116 hashed_password = md5(password_8bit).hexdigest() 117 elif algorithm == 'sha1': 118 hashed_password = sha1(password_8bit).hexdigest() 119 elif algorithm == 'custom': 120 custom_encryption_path = turbogears.config.get( 121 'identity.custom_encryption', None) 122 if custom_encryption_path: 123 custom_encryption = turbogears.util.load_class( 124 custom_encryption_path) 125 if custom_encryption: 126 hashed_password = custom_encryption(password_8bit) 127 # Make sure the hashed password is a unicode object at the end of the 128 # process, because SQLAlchemy _wants_ that for Unicode columns. 129 if not isinstance(hashed_password, unicode): 130 hashed_password = hashed_password.decode('utf-8') 131 return hashed_password
132 133 _encrypt_password = deprecated( 134 "Use identity.encrypt_pw_with_algorithm instead." 135 )(encrypt_pw_with_algorithm) 136 137
138 -def encrypt_password(cleartext):
139 return current_provider.encrypt_password(cleartext)
140 141
142 -class IdentityWrapper(object):
143 """A wrapper class for the thread local data. 144 145 This allows developers to access the current user information via 146 turbogears.identity.current and get the identity for the current request. 147 148 """ 149
150 - def identity(self):
151 try: 152 identity = cherrypy.request.identity 153 154 except AttributeError: 155 identity = None 156 157 if not identity: 158 if not request_available(): 159 raise RequestRequiredException() 160 161 raise IdentityManagementNotEnabledException() 162 163 return identity
164
165 - def __getattr__(self, name):
166 """Return the named attribute of the global state.""" 167 identity = self.identity() 168 if name == '__str__': 169 return identity.__str__ 170 171 elif name == '__repr__': 172 return identity.__repr__ 173 174 else: 175 return getattr(identity, name)
176
177 - def __setattr__(self, name, value):
178 """Stash a value in the global state.""" 179 identity = self.identity() 180 setattr(identity, name, value)
181 182
183 -class ProviderWrapper(object):
184
185 - def __getattr__(self, name):
186 try: 187 provider = cherrypy.request.identityProvider 188 189 except AttributeError: 190 try: 191 provider = create_default_provider() 192 except Exception, exc: 193 log.warning("Could not create default identity provider: %s", exc) 194 provider = None 195 196 if provider is None: 197 if not request_available(): 198 raise RequestRequiredException() 199 200 raise IdentityManagementNotEnabledException() 201 202 return getattr(provider, name)
203 204 current = IdentityWrapper() 205 current_provider = ProviderWrapper() 206