# # Extensible User Folder # # Postgres Authentication Source for exUserFolder # # (C) Copyright 2000,2001 The Internet (Aust) Pty Ltd # ACN: 082 081 472 ABN: 83 082 081 472 # All Rights Reserved # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # Author: Andrew Milton # $Id: pgAuthSource.py,v 1.2 2001/12/01 08:40:05 akm Exp $ # # This class only authenticates users, it stores no properties. # import string,Acquisition,md5 from Globals import HTMLFile, MessageDialog, INSTANCE_HOME from OFS.Folder import Folder from Products.ZSQLMethods.SQL import SQL from Products.exUserFolder.exUserFolder import exUserFolder from Products.exUserFolder.Plugins import PluginRegister try: from crypt import crypt except: from Products.exUserFolder.fcrypt.fcrypt import crypt def manage_addpgAuthSource(self, REQUEST): """ Add a Postgres Auth Source """ connection=REQUEST['pgauth_connection'] userTable=REQUEST['pgauth_userTable'] usernameColumn=REQUEST['pgauth_usernameColumn'] passwordColumn=REQUEST['pgauth_passwordColumn'] roleTable=REQUEST['pgauth_roleTable'] roleColumn=REQUEST['pgauth_roleColumn'] o = pgAuthSource(connection, userTable, usernameColumn, passwordColumn, roleTable, roleColumn) self._setObject('pgAuthSource', o, None, None, 0) o=getattr(self,'pgAuthSource') if hasattr(o, 'postInitialisation'): o.postInitialisation(REQUEST) self.currentAuthSource=o return '' manage_addpgAuthSourceForm=HTMLFile('manage_addpgAuthSourceForm', globals()) manage_editpgAuthSourceForm=HTMLFile('manage_editpgAuthSourceForm', globals()) class pgAuthSource(Folder): """ Authenticate Users against a Postgres Database """ meta_type='Authorisation Source' title='Advanced Postgresql Authentication' icon ='misc_/exUserFolder/exUserFolderPlugin.gif' manage_tabs=Acquisition.Acquired manage_editForm=manage_editpgAuthSourceForm # # You can define this to go off and do the authentication instead of # using the basic one inside the User Object # remoteAuthMethod=None def __init__(self, connection, userTable, usernameColumn, passwordColumn, roleTable, roleColumn): self.id='pgAuthSource' self.connection=connection self.userTable=userTable self.usernameColumn=usernameColumn self.passwordColumn=passwordColumn self.roleTable=roleTable self.roleColumn=roleColumn self.addSQLQueries() def manage_editAuthSource(self, REQUEST): """ Edit a Postgres Auth Source """ self.connection=REQUEST['pgauth_connection'] self.userTable=REQUEST['pgauth_userTable'] self.usernameColumn=REQUEST['pgauth_usernameColumn'] self.passwordColumn=REQUEST['pgauth_passwordColumn'] self.roleTable=REQUEST['pgauth_roleTable'] self.roleColumn=REQUEST['pgauth_roleColumn'] self.delSQLQueries() self.addSQLQueries() # Re-add queries with new parameters def createUser(self, username, password, roles): """ Add A Username """ if type(roles) != type([]): if roles: roles=list(roles) else: roles=[] secret=self.cryptPassword(username, password) self.sqlInsertUser(username=username, password=secret) for n in roles: self.insertUserRole(username, n) def insertUserRole(self, username, rolename): """ Add User Role """ self.sqlInsertUserRole(username=username, rolename=rolename) def deleteUserRoles(self, username): """ Delete User Roles """ self.sqlDeleteUserRoles(username=username) def updateUser(self, username, password, roles): if type(roles) != type([]): if roles: roles=list(roles) else: roles=[] # Don't change passwords if it's null if password: secret=self.cryptPassword(username, password) self.sqlUpdateUserPassword(username=username, password=secret) self.deleteUserRoles(username) for n in roles: self.insertUserRole(username, n) def delSQLQueries(self): sqllist=self.objectIds('Z SQL Method') self.manage_delObjects(ids=sqllist) def addSQLQueries(self): sqlListUsers=SQL( 'sqlListUsers', 'List All Users', self.connection, 'userTable=%s'%(self.userTable), _sqlListUsers) self._setObject('sqlListUsers', sqlListUsers) sqlListOneUser=SQL( 'sqlListOneUser', 'List ONE User', self.connection, 'userTable=%s usernameColumn=%s username:string'%( self.userTable, self.usernameColumn), _sqlListOneUser) self._setObject('sqlListOneUser', sqlListOneUser) sqlListUserRoles=SQL( 'sqlListUserRoles', 'List User Roles', self.connection, 'roleTable=%s usernameColumn=%s username:string'%( self.roleTable, self.usernameColumn), _sqlListUserRoles) self._setObject('sqlListUserRoles', sqlListUserRoles) sqlDeleteOneUser=SQL( 'sqlDeleteOneUser', 'Delete One User', self.connection, 'userTable=%s usernameColumn=%s username:string'%( self.userTable,self.usernameColumn), _sqlDeleteOneUser) self._setObject('sqlDeleteOneUser', sqlDeleteOneUser) sqlDeleteUserRoles=SQL( 'sqlDeleteUserRoles', 'Delete User Roles', self.connection, 'roleTable=%s usernameColumn=%s username:string'%( self.roleTable,self.usernameColumn), _sqlDeleteUserRoles) self._setObject('sqlDeleteUserRoles', sqlDeleteUserRoles) sqlInsertUser=SQL( 'sqlInsertUser', 'Insert One User', self.connection, 'userTable=%s usernameColumn=%s passwordColumn=%s username:string password:string'%( self.userTable, self.usernameColumn, self.passwordColumn), _sqlInsertUser) self._setObject('sqlInsertUser', sqlInsertUser) sqlInsertUserRole=SQL( 'sqlInsertUserRole', 'Insert User Role', self.connection, 'roleTable=%s usernameColumn=%s roleColumn=%s username:string rolename:string'%( self.roleTable, self.usernameColumn, self.roleColumn), _sqlInsertUserRole) self._setObject('sqlInsertUserRole', sqlInsertUserRole) sqlUpdateUserPassword=SQL( 'sqlUpdateUserPassword', 'Update just the password', self.connection, 'userTable=%s usernameColumn=%s passwordColumn=%s username:string password:string'%(self.userTable, self.usernameColumn, self.passwordColumn), _sqlUpdateUserPassword) self._setObject('sqlUpdateUserPassword', sqlUpdateUserPassword) # Original cryptPassword function def cryptPassword(self, username, password): salt =username[:2] secret = crypt(password, salt) return secret # Alternate cryptPassword function, returns md5 hash of the password # def cryptPassword(self, username, password): # passhash = md5.new(password) # secret = passhash.hexdigest() # return secret # Alternate cryptPassword function, returns plain text of the password. # def cryptPassword(self, username, password): # return password def deleteUsers(self, userids): for uid in userids: self.sqlDeleteUserRoles(username=uid) self.sqlDeleteOneUser(username=uid) def listUserNames(self): """Returns a real list of user names """ users = [] result=self.sqlListUsers() for n in result: username=sqlattr(n,self.usernameColumn) users.append(username) return users def listUsers(self): """Returns a list of user names or [] if no users exist""" users = [] result=self.sqlListUsers() for n in result: username=sqlattr(n,self.usernameColumn) N={'username':username} users.append(N) return users def listOneUser(self,username): users = [] result=self.sqlListOneUser(username=username) for n in result: username=sqlattr(n,self.usernameColumn) password=sqlattr(n,self.passwordColumn) roles=self.listUserRoles(username) N={'username':username, 'password':password, 'roles':roles} users.append(N) return users def listUserRoles(self,username): roles = [] result = self.sqlListUserRoles(username=username) for n in result: role=sqlattr(n, self.roleColumn) N=role roles.append(N) return roles def getUsers(self): """Return a list of user objects or [] if no users exist""" data=[] try: items=self.listusers() except: return data for people in items: roles=string.split(people['roles'],',') user=User(people['username'], roles, '') data.append(user) return data def postInitialisation(self, REQUEST): pass pgAuthReg=PluginRegister('pgAuthSourceAdv', 'Advanced Postgresql Authentication Source', pgAuthSource, manage_addpgAuthSourceForm, manage_addpgAuthSource, manage_editpgAuthSourceForm) exUserFolder.authSources['pgAuthSourceAdv']=pgAuthReg from string import upper, lower import Missing mt=type(Missing.Value) def typeconv(val): if type(val)==mt: return '' return val def sqlattr(ob, attr): name=attr if hasattr(ob, attr): return typeconv(getattr(ob, attr)) attr=upper(attr) if hasattr(ob, attr): return typeconv(getattr(ob, attr)) attr=lower(attr) if hasattr(ob, attr): return typeconv(getattr(ob, attr)) raise NameError, name _sqlListUsers=""" SELECT * FROM """ _sqlListOneUser=""" SELECT * FROM where = """ _sqlListUserRoles=""" SELECT * FROM where = """ _sqlDeleteOneUser=""" DELETE FROM where = """ _sqlDeleteUserRoles=""" DELETE FROM where = """ _sqlInsertUser=""" INSERT INTO (, ) VALUES (, ) """ _sqlInsertUserRole=""" INSERT INTO (, ) VALUES (, ) """ _sqlUpdateUserPassword=""" UPDATE set = WHERE = """