comparison doc/customizing.txt @ 2017:31d920b31642

Update customization examples too, expand upgrade notice a bit.
author Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
date Sat, 14 Feb 2004 17:18:01 +0000
parents 2112962f5bb1
children be047db3dd3d
comparison
equal deleted inserted replaced
2016:2112962f5bb1 2017:31d920b31642
1 =================== 1 ===================
2 Customising Roundup 2 Customising Roundup
3 =================== 3 ===================
4 4
5 :Version: $Revision: 1.114 $ 5 :Version: $Revision: 1.115 $
6 6
7 .. This document borrows from the ZopeBook section on ZPT. The original is at: 7 .. This document borrows from the ZopeBook section on ZPT. The original is at:
8 http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx 8 http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx
9 9
10 .. contents:: 10 .. contents::
890 them to :filter. 890 them to :filter.
891 891
892 - Also handle the ":queryname" variable and save off the query to the 892 - Also handle the ":queryname" variable and save off the query to the
893 user's query list. 893 user's query list.
894 894
895 Each of the actions is implemented by a corresponding ``*actionAction*`` 895 Each of the actions is implemented by a corresponding ``*XxxAction*`` (where
896 (where "action" is the name of the action) method on the 896 "Xxx" is the name of the action) class in the ``roundup.cgi.actions`` module.
897 ``roundup.cgi.Client`` class, which also happens to be available in your 897 These classes are registered with ``roundup.cgi.client.Client`` which also
898 tracker instance as ``interfaces.Client``. So if you need to define new 898 happens to be available in your tracker instance as ``interfaces.Client``. So
899 actions, you may add them there (see `defining new web actions`_). 899 if you need to define new actions, you may add them there (see `defining new
900 900 web actions`_).
901 Each action also has a corresponding ``*actionPermission*`` (where 901
902 "action" is the name of the action) method which determines whether the 902 Each action class also has a ``*permission*`` method which determines whether
903 action is permissible given the current user. The base permission checks 903 the action is permissible given the current user. The base permission checks
904 are: 904 are:
905 905
906 **login** 906 **login**
907 Determine whether the user has permission to log in. Base behaviour is 907 Determine whether the user has permission to log in. Base behaviour is
908 to check the user has "Web Access". 908 to check the user has "Web Access".
2099 def handle(self): 2099 def handle(self):
2100 ''' Perform some action. No return value is required. 2100 ''' Perform some action. No return value is required.
2101 ''' 2101 '''
2102 2102
2103 The *self.client* attribute is an instance of your tracker ``instance.Client`` 2103 The *self.client* attribute is an instance of your tracker ``instance.Client``
2104 class - thus it's mostly implemented by ``roundup.cgi.Client``. See the 2104 class - thus it's mostly implemented by ``roundup.cgi.client.Client``. See the
2105 docstring of that class for details of what it can do. 2105 docstring of that class for details of what it can do.
2106 2106
2107 The method will typically check the ``self.form`` variable's contents. 2107 The method will typically check the ``self.form`` variable's contents.
2108 It may then: 2108 It may then:
2109 2109
2824 the ``crypt`` module in your Python distribution). An example entry 2824 the ``crypt`` module in your Python distribution). An example entry
2825 would be:: 2825 would be::
2826 2826
2827 admin:aamrgyQfDFSHw 2827 admin:aamrgyQfDFSHw
2828 2828
2829 Each user of Roundup must still have their information stored in the 2829 Each user of Roundup must still have their information stored in the Roundup
2830 Roundup database - we just use the passwd file to check their password. 2830 database - we just use the passwd file to check their password. To do this, we
2831 To do this, we add the following code to our ``Client`` class in the 2831 need to override the standard ``verifyPassword`` method defined in
2832 tracker home ``interfaces.py`` module:: 2832 ``roundup.cgi.actions.LoginAction`` and register the new class with our
2833 2833 ``Client`` class in the tracker home ``interfaces.py`` module::
2834 def verifyPassword(self, userid, password): 2834
2835 # get the user's username 2835 from roundup.cgi.actions import LoginAction
2836 username = self.db.user.get(userid, 'username') 2836
2837 2837 class ExternalPasswordLoginAction(LoginAction):
2838 # the passwords are stored in the "passwd.txt" file in the 2838 def verifyPassword(self, userid, password):
2839 # tracker home 2839 # get the user's username
2840 file = os.path.join(self.db.config.TRACKER_HOME, 'passwd.txt') 2840 username = self.db.user.get(userid, 'username')
2841 2841
2842 # see if we can find a match 2842 # the passwords are stored in the "passwd.txt" file in the
2843 for ent in [line.strip().split(':') for line in 2843 # tracker home
2844 open(file).readlines()]: 2844 file = os.path.join(self.db.config.TRACKER_HOME, 'passwd.txt')
2845 if ent[0] == username: 2845
2846 return crypt.crypt(password, ent[1][:2]) == ent[1] 2846 # see if we can find a match
2847 2847 for ent in [line.strip().split(':') for line in
2848 # user doesn't exist in the file 2848 open(file).readlines()]:
2849 return 0 2849 if ent[0] == username:
2850 return crypt.crypt(password, ent[1][:2]) == ent[1]
2851
2852 # user doesn't exist in the file
2853 return 0
2854
2855 class Client(client.Client):
2856 actions = client.Client.actions + (
2857 ('login', ExternalPasswordLoginAction)
2858 )
2850 2859
2851 What this does is look through the file, line by line, looking for a 2860 What this does is look through the file, line by line, looking for a
2852 name that matches. 2861 name that matches.
2853 2862
2854 We also remove the redundant password fields from the ``user.item`` 2863 We also remove the redundant password fields from the ``user.item``
3199 workflow). See the example `Using a UN*X passwd file as the user database`_ 3208 workflow). See the example `Using a UN*X passwd file as the user database`_
3200 for more information about doing this. 3209 for more information about doing this.
3201 3210
3202 To authenticate off the LDAP store (rather than using the passwords in the 3211 To authenticate off the LDAP store (rather than using the passwords in the
3203 roundup user database) you'd use the same python-ldap module inside an 3212 roundup user database) you'd use the same python-ldap module inside an
3204 extension to the cgi interface. You'd do this by adding a method called 3213 extension to the cgi interface. You'd do this by overriding the method called
3205 "verifyPassword" to the Client class in your tracker's interfaces.py 3214 "verifyPassword" on the LoginAction class in your tracker's interfaces.py
3206 module. The method is implemented by default as:: 3215 module (see `using an external password validation source`_). The method is
3216 implemented by default as::
3207 3217
3208 def verifyPassword(self, userid, password): 3218 def verifyPassword(self, userid, password):
3209 ''' Verify the password that the user has supplied 3219 ''' Verify the password that the user has supplied
3210 ''' 3220 '''
3211 stored = self.db.user.get(self.userid, 'password') 3221 stored = self.db.user.get(self.userid, 'password')

Roundup Issue Tracker: http://roundup-tracker.org/