[Zope-dev] SQL user source, how is this?
Harry Henry Gebel
hgebel@inet.net
Mon, 16 Oct 2000 13:28:36 -0400
I am writing a UserSource that gets it's information from an SQL database,
here it is:
''' CCUserSource, a LoginManager user source for the ##### project. '''
from sha import sha
from Products.LoginManager.UserSources import BasicUserSource
class CCUserSource(BasicUserSource):
"""
CCUserSource is a ZPatterns plug-in intended to be used as a user source in
LoginManager. It queries a database adapter to acquire authentication
information on a user, and sets a user's role based on the user's age. A
database connection with an id of cc_user_database must be visible. """
# string displayed in "Add Product" drop-down box.
meta_type = "##### User Source"
# public functions
def retrieveItem(self, name):
'''
Return a user object if user exists in database, otherwise return None '''
# call database adapter, if we can't connect return None
try:
result = self.__query(
"select username from users where username='%s'" % name)
except:
return None
# return a user object if user exists in database
if result:
return self._RawItem(name)
else:
return None
def rolesForUser(self, user):
''' Calculate role from age '''
return ['Manager']
def domainsForUser(self, user):
''' Allow users from all domains '''
return []
def authenticateUser(self, user, password, request):
""" Verify user's password, return true if correct, 0 if incorrect """
# get SHA encoded password and salt from the database
passw = self.__query(
"select password from users where username = '%s'" % user.getUserName())
(salt, passw) = (passw[:2], passw[2:])
# apply salt to user-supplied password and generate hash
hash = sha(salt + password).hexdigest()
# return result of match
return hash == passw
# private functions
def __query(self, query):
'''
Perform a query on cc_user_database, return the results of the query, return
None on no result '''
# find database connection, let caller catch exceptions
dbc = getattr(self, 'cc_user_database')
db = dbc()
# return results of database query
# query returns result in form
# ([field_data], [(row1), ...])
# all of our queries have max 1 result and only 1 column, so process
# accordingly
try:
result = db.query(query)[1][0][0]
except:
result = None
return result
It is working, but I have some questions:
1. Am I doing anything wrong that will bite me later, especially I have not
implemented all of the cache* methods called in GenericUserFolder because I
don't understand what these do or what they are for. Are these important
for my product?
2. I would like my client to be able to specify an alternate database
connection id if he does not want to use the default connection id of
cc_user_database. If he goes to his CCUserSource's "properties" tab and
adds a property of use_database_id with the connection id he wants to use,
how do I access it (this is my first Zope product, so I am learning the
internals as I go along). Can I use
self.use_database_id
or do I have to use
getattr(self, 'use_database_id')
or do I have to use a completely different method to access properties.
PS: I know I am giving everybody that passes authentication the manager role, I
did this for testing purposes and haven't changed it yet because I have not
been given me a list of the roles they want to use.
--
Harry Henry Gebel, ICQ# 76308382
West Dover Hundred, Delaware