SQL user source, how is this?
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
At 01:28 PM 10/16/00 -0400, Harry Henry Gebel wrote:
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?
The caching stuff is to avoid repeated database lookups. Keep in mind that your system will be issuing SQL queries on every web hit. Note that if you were to use actual Z SQL Method objects instead of raw SQL from Python, you could set the cache parameters on the Method objects to do most of the caching work for you.
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
Yes, you can do this. The easiest way is to add this to your class: _properties=( {'id':'title', 'type': 'string', 'mode': 'w'}, {'id':'use_database_id', 'type': 'string', 'mode': 'w'}, ) use_database_id = "cc_user_database" This will make the property always exist and it will initially default to "cc_user_database".
participants (2)
-
Harry Henry Gebel -
Phillip J. Eby