Mercurial > p > roundup > code
comparison doc/customizing.txt @ 2983:9614a101b68f
Stuff from the train ride this morning:
- Extend the property concept in Permissions to allow a list of properties
- Fix the cgi templating code to check the correct permission when
rendering edit fields
- A swag of changes (just the start) fixing up the customisation doc for
the new tracker layout and permissions setup
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Tue, 30 Nov 2004 08:32:57 +0000 |
| parents | 1ae91c2fa5fe |
| children | b9a55628a78d |
comparison
equal
deleted
inserted
replaced
| 2982:22f16d0646ce | 2983:9614a101b68f |
|---|---|
| 1 =================== | 1 =================== |
| 2 Customising Roundup | 2 Customising Roundup |
| 3 =================== | 3 =================== |
| 4 | 4 |
| 5 :Version: $Revision: 1.159 $ | 5 :Version: $Revision: 1.160 $ |
| 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:: |
| 288 Note: if you modify the schema, you'll most likely need to edit the | 288 Note: if you modify the schema, you'll most likely need to edit the |
| 289 `web interface`_ HTML template files and `detectors`_ to reflect | 289 `web interface`_ HTML template files and `detectors`_ to reflect |
| 290 your changes. | 290 your changes. |
| 291 | 291 |
| 292 A tracker schema defines what data is stored in the tracker's database. | 292 A tracker schema defines what data is stored in the tracker's database. |
| 293 Schemas are defined using Python code in the ``dbinit.py`` module of your | 293 Schemas are defined using Python code in the ``schema.py`` module of your |
| 294 tracker. | 294 tracker. |
| 295 | 295 |
| 296 The ``dbinit.py`` module | 296 The ``schema.py`` module |
| 297 ------------------------ | 297 ------------------------ |
| 298 | 298 |
| 299 The ``dbinit.py`` module contains two functions: | 299 The ``schema.py`` module contains two functions: |
| 300 | 300 |
| 301 **open** | 301 **open** |
| 302 This function defines what your tracker looks like on the inside, the | 302 This function defines what your tracker looks like on the inside, the |
| 303 **schema** of the tracker. It defines the **Classes** and **properties** | 303 **schema** of the tracker. It defines the **Classes** and **properties** |
| 304 on each class. It also defines the **security** for those Classes. The | 304 on each class. It also defines the **security** for those Classes. The |
| 700 priority, resolution, ...) may be done either before or after the | 700 priority, resolution, ...) may be done either before or after the |
| 701 tracker is initialised. The actual method of doing so is completely | 701 tracker is initialised. The actual method of doing so is completely |
| 702 different in each case though, so be careful to use the right one. | 702 different in each case though, so be careful to use the right one. |
| 703 | 703 |
| 704 **Changing content before tracker initialisation** | 704 **Changing content before tracker initialisation** |
| 705 Edit the dbinit module in your tracker to alter the items created in | 705 Edit the schema module in your tracker to alter the items created in |
| 706 using the ``create()`` methods. | 706 using the ``create()`` methods. |
| 707 | 707 |
| 708 **Changing content after tracker initialisation** | 708 **Changing content after tracker initialisation** |
| 709 As the "admin" user, click on the "class list" link in the web | 709 As the "admin" user, click on the "class list" link in the web |
| 710 interface to bring up a list of all database classes. Click on the | 710 interface to bring up a list of all database classes. Click on the |
| 721 Security / Access Controls | 721 Security / Access Controls |
| 722 ========================== | 722 ========================== |
| 723 | 723 |
| 724 A set of Permissions is built into the security module by default: | 724 A set of Permissions is built into the security module by default: |
| 725 | 725 |
| 726 - Create (everything) | |
| 726 - Edit (everything) | 727 - Edit (everything) |
| 727 - View (everything) | 728 - View (everything) |
| 728 | 729 |
| 729 Every Class you define in your tracker's schema also gets an Edit and View | 730 Every Class you define in your tracker's schema also gets an Create, Edit |
| 730 Permission of its own. | 731 and View Permission of its own. |
| 731 | 732 |
| 732 The default interfaces define: | 733 The default interfaces define: |
| 733 | 734 |
| 734 - Web Registration | 735 - Web Registration |
| 735 - Web Access | 736 - Web Access |
| 737 - Email Registration | 738 - Email Registration |
| 738 - Email Access | 739 - Email Access |
| 739 | 740 |
| 740 These are hooked into the default Roles: | 741 These are hooked into the default Roles: |
| 741 | 742 |
| 742 - Admin (Edit everything, View everything, Web Roles) | 743 - Admin (Create, Edit, View and everything; Web Roles) |
| 743 - User (Web Access, Email Access) | 744 - User (Web Access; Email Access) |
| 744 - Anonymous (Web Registration, Email Registration) | 745 - Anonymous (Web Registration; Email Registration) |
| 745 | 746 |
| 746 And finally, the "admin" user gets the "Admin" Role, and the "anonymous" | 747 And finally, the "admin" user gets the "Admin" Role, and the "anonymous" |
| 747 user gets "Anonymous" assigned when the database is initialised on | 748 user gets "Anonymous" assigned when the tracker is installed. |
| 748 installation. The two default schemas then define: | 749 |
| 749 | 750 For the "User" Role, the "classic" tracker defines: |
| 750 - Edit issue, View issue (both) | 751 |
| 751 - Edit file, View file (both) | 752 - Create, Edit and View issue, file, msg, query, keyword |
| 752 - Edit msg, View msg (both) | 753 - View priority, status |
| 753 - Edit support, View support (extended only) | 754 - View user |
| 754 | 755 - Edit their own record |
| 755 and assign those Permissions to the "User" Role. Put together, these | 756 |
| 756 settings appear in the ``open()`` function of the tracker ``dbinit.py`` | 757 And the "Anonymous" Role is defined as: |
| 757 (the following is taken from the "minimal" template's ``dbinit.py``):: | 758 |
| 759 - Create user (for registration) | |
| 760 - View issue, file, msg, query, keyword, priority, status | |
| 761 | |
| 762 Put together, these settings appear in the tracker's ``schema.py`` file:: | |
| 758 | 763 |
| 759 # | 764 # |
| 760 # SECURITY SETTINGS | 765 # TRACKER SECURITY SETTINGS |
| 761 # | 766 # |
| 762 # and give the regular users access to the web and email interface | 767 # See the configuration and customisation document for information |
| 768 # about security setup. | |
| 769 | |
| 770 # | |
| 771 # REGULAR USERS | |
| 772 # | |
| 773 # Give the regular users access to the web and email interface | |
| 763 p = db.security.getPermission('Web Access') | 774 p = db.security.getPermission('Web Access') |
| 764 db.security.addPermissionToRole('User', p) | 775 db.security.addPermissionToRole('User', p) |
| 765 p = db.security.getPermission('Email Access') | 776 p = db.security.getPermission('Email Access') |
| 766 db.security.addPermissionToRole('User', p) | 777 db.security.addPermissionToRole('User', p) |
| 767 | 778 |
| 779 # Assign the access and edit Permissions for issue, file and message | |
| 780 # to regular users now | |
| 781 for cl in 'issue', 'file', 'msg', 'query', 'keyword': | |
| 782 p = db.security.getPermission('View', cl) | |
| 783 db.security.addPermissionToRole('User', p) | |
| 784 p = db.security.getPermission('Edit', cl) | |
| 785 db.security.addPermissionToRole('User', p) | |
| 786 p = db.security.getPermission('Create', cl) | |
| 787 db.security.addPermissionToRole('User', p) | |
| 788 for cl in 'priority', 'status': | |
| 789 p = db.security.getPermission('View', cl) | |
| 790 db.security.addPermissionToRole('User', p) | |
| 791 | |
| 768 # May users view other user information? Comment these lines out | 792 # May users view other user information? Comment these lines out |
| 769 # if you don't want them to | 793 # if you don't want them to |
| 770 p = db.security.getPermission('View', 'user') | 794 p = db.security.getPermission('View', 'user') |
| 771 db.security.addPermissionToRole('User', p) | 795 db.security.addPermissionToRole('User', p) |
| 772 | 796 |
| 773 # Assign the appropriate permissions to the anonymous user's | 797 # Users should be able to edit their own details. Note that this |
| 774 # Anonymous role. Choices here are: | 798 # permission is limited to only the situation where the Viewed or |
| 775 # - Allow anonymous users to register through the web | 799 # Edited item is their own. |
| 776 p = db.security.getPermission('Web Registration') | 800 def own_record(db, userid, itemid): |
| 801 '''Determine whether the userid matches the item being accessed.''' | |
| 802 return userid == itemid | |
| 803 p = db.security.addPermission(name='View', klass='user', check=own_record, | |
| 804 description="User is allowed to view their own user details") | |
| 805 p = db.security.addPermission(name='Edit', klass='user', check=own_record, | |
| 806 description="User is allowed to edit their own user details") | |
| 807 db.security.addPermissionToRole('User', p) | |
| 808 | |
| 809 # | |
| 810 # ANONYMOUS USER PERMISSIONS | |
| 811 # | |
| 812 # Let anonymous users access the web interface. Note that almost all | |
| 813 # trackers will need this Permission. The only situation where it's not | |
| 814 # required is in a tracker that uses an HTTP Basic Authenticated front-end. | |
| 815 p = db.security.getPermission('Web Access') | |
| 777 db.security.addPermissionToRole('Anonymous', p) | 816 db.security.addPermissionToRole('Anonymous', p) |
| 778 # - Allow anonymous (new) users to register through the email | 817 |
| 779 # gateway | 818 # Let anonymous users access the email interface (note that this implies |
| 780 p = db.security.getPermission('Email Registration') | 819 # that they will be registered automatically, hence they will need the |
| 820 # "Create" user Permission below) | |
| 821 p = db.security.getPermission('Email Access') | |
| 781 db.security.addPermissionToRole('Anonymous', p) | 822 db.security.addPermissionToRole('Anonymous', p) |
| 823 | |
| 824 # Assign the appropriate permissions to the anonymous user's Anonymous | |
| 825 # Role. Choices here are: | |
| 826 # - Allow anonymous users to register | |
| 827 p = db.security.getPermission('Create', 'user') | |
| 828 db.security.addPermissionToRole('Anonymous', p) | |
| 829 | |
| 830 # Allow anonymous users access to view issues (and the related, linked | |
| 831 # information) | |
| 832 for cl in 'issue', 'file', 'msg', 'keyword', 'priority', 'status': | |
| 833 p = db.security.getPermission('View', cl) | |
| 834 db.security.addPermissionToRole('Anonymous', p) | |
| 835 | |
| 836 # [OPTIONAL] | |
| 837 # Allow anonymous users access to create or edit "issue" items (and the | |
| 838 # related file and message items) | |
| 839 #for cl in 'issue', 'file', 'msg': | |
| 840 # p = db.security.getPermission('Create', cl) | |
| 841 # db.security.addPermissionToRole('Anonymous', p) | |
| 842 # p = db.security.getPermission('Edit', cl) | |
| 843 # db.security.addPermissionToRole('Anonymous', p) | |
| 782 | 844 |
| 783 | 845 |
| 784 New User Roles | 846 New User Roles |
| 785 -------------- | 847 -------------- |
| 786 | 848 |
| 804 Adding a new Permission | 866 Adding a new Permission |
| 805 ~~~~~~~~~~~~~~~~~~~~~~~ | 867 ~~~~~~~~~~~~~~~~~~~~~~~ |
| 806 | 868 |
| 807 When adding a new Permission, you will need to: | 869 When adding a new Permission, you will need to: |
| 808 | 870 |
| 809 1. add it to your tracker's dbinit so it is created, using | 871 1. add it to your tracker's ``schema.py`` so it is created, using |
| 810 ``security.addPermission``, for example:: | 872 ``security.addPermission``, for example:: |
| 811 | 873 |
| 812 self.security.addPermission(name="View", klass='frozzle', | 874 self.security.addPermission(name="View", klass='frozzle', |
| 813 description="User is allowed to access frozzles") | 875 description="User is allowed to access frozzles") |
| 814 | 876 |
| 817 "``roundup-admin security``") | 879 "``roundup-admin security``") |
| 818 3. add it to the relevant HTML interface templates | 880 3. add it to the relevant HTML interface templates |
| 819 4. add it to the appropriate xxxPermission methods on in your tracker | 881 4. add it to the appropriate xxxPermission methods on in your tracker |
| 820 interfaces module | 882 interfaces module |
| 821 | 883 |
| 884 The ``addPermission`` method takes a couple of optional parameters: | |
| 885 | |
| 886 **properties** | |
| 887 A sequence of property names that are the only properties to apply the | |
| 888 new Permission to (eg. ``... klass='user', properties=('name', | |
| 889 'email') ...``) | |
| 890 **code** | |
| 891 A function to be execute which returns boolean determining whether the | |
| 892 Permission is allowed. The function has the signature ``check(db, userid, | |
| 893 itemid)`` where ``db`` is a handle on the open database, ``userid`` is | |
| 894 the user attempting access and ``itemid`` is the specific item being | |
| 895 accessed. | |
| 822 | 896 |
| 823 Example Scenarios | 897 Example Scenarios |
| 824 ~~~~~~~~~~~~~~~~~ | 898 ~~~~~~~~~~~~~~~~~ |
| 825 | 899 |
| 826 **automatic registration of users in the e-mail gateway** | 900 **automatic registration of users in the e-mail gateway** |
| 1059 | 1133 |
| 1060 Each action class also has a ``*permission*`` method which determines whether | 1134 Each action class also has a ``*permission*`` method which determines whether |
| 1061 the action is permissible given the current user. The base permission checks | 1135 the action is permissible given the current user. The base permission checks |
| 1062 are: | 1136 are: |
| 1063 | 1137 |
| 1138 XXX REVIEW for Permissions changes | |
| 1139 | |
| 1064 **login** | 1140 **login** |
| 1065 Determine whether the user has permission to log in. Base behaviour is | 1141 Determine whether the user has permission to log in. Base behaviour is |
| 1066 to check the user has "Web Access". | 1142 to check the user has "Web Access". |
| 1067 **logout** | 1143 **logout** |
| 1068 No permission checks are made. | 1144 No permission checks are made. |
| 1069 **register** | 1145 **register** |
| 1070 Determine whether the user has permission to register. Base behaviour | 1146 Determine whether the user has permission to register. Base behaviour |
| 1071 is to check the user has the "Web Registration" Permission. | 1147 is to check the user has the "Web Registration" Permission. |
| 1072 **edit** | 1148 **edit** |
| 1073 Determine whether the user has permission to edit this item. Base | 1149 Determine whether the user has permission to edit this item. If we're |
| 1074 behaviour is to check whether the user can edit this class. If we're | |
| 1075 editing the "user" class, users are allowed to edit their own details - | 1150 editing the "user" class, users are allowed to edit their own details - |
| 1076 unless they try to edit the "roles" property, which requires the | 1151 unless they try to edit the "roles" property, which requires the |
| 1077 special Permission "Web Roles". | 1152 special Permission "Web Roles". |
| 1078 **new** | 1153 **new** |
| 1079 Determine whether the user has permission to create (or edit) this | 1154 Determine whether the user has permission to create this item. No |
| 1080 item. Base behaviour is to check the user can edit this class. No | |
| 1081 additional property checks are made. Additionally, new user items may | 1155 additional property checks are made. Additionally, new user items may |
| 1082 be created if the user has the "Web Registration" Permission. | 1156 be created if the user has the "Web Registration" Permission. |
| 1083 **editCSV** | 1157 **editCSV** |
| 1084 Determine whether the user has permission to edit this class. Base | 1158 Determine whether the user has permission to edit this class. Base |
| 1085 behaviour is to check whether the user may edit this class. | 1159 behaviour is to check whether the user may edit this class. |
| 1162 The value of the form variable is converted | 1236 The value of the form variable is converted |
| 1163 appropriately, depending on the type of the property. | 1237 appropriately, depending on the type of the property. |
| 1164 | 1238 |
| 1165 For a Link('klass') property, the form value is a | 1239 For a Link('klass') property, the form value is a |
| 1166 single key for 'klass', where the key field is | 1240 single key for 'klass', where the key field is |
| 1167 specified in dbinit.py. | 1241 specified in schema.py. |
| 1168 | 1242 |
| 1169 For a Multilink('klass') property, the form value is a | 1243 For a Multilink('klass') property, the form value is a |
| 1170 comma-separated list of keys for 'klass', where the | 1244 comma-separated list of keys for 'klass', where the |
| 1171 key field is specified in dbinit.py. | 1245 key field is specified in schema.py. |
| 1172 | 1246 |
| 1173 Note that for simple-form-variables specifiying Link | 1247 Note that for simple-form-variables specifiying Link |
| 1174 and Multilink properties, the linked-to class must | 1248 and Multilink properties, the linked-to class must |
| 1175 have a key field. | 1249 have a key field. |
| 1176 | 1250 |
| 2508 Adding a field to the database | 2582 Adding a field to the database |
| 2509 :::::::::::::::::::::::::::::: | 2583 :::::::::::::::::::::::::::::: |
| 2510 | 2584 |
| 2511 This is the easiest part of the change. The category would just be a | 2585 This is the easiest part of the change. The category would just be a |
| 2512 plain string, nothing fancy. To change what is in the database you need | 2586 plain string, nothing fancy. To change what is in the database you need |
| 2513 to add some lines to the ``open()`` function in ``dbinit.py``. Under the | 2587 to add some lines to the ``open()`` function in ``schema.py``. Under the |
| 2514 comment:: | 2588 comment:: |
| 2515 | 2589 |
| 2516 # add any additional database schema configuration here | 2590 # add any additional database schema configuration here |
| 2517 | 2591 |
| 2518 add:: | 2592 add:: |
| 2531 | 2605 |
| 2532 Adding the above lines allows us to create categories, but they're not | 2606 Adding the above lines allows us to create categories, but they're not |
| 2533 tied to the issues that we are going to be creating. It's just a list of | 2607 tied to the issues that we are going to be creating. It's just a list of |
| 2534 categories off on its own, which isn't much use. We need to link it in | 2608 categories off on its own, which isn't much use. We need to link it in |
| 2535 with the issues. To do that, find the lines in the ``open()`` function | 2609 with the issues. To do that, find the lines in the ``open()`` function |
| 2536 in ``dbinit.py`` which set up the "issue" class, and then add a link to | 2610 in ``schema.py`` which set up the "issue" class, and then add a link to |
| 2537 the category:: | 2611 the category:: |
| 2538 | 2612 |
| 2539 issue = IssueClass(db, "issue", ... , | 2613 issue = IssueClass(db, "issue", ... , |
| 2540 category=Multilink("category"), ... ) | 2614 category=Multilink("category"), ... ) |
| 2541 | 2615 |
| 2550 Populating the new category class | 2624 Populating the new category class |
| 2551 ::::::::::::::::::::::::::::::::: | 2625 ::::::::::::::::::::::::::::::::: |
| 2552 | 2626 |
| 2553 If you haven't initialised the database with the roundup-admin | 2627 If you haven't initialised the database with the roundup-admin |
| 2554 "initialise" command, then you can add the following to the tracker | 2628 "initialise" command, then you can add the following to the tracker |
| 2555 ``dbinit.py`` in the ``init()`` function under the comment:: | 2629 ``schema.py`` in the ``init()`` function under the comment:: |
| 2556 | 2630 |
| 2557 # add any additional database create steps here - but only if you | 2631 # add any additional database create steps here - but only if you |
| 2558 # haven't initialised the database with the admin "initialise" command | 2632 # haven't initialised the database with the admin "initialise" command |
| 2559 | 2633 |
| 2560 Add:: | 2634 Add:: |
| 2589 doesn't suit us, as we want any user to be able to create new categories | 2663 doesn't suit us, as we want any user to be able to create new categories |
| 2590 as required, and obviously everyone needs to be able to view the | 2664 as required, and obviously everyone needs to be able to view the |
| 2591 categories of issues for it to be useful. | 2665 categories of issues for it to be useful. |
| 2592 | 2666 |
| 2593 We therefore need to change the security of the category objects. This | 2667 We therefore need to change the security of the category objects. This |
| 2594 is also done in the ``open()`` function of ``dbinit.py``. | 2668 is also done in the ``open()`` function of ``schema.py``. |
| 2595 | 2669 |
| 2596 There are currently two loops which set up permissions and then assign | 2670 There are currently two loops which set up permissions and then assign |
| 2597 them to various roles. Simply add the new "category" to both lists:: | 2671 them to various roles. Simply add the new "category" to both lists:: |
| 2598 | 2672 |
| 2599 # Assign the access and edit permissions for issue, file and message | 2673 # Assign the access and edit permissions for issue, file and message |
| 2906 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 2980 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 2907 | 2981 |
| 2908 We want to log the dates and amount of time spent working on issues, and | 2982 We want to log the dates and amount of time spent working on issues, and |
| 2909 be able to give a summary of the total time spent on a particular issue. | 2983 be able to give a summary of the total time spent on a particular issue. |
| 2910 | 2984 |
| 2911 1. Add a new class to your tracker ``dbinit.py``:: | 2985 1. Add a new class to your tracker ``schema.py``:: |
| 2912 | 2986 |
| 2913 # storage for time logging | 2987 # storage for time logging |
| 2914 timelog = Class(db, "timelog", period=Interval()) | 2988 timelog = Class(db, "timelog", period=Interval()) |
| 2915 | 2989 |
| 2916 Note that we automatically get the date of the time log entry | 2990 Note that we automatically get the date of the time log entry |
| 2917 creation through the standard property "creation". | 2991 creation through the standard property "creation". |
| 2918 | 2992 |
| 2919 2. Link to the new class from your issue class (again, in | 2993 2. Link to the new class from your issue class (again, in |
| 2920 ``dbinit.py``):: | 2994 ``schema.py``):: |
| 2921 | 2995 |
| 2922 issue = IssueClass(db, "issue", | 2996 issue = IssueClass(db, "issue", |
| 2923 assignedto=Link("user"), topic=Multilink("keyword"), | 2997 assignedto=Link("user"), topic=Multilink("keyword"), |
| 2924 priority=Link("priority"), status=Link("status"), | 2998 priority=Link("priority"), status=Link("status"), |
| 2925 times=Multilink("timelog")) | 2999 times=Multilink("timelog")) |
| 3010 | 3084 |
| 3011 1. Figure out what information you're going to want to capture. OK, so | 3085 1. Figure out what information you're going to want to capture. OK, so |
| 3012 this is obvious, but sometimes it's better to actually sit down for a | 3086 this is obvious, but sometimes it's better to actually sit down for a |
| 3013 while and think about the schema you're going to implement. | 3087 while and think about the schema you're going to implement. |
| 3014 | 3088 |
| 3015 2. Add the new issue class to your tracker's ``dbinit.py`` - in this | 3089 2. Add the new issue class to your tracker's ``schema.py`` - in this |
| 3016 example, we're adding a "system support" class. Just after the "issue" | 3090 example, we're adding a "system support" class. Just after the "issue" |
| 3017 class definition in the "open" function, add:: | 3091 class definition in the "open" function, add:: |
| 3018 | 3092 |
| 3019 support = IssueClass(db, "support", | 3093 support = IssueClass(db, "support", |
| 3020 assignedto=Link("user"), topic=Multilink("keyword"), | 3094 assignedto=Link("user"), topic=Multilink("keyword"), |
| 3458 We needed the ability to mark certain issues as "blockers" - that is, | 3532 We needed the ability to mark certain issues as "blockers" - that is, |
| 3459 they can't be resolved until another issue (the blocker) they rely on is | 3533 they can't be resolved until another issue (the blocker) they rely on is |
| 3460 resolved. To achieve this: | 3534 resolved. To achieve this: |
| 3461 | 3535 |
| 3462 1. Create a new property on the issue Class, | 3536 1. Create a new property on the issue Class, |
| 3463 ``blockers=Multilink("issue")``. Edit your tracker's dbinit.py file. | 3537 ``blockers=Multilink("issue")``. Edit your tracker's schema.py file. |
| 3464 Where the "issue" class is defined, something like:: | 3538 Where the "issue" class is defined, something like:: |
| 3465 | 3539 |
| 3466 issue = IssueClass(db, "issue", | 3540 issue = IssueClass(db, "issue", |
| 3467 assignedto=Link("user"), topic=Multilink("keyword"), | 3541 assignedto=Link("user"), topic=Multilink("keyword"), |
| 3468 priority=Link("priority"), status=Link("status")) | 3542 priority=Link("priority"), status=Link("status")) |
| 3614 The change in the database to make is that for any user there should be | 3688 The change in the database to make is that for any user there should be |
| 3615 a list of topics for which he wants to be put on the nosy list. Adding | 3689 a list of topics for which he wants to be put on the nosy list. Adding |
| 3616 a ``Multilink`` of ``keyword`` seem to fullfill this (note that within | 3690 a ``Multilink`` of ``keyword`` seem to fullfill this (note that within |
| 3617 the code topics are called ``keywords``.) As such, all what has to be | 3691 the code topics are called ``keywords``.) As such, all what has to be |
| 3618 done is to add a new field to the definition of ``user`` within the | 3692 done is to add a new field to the definition of ``user`` within the |
| 3619 file ``dbinit.py``. We will call this new field ``nosy_keywords``, and | 3693 file ``schema.py``. We will call this new field ``nosy_keywords``, and |
| 3620 the updated definition of user will be:: | 3694 the updated definition of user will be:: |
| 3621 | 3695 |
| 3622 user = Class(db, "user", | 3696 user = Class(db, "user", |
| 3623 username=String(), password=Password(), | 3697 username=String(), password=Password(), |
| 3624 address=String(), realname=String(), | 3698 address=String(), realname=String(), |
| 3762 ----------------------------------- | 3836 ----------------------------------- |
| 3763 | 3837 |
| 3764 Restricting the list of users that are assignable to a task | 3838 Restricting the list of users that are assignable to a task |
| 3765 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 3839 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 3766 | 3840 |
| 3767 1. In your tracker's "dbinit.py", create a new Role, say "Developer":: | 3841 1. In your tracker's ``schema.py``, create a new Role, say "Developer":: |
| 3768 | 3842 |
| 3769 db.security.addRole(name='Developer', description='A developer') | 3843 db.security.addRole(name='Developer', description='A developer') |
| 3770 | 3844 |
| 3771 2. Just after that, create a new Permission, say "Fixer", specific to | 3845 2. Just after that, create a new Permission, say "Fixer", specific to |
| 3772 "issue":: | 3846 "issue":: |
| 3827 and has limited access. One of the Permissions they have is the new "Edit | 3901 and has limited access. One of the Permissions they have is the new "Edit |
| 3828 Own" on issues (regular users have "Edit".) We back up the permissions with | 3902 Own" on issues (regular users have "Edit".) We back up the permissions with |
| 3829 an auditor. | 3903 an auditor. |
| 3830 | 3904 |
| 3831 First up, we create the new Role and Permission structure in | 3905 First up, we create the new Role and Permission structure in |
| 3832 ``dbinit.py``:: | 3906 ``schema.py``:: |
| 3833 | 3907 |
| 3834 # New users not approved by the admin | 3908 # New users not approved by the admin |
| 3835 db.security.addRole(name='Provisional User', | 3909 db.security.addRole(name='Provisional User', |
| 3836 description='New user registered via web or email') | 3910 description='New user registered via web or email') |
| 3837 p = db.security.addPermission(name='Edit Own', klass='issue', | 3911 p = db.security.addPermission(name='Edit Own', klass='issue', |
