|
2 | 2 | Customising Roundup |
3 | 3 | =================== |
4 | 4 |
|
5 | | -:Version: $Revision: 1.114 $ |
| 5 | +:Version: $Revision: 1.115 $ |
6 | 6 |
|
7 | 7 | .. This document borrows from the ZopeBook section on ZPT. The original is at: |
8 | 8 | http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx |
@@ -892,15 +892,15 @@ of: |
892 | 892 | - Also handle the ":queryname" variable and save off the query to the |
893 | 893 | user's query list. |
894 | 894 |
|
895 | | -Each of the actions is implemented by a corresponding ``*actionAction*`` |
896 | | -(where "action" is the name of the action) method on the |
897 | | -``roundup.cgi.Client`` class, which also happens to be available in your |
898 | | -tracker instance as ``interfaces.Client``. So if you need to define new |
899 | | -actions, you may add them there (see `defining new web actions`_). |
| 895 | +Each of the actions is implemented by a corresponding ``*XxxAction*`` (where |
| 896 | +"Xxx" is the name of the action) class in the ``roundup.cgi.actions`` module. |
| 897 | +These classes are registered with ``roundup.cgi.client.Client`` which also |
| 898 | +happens to be available in your tracker instance as ``interfaces.Client``. So |
| 899 | +if you need to define new actions, you may add them there (see `defining new |
| 900 | +web actions`_). |
900 | 901 |
|
901 | | -Each action also has a corresponding ``*actionPermission*`` (where |
902 | | -"action" is the name of the action) method which determines whether the |
903 | | -action is permissible given the current user. The base permission checks |
| 902 | +Each action class also has a ``*permission*`` method which determines whether |
| 903 | +the action is permissible given the current user. The base permission checks |
904 | 904 | are: |
905 | 905 |
|
906 | 906 | **login** |
@@ -2101,7 +2101,7 @@ The action classes have the following interface:: |
2101 | 2101 | ''' |
2102 | 2102 |
|
2103 | 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 | 2105 | docstring of that class for details of what it can do. |
2106 | 2106 |
|
2107 | 2107 | The method will typically check the ``self.form`` variable's contents. |
@@ -2826,27 +2826,36 @@ would be:: |
2826 | 2826 |
|
2827 | 2827 | admin:aamrgyQfDFSHw |
2828 | 2828 |
|
2829 | | -Each user of Roundup must still have their information stored in the |
2830 | | -Roundup database - we just use the passwd file to check their password. |
2831 | | -To do this, we add the following code to our ``Client`` class in the |
2832 | | -tracker home ``interfaces.py`` module:: |
| 2829 | +Each user of Roundup must still have their information stored in the Roundup |
| 2830 | +database - we just use the passwd file to check their password. To do this, we |
| 2831 | +need to override the standard ``verifyPassword`` method defined in |
| 2832 | +``roundup.cgi.actions.LoginAction`` and register the new class with our |
| 2833 | +``Client`` class in the tracker home ``interfaces.py`` module:: |
2833 | 2834 |
|
2834 | | - def verifyPassword(self, userid, password): |
2835 | | - # get the user's username |
2836 | | - username = self.db.user.get(userid, 'username') |
| 2835 | + from roundup.cgi.actions import LoginAction |
2837 | 2836 |
|
2838 | | - # the passwords are stored in the "passwd.txt" file in the |
2839 | | - # tracker home |
2840 | | - file = os.path.join(self.db.config.TRACKER_HOME, 'passwd.txt') |
| 2837 | + class ExternalPasswordLoginAction(LoginAction): |
| 2838 | + def verifyPassword(self, userid, password): |
| 2839 | + # get the user's username |
| 2840 | + username = self.db.user.get(userid, 'username') |
2841 | 2841 |
|
2842 | | - # see if we can find a match |
2843 | | - for ent in [line.strip().split(':') for line in |
2844 | | - open(file).readlines()]: |
2845 | | - if ent[0] == username: |
2846 | | - return crypt.crypt(password, ent[1][:2]) == ent[1] |
| 2842 | + # the passwords are stored in the "passwd.txt" file in the |
| 2843 | + # tracker home |
| 2844 | + file = os.path.join(self.db.config.TRACKER_HOME, 'passwd.txt') |
2847 | 2845 |
|
2848 | | - # user doesn't exist in the file |
2849 | | - return 0 |
| 2846 | + # see if we can find a match |
| 2847 | + for ent in [line.strip().split(':') for line in |
| 2848 | + open(file).readlines()]: |
| 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 | 2860 | What this does is look through the file, line by line, looking for a |
2852 | 2861 | name that matches. |
@@ -3201,9 +3210,10 @@ for more information about doing this. |
3201 | 3210 |
|
3202 | 3211 | To authenticate off the LDAP store (rather than using the passwords in the |
3203 | 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 |
3205 | | -"verifyPassword" to the Client class in your tracker's interfaces.py |
3206 | | -module. The method is implemented by default as:: |
| 3213 | +extension to the cgi interface. You'd do this by overriding the method called |
| 3214 | +"verifyPassword" on the LoginAction class in your tracker's interfaces.py |
| 3215 | +module (see `using an external password validation source`_). The method is |
| 3216 | +implemented by default as:: |
3207 | 3217 |
|
3208 | 3218 | def verifyPassword(self, userid, password): |
3209 | 3219 | ''' Verify the password that the user has supplied |
|
0 commit comments