Mercurial > p > roundup > code
comparison doc/customizing.txt @ 7268:91125d474c1e
doc updates, normalize roundup => Roundup, add links, typo fixes
In Tracker in a Nutshell section
Document interfaces.py in table
Add links for auditors/reactors to detectors section in table
Add links for actions in table
Also mark optional components
Change roundup to canonical Roundup.
Fix unordered lists that were indented causing a list inside a
blockquote. UL lists are not unindented.
Move internal hyperlink references above the section heading they
refer to. Links were jumping after the heading which disorients the
user.
Change reference to never deleting 'users' class to be 'user' class.
fix typos
Remove uneeded trailing whitespace.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Mon, 24 Apr 2023 00:21:25 -0400 |
| parents | 519fb6dca72b |
| children | 90c70726e882 |
comparison
equal
deleted
inserted
replaced
| 7267:519fb6dca72b | 7268:91125d474c1e |
|---|---|
| 54 single: tracker; structure lib directory | 54 single: tracker; structure lib directory |
| 55 | 55 |
| 56 =================== ======================================================== | 56 =================== ======================================================== |
| 57 Tracker File Description | 57 Tracker File Description |
| 58 =================== ======================================================== | 58 =================== ======================================================== |
| 59 config.ini Holds the basic `tracker configuration`_ | 59 config.ini Holds the basic `tracker configuration`_ |
| 60 schema.py Holds the `tracker schema`_ | 60 schema.py Holds the `tracker schema`_ |
| 61 initial_data.py Holds any data to be entered into the database when the | 61 initial_data.py Holds any data to be entered into the database when the |
| 62 tracker is initialised. | 62 tracker is initialised (optional) |
| 63 db/ Holds the tracker's database | 63 interfaces.py Allows `modifying the core of Roundup`_ (optional) |
| 64 db/files/ Holds the tracker's upload files and messages | 64 db/ Holds the tracker's database |
| 65 db/files/ Holds the tracker's upload files and messages | |
| 65 db/backend_name Names the database back-end for the tracker (obsolete). | 66 db/backend_name Names the database back-end for the tracker (obsolete). |
| 66 Current way uses the ``backend`` setting in the rdbms | 67 Use the ``backend`` setting in the ``[rdbms]`` |
| 67 section of config.ini. | 68 section of ``config.ini`` instead. |
| 68 detectors/ Auditors and reactors for this tracker | 69 detectors/ `Auditors and reactors`_ for this tracker |
| 69 extensions/ Additional actions and `templating utilities`_ | 70 extensions/ Additional `actions`_ and `templating utilities`_ |
| 70 html/ Web interface templates, images and style sheets | 71 html/ Web interface templates, images and style sheets |
| 71 lib/ optional common imports for detectors and extensions | 72 lib/ optional common imports for detectors and extensions |
| 72 =================== ======================================================== | 73 =================== ======================================================== |
| 73 | 74 |
| 74 | 75 |
| 75 .. index:: config.ini | 76 .. index:: config.ini |
| 77 | 78 |
| 78 Tracker Configuration | 79 Tracker Configuration |
| 79 ===================== | 80 ===================== |
| 80 | 81 |
| 81 The ``config.ini`` located in your tracker home contains the basic | 82 The ``config.ini`` located in your tracker home contains the basic |
| 82 configuration for the web and e-mail components of roundup's interfaces. | 83 configuration for the web and e-mail components of Roundup's interfaces. |
| 83 | 84 |
| 84 Changes to the data captured by your tracker is controlled by the `tracker | 85 Changes to the data captured by your tracker is controlled by the `tracker |
| 85 schema`_. Some configuration is also performed using permissions - see the | 86 schema`_. Some configuration is also performed using permissions - see the |
| 86 `security / access controls`_ section. For example, to allow users to | 87 `security / access controls`_ section. For example, to allow users to |
| 87 automatically register through the email interface, you must grant the | 88 automatically register through the email interface, you must grant the |
| 196 | 197 |
| 197 umask -- ``02`` | 198 umask -- ``02`` |
| 198 Defines the file creation mode mask. | 199 Defines the file creation mode mask. |
| 199 | 200 |
| 200 csv_field_size -- ``131072`` | 201 csv_field_size -- ``131072`` |
| 201 Maximum size of a csv-field during import. Roundups export | 202 Maximum size of a csv-field during import. Roundup's export |
| 202 format is a csv (comma separated values) variant. The csv | 203 format is a csv (comma separated values) variant. The csv |
| 203 reader has a limit on the size of individual fields | 204 reader has a limit on the size of individual fields |
| 204 starting with python 2.5. Set this to a higher value if you | 205 starting with python 2.5. Set this to a higher value if you |
| 205 get the error 'Error: field larger than field limit' during | 206 get the error 'Error: field larger than field limit' during |
| 206 import. | 207 import. |
| 207 | 208 |
| 208 .. index:: config.ini; sections tracker | 209 .. index:: config.ini; sections tracker |
| 209 | 210 |
| 210 Section **tracker** | 211 Section **tracker** |
| 211 name -- ``Roundup issue tracker`` | 212 name -- ``Roundup issue tracker`` |
| 212 A descriptive name for your roundup instance. | 213 A descriptive name for your Roundup instance. |
| 213 | 214 |
| 214 web -- ``http://host.example/demo/`` | 215 web -- ``http://host.example/demo/`` |
| 215 The web address that the tracker is viewable at. | 216 The web address that the tracker is viewable at. |
| 216 This will be included in information sent to users of the tracker. | 217 This will be included in information sent to users of the tracker. |
| 217 The URL MUST include the cgi-bin part or anything else | 218 The URL MUST include the cgi-bin part or anything else |
| 218 that is required to get to the home page of the tracker. | 219 that is required to get to the home page of the tracker. |
| 219 You MUST include a trailing '/' in the URL. | 220 You MUST include a trailing '/' in the URL. |
| 220 | 221 |
| 221 email -- ``issue_tracker`` | 222 email -- ``issue_tracker`` |
| 222 Email address that mail to roundup should go to. | 223 Email address that mail to Roundup should go to. |
| 223 | 224 |
| 224 language -- default *blank* | 225 language -- default *blank* |
| 225 Default locale name for this tracker. If this option is not set, the | 226 Default locale name for this tracker. If this option is not set, the |
| 226 language is determined by the environment variable LANGUAGE, LC_ALL, | 227 language is determined by the environment variable LANGUAGE, LC_ALL, |
| 227 LC_MESSAGES, or LANG, in that order of preference. | 228 LC_MESSAGES, or LANG, in that order of preference. |
| 339 | 340 |
| 340 domain -- ``localhost`` | 341 domain -- ``localhost`` |
| 341 Domain name used for email addresses. | 342 Domain name used for email addresses. |
| 342 | 343 |
| 343 host -- default *blank* | 344 host -- default *blank* |
| 344 SMTP mail host that roundup will use to send mail | 345 SMTP mail host that Roundup will use to send mail |
| 345 | 346 |
| 346 username -- default *blank* | 347 username -- default *blank* |
| 347 SMTP login name. Set this if your mail host requires authenticated access. | 348 SMTP login name. Set this if your mail host requires authenticated access. |
| 348 If username is not empty, password (below) MUST be set! | 349 If username is not empty, password (below) MUST be set! |
| 349 | 350 |
| 388 precedence. The path may be either absolute or relative to the directory | 389 precedence. The path may be either absolute or relative to the directory |
| 389 containig this config file. | 390 containig this config file. |
| 390 | 391 |
| 391 add_authorinfo -- ``yes`` | 392 add_authorinfo -- ``yes`` |
| 392 Add a line with author information at top of all messages send by | 393 Add a line with author information at top of all messages send by |
| 393 roundup. | 394 Roundup. |
| 394 | 395 |
| 395 add_authoremail -- ``yes`` | 396 add_authoremail -- ``yes`` |
| 396 Add the mail address of the author to the author information at the | 397 Add the mail address of the author to the author information at the |
| 397 top of all messages. If this is false but add_authorinfo is true, | 398 top of all messages. If this is false but add_authorinfo is true, |
| 398 only the name of the actor is added which protects the mail address | 399 only the name of the actor is added which protects the mail address |
| 474 blankline_re -- ``[\r\n]+\s*[\r\n]+`` | 475 blankline_re -- ``[\r\n]+\s*[\r\n]+`` |
| 475 Regular expression matching a blank line. Value is Python Regular | 476 Regular expression matching a blank line. Value is Python Regular |
| 476 Expression (UTF8-encoded). | 477 Expression (UTF8-encoded). |
| 477 | 478 |
| 478 ignore_alternatives -- ``no`` | 479 ignore_alternatives -- ``no`` |
| 479 When parsing incoming mails, roundup uses the first | 480 When parsing incoming mails, Roundup uses the first |
| 480 text/plain part it finds. If this part is inside a | 481 text/plain part it finds. If this part is inside a |
| 481 multipart/alternative, and this option is set, all other | 482 multipart/alternative, and this option is set, all other |
| 482 parts of the multipart/alternative are ignored. The default | 483 parts of the multipart/alternative are ignored. The default |
| 483 is to keep all parts and attach them to the issue. | 484 is to keep all parts and attach them to the issue. |
| 484 | 485 |
| 718 What you can't do to the schema | 719 What you can't do to the schema |
| 719 ------------------------------- | 720 ------------------------------- |
| 720 | 721 |
| 721 You must never: | 722 You must never: |
| 722 | 723 |
| 723 **Remove the users class** | 724 **Remove the user class** |
| 724 This class is the only *required* class in Roundup. | 725 This class is the only *required* class in Roundup. |
| 725 | 726 |
| 726 **Remove the "username", "address", "password" or "realname" user properties** | 727 **Remove the "username", "address", "password" or "realname" user properties** |
| 727 Various parts of Roundup require these properties. Don't remove them. | 728 Various parts of Roundup require these properties. Don't remove them. |
| 728 | 729 |
| 765 keyword | 766 keyword |
| 766 Initially empty, will hold keywords useful for searching issues. | 767 Initially empty, will hold keywords useful for searching issues. |
| 767 | 768 |
| 768 user | 769 user |
| 769 Initially holding the "admin" user, will eventually have an entry | 770 Initially holding the "admin" user, will eventually have an entry |
| 770 for all users using roundup. | 771 for all users using Roundup. |
| 771 | 772 |
| 772 msg | 773 msg |
| 773 Initially empty, will hold all e-mail messages sent to or | 774 Initially empty, will hold all e-mail messages sent to or |
| 774 generated by roundup. | 775 generated by Roundup. |
| 775 | 776 |
| 776 file | 777 file |
| 777 Initially empty, will hold all files attached to issues. | 778 Initially empty, will hold all files attached to issues. |
| 778 | 779 |
| 779 issue | 780 issue |
| 892 events. | 893 events. |
| 893 | 894 |
| 894 .. index:: triple: schema; property attributes; try_id_parsing | 895 .. index:: triple: schema; property attributes; try_id_parsing |
| 895 | 896 |
| 896 - ``try_id_parsing`` is turned on by default. If entering a number | 897 - ``try_id_parsing`` is turned on by default. If entering a number |
| 897 into a Link or Multilink field, roundup interprets this number as an | 898 into a Link or Multilink field, Roundup interprets this number as an |
| 898 ID of the item to link to. Sometimes items can have numeric names | 899 ID of the item to link to. Sometimes items can have numeric names |
| 899 (like, e.g., product codes). For these roundup needs to match the | 900 (like, e.g., product codes). For these Roundup needs to match the |
| 900 numeric name and should never match an ID. In this case you can set | 901 numeric name and should never match an ID. In this case you can set |
| 901 ``try_id_parsing='no'``. | 902 ``try_id_parsing='no'``. |
| 902 | 903 |
| 903 .. index:: triple: schema; property attributes; rev_multilink | 904 .. index:: triple: schema; property attributes; rev_multilink |
| 904 | 905 |
| 962 | 963 |
| 963 .. index:: triple: schema; property attributes; msg_header_property | 964 .. index:: triple: schema; property attributes; msg_header_property |
| 964 | 965 |
| 965 - The ``msg_header_property`` is used by the mail gateway when sending | 966 - The ``msg_header_property`` is used by the mail gateway when sending |
| 966 out messages. When a link or multilink property of an issue changes, | 967 out messages. When a link or multilink property of an issue changes, |
| 967 roundup creates email headers of the form:: | 968 Roundup creates email headers of the form:: |
| 968 | 969 |
| 969 X-Roundup-issue-prop: value | 970 X-Roundup-issue-prop: value |
| 970 | 971 |
| 971 where ``value`` is the ``name`` property for the linked item(s). | 972 where ``value`` is the ``name`` property for the linked item(s). |
| 972 For example, if you have a multilink for attached_files in your | 973 For example, if you have a multilink for attached_files in your |
| 1056 type of the file. | 1057 type of the file. |
| 1057 | 1058 |
| 1058 Roundup by default considers the contents of the file immutable. This | 1059 Roundup by default considers the contents of the file immutable. This |
| 1059 is to assist in maintaining an accurate record of correspondence. The | 1060 is to assist in maintaining an accurate record of correspondence. The |
| 1060 distributed tracker templates do not enforce this. So if you have | 1061 distributed tracker templates do not enforce this. So if you have |
| 1061 access to the roundup tracker directory, you can edit the files (make | 1062 access to the Roundup tracker directory, you can edit the files (make |
| 1062 sure to preserve mode, owner and group) to remove information (e.g. if | 1063 sure to preserve mode, owner and group) to remove information (e.g. if |
| 1063 somebody includes a password or you need to redact proprietary | 1064 somebody includes a password or you need to redact proprietary |
| 1064 information). Obviously the journal for the message/file will not | 1065 information). Obviously the journal for the message/file will not |
| 1065 report that the file has changed. | 1066 report that the file has changed. |
| 1066 | 1067 |
| 1071 | 1072 |
| 1072 If you need to delete an entire file, replace the file contents with:: | 1073 If you need to delete an entire file, replace the file contents with:: |
| 1073 | 1074 |
| 1074 [file contents deleted due to spam 202-10-21 --myname] | 1075 [file contents deleted due to spam 202-10-21 --myname] |
| 1075 | 1076 |
| 1076 rather than deleting the file. If you actually delete the file roundup | 1077 rather than deleting the file. If you actually delete the file Roundup |
| 1077 will report an error to the user and email the administrator. If you | 1078 will report an error to the user and email the administrator. If you |
| 1078 empty the file, a user downloading the file using the direct URL | 1079 empty the file, a user downloading the file using the direct URL |
| 1079 (e.g. ``tracker/msg22``) may be confused and think something is broken | 1080 (e.g. ``tracker/msg22``) may be confused and think something is broken |
| 1080 when they receive an empty file. Retiring a file/msg does not prevent | 1081 when they receive an empty file. Retiring a file/msg does not prevent |
| 1081 access to the file using the direct URL. Retiring an item only removes | 1082 access to the file using the direct URL. Retiring an item only removes |
| 1119 where ``hello`` is a file on local disk. | 1120 where ``hello`` is a file on local disk. |
| 1120 | 1121 |
| 1121 You can enforce immutability in your tracker by adding an auditor (see | 1122 You can enforce immutability in your tracker by adding an auditor (see |
| 1122 detectors_) for the file/msg class that rejects changes to the content | 1123 detectors_) for the file/msg class that rejects changes to the content |
| 1123 property. The auditor could also add a journal entry so that a change | 1124 property. The auditor could also add a journal entry so that a change |
| 1124 via the roundup mechanism is reported. Using a mixin (see: | 1125 via the Roundup mechanism is reported. Using a mixin (see: |
| 1125 https://wiki.roundup-tracker.org/MixinClassFileClass) to augment the | 1126 https://wiki.roundup-tracker.org/MixinClassFileClass) to augment the |
| 1126 file class allows for other possibilities including signing the file, or | 1127 file class allows for other possibilities including signing the file, or |
| 1127 recording a checksum in the database and validating the file contents | 1128 recording a checksum in the database and validating the file contents |
| 1128 at the time it gets read. This allows detection of changes done on the | 1129 at the time it gets read. This allows detection of changes done on the |
| 1129 filesystem outside of the roundup mechanism. | 1130 filesystem outside of the Roundup mechanism. |
| 1130 | 1131 |
| 1131 .. index:: triple: schema; class property; messages | 1132 .. index:: triple: schema; class property; messages |
| 1132 triple: schema; class property; files | 1133 triple: schema; class property; files |
| 1133 triple: schema; class property; nosy | 1134 triple: schema; class property; nosy |
| 1134 triple: schema; class property; superseder | 1135 triple: schema; class property; superseder |
| 1163 .. index:: roundup-admin; setting assignedto on an issue | 1164 .. index:: roundup-admin; setting assignedto on an issue |
| 1164 | 1165 |
| 1165 Select a String property of the class to be the key property. The key | 1166 Select a String property of the class to be the key property. The key |
| 1166 property must be unique, and allows references to the items in the class | 1167 property must be unique, and allows references to the items in the class |
| 1167 by the content of the key property. That is, we can refer to users by | 1168 by the content of the key property. That is, we can refer to users by |
| 1168 their username: for example, let's say that there's an issue in roundup, | 1169 their username: for example, let's say that there's an issue in Roundup, |
| 1169 issue 23. There's also a user, richard, who happens to be user 2. To | 1170 issue 23. There's also a user, richard, who happens to be user 2. To |
| 1170 assign an issue to him, we could do either of:: | 1171 assign an issue to him, we could do either of:: |
| 1171 | 1172 |
| 1172 roundup-admin set issue23 assignedto=2 | 1173 roundup-admin set issue23 assignedto=2 |
| 1173 | 1174 |
| 1185 Select a property of the class to be the label property. The label | 1186 Select a property of the class to be the label property. The label |
| 1186 property is used whereever an item should be uniquely identified, e.g., | 1187 property is used whereever an item should be uniquely identified, e.g., |
| 1187 when displaying a link to an item. If setlabelprop is not specified for | 1188 when displaying a link to an item. If setlabelprop is not specified for |
| 1188 a class, the following values are tried for the label: | 1189 a class, the following values are tried for the label: |
| 1189 | 1190 |
| 1190 * the key of the class (see the `setkey(property)`_ section above) | 1191 * the key of the class (see the `setkey(property)`_ section above) |
| 1191 * the "name" property | 1192 * the "name" property |
| 1192 * the "title" property | 1193 * the "title" property |
| 1193 * the first property from the sorted property name list | 1194 * the first property from the sorted property name list |
| 1194 | 1195 |
| 1195 So in most cases you can get away without specifying setlabelprop | 1196 So in most cases you can get away without specifying setlabelprop |
| 1196 explicitly. | 1197 explicitly. |
| 1197 | 1198 |
| 1198 You should make sure that users have View access to this property or | 1199 You should make sure that users have View access to this property or |
| 1210 e.g., when grouping or sorting class A by a link to class B in the user | 1211 e.g., when grouping or sorting class A by a link to class B in the user |
| 1211 interface, the order property of class B is used for sorting. If | 1212 interface, the order property of class B is used for sorting. If |
| 1212 setorderprop is not specified for a class, the following values are tried | 1213 setorderprop is not specified for a class, the following values are tried |
| 1213 for the order property: | 1214 for the order property: |
| 1214 | 1215 |
| 1215 * the property named "order" | 1216 * the property named "order" |
| 1216 * the label property (see `setlabelprop(property)`_ above) | 1217 * the label property (see `setlabelprop(property)`_ above) |
| 1217 | 1218 |
| 1218 So in most cases you can get away without specifying setorderprop | 1219 So in most cases you can get away without specifying setorderprop |
| 1219 explicitly. | 1220 explicitly. |
| 1220 | 1221 |
| 1221 .. index: triple: schema; class method; create | 1222 .. index: triple: schema; class method; create |
| 1258 | 1259 |
| 1259 .. _Roundup wiki: | 1260 .. _Roundup wiki: |
| 1260 https://wiki.roundup-tracker.org/ | 1261 https://wiki.roundup-tracker.org/ |
| 1261 | 1262 |
| 1262 .. index:: !detectors | 1263 .. index:: !detectors |
| 1264 .. _detectors: | |
| 1265 .. _Auditors and reactors: | |
| 1263 | 1266 |
| 1264 Detectors - adding behaviour to your tracker | 1267 Detectors - adding behaviour to your tracker |
| 1265 ============================================ | 1268 ============================================ |
| 1266 .. _detectors: | |
| 1267 | 1269 |
| 1268 Detectors are initialised every time you open your tracker database, so | 1270 Detectors are initialised every time you open your tracker database, so |
| 1269 you're free to add and remove them any time, even after the database is | 1271 you're free to add and remove them any time, even after the database is |
| 1270 initialised via the ``roundup-admin initialise`` command. | 1272 initialised via the ``roundup-admin initialise`` command. |
| 1271 | 1273 |
| 1444 comes from "the system" and not a user). | 1446 comes from "the system" and not a user). |
| 1445 | 1447 |
| 1446 | 1448 |
| 1447 .. index:: extensions | 1449 .. index:: extensions |
| 1448 .. index:: extensions; add python functions to tracker | 1450 .. index:: extensions; add python functions to tracker |
| 1451 .. _extensions: | |
| 1452 .. _actions: | |
| 1449 | 1453 |
| 1450 Extensions - adding capabilities to your tracker | 1454 Extensions - adding capabilities to your tracker |
| 1451 ================================================ | 1455 ================================================ |
| 1452 .. _extensions: | |
| 1453 | 1456 |
| 1454 While detectors_ add new behavior by reacting to changes in tracked | 1457 While detectors_ add new behavior by reacting to changes in tracked |
| 1455 objects, `extensions` add new actions and utilities to Roundup, which | 1458 objects, `extensions` add new actions and utilities to Roundup, which |
| 1456 are mostly used to enhance web interface. | 1459 are mostly used to enhance web interface. |
| 1457 | 1460 |
| 1463 Note that at this point web interface is not loaded, but extensions still | 1466 Note that at this point web interface is not loaded, but extensions still |
| 1464 can register actions for in tracker instance. This may be fixed in | 1467 can register actions for in tracker instance. This may be fixed in |
| 1465 Roundup 1.6 by introducing ``init_web(client)`` callback or a more | 1468 Roundup 1.6 by introducing ``init_web(client)`` callback or a more |
| 1466 flexible extension point mechanism. | 1469 flexible extension point mechanism. |
| 1467 | 1470 |
| 1468 | 1471 * ``instance.registerUtil`` is used for adding `templating utilities`_ |
| 1469 * ``instance.registerUtil`` is used for adding `templating utilities`_ | 1472 (see `adding a time log to your issues`_ for an example) |
| 1470 (see `adding a time log to your issues`_ for an example) | 1473 |
| 1471 | 1474 * ``instance.registerAction`` is used to add more actions to instance |
| 1472 * ``instance.registerAction`` is used to add more actions to instance | 1475 and to web interface. See `Defining new web actions`_ for details. |
| 1473 and to web interface. See `Defining new web actions`_ for details. | 1476 Generic action can be added by inheriting from ``action.Action`` |
| 1474 Generic action can be added by inheriting from ``action.Action`` | 1477 instead of ``cgi.action.Action``. |
| 1475 instead of ``cgi.action.Action``. | 1478 |
| 1476 | 1479 .. _interfaces.py: |
| 1477 interfaces.py - hooking into the core of roundup | 1480 .. _modifying the core of Roundup: |
| 1481 | |
| 1482 interfaces.py - hooking into the core of Roundup | |
| 1478 ================================================ | 1483 ================================================ |
| 1479 .. _interfaces.py: | 1484 |
| 1480 | 1485 There is a magic trick for hooking into the core of Roundup. Using |
| 1481 There is a magic trick for hooking into the core of roundup. Using | |
| 1482 this you can: | 1486 this you can: |
| 1483 | 1487 |
| 1484 * modify class data structures | 1488 * modify class data structures |
| 1485 * monkey patch core code to add new functionality | 1489 * monkey patch core code to add new functionality |
| 1486 * modify the email gateway | 1490 * modify the email gateway |
| 1487 * add new rest endpoints | 1491 * add new rest endpoints |
| 1488 | 1492 |
| 1489 but with great power comes great responsibility. | 1493 but with great power comes great responsibility. |
| 1490 | 1494 |
| 1491 Interfaces.py has been around since the earliest releases of roundup | 1495 Interfaces.py has been around since the earliest releases of Roundup |
| 1492 and used to be the main way to get a lot of customization done. In | 1496 and used to be the main way to get a lot of customization done. In |
| 1493 modern roundup, the extensions_ mechanism is used, but there are | 1497 modern Roundup, the extensions_ mechanism is used, but there are |
| 1494 places where interfaces.py is still useful. Note that the tracker | 1498 places where interfaces.py is still useful. Note that the tracker |
| 1495 directories are not on the Python system path when interfaces.py is | 1499 directories are not on the Python system path when interfaces.py is |
| 1496 evaluated. You need to add library directories explictly by | 1500 evaluated. You need to add library directories explictly by |
| 1497 modifying sys.path. | 1501 modifying sys.path. |
| 1498 | 1502 |
| 1512 | 1516 |
| 1513 In this case static files delivered using @@file will have cache | 1517 In this case static files delivered using @@file will have cache |
| 1514 headers set. These files are searched for along the `static_files` | 1518 headers set. These files are searched for along the `static_files` |
| 1515 path in the tracker's `config.ini`. In the example above: | 1519 path in the tracker's `config.ini`. In the example above: |
| 1516 | 1520 |
| 1517 * a css file (e.g. @@file/style.css) will be cached for an hour | 1521 * a css file (e.g. @@file/style.css) will be cached for an hour |
| 1518 * javascript files (e.g. @@file/libraries/jquery.js) will be cached | 1522 * javascript files (e.g. @@file/libraries/jquery.js) will be cached |
| 1519 for 30 seconds | 1523 for 30 seconds |
| 1520 * a file named rss.xml will be cached for 15 minutes | 1524 * a file named rss.xml will be cached for 15 minutes |
| 1521 * a file named local.js will be cached for 2 hours | 1525 * a file named local.js will be cached for 2 hours |
| 1522 | 1526 |
| 1523 Note that a file name match overrides the mime type settings. | 1527 Note that a file name match overrides the mime type settings. |
| 1524 | 1528 |
| 1525 | 1529 |
| 1526 Example: Implement password complexity checking | 1530 Example: Implement password complexity checking |
| 1616 | 1620 |
| 1617 test-issues@example.com roundup-test@roundup-vm.example.com | 1621 test-issues@example.com roundup-test@roundup-vm.example.com |
| 1618 test-support@example.com roundup-test+support-a@roundup-vm.example.com | 1622 test-support@example.com roundup-test+support-a@roundup-vm.example.com |
| 1619 test@support.example.com roundup-test+support-b@roundup-vm.example.com | 1623 test@support.example.com roundup-test+support-b@roundup-vm.example.com |
| 1620 | 1624 |
| 1621 These modifications to the mail gateway for roundup allows anonymous | 1625 These modifications to the mail gateway for Roundup allows anonymous |
| 1622 submissions. It hides all of the requesters under the "support" | 1626 submissions. It hides all of the requesters under the "support" |
| 1623 user. It also makes some other modifications to the mail parser | 1627 user. It also makes some other modifications to the mail parser |
| 1624 allowing keywords to be set and prefixes to be defined based on the | 1628 allowing keywords to be set and prefixes to be defined based on the |
| 1625 delivery alias. | 1629 delivery alias. |
| 1626 | 1630 |
| 1729 else: | 1733 else: |
| 1730 # parse the message normally | 1734 # parse the message normally |
| 1731 return roundup.mailgw.parsedMessage(mailgw, message) | 1735 return roundup.mailgw.parsedMessage(mailgw, message) |
| 1732 | 1736 |
| 1733 This is the most complex example section. The mail gateway is also one | 1737 This is the most complex example section. The mail gateway is also one |
| 1734 of the more complex subsystems in roundup, and modifying it is not | 1738 of the more complex subsystems in Roundup, and modifying it is not |
| 1735 trivial. | 1739 trivial. |
| 1736 | 1740 |
| 1737 Other Examples | 1741 Other Examples |
| 1738 -------------- | 1742 -------------- |
| 1739 | 1743 |
| 2016 A sequence of property names that are the only properties to apply the | 2020 A sequence of property names that are the only properties to apply the |
| 2017 new Permission to (eg. ``... klass='user', properties=('name', | 2021 new Permission to (eg. ``... klass='user', properties=('name', |
| 2018 'email') ...``) | 2022 'email') ...``) |
| 2019 **props_only** | 2023 **props_only** |
| 2020 A boolean value (set to false by default) that is a new feature | 2024 A boolean value (set to false by default) that is a new feature |
| 2021 in roundup 1.6. | 2025 in Roundup 1.6. |
| 2022 A permission defined using: | 2026 A permission defined using: |
| 2023 | 2027 |
| 2024 ``properties=('list', 'of', 'property', 'names')`` | 2028 ``properties=('list', 'of', 'property', 'names')`` |
| 2025 | 2029 |
| 2026 is used to determine access for things other than just those | 2030 is used to determine access for things other than just those |
| 2411 Protecting users from web application attacks | 2415 Protecting users from web application attacks |
| 2412 --------------------------------------------- | 2416 --------------------------------------------- |
| 2413 | 2417 |
| 2414 There is a class of attacks known as Cross Site Request Forgeries | 2418 There is a class of attacks known as Cross Site Request Forgeries |
| 2415 (CSRF). Malicious code running in the browser can making a | 2419 (CSRF). Malicious code running in the browser can making a |
| 2416 request to roundup while you are logged into roundup. The | 2420 request to Roundup while you are logged into Roundup. The |
| 2417 malicious code piggy backs on your existing roundup session to | 2421 malicious code piggy backs on your existing Roundup session to |
| 2418 make changes without your knowledge. Roundup 1.6 has support for | 2422 make changes without your knowledge. Roundup 1.6 has support for |
| 2419 defending against this by analyzing the | 2423 defending against this by analyzing the |
| 2420 | 2424 |
| 2421 * Referer, | 2425 * Referer, |
| 2422 * Origin, and | 2426 * Origin, and |
| 2426 HTTP headers. It compares the headers to the value of the web setting | 2430 HTTP headers. It compares the headers to the value of the web setting |
| 2427 in the [tracker] section of the tracker's ``config.ini``. | 2431 in the [tracker] section of the tracker's ``config.ini``. |
| 2428 | 2432 |
| 2429 Also a per form token (also called a nonce) can be enabled for | 2433 Also a per form token (also called a nonce) can be enabled for |
| 2430 the tracker using the ``csrf_enforce_token`` option in | 2434 the tracker using the ``csrf_enforce_token`` option in |
| 2431 config.ini. When enabled, roundup will validate a hidden form | 2435 config.ini. When enabled, Roundup will validate a hidden form |
| 2432 field called ``@csrf``. If the validation fails (or the token | 2436 field called ``@csrf``. If the validation fails (or the token |
| 2433 is used more than once) the request is rejected. The ``@csrf`` | 2437 is used more than once) the request is rejected. The ``@csrf`` |
| 2434 input field is added automatically by calling the ``submit`` | 2438 input field is added automatically by calling the ``submit`` |
| 2435 function/path. It can also be added manually by calling | 2439 function/path. It can also be added manually by calling |
| 2436 anti_csrf_nonce() directly. For example: | 2440 anti_csrf_nonce() directly. For example:: |
| 2437 | 2441 |
| 2438 <input name="@csrf" type="hidden" | 2442 <input name="@csrf" type="hidden" |
| 2439 tal:attributes="value python:utils.anti_csrf_nonce(lifetime=10)"> | 2443 tal:attributes="value python:utils.anti_csrf_nonce(lifetime=10)"> |
| 2440 | 2444 |
| 2441 By default a nonce lifetime is 2 weeks. However the lifetime (in | 2445 By default a nonce lifetime is 2 weeks. However the lifetime (in |
| 2448 The token protects you because malicious code supplied by another | 2452 The token protects you because malicious code supplied by another |
| 2449 site is unable to obtain the token. Thus many attempts they make | 2453 site is unable to obtain the token. Thus many attempts they make |
| 2450 to submit a request are rejected. | 2454 to submit a request are rejected. |
| 2451 | 2455 |
| 2452 The protection on the xmlrpc interface is untested, but is based | 2456 The protection on the xmlrpc interface is untested, but is based |
| 2453 on a valid header check against the roundup url and the presence | 2457 on a valid header check against the Roundup url and the presence |
| 2454 of the ``X-REQUESTED-WITH`` header. Work to improve this is a | 2458 of the ``X-REQUESTED-WITH`` header. Work to improve this is a |
| 2455 future project after the 1.6 release. | 2459 future project after the 1.6 release. |
| 2456 | 2460 |
| 2457 The enforcement levels can be modified in ``config.ini``. Refer to | 2461 The enforcement levels can be modified in ``config.ini``. Refer to |
| 2458 that file for details. | 2462 that file for details. |
| 2746 Templating engines | 2750 Templating engines |
| 2747 ~~~~~~~~~~~~~~~~~~ | 2751 ~~~~~~~~~~~~~~~~~~ |
| 2748 | 2752 |
| 2749 Since version 1.4.20 Roundup supports two templating engines: | 2753 Since version 1.4.20 Roundup supports two templating engines: |
| 2750 | 2754 |
| 2751 * the original `Template Attribute Language`_ (TAL) engine from Zope | 2755 * the original `Template Attribute Language`_ (TAL) engine from Zope |
| 2752 * the standalone Chameleon templating engine. Chameleon is intended | 2756 * the standalone Chameleon templating engine. Chameleon is intended |
| 2753 as a replacement for the original TAL engine, and supports the | 2757 as a replacement for the original TAL engine, and supports the |
| 2754 same syntax, but they are not 100% compatible. The major (and most | 2758 same syntax, but they are not 100% compatible. The major (and most |
| 2755 likely the only) incompatibility is the default expression type being | 2759 likely the only) incompatibility is the default expression type being |
| 2756 ``python:`` instead of ``path:``. See also "Incompatibilities and | 2760 ``python:`` instead of ``path:``. See also "Incompatibilities and |
| 2757 differences" section of `Chameleon documentation`__. | 2761 differences" section of `Chameleon documentation`__. |
| 2758 | 2762 |
| 2759 Version 1.5.0 added experimental support for the `jinja2`_ templating | 2763 Version 1.5.0 added experimental support for the `jinja2`_ templating |
| 2760 language. You must install the `jinja2`_ module in order to use it. The | 2764 language. You must install the `jinja2`_ module in order to use it. The |
| 2761 ``jinja2`` template supplied with Roundup has the templates rewritten | 2765 ``jinja2`` template supplied with Roundup has the templates rewritten |
| 2762 to use ``jinja2`` rather than TAL. A number of trackers are running | 2766 to use ``jinja2`` rather than TAL. A number of trackers are running |
| 3026 The following variables are available to templates. | 3030 The following variables are available to templates. |
| 3027 | 3031 |
| 3028 **context** | 3032 **context** |
| 3029 The current context. This is either None, a `hyperdb class wrapper`_ | 3033 The current context. This is either None, a `hyperdb class wrapper`_ |
| 3030 or a `hyperdb item wrapper`_ | 3034 or a `hyperdb item wrapper`_ |
| 3035 | |
| 3031 **request** | 3036 **request** |
| 3032 Includes information about the current request, including: | 3037 Includes information about the current request, including: |
| 3033 - the current index information (``filterspec``, ``filter`` args, | 3038 |
| 3034 ``properties``, etc) parsed out of the form. | 3039 - the current index information (``filterspec``, ``filter`` |
| 3035 - methods for easy filterspec link generation | 3040 args, ``properties``, etc) parsed out of the form. |
| 3036 - "form" | 3041 - methods for easy filterspec link generation |
| 3037 The current CGI form information as a mapping of form argument name | 3042 - "form" |
| 3038 to value (specifically a cgi.FieldStorage) | 3043 The current CGI form information as a mapping of form argument name |
| 3039 - "env" the CGI environment variables | 3044 to value (specifically a cgi.FieldStorage) |
| 3040 - "base" the base URL for this instance | 3045 - "env" the CGI environment variables |
| 3041 - "user" a HTMLItem instance for the current user | 3046 - "base" the base URL for this instance |
| 3042 - "language" as determined by the browser or config | 3047 - "user" a HTMLItem instance for the current user |
| 3043 - "classname" the current classname (possibly None) | 3048 - "language" as determined by the browser or config |
| 3044 - "template" the current template (suffix, also possibly None) | 3049 - "classname" the current classname (possibly None) |
| 3050 - "template" the current template (suffix, also possibly None) | |
| 3045 **config** | 3051 **config** |
| 3046 This variable holds all the values defined in the tracker config.ini | 3052 This variable holds all the values defined in the tracker config.ini |
| 3047 file (eg. TRACKER_NAME, etc.) | 3053 file (eg. TRACKER_NAME, etc.) |
| 3048 **db** | 3054 **db** |
| 3049 The current database, used to access arbitrary database items. | 3055 The current database, used to access arbitrary database items. |
| 3658 roman Current position in the sequence as lowercase roman | 3664 roman Current position in the sequence as lowercase roman |
| 3659 numerals. | 3665 numerals. |
| 3660 Roman Same as roman(), except uppercase. | 3666 Roman Same as roman(), except uppercase. |
| 3661 =============== ========================================================= | 3667 =============== ========================================================= |
| 3662 | 3668 |
| 3669 .. _templating utilities: | |
| 3663 | 3670 |
| 3664 The utils variable | 3671 The utils variable |
| 3665 ~~~~~~~~~~~~~~~~~~ | 3672 ~~~~~~~~~~~~~~~~~~ |
| 3666 .. _templating utilities: | |
| 3667 | 3673 |
| 3668 This is implemented by the | 3674 This is implemented by the |
| 3669 ``roundup.cgi.templating.TemplatingUtils`` class, which may be extended | 3675 ``roundup.cgi.templating.TemplatingUtils`` class, which may be extended |
| 3670 with additional methods by extensions_. | 3676 with additional methods by extensions_. |
| 3671 | 3677 |
| 4510 </td> | 4516 </td> |
| 4511 </tr> | 4517 </tr> |
| 4512 | 4518 |
| 4513 The ``context/submit`` bit generates the submit button but also | 4519 The ``context/submit`` bit generates the submit button but also |
| 4514 generates the @action and @csrf hidden fields. The @action field is | 4520 generates the @action and @csrf hidden fields. The @action field is |
| 4515 used to tell roundup how to process the form. The @csrf field provides | 4521 used to tell Roundup how to process the form. The @csrf field provides |
| 4516 a unique single use token to defend against CSRF attacks. (More about | 4522 a unique single use token to defend against CSRF attacks. (More about |
| 4517 anti-csrf measures can be found in ``upgrading.txt``.) | 4523 anti-csrf measures can be found in ``upgrading.txt``.) |
| 4518 | 4524 |
| 4519 Finally we finish off the tags we used at the start to do the METAL | 4525 Finally we finish off the tags we used at the start to do the METAL |
| 4520 stuff:: | 4526 stuff:: |
| 4688 Finally we have to edit ``html/page.html`` again. This time, we need to | 4694 Finally we have to edit ``html/page.html`` again. This time, we need to |
| 4689 tell it that when the user clicks on "Unassigned Issues" or "All Issues", | 4695 tell it that when the user clicks on "Unassigned Issues" or "All Issues", |
| 4690 the category column should be included in the resulting list. If you | 4696 the category column should be included in the resulting list. If you |
| 4691 scroll down the page file, you can see the links with lots of options. | 4697 scroll down the page file, you can see the links with lots of options. |
| 4692 The option that we are interested in is the ``:columns=`` one which | 4698 The option that we are interested in is the ``:columns=`` one which |
| 4693 tells roundup which fields of the issue to display. Simply add | 4699 tells Roundup which fields of the issue to display. Simply add |
| 4694 "category" to that list and it all should work. | 4700 "category" to that list and it all should work. |
| 4695 | 4701 |
| 4696 Adding a time log to your issues | 4702 Adding a time log to your issues |
| 4697 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 4703 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 4698 | 4704 |
| 5000 On some systems the primary store of users is the UN*X passwd file. It | 5006 On some systems the primary store of users is the UN*X passwd file. It |
| 5001 holds information on users such as their username, real name, password | 5007 holds information on users such as their username, real name, password |
| 5002 and primary user group. | 5008 and primary user group. |
| 5003 | 5009 |
| 5004 Roundup can use this store as its primary source of user information, | 5010 Roundup can use this store as its primary source of user information, |
| 5005 but it needs additional information too - email address(es), roundup | 5011 but it needs additional information too - email address(es), Roundup |
| 5006 Roles, vacation flags, roundup hyperdb item ids, etc. Also, "retired" | 5012 Roles, vacation flags, Roundup hyperdb item ids, etc. Also, "retired" |
| 5007 users must still exist in the user database, unlike some passwd files in | 5013 users must still exist in the user database, unlike some passwd files in |
| 5008 which the users are removed when they no longer have access to a system. | 5014 which the users are removed when they no longer have access to a system. |
| 5009 | 5015 |
| 5010 To make use of the passwd file, we therefore synchronise between the two | 5016 To make use of the passwd file, we therefore synchronise between the two |
| 5011 user stores. We also use the passwd file to validate the user logins, as | 5017 user stores. We also use the passwd file to validate the user logins, as |
| 5013 validation source`_. We keep the user lists in sync using a fairly | 5019 validation source`_. We keep the user lists in sync using a fairly |
| 5014 simple script that runs once a day, or several times an hour if more | 5020 simple script that runs once a day, or several times an hour if more |
| 5015 immediate access is needed. In short, it: | 5021 immediate access is needed. In short, it: |
| 5016 | 5022 |
| 5017 1. parses the passwd file, finding usernames, passwords and real names, | 5023 1. parses the passwd file, finding usernames, passwords and real names, |
| 5018 2. compares that list to the current roundup user list: | 5024 2. compares that list to the current Roundup user list: |
| 5019 | 5025 |
| 5020 a. entries no longer in the passwd file are *retired* | 5026 a. entries no longer in the passwd file are *retired* |
| 5021 b. entries with mismatching real names are *updated* | 5027 b. entries with mismatching real names are *updated* |
| 5022 c. entries only exist in the passwd file are *created* | 5028 c. entries only exist in the passwd file are *created* |
| 5023 | 5029 |
| 5133 Using an LDAP database for user information | 5139 Using an LDAP database for user information |
| 5134 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 5140 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 5135 | 5141 |
| 5136 A script that reads users from an LDAP store using | 5142 A script that reads users from an LDAP store using |
| 5137 https://pypi.org/project/python-ldap/ and then compares the list to the users in the | 5143 https://pypi.org/project/python-ldap/ and then compares the list to the users in the |
| 5138 roundup user database would be pretty easy to write. You'd then have it run | 5144 Roundup user database would be pretty easy to write. You'd then have it run |
| 5139 once an hour / day (or on demand if you can work that into your LDAP store | 5145 once an hour / day (or on demand if you can work that into your LDAP store |
| 5140 workflow). See the example `Using a UN*X passwd file as the user database`_ | 5146 workflow). See the example `Using a UN*X passwd file as the user database`_ |
| 5141 for more information about doing this. | 5147 for more information about doing this. |
| 5142 | 5148 |
| 5143 To authenticate off the LDAP store (rather than using the passwords in the | 5149 To authenticate off the LDAP store (rather than using the passwords in the |
| 6234 | 6240 |
| 6235 def init(instance): | 6241 def init(instance): |
| 6236 '''Override the default edit action with this new version''' | 6242 '''Override the default edit action with this new version''' |
| 6237 instance.registerAction('edit', Edit2Action) | 6243 instance.registerAction('edit', Edit2Action) |
| 6238 | 6244 |
| 6239 This code is a wrapper for the roundup EditItemAction. It checks the | 6245 This code is a wrapper for the Roundup EditItemAction. It checks the |
| 6240 form's submit button to save the value element. The rest of the changes | 6246 form's submit button to save the value element. The rest of the changes |
| 6241 needed for the Silent Submit feature involves editing | 6247 needed for the Silent Submit feature involves editing |
| 6242 html/issue.item.html to add the silent submit button. In | 6248 html/issue.item.html to add the silent submit button. In |
| 6243 the stock issue.item.html the submit button is on a line that contains | 6249 the stock issue.item.html the submit button is on a line that contains |
| 6244 "submit button". Replace that line with something like the following:: | 6250 "submit button". Replace that line with something like the following:: |
