[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
gnue/common doc/technotes/00005.txt doc/technot...
From: |
Jason Cater |
Subject: |
gnue/common doc/technotes/00005.txt doc/technot... |
Date: |
Wed, 18 Sep 2002 02:49:28 -0400 |
CVSROOT: /home/cvs
Module name: gnue
Changes by: Jason Cater <address@hidden> 02/09/18 02:49:27
Modified files:
common/doc/technotes: 00005.txt index.html index.txt
common/src : GBaseApp.py GConnections.py GLoginHandler.py
Log message:
added support for custom login authenticators; read common technote
00005.txt for more information
CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/common/doc/technotes/00005.txt.diff?cvsroot=OldCVS&tr1=1.1&tr2=1.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/common/doc/technotes/index.html.diff?cvsroot=OldCVS&tr1=1.2&tr2=1.3&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/common/doc/technotes/index.txt.diff?cvsroot=OldCVS&tr1=1.4&tr2=1.5&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/common/src/GBaseApp.py.diff?cvsroot=OldCVS&tr1=1.26&tr2=1.27&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/common/src/GConnections.py.diff?cvsroot=OldCVS&tr1=1.43&tr2=1.44&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/common/src/GLoginHandler.py.diff?cvsroot=OldCVS&tr1=1.5&tr2=1.6&r1=text&r2=text
Patches:
Index: gnue/common/doc/technotes/00005.txt
diff -c gnue/common/doc/technotes/00005.txt:1.1
gnue/common/doc/technotes/00005.txt:1.2
*** gnue/common/doc/technotes/00005.txt:1.1 Thu Jul 18 14:40:47 2002
--- gnue/common/doc/technotes/00005.txt Wed Sep 18 02:49:27 2002
***************
*** 1,33 ****
Title: Writing a Custom Login/Authentication Handler
! Status: Obsolete
Introduction
------------
! By default, GNUe clients look at a database connection, determine what
! fields it needs in order to login (e.g., username and password), and then
! asks its platform/interface dependent login handler to prompt the user for
! this information. Once returned, the client connects to the database using
! this information.
! If needed, you can intercept a client's normal login handler to add your
own behavior.
Why?
----
! Sometimes it is not enough to prompt for the "database" login. Perhaps
! you want finer control over logins, or simply need to authenticate against
something besides the database.
! You might want to authenticate against an NIS source, LDAP, or some custom
! source. Maybe you have many users and want to authenticate against rows in
! a database table and have the actual database login name/password be a
! common one that no one knows; i.e., while users Jason and James might log
! in using "jason" and "james", they might both connect to the database as
! "commonuser". Since you may not trust James, you only want him to know
! that he is logging in as "james" and never know that he is being connected
as "commonuser".
--- 1,34 ----
Title: Writing a Custom Login/Authentication Handler
! Status: Current
! Revised: 18-SEP-2002
Introduction
------------
! By default, GNUe clients look at a database connection, determine what
! fields it needs in order to login (e.g., username and password), and then
! asks its platform/interface dependent login handler to prompt the user for
! this information. Once returned, the client connects to the database using
! this information.
! If needed, you can intercept a client's normal login handler to add your
own behavior.
Why?
----
! Sometimes it is not enough to prompt for the "database" login. Perhaps
! you want finer control over logins, or simply need to authenticate against
something besides the database.
! You might want to authenticate against an NIS source, LDAP, or some custom
! source. Maybe you have many users and want to authenticate against rows in
! a database table and have the actual database login name/password be a
! common one that no one knows; i.e., while users Jason and James might log
! in using "jason" and "james", they might both connect to the database as
! "commonuser". Since you may not trust James, you only want him to know
! that he is logging in as "james" and never know that he is being connected
as "commonuser".
***************
*** 35,172 ****
What do I do?
-------------
! First, a little explanation of how logins work:
!
! 1. A client needs to initialize a connection to a database, so it passes
GNUe-Common a description of the database and asks for it to connect.
! 2. GNUe-Common looks at the database description, determines what values
are needed to connect (usually, username and password).
! 3. GNUe-Common creates an instance of (or uses an existing instance of)
gnue.common.GLoginHander.LoginHandler, or if the client provides a
more advanced login handler (e.g., GNUe Form's graphical handler), an
instance of this.
! 4. GNUe-Common calls LoginHandler.getLogin(), passing it basic information
! about the needed connection and a list of values that login handler
! should provide (i.e., '_username' & '_password').
!
! 5. GNUe-Common uses the results of the call to LoginHandler.getLogin() to
! create a connection to the database.
!
!
! Now, if needed, you can subclass LoginHandler (basically intercepting
! steps #3-4 above) and provide your own functionality. All that is needed
! is for you to provide class with a method called getLogin that takes as
! input a tuple of:
!
! (database id, description, (requiredValues) )
!
! and return a hash containing a dictionary/hash:
!
! { 'field': 'value' }.
!
! RequiredValues is a tuple of tuples containing:
!
! (value id, value description, isPassword)
!
! Example of a getLogin call as used by GNUe Common
!
! loginHandler.getLogin ('gnue', # Connection ID
! 'GNUe Test Database', # Connection Name
! ( ('_username','User Name', 0), # Required
! ('_password','Password', 1) ) ) # Fields
!
! You would want to write your own handler as such:
!
!
! #####################################################
! #
! # Template for a custom login handler
! #
!
! # Import the base login handler;
! # Note: it is important that this line not change.
! from gnue.common.GLoginHander import LoginHandler
!
! # Do not rename this class.
! # GNUe clients expect to see a MyLoginHander class
! class MyLoginHandler(LoginHandler):
!
! #
! # getLogin is passed an list consisting of:
! # Connection Name
! # Connection Comments/Description
! # List of Fields to Input:
! # Attribute Name, Label/Description, Is Password?
! #
! # It should return a dictionary of {Attribute Name: Inputted Value}
! #
! def getLogin(self, loginData):
!
! connName = loginData[0]
! connDescription = loginData[1]
! requiredFields = loginData[2]
!
! # Perform any tasks prior to prompting for username/password.
! # At this point, you might want to add your needed fields to
! # requiredFields or set default values. Note: to set default
! # values, set 'self._defaults['fieldname'] = 'default'
! # (e.g., 'self._defaults['_username'] = os.env['LOGNAME'] )
!
! loginFields = LoginHandler.getLogin (self, (connName,
! connDescription,
! requiredFields) )
!
! # Perform any tasks prior to returning username/password
! # The entered username/password is stored in loginFields['_username']
! # and loginFields['_password']. At this point
!
! return loginFields
!
! #
! #####################################################
!
!
! Save this file as a .py file and put it's location in your gnue.conf (change
! "loginHandler =" to "loginHandler = /path/to/myhandler.py" )
If all goes well, your login handler will be used the next time you log in.
! Some notes:
! 1) GNUe-Common will expect to see to two objects in your handler's
! namespace: LoginHandler (from the import statement) and
MyLoginHandler (your customized login class)
! For this reason, do NOT change the import statement to read:
from gnue.common import GLoginHandler
and then change the class' parent to be GLoginHandler.LoginHandler.
If you do, your customized handler will probably not work the way
! you expect.
2) Almost the only restriction placed on getLogin's functionality is
! that it must return a hash containing at least the values requested
! when getLogin was called, using the value id's supplied. Your code,
in theory, can do whatever it needs in order to return these values.
! HOWEVER: Even though it is possible, it is NOT recommended that you
! try to write your code to prompt for the values. It is HIGHLY
! recommended that you call LoginHandler.getLogin (your superclass's
! getLogin) to prompt for input. The superclass' LoginHandler will
! know how to handle the current user's environment (i.e., should it
! display a GTK login box, generate HTML for a login box, not display
a box at all, but prompt using good ol' fashioned text prompts?)
! It is quite extensible. If you need to prompt for more fields than
! simply Username and Password, then simply add a definition to your
! requiredFields tuple and let the superclass' getLogin prompt for you.
If you have written a customized login handler using backends not currently
! in our samples file (i.e., against NIS, Kerberos, LDAP, etc) and would like
! to donate your example for others to learn from, please email it to:
address@hidden
-
--- 36,203 ----
What do I do?
-------------
! First, a little explanation of how logins work:
!
! 1. A client needs to initialize a connection to a database, so it passes
GNUe-Common a description of the database and asks for it to connect.
! 2. GNUe-Common looks at the database description, determines what values
are needed to connect (usually, username and password).
! 3. GNUe-Common creates an instance of (or uses an existing instance of)
gnue.common.GLoginHander.LoginHandler, or if the client provides a
more advanced login handler (e.g., GNUe Form's graphical handler), an
instance of this.
! 4. GNUe-Common calls LoginHandler.getLogin(), passing it basic information
! about the needed connection and a list of values that login handler
! should provide (i.e., '_username' & '_password').
!
! 5. GNUe-Common uses the results of the call to LoginHandler.getLogin() to
! create a connection to the database.
!
!
! Now, if needed, you can create an Authenticator class that basically
! intervenes in between steps #3-4 above and provide your own functionality.
If all goes well, your login handler will be used the next time you log in.
! Some notes:
! 1) GNUe-Common will expect to see to two objects in your handler's
! namespace: LoginHandler (from the import statement) and
MyLoginHandler (your customized login class)
! For this reason, do NOT change the import statement to read:
from gnue.common import GLoginHandler
and then change the class' parent to be GLoginHandler.LoginHandler.
If you do, your customized handler will probably not work the way
! you expect.
2) Almost the only restriction placed on getLogin's functionality is
! that it must return a hash containing at least the values requested
! when getLogin was called, using the value id's supplied. Your code,
in theory, can do whatever it needs in order to return these values.
! HOWEVER: Even though it is possible, it is NOT recommended that you
! try to write your code to prompt for the values. It is HIGHLY
! recommended that you return values in the getLoginFields method so
! LoginHandler.getLogin can prompt for input. The LoginHandler will
! know how to handle the current user's environment (i.e., should it
! display a GTK login box, generate HTML for a login box, not display
a box at all, but prompt using good ol' fashioned text prompts?)
! It is quite extensible. If you need to prompt for more fields than
! simply Username and Password, then simply add a definition to your
! requiredFields tuple and let the LoginHandler's getLogin prompt for
! you.
!
!
! There are three steps to adding a custom authenticator:
!
! 1. Create (or copy) a Python file that implements an Authenticator.
! An Authenticator contains a class called Authenticator, which has
! two methods, getRequiredFields() and login(). See the example below
! for details on what's expected from these two methods.
!
! 2. Place this file in either your Python search path, or in a
! path specified by ImportPath (in the [common] section of gnue.conf)
!
! 3. In your connections.conf file, add a custom_auth parameter that
! is the name of the file (without the path or .py extension):
!
! [myconn]
! adapter = psycopg
! host = localhost
! dbname = mydb
! custom_auth = MyPostgresAuthenticator
!
!
! Creating a custom authenticator
! ===============================
! A slightly more complicated example. You have a table in one of your
databases
! called "users", that has a user and password field.
!
! Your users will connect to the database using the username and password:
! dbUser and dbPassword.
!
! You, however, want them to use their own username and password to be
! authenticated, but after getting authenticated, the database only cares
! about the real "dbUser" and "dbPassword".
!
! File: MyPostgresAuthenticator.py
!
===============================================================================
! import psycopg
! from gnue.common.GConnections import LoginError
!
! class Authenticator:
! #
! # getLoginFields is passed an list consisting of:
! # Fields to Input:
! # Attribute Name, Label/Description, Is Password?
! #
! # This list is a list of the values the dbdriver
! # expects to get back in order to login.
! #
! # It should return a similarly formatted list that
! # tells the LoginHandler what values need to be
! # prompted for. (Typically, _username and _password)
! # If nothing should be prompted (e.g., you have a
! # certificate) then return () (an empty list).
! #
! def getLoginFields(self, dbRequiredFields):
! return dbRequiredFields
!
! #
! # Authenticate the user givem the values prompted for.
! # If the information is incorrect, then raise
! # gnue.common.GConnections.LoginError
! #
! # It should return a dictionary of {Attribute Name: Value}
! #
! def login(self, loginData):
! conn = psycopg.connect(user="theValidator",
! password="hotmomma",
! dbname="logins",
! host="localhost"')
! cursor = conn.cursor()
! results = cursor.execute (
! 'select 1 from users where username=%s and password=%s',
! (loginData['_username'],
! loginData['_password']) )
! if not results.fetchone():
! raise LoginError
! else:
! loginData['_username'] = 'dbLogin'
! loginData['_password'] = 'dbPassword'
!
===============================================================================
!
! Note: there are no hard and fast rules about what can go into the
! connections.conf file. If your authenticator needs more information
! stored in connections.conf, it is fine to do so.
!
! However, to avoid namespace collisions, you should probably prefix
! any custom connection.conf entries with common prefix. For example,
! if you are writing an NIS adapter, you should prefix entries in
! connections.conf like:
!
! auth_nis_domain = MYDOMAIN
!
! instead of something like:
!
! domain = MYDOMAIN
!
! More examples:
!
! auth_ldap_*
! auth_pg_*
! auth_mysql_*
! auth_kerberos_*
! auth_custom_*
If you have written a customized login handler using backends not currently
! in our samples file (i.e., against NIS, Kerberos, LDAP, etc) and would like
! to donate your example for others to learn from, please email it to:
address@hidden
Index: gnue/common/doc/technotes/index.html
diff -c gnue/common/doc/technotes/index.html:1.2
gnue/common/doc/technotes/index.html:1.3
*** gnue/common/doc/technotes/index.html:1.2 Wed Sep 4 19:29:11 2002
--- gnue/common/doc/technotes/index.html Wed Sep 18 02:49:27 2002
***************
*** 17,33 ****
<tr><td><a href="00002.txt">00002.txt</a></td><td>Overview of i18n support in
GNUe tools</td></tr>
<tr><td><a href="00003.txt">00003.txt</a></td><td>Menu Support in
triggers</td></tr>
<tr><td><a href="00004.txt">00004.txt</a></td><td>GNUe Client startup
sequence</td></tr>
- <tr><td><a href="00006.txt">00006.txt</a></td><td>Trigger Extension for
datasources</td></tr>
- </table>
-
-
-
- <h3>Obsolete Tech Notes</h3>
-
- <table border="1" width="100%">
- <tr><th>File</th><th>Title</th></tr>
-
<tr><td><a href="00005.txt">00005.txt</a></td><td>Writing a Custom
Login/Authentication Handler</td></tr>
</table>
--- 17,24 ----
<tr><td><a href="00002.txt">00002.txt</a></td><td>Overview of i18n support in
GNUe tools</td></tr>
<tr><td><a href="00003.txt">00003.txt</a></td><td>Menu Support in
triggers</td></tr>
<tr><td><a href="00004.txt">00004.txt</a></td><td>GNUe Client startup
sequence</td></tr>
<tr><td><a href="00005.txt">00005.txt</a></td><td>Writing a Custom
Login/Authentication Handler</td></tr>
+ <tr><td><a href="00006.txt">00006.txt</a></td><td>Trigger Extension for
datasources</td></tr>
</table>
Index: gnue/common/doc/technotes/index.txt
diff -c gnue/common/doc/technotes/index.txt:1.4
gnue/common/doc/technotes/index.txt:1.5
*** gnue/common/doc/technotes/index.txt:1.4 Wed Sep 4 19:29:11 2002
--- gnue/common/doc/technotes/index.txt Wed Sep 18 02:49:27 2002
***************
*** 13,29 ****
00002.txt Overview of i18n support in GNUe tools
00003.txt Menu Support in triggers
00004.txt GNUe Client startup sequence
- 00006.txt Trigger Extension for datasources
- ---------- ------------------------------------------------------------------
-
-
- ==============================================================================
- Obsolete Tech Notes
- ==============================================================================
-
- File Title
- ---------- ------------------------------------------------------------------
00005.txt Writing a Custom Login/Authentication Handler
---------- ------------------------------------------------------------------
--- 13,20 ----
00002.txt Overview of i18n support in GNUe tools
00003.txt Menu Support in triggers
00004.txt GNUe Client startup sequence
00005.txt Writing a Custom Login/Authentication Handler
+ 00006.txt Trigger Extension for datasources
---------- ------------------------------------------------------------------
Index: gnue/common/src/GBaseApp.py
diff -c gnue/common/src/GBaseApp.py:1.26 gnue/common/src/GBaseApp.py:1.27
*** gnue/common/src/GBaseApp.py:1.26 Wed Sep 18 01:13:01 2002
--- gnue/common/src/GBaseApp.py Wed Sep 18 02:49:27 2002
***************
*** 214,220 ****
# Add custom import to python's namespace
try:
extrapaths = gConfig('ImportPath')
- print extrapaths
except:
extrapaths = ""
if extrapaths:
--- 214,219 ----
***************
*** 222,228 ****
p = string.strip(path)
if not p in sys.path:
sys.path.append(p)
- print "Appending %s" % p
# Get the connection definitions
if connections != None:
--- 221,226 ----
Index: gnue/common/src/GConnections.py
diff -c gnue/common/src/GConnections.py:1.43
gnue/common/src/GConnections.py:1.44
*** gnue/common/src/GConnections.py:1.43 Tue Sep 17 16:41:27 2002
--- gnue/common/src/GConnections.py Wed Sep 18 02:49:27 2002
***************
*** 56,61 ****
--- 56,63 ----
# in an unreadable format.
pass
+ LoginError = GDataObjects.LoginError
+
class GConnections:
***************
*** 242,257 ****
loginData['_password'] = loginData['password']
del loginData['password']
haveAllInformation = 1
! for rf, dummy1, dummy2 in dataObject.getLoginFields():
if not (loginData.has_key(rf) and loginData[rf] != None):
haveAllInformation = 0
break
if haveAllInformation:
!
! dataObject.connect(loginData)
GDebug.printMesg(5, 'I had enough information to connect to %s
without asking the user' % connection_name)
# Save the newly opened connection for future datasources
self._openConnections[connection_name] =
dataObject.getDataConnection()
--- 244,268 ----
loginData['_password'] = loginData['password']
del loginData['password']
+ # Load
+ if loginData.has_key('custom_auth'):
+ authenticator = dyn_import(loginData['custom_auth']).Authenticator()
+ checkFields =
authenticator.getLoginFields(dataObject.getLoginFields())
+ else:
+ checkFields = dataObject.getLoginFields()
+ authenticator = None
haveAllInformation = 1
! for rf, dummy1, dummy2 in checkFields:
if not (loginData.has_key(rf) and loginData[rf] != None):
haveAllInformation = 0
break
if haveAllInformation:
! if authenticator:
! dataObject.connect(authenticator.login(loginData))
! else:
! dataObject.connect(loginData)
GDebug.printMesg(5, 'I had enough information to connect to %s
without asking the user' % connection_name)
# Save the newly opened connection for future datasources
self._openConnections[connection_name] =
dataObject.getDataConnection()
Index: gnue/common/src/GLoginHandler.py
diff -c gnue/common/src/GLoginHandler.py:1.5
gnue/common/src/GLoginHandler.py:1.6
*** gnue/common/src/GLoginHandler.py:1.5 Fri May 3 19:07:18 2002
--- gnue/common/src/GLoginHandler.py Wed Sep 18 02:49:27 2002
***************
*** 11,22 ****
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
! # You should have received a copy of the GNU General Public
! # License along with program; see the file COPYING. If not,
! # write to the Free Software Foundation, Inc., 59 Temple Place
# - Suite 330, Boston, MA 02111-1307, USA.
#
! # Copyright 2000, 2001 Free Software Foundation
#
# FILE:
# GConnections.py
--- 11,22 ----
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
! # You should have received a copy of the GNU General Public
! # License along with program; see the file COPYING. If not,
! # write to the Free Software Foundation, Inc., 59 Temple Place
# - Suite 330, Boston, MA 02111-1307, USA.
#
! # Copyright 2000-2002 Free Software Foundation
#
# FILE:
# GConnections.py
***************
*** 26,33 ****
# (design to be subclassed by the UI portion).
#
# NOTES:
- #
- # HISTORY:
#
--- 26,31 ----
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- gnue/common doc/technotes/00005.txt doc/technot...,
Jason Cater <=