Mercurial > p > roundup > code
comparison doc/upgrading.txt @ 7464:82bbb95e5690 issue2550923_computed_property
merge from tip into issue2550923_computed_property
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Thu, 08 Jun 2023 00:10:32 -0400 |
| parents | bed28b64c581 |
| children | a072331c843b |
comparison
equal
deleted
inserted
replaced
| 7045:ca90f7270cd4 | 7464:82bbb95e5690 |
|---|---|
| 1 .. meta:: | 1 .. meta:: |
| 2 :description: | 2 :description: |
| 3 Critical documentation on how to upgrade the Roundup Issue | 3 Critical documentation for upgrading the Roundup Issue |
| 4 Tracker. Actions that must or can be taken when upgrading from | 4 Tracker. Actions that must be taken when upgrading from |
| 5 one version to another are documented here. | 5 one version to another are documented here. |
| 6 | 6 |
| 7 .. index:: Upgrading | 7 .. index:: Upgrading |
| 8 | 8 |
| 9 ====================================== | 9 ====================================== |
| 10 Upgrading to newer versions of Roundup | 10 Upgrading to newer versions of Roundup |
| 11 ====================================== | 11 ====================================== |
| 12 | 12 |
| 13 Please read each section carefully and edit your tracker home files | 13 Please read each section carefully and edit the files in your tracker home |
| 14 accordingly. Note that there is information about upgrade procedures in the | 14 accordingly. Note that there is information about upgrade procedures in the |
| 15 `administration guide`_ in the `Software Upgrade`_ section. | 15 `administration guide`_ in the `Software Upgrade`_ section. |
| 16 | 16 |
| 17 If a specific version transition isn't mentioned here (eg. 0.6.7 to 0.6.8) | 17 If a specific version transition isn't mentioned here (e.g. 0.6.7 to |
| 18 then you don't need to do anything. If you're upgrading from 0.5.6 to | 18 0.6.8) then you don't need to do anything. If you're upgrading from |
| 19 0.6.8 though, you'll need to check the "0.5 to 0.6" and "0.6.x to 0.6.3" | 19 0.5.6 to 0.6.8 though, you'll need to apply the "0.5 to 0.6" and |
| 20 steps. | 20 "0.6.x to 0.6.3" steps. |
| 21 | 21 |
| 22 **IMPORTANT** The v1.5.x releases of Roundup were the last to support | 22 General steps: |
| 23 Python v2.5 and v2.6. Starting with the v1.6 releases of Roundup | 23 |
| 24 Python version 2.7 that is newer than 2.7.2 is required to run | 24 1. Make note of your current Roundup version. |
| 25 roundup. Starting with Roundup version 2.0.0 we also support Python 3 | 25 2. Take your Roundup installation offline (web, email, |
| 26 versions newer than 3.4. | 26 cron scripts, roundup-admin etc.) |
| 27 3. Backup your Roundup instance | |
| 28 4. Install the new version of Roundup (preferably in a new virtual | |
| 29 environment) | |
| 30 5. Make version specific changes as described below for | |
| 31 each version transition. If you are starting at 1.5.0 | |
| 32 and installing to 2.3.0, you need to make the changes for **all** | |
| 33 versions starting at 1.5 and ending at 2.3. E.G. | |
| 34 1.5.0 -> 1.5.1, 1.5.1 -> 1.6.0, ..., 2.1.0 -> 2.2.0, | |
| 35 2.2.0 -> 2.3.0. | |
| 36 6. Run ``roundup-admin -i <tracker_home> migrate`` using the newer | |
| 37 version of Roundup for **all** the trackers you have | |
| 38 upgraded. This will update the database if it is required. | |
| 39 7. Bring your Roundup instance back online | |
| 40 8. Test | |
| 41 | |
| 42 .. note:: | |
| 43 The v1.5.x releases of Roundup were the last to support | |
| 44 Python v2.5 and v2.6. Starting with the v1.6 releases of Roundup | |
| 45 Python version 2.7 that is newer than 2.7.2 is required to run | |
| 46 Roundup. Starting with Roundup version 2.0.0 we also support Python 3 | |
| 47 versions newer than 3.6. | |
| 48 | |
| 49 Recent release notes have the following labels: | |
| 50 | |
| 51 * required - Roundup will not work properly if these steps are not done | |
| 52 * recommended - Roundup will still work, but these steps can cause | |
| 53 security or stability issues if not done. | |
| 54 * optional - new features or changes to existing features you might | |
| 55 want to use | |
| 56 * info - important possibly visible changes in how things operate | |
| 57 | |
| 58 If you use virtual environments for your installation, you can run | |
| 59 trackers with different versions of Roundup. So you can have one tracker | |
| 60 using version 2.2.0 and another tracker using version 1.6.1. This | |
| 61 allows you to upgrade trackers one at a time rather than having to | |
| 62 upgrade all your trackers at once. | |
| 63 | |
| 64 .. note:: | |
| 65 | |
| 66 This file only includes versions released in the last 10 | |
| 67 years. If you are upgrading from an older version, start with the | |
| 68 changes in the `historical migration <upgrading-history.html>`_ | |
| 69 document. | |
| 70 | |
| 71 .. admonition:: Python 2 Support | |
| 72 | |
| 73 If you are running Roundup under Python 2, you should make plans to | |
| 74 switch to Python 3. The continuous Integration (CI) and other services | |
| 75 used for developing Roundup are dropping support for Python 2. Also | |
| 76 optional packages are dropping Python 2 support. As a result Python 2 | |
| 77 may not be supported for many more release cycles. | |
| 78 | |
| 79 .. admonition:: XHTML Support Deprecation Notice | |
| 80 | |
| 81 If you are running a tracker where the ``html_version`` setting in | |
| 82 ``config.ini`` is ``xhtml``, you should plan to change your | |
| 83 templates to use html (HTML5). If you are affected by this, please | |
| 84 send email to the roundup-users mailing list (roundup-users at | |
| 85 lists.sourceforge.net). Version 2.3.0 is expected to be the last | |
| 86 version to support XHTML. | |
| 27 | 87 |
| 28 Contents: | 88 Contents: |
| 29 | 89 |
| 30 .. contents:: | 90 .. contents:: |
| 31 :local: | 91 :local: |
| 44 | 104 |
| 45 to generate a new ini file preserving all your settings. | 105 to generate a new ini file preserving all your settings. |
| 46 You can then merge any local comments from the tracker's | 106 You can then merge any local comments from the tracker's |
| 47 ``config.ini`` to ``newconfig.ini`` and replace | 107 ``config.ini`` to ``newconfig.ini`` and replace |
| 48 ``config.ini`` with ``newconfig.ini``. | 108 ``config.ini`` with ``newconfig.ini``. |
| 109 | |
| 110 ``updateconfig`` will tell you if it is changing old default | |
| 111 values or if a value must be changed manually. | |
| 112 | |
| 113 Using the roundup-mailgw script (required) | |
| 114 ------------------------------------------ | |
| 115 | |
| 116 In previous versions the roundup-mailgw script had a ``-C`` (or | |
| 117 ``--class``) option for specifying a class to be used with ``-S`` (or | |
| 118 ``--set``) option(s). In the latest version the ``-C`` option is gone, | |
| 119 the class for this option is specified as a prefix, e.g. instead of :: | |
| 120 | |
| 121 roundup-mailgw -C issue -S issueprop=value | |
| 122 | |
| 123 You now specify :: | |
| 124 | |
| 125 roundup-mailgw -S issue.issueprop=value | |
| 126 | |
| 127 If multiple values need to be set, this can be achieved with multiple | |
| 128 ``-S`` options or with delimiting multiple values with a semicolon (in | |
| 129 that case the string needs to be quoted because semicolon is a shell | |
| 130 special character):: | |
| 131 | |
| 132 roundup-mailgw -S 'issue.issueprop1=value1;issueprop2=value2' | |
| 133 roundup-mailgw -S issue.issueprop1=value1 -S issue.issueprop2=value2 | |
| 134 | |
| 135 are equivalent. Note that the class is provided as a prefix for the | |
| 136 set-string, not for each property. The class can be omitted altogether | |
| 137 in which case it defaults to ``msg`` (this default existed in previous | |
| 138 versions). | |
| 139 | |
| 140 If you do not use the ``-C`` (or ``--class``) option in your current | |
| 141 setup of mailgw you don't need to change anything. | |
| 142 | |
| 143 Replace Create User permission for Anonymous with Register (required) | |
| 144 --------------------------------------------------------------------- | |
| 145 | |
| 146 Check your trackers schema.py. If you have the following code:: | |
| 147 | |
| 148 db.security.addPermissionToRole('Anonymous', 'Create', 'user') | |
| 149 | |
| 150 after the permission for Anonymous 'Email Access', change it to:: | |
| 151 | |
| 152 db.security.addPermissionToRole('Anonymous', 'Register', 'user') | |
| 153 | |
| 154 The comment for Anonymous 'Email Access' may refer to Create. Change | |
| 155 it to refer to Register. | |
| 156 | |
| 157 This will be an issue if you used the devel or responsive tracker | |
| 158 templates. If you used a classic, minimal or jinja2 template the | |
| 159 permission change (but not the comment change) should be done already. | |
| 49 | 160 |
| 50 Rdbms version change from 7 to 8 (required) | 161 Rdbms version change from 7 to 8 (required) |
| 51 ------------------------------------------- | 162 ------------------------------------------- |
| 52 | 163 |
| 53 This release includes a change that requires updates to the | 164 This release includes a change that requires updates to the |
| 110 is done to minimize confusion. Because the data is | 221 is done to minimize confusion. Because the data is |
| 111 ephemeral, there is no plan to migrate this data to the new | 222 ephemeral, there is no plan to migrate this data to the new |
| 112 SQLite databases. If you want to keep using the data set the | 223 SQLite databases. If you want to keep using the data set the |
| 113 ``sessiondb`` ``backend`` option as described above. | 224 ``sessiondb`` ``backend`` option as described above. |
| 114 | 225 |
| 226 Update ``config.ini``'s ``password_pbkdf2_default_rounds`` (required) | |
| 227 --------------------------------------------------------------------- | |
| 228 | |
| 229 Roundup hashes passwords using PBKDF2 with SHA1. In this release, you | |
| 230 can `upgrade to PBKDF2-SHA512 from current PBKDF2-SHA1`. If you | |
| 231 upgrade, you want to set the default rounds according to the | |
| 232 PBKDF2-SHA512 upgrading directions. Note that this algorithm is | |
| 233 expected to be the default in a future version of Roundup. | |
| 234 | |
| 235 If you don't want to upgrade, we recommend that you increase the | |
| 236 default number of rounds from the original 10000. PBKDF2 has a | |
| 237 parameter that makes hashing a password more difficult to do. The | |
| 238 original 10000 value was set years ago. It has not been updated for | |
| 239 advancements in computing power. | |
| 240 | |
| 241 This release of Roundup changes the value to 2000000 (2 | |
| 242 million). This exceeds the current `recommended setting of | |
| 243 1,300,000`_ for PBKDF2 when used with SHA1. | |
| 244 | |
| 245 .. caution:: | |
| 246 | |
| 247 If you were using the old 10000 value, **it will be automatically | |
| 248 upgraded** to 2 million by using ``roundup-admin``'s | |
| 249 ``updateconfig``. If you were not using the old 10000 default, you | |
| 250 should update it manually. | |
| 251 | |
| 252 After the change users will still be able to log in using the older | |
| 253 10000 round hashed passwords. If ``migrate_passwords`` is set to | |
| 254 ``yes``, passwords will be automatically re-hashed using the new | |
| 255 higher value when the user logs in. If | |
| 256 ``password_pbkdf2_default_rounds`` is set to a lower value than was | |
| 257 used to hash a password, the password will not be rehashed so the | |
| 258 higher value will be kept. The lower value will be used only if the | |
| 259 password is changed using the web or command line. | |
| 260 | |
| 261 Increasing the number of rounds will slow down re-hashing. That's the | |
| 262 whole point. Sadly it will also slow down logins. Usually the hash | |
| 263 takes under 1 second, but if you are using a slow chip (e.g. an ARM V6 | |
| 264 at 700 bogo mips) it can take 30 seconds to compute the 2000000 | |
| 265 rounds. The slowdown is linear. So what takes .001 seconds at 10000 | |
| 266 rounds will take: ``2000000/10000 * .001 = 200 * .001`` seconds or 0.2 | |
| 267 seconds. | |
| 268 | |
| 269 You can see how long it will take by using the new ``roundup-admin`` | |
| 270 ``perftest`` command. After you have finished migrating your database, | |
| 271 run:: | |
| 272 | |
| 273 roundup-admin -i <tracker_home> perftest password scheme=PBKDF2 rounds=10000 | |
| 274 | |
| 275 and then:: | |
| 276 | |
| 277 roundup-admin -i <tracker_home> perftest password scheme=PBKDF2 rounds=2,000,000 | |
| 278 | |
| 279 so see the difference. Output from this command looks like:: | |
| 280 | |
| 281 Hash time: 0.203151849s scheme: PBKDF2 rounds: 10000 | |
| 282 | |
| 283 If your testing reports a hash time above 0.5 seconds for 10000 | |
| 284 rounds, there may be another issue. See if executing:: | |
| 285 | |
| 286 python3 -c 'from hashlib import pbkdf2_hmac' | |
| 287 | |
| 288 produces an error. | |
| 289 | |
| 290 If you get an ImportError, you are using Roundup's fallback PBKDF2 | |
| 291 implementation. It is much slower than the library version. As a | |
| 292 result re-encrypting the password (and logging in, which requires | |
| 293 calculating the encrypted password) will be very slow. | |
| 294 | |
| 295 You should find out how to make the import succeed. You may need to | |
| 296 install an OS vendor package or some other library. | |
| 297 | |
| 298 .. _recommended setting of 1,300,000: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#pbkdf2 | |
| 299 | |
| 300 Upgrade to PBKDF2-SHA512 from current PBKDF2-SHA1 (recommended) | |
| 301 --------------------------------------------------------------- | |
| 302 | |
| 303 We recommend that you upgrade to using PBKDF2-SHA512 for hashing your | |
| 304 passwords. This is a more secure method than the old PBKDF2 (with | |
| 305 SHA1). Because the algorithm is more secure, it uses a smaller value | |
| 306 for ``password_pbkdf2_default_rounds``. Setting | |
| 307 ``password_pbkdf2_default_rounds`` to ``250000`` exceeds the current | |
| 308 `recommended setting of 210,000`_ iterations for PBKDF2 when used with | |
| 309 SHA512. | |
| 310 | |
| 311 You can see how long this takes to calculate on your hardware using | |
| 312 ``roundup-admin``'s perftest command. For example:: | |
| 313 | |
| 314 roundup-admin -i <tracker_home> perftest password scheme=PBKDF2S5 rounds=250,000 | |
| 315 | |
| 316 produces:: | |
| 317 | |
| 318 Hash time: 0.161892945 seconds, scheme: PBKDF2S5, rounds: 250000 | |
| 319 | |
| 320 Any increase in the number of rounds will cause the password to | |
| 321 automatically be rehashed to the higher value the next time the user | |
| 322 logs in via the web interface. Changing the number of rounds to a | |
| 323 **lower** value will not trigger a rehash during login unless the | |
| 324 scheme is also being changed. The lower number will be used only when | |
| 325 the password is explicitly changed using the web interface or the | |
| 326 command line (``roundup-admin`` for example). | |
| 327 | |
| 328 Change the default hashing scheme by adding the following lines to | |
| 329 |the interfaces.py file|_ in your tracker home:: | |
| 330 | |
| 331 ## Use PBDKF2S5 (PBKDF2-SHA512) for passwords. Re-hash old PBDFK2 | |
| 332 # Force password with scheme PBKDF2 (SHA1) to get re-hashed | |
| 333 Password.deprecated_schemes.insert(0, Password.known_schemes[0]) | |
| 334 # choose PBKDF2S5 as the scheme to use for rehashing. | |
| 335 Password.default_scheme = Password.experimental_schemes[0] | |
| 336 | |
| 337 You may need to create the ``interfaces.py`` file if it doesn't exist. | |
| 338 In the future, when the default hash is changed to PBKDF2S5, upgrade | |
| 339 directions will include instructions to remove these lines and | |
| 340 the file ``interfaces.py`` if it becomes empty. | |
| 341 | |
| 342 You can verify that PBKDF2S5 is used by default by running:: | |
| 343 | |
| 344 roundup-admin -i <tracker_home> perftest password rounds=250,000 | |
| 345 | |
| 346 and verify that the scheme is PBKDF2S5. | |
| 347 | |
| 348 .. _the interfaces.py file: | |
| 349 reference.html#interfaces-py-hooking-into-the-core-of-roundup | |
| 350 | |
| 351 .. |the interfaces.py file| replace:: the ``interfaces.py`` file | |
| 352 | |
| 353 .. _recommended setting of 210,000: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#pbkdf2 | |
| 354 | |
| 355 jQuery updated with updates to user.help.html (recommended) | |
| 356 ----------------------------------------------------------- | |
| 357 | |
| 358 The devel and responsive templates shipped with an old version of | |
| 359 jQuery. According to automated tests, it may have a security issue. It | |
| 360 has been updated to the current version: 3.6.3. If your tracker is | |
| 361 based on one of these templates (see the ``TEMPLATE-INFO.txt`` file in | |
| 362 your tracker), remove the old ``html/jquery.js`` file from your | |
| 363 tracker and copy the new ``jquery-3.6.3.js`` file from the template | |
| 364 directory to your tracker's ``html`` directory. Also copy in the new | |
| 365 ``user.help.html`` file. It now references the new ``jquery-3.6.3.js`` | |
| 366 file. | |
| 367 | |
| 368 | |
| 115 Session/OTK data storage using Redis (optional) | 369 Session/OTK data storage using Redis (optional) |
| 116 ----------------------------------------------- | 370 ----------------------------------------------- |
| 117 | 371 |
| 118 You can store your ephemeral data in a Redis database. This | 372 You can store your ephemeral data in a Redis database. This |
| 119 provides significantly better performance for ephemeral data | 373 provides significantly better performance for ephemeral data |
| 161 If you find WAL mode is not working for you, you can set the | 415 If you find WAL mode is not working for you, you can set the |
| 162 journal method to a rollback journal (``delete`` mode) by | 416 journal method to a rollback journal (``delete`` mode) by |
| 163 using step 2 and replacing ``wal`` with ``delete``. (Note: | 417 using step 2 and replacing ``wal`` with ``delete``. (Note: |
| 164 SQLite supports other journaling modes, but only ``wal`` and | 418 SQLite supports other journaling modes, but only ``wal`` and |
| 165 ``delete`` persist. Roundup doesn't set a journaling mode | 419 ``delete`` persist. Roundup doesn't set a journaling mode |
| 166 when it opens the database, so options such as ``truncate`` | 420 when it opens the database, so journaling mode options such |
| 167 are not used.) | 421 as ``truncate`` are not useful.) |
| 168 | 422 |
| 169 For details on WAL mode see `<https://www.sqlite.org/wal.html>`_ | 423 For details on WAL mode see `<https://www.sqlite.org/wal.html>`_ |
| 170 and `<https://www.sqlite.org/pragma.html#pragma_journal_mode>`_. | 424 and `<https://www.sqlite.org/pragma.html#pragma_journal_mode>`_. |
| 171 | 425 |
| 172 Change in processing of In-Reply_to email header | 426 Change in processing allowed_api_origins setting (info) |
| 173 ------------------------------------------------ | 427 ------------------------------------------------------- |
| 428 | |
| 429 In this release you can use both ``*`` (as the first origin) and | |
| 430 explicit origins in the `allowed_api_origins`` setting in | |
| 431 ``config.ini``. (Before it was only one or the other.) | |
| 432 | |
| 433 You do not need to use ``*``. If you do, it allows any client | |
| 434 anonymous (unauthenticated) access to the Roundup tracker. This | |
| 435 is the same as browsing the tracker without logging in. If they | |
| 436 try to provide credentials, access to the data will be denied by | |
| 437 `CORS`_. | |
| 438 | |
| 439 If you include explicit origins (e.g. \https://example.com), | |
| 440 users from those origins will not be blocked if they use | |
| 441 credentials to log in. | |
| 442 | |
| 443 .. _CORS: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS | |
| 444 | |
| 445 Change in processing of In-Reply_to email header (info) | |
| 446 ------------------------------------------------------- | |
| 174 | 447 |
| 175 Messages received via email usually include a ``[issue23]`` | 448 Messages received via email usually include a ``[issue23]`` |
| 176 designator in the subject line. This indicates what issue is | 449 designator in the subject line. This indicates what issue is |
| 177 being updated. If the designator is missing, Roundup tries | 450 being updated. If the designator is missing, Roundup tries |
| 178 to find the correct issue by using the in-reply-to email | 451 to find the correct issue by using the in-reply-to email |
| 190 | 463 |
| 191 If you don't have messages assigned to multiple issues you | 464 If you don't have messages assigned to multiple issues you |
| 192 will see no change. If you do have multi-linked messages | 465 will see no change. If you do have multi-linked messages |
| 193 this will hopefully result in better message->issue | 466 this will hopefully result in better message->issue |
| 194 matching. | 467 matching. |
| 468 | |
| 469 Incremental/batch full test reindexing with roundup-admin (info) | |
| 470 ---------------------------------------------------------------- | |
| 471 | |
| 472 The ``reindex`` command in ``roundup-admin`` can reindex | |
| 473 a range of items. For example:: | |
| 474 | |
| 475 roundup-admin -i ... reindex issues:1-1000 | |
| 476 | |
| 477 will reindex only the first 1000 issues. This is useful since | |
| 478 reindexing can take a while and slow down the tracker. By running | |
| 479 it in batches you can control when the reindex runs rather than having | |
| 480 to wait for it to complete all the reindexing. See the man page or | |
| 481 `administration guide`_ for details. | |
| 195 | 482 |
| 196 .. index:: Upgrading; 2.1.0 to 2.2.0 | 483 .. index:: Upgrading; 2.1.0 to 2.2.0 |
| 197 | 484 |
| 198 Migrating from 2.1.0 to 2.2.0 | 485 Migrating from 2.1.0 to 2.2.0 |
| 199 ============================= | 486 ============================= |
| 347 Change passwords using crypt module (optional) | 634 Change passwords using crypt module (optional) |
| 348 ---------------------------------------------- | 635 ---------------------------------------------- |
| 349 | 636 |
| 350 The crypt module is being removed from the standard library. Any | 637 The crypt module is being removed from the standard library. Any |
| 351 stored password using crypt encoding will fail to verify once the | 638 stored password using crypt encoding will fail to verify once the |
| 352 crypt module is removed (expected in Python 3.13 see | 639 crypt module is removed (expected in Python 3.13 see `pep-0594 |
| 353 pep-0594). Automatic migration of passwords (if enabled in config.ini) | 640 <https://peps.python.org/pep-0594/>`_). Automatic migration of |
| 354 re-encrypts old passwords using something other than crypt if a user | 641 passwords (if enabled in config.ini) re-encrypts old passwords using |
| 355 logs in using the web interface. | 642 something other than crypt if a user logs in using the web interface. |
| 356 | 643 |
| 357 You can find users with passwords still encrypted using crypt by | 644 You can find users with passwords still encrypted using crypt by |
| 358 running:: | 645 running:: |
| 359 | 646 |
| 360 roundup-admin -i <tracker_home> table password,id,username | 647 roundup-admin -i <tracker_home> table password,id,username |
| 403 | 690 |
| 404 in your TAL based templates. The ``jinja2`` based templates are | 691 in your TAL based templates. The ``jinja2`` based templates are |
| 405 missing this file, but if you implemented one you want to surround the | 692 missing this file, but if you implemented one you want to surround the |
| 406 jinja2 code with:: | 693 jinja2 code with:: |
| 407 | 694 |
| 408 {% if context.is_view_ok() %} | 695 {% if context.is_edit_ok() %} |
| 409 <submit button code here> | 696 <submit button code here> |
| 410 {% endif %} | 697 {% endif %} |
| 411 | 698 |
| 412 | 699 |
| 413 .. index:: Upgrading; 2.0.0 to 2.1.0 | 700 .. index:: Upgrading; 2.0.0 to 2.1.0 |
| 414 | 701 |
| 415 Migrating from 2.0.0 to 2.1.0 | 702 Migrating from 2.0.0 to 2.1.0 |
| 416 ============================= | 703 ============================= |
| 417 | 704 |
| 418 Rdbms version change from 5 to 6 (**) | 705 Rdbms version change from 5 to 6 (required) |
| 419 ------------------------------------- | 706 ------------------------------------------- |
| 420 | 707 |
| 421 To fix an issue with importing databases, the database has to be | 708 To fix an issue with importing databases, the database has to be |
| 422 upgraded for rdbms backends. | 709 upgraded for rdbms backends. |
| 423 | 710 |
| 424 You should run the ``roundup-admin migrate`` command for your | 711 You should run the ``roundup-admin migrate`` command for your |
| 488 database level. If you had a database that was at version 4 and | 775 database level. If you had a database that was at version 4 and |
| 489 then upgraded to version 5 you have the uniqueness enforcing | 776 then upgraded to version 5 you have the uniqueness enforcing |
| 490 constraint. Running migrate updates to schema version 6 and installs | 777 constraint. Running migrate updates to schema version 6 and installs |
| 491 the unique index constraint if it is missing. | 778 the unique index constraint if it is missing. |
| 492 | 779 |
| 493 Setuptools is now required to install | 780 Setuptools is now required to install (info) |
| 494 ------------------------------------- | 781 -------------------------------------------- |
| 495 | 782 |
| 496 Roundup install now uses setuptools rather than distutils. You must | 783 Roundup install now uses setuptools rather than distutils. You must |
| 497 install setuptools. Use the version packgaged by your OS vendor. If | 784 install setuptools. Use the version packgaged by your OS vendor. If |
| 498 your OS vendor doesn't supply setuptools use ``pip install | 785 your OS vendor doesn't supply setuptools use ``pip install |
| 499 setuptools``. (You may need pip3 rather than pip if using python3.) | 786 setuptools``. (You may need pip3 rather than pip if using python3.) |
| 500 | 787 |
| 501 Define Authentication Header | 788 Define Authentication Header (optional) |
| 502 ---------------------------- | 789 --------------------------------------- |
| 503 | 790 |
| 504 The web server in front of roundup (apache, nginx) can perform user | 791 The web server in front of roundup (apache, nginx) can perform user |
| 505 authentication. It can pass the authenticated username to the backend | 792 authentication. It can pass the authenticated username to the backend |
| 506 in a variable. By default roundup looks for the ``REMOTE_USER`` | 793 in a variable. By default roundup looks for the ``REMOTE_USER`` |
| 507 variable. This can be changed by setting the parameter | 794 variable. This can be changed by setting the parameter |
| 539 | 826 |
| 540 At the time this is written, support is experimental. If you use it | 827 At the time this is written, support is experimental. If you use it |
| 541 you should notify the roundup maintainers using the roundup-users | 828 you should notify the roundup maintainers using the roundup-users |
| 542 at lists.sourceforge.net mailing list. | 829 at lists.sourceforge.net mailing list. |
| 543 | 830 |
| 544 Classname Format Enforced | 831 Classname Format Enforced (info) |
| 545 ------------------------- | 832 -------------------------------- |
| 546 | 833 |
| 547 Check schema.py and look at all Class(), IssueClass(), FileClass() | 834 Check schema.py and look at all Class(), IssueClass(), FileClass() |
| 548 calls. The second argument is the classname. All classnames must: | 835 calls. The second argument is the classname. All classnames must: |
| 549 | 836 |
| 550 * start with an alphabetic character | 837 * start with an alphabetic character |
| 552 * not end with a digit | 839 * not end with a digit |
| 553 | 840 |
| 554 this was not enforced before. Using non-standard classnames could lead | 841 this was not enforced before. Using non-standard classnames could lead |
| 555 to other issues. | 842 to other issues. |
| 556 | 843 |
| 557 jQuery updated with updates to user.help.html | 844 jQuery updated with updates to user.help.html (recommended) |
| 558 --------------------------------------------- | 845 ----------------------------------------------------------- |
| 559 | 846 |
| 560 The devel and responsive templates shipped with an old version of | 847 The devel and responsive templates shipped with an old version of |
| 561 jQuery with some security issues. It has been updated to the current | 848 jQuery with some security issues. It has been updated to the current |
| 562 version: 3.5.1. If your tracker is based on one of these templates | 849 version: 3.5.1. If your tracker is based on one of these templates |
| 563 (see the ``TEMPLATE-INFO.txt`` file in your tracker), remove the old | 850 (see the ``TEMPLATE-INFO.txt`` file in your tracker), remove the old |
| 566 ``html`` directory. Also copy in the new ``user.help.html`` file. It now | 853 ``html`` directory. Also copy in the new ``user.help.html`` file. It now |
| 567 references the new ``jquery-3.5.1.js`` file and also fixes a bug that | 854 references the new ``jquery-3.5.1.js`` file and also fixes a bug that |
| 568 prevented applying the change from the helper to the field on the main | 855 prevented applying the change from the helper to the field on the main |
| 569 form. | 856 form. |
| 570 | 857 |
| 571 Roundup-admin security stops on incorrect properties | 858 Roundup-admin security stops on incorrect properties (info) |
| 572 ---------------------------------------------------- | 859 ----------------------------------------------------------- |
| 573 | 860 |
| 574 The ``roundup-admin ... security`` command used to continue | 861 The ``roundup-admin ... security`` command used to continue |
| 575 running through the rest of the security roles after reporting a | 862 running through the rest of the security roles after reporting a |
| 576 property error. Now it stops after reporting the incorrect property. | 863 property error. Now it stops after reporting the incorrect property. |
| 577 | 864 |
| 578 If run non-interactively, it exits with status 1. It can now be | 865 If run non-interactively, it exits with status 1. It can now be |
| 579 used in a startup script to detect permission errors. | 866 used in a startup script to detect permission errors. |
| 580 | 867 |
| 581 Futureproof devel and responsive timezone selection extension | 868 Futureproof devel and responsive timezone selection extension (recommended) |
| 582 ------------------------------------------------------------- | 869 --------------------------------------------------------------------------- |
| 583 | 870 |
| 584 The devel and responsive (derived from devel) templates use a select | 871 The devel and responsive (derived from devel) templates use a select |
| 585 control to list all available timezones when pytz is used. It | 872 control to list all available timezones when pytz is used. It |
| 586 sanitizes the data using cgi.escape. Cgi.escape is deprecated and | 873 sanitizes the data using cgi.escape. Cgi.escape is deprecated and |
| 587 removed in newer pythons. Change your ``extensions/timezone.py`` | 874 removed in newer pythons. Change your ``extensions/timezone.py`` |
| 611 ============================= | 898 ============================= |
| 612 | 899 |
| 613 .. index:: roundup-admin; updateconfig subcommand | 900 .. index:: roundup-admin; updateconfig subcommand |
| 614 | 901 |
| 615 | 902 |
| 616 Python 2 MYSQL users MUST READ | 903 Python 2 MYSQL users MUST READ (required) |
| 617 ------------------------------ | 904 ----------------------------------------- |
| 618 | 905 |
| 619 To fix issues with encoding of data and text searching, roundup now | 906 To fix issues with encoding of data and text searching, roundup now |
| 620 explicitly sets the database connection character set. Roundup prior | 907 explicitly sets the database connection character set. Roundup prior |
| 621 to 2.0 used the default character set which was not always utf-8. All | 908 to 2.0 used the default character set which was not always utf-8. All |
| 622 roundup data is manipulated in utf-8. This mismatch causes issues with | 909 roundup data is manipulated in utf-8. This mismatch causes issues with |
| 698 roundup-users AT lists.sourceforge.net mailing list. | 985 roundup-users AT lists.sourceforge.net mailing list. |
| 699 | 986 |
| 700 As people report successful or unsuccessful conversions, we will update | 987 As people report successful or unsuccessful conversions, we will update |
| 701 the errata page at: https://wiki.roundup-tracker.org/ReleaseErrata. | 988 the errata page at: https://wiki.roundup-tracker.org/ReleaseErrata. |
| 702 | 989 |
| 703 Upgrade tracker's config.ini file | 990 Upgrade tracker's config.ini file (recommended) |
| 704 --------------------------------- | 991 ----------------------------------------------- |
| 705 | 992 |
| 706 Once you have installed the new roundup, use:: | 993 Once you have installed the new roundup, use:: |
| 707 | 994 |
| 708 roundup-admin -i /path/to/tracker updateconfig newconfig.ini | 995 roundup-admin -i /path/to/tracker updateconfig newconfig.ini |
| 709 | 996 |
| 711 merge any local comments from the tracker's ``config.ini`` into | 998 merge any local comments from the tracker's ``config.ini`` into |
| 712 ``newconfig.ini``. Compare the old and new files and configure any new | 999 ``newconfig.ini``. Compare the old and new files and configure any new |
| 713 settings as you want. Then replace ``config.ini`` with the | 1000 settings as you want. Then replace ``config.ini`` with the |
| 714 ``newconfig.ini`` file. | 1001 ``newconfig.ini`` file. |
| 715 | 1002 |
| 716 Python 3 support | 1003 .. _Python 3 support: |
| 717 ---------------- | 1004 |
| 1005 Python 3 support (info) | |
| 1006 ----------------------- | |
| 718 | 1007 |
| 719 Many of the ``.html`` and ``.py`` files from Roundup that are copied | 1008 Many of the ``.html`` and ``.py`` files from Roundup that are copied |
| 720 into tracker directories have changed for Python 3 support. If you | 1009 into tracker directories have changed for Python 3 support. If you |
| 721 wish to move an existing tracker to Python 3, you need to merge in | 1010 wish to move an existing tracker to Python 3, you need to merge in |
| 722 those changes. Also you need to make sure that locally created python | 1011 those changes. Also you need to make sure that locally created python |
| 744 roundup-admin -i ... updateconfig newconfig.ini`` if you want to go | 1033 roundup-admin -i ... updateconfig newconfig.ini`` if you want to go |
| 745 back to using python 2. (Note going back to Python 2 will require | 1034 back to using python 2. (Note going back to Python 2 will require |
| 746 the same steps as moving from 2 to 3 except using Python 3 to perform | 1035 the same steps as moving from 2 to 3 except using Python 3 to perform |
| 747 the export.) | 1036 the export.) |
| 748 | 1037 |
| 749 Rate Limit New User Registration | 1038 Rate Limit New User Registration (info) |
| 750 -------------------------------- | 1039 --------------------------------------- |
| 751 | 1040 |
| 752 The new user registration form can be abused by bots to allow | 1041 The new user registration form can be abused by bots to allow |
| 753 automated registration for spamming. This can be limited by using the | 1042 automated registration for spamming. This can be limited by using the |
| 754 new ``config.ini`` ``[web]`` option called | 1043 new ``config.ini`` ``[web]`` option called |
| 755 ``registration_delay``. The default is 4 and is the number of seconds | 1044 ``registration_delay``. The default is 4 and is the number of seconds |
| 778 (see: https://hg.python.org/tracker/python-dev/rev/83477f735132), you | 1067 (see: https://hg.python.org/tracker/python-dev/rev/83477f735132), you |
| 779 can back the code out of the tracker. You must change the name of the | 1068 can back the code out of the tracker. You must change the name of the |
| 780 field in the html template to ``opaqueregistration`` from ``opaque`` | 1069 field in the html template to ``opaqueregistration`` from ``opaque`` |
| 781 in order to use the core code. | 1070 in order to use the core code. |
| 782 | 1071 |
| 783 PGP mail processing | 1072 PGP mail processing (required) |
| 784 ------------------- | 1073 ------------------------------ |
| 785 | 1074 |
| 786 Roundup now uses the ``gpg`` module instead of ``pyme`` to process PGP | 1075 Roundup now uses the ``gpg`` module instead of ``pyme`` to process PGP |
| 787 mail. If you have PGP processing enabled, make sure the ``gpg`` | 1076 mail. If you have PGP processing enabled, make sure the ``gpg`` |
| 788 module is installed. | 1077 module is installed. |
| 789 | 1078 |
| 790 MySQL client module | 1079 MySQL client module (recommended) |
| 791 ------------------- | 1080 --------------------------------- |
| 792 | 1081 |
| 793 Although the ``MySQLdb`` module from | 1082 Although the ``MySQLdb`` module from |
| 794 https://pypi.org/project/MySQL-python/ is still supported, it is | 1083 https://pypi.org/project/MySQL-python/ is still supported, it is |
| 795 recommended to switch to the updated module from | 1084 recommended to switch to the updated module from |
| 796 https://pypi.org/project/mysqlclient/. | 1085 https://pypi.org/project/mysqlclient/. |
| 797 | 1086 |
| 798 XMLRPC Access Role | 1087 XMLRPC Access Role (info/required) |
| 799 ------------------ | 1088 ---------------------------------- |
| 800 | 1089 |
| 801 A new permission has been added to control access to the XMLRPC | 1090 A new permission has been added to control access to the XMLRPC |
| 802 endpoint. If the user doesn't have the new "Xmlrpc Access" permission, | 1091 endpoint. If the user doesn't have the new "Xmlrpc Access" permission, |
| 803 they will not be able to log in using the /xmlrpc end point. To add | 1092 they will not be able to log in using the /xmlrpc end point. To add |
| 804 this new permission to the "User" role you should change your | 1093 this new permission to the "User" role you should change your |
| 807 db.security.addPermissionToRole('User', 'Xmlrpc Access') | 1096 db.security.addPermissionToRole('User', 'Xmlrpc Access') |
| 808 | 1097 |
| 809 This is usually included near where other permissions like "Web Access" | 1098 This is usually included near where other permissions like "Web Access" |
| 810 or "Email Access" are assigned. | 1099 or "Email Access" are assigned. |
| 811 | 1100 |
| 812 New values for db.tx_Source | 1101 New values for db.tx_Source (info) |
| 813 --------------------------- | 1102 ---------------------------------- |
| 814 | 1103 |
| 815 The database attribute tx_Source reports "xmlrpc" and "rest" when the | 1104 The database attribute tx_Source reports "xmlrpc" and "rest" when the |
| 816 /xmlrpc and /rest web endpoints are used. Check all code (extensions, | 1105 /xmlrpc and /rest web endpoints are used. Check all code (extensions, |
| 817 detectors, lib) in trackers looking for tx_Source. If you have code | 1106 detectors, lib) in trackers looking for tx_Source. If you have code |
| 818 like:: | 1107 like:: |
| 831 or:: | 1120 or:: |
| 832 | 1121 |
| 833 if db.tx_Source in ['web', 'rest', 'xmlrpc', 'email-sig-openpgp', 'cli' ]: | 1122 if db.tx_Source in ['web', 'rest', 'xmlrpc', 'email-sig-openpgp', 'cli' ]: |
| 834 | 1123 |
| 835 | 1124 |
| 836 CSV export changes | 1125 CSV export changes (info) |
| 837 ------------------ | 1126 ------------------------- |
| 838 | 1127 |
| 839 The original Roundup CSV export function for indexes reported id | 1128 The original Roundup CSV export function for indexes reported id |
| 840 numbers for links. The wiki had a version that resolved the id's to | 1129 numbers for links. The wiki had a version that resolved the id's to |
| 841 names, so it would report ``open`` rather than ``2`` or | 1130 names, so it would report ``open`` rather than ``2`` or |
| 842 ``user2;user3`` rather than ``[2,3]``. | 1131 ``user2;user3`` rather than ``[2,3]``. |
| 861 be added for missing parameters. | 1150 be added for missing parameters. |
| 862 | 1151 |
| 863 This turns exported values that may look like formulas into strings so | 1152 This turns exported values that may look like formulas into strings so |
| 864 some versions of Excel won't try to interpret them as a formula. | 1153 some versions of Excel won't try to interpret them as a formula. |
| 865 | 1154 |
| 866 Update userauditor.py to restrict usernames | 1155 Update userauditor.py to restrict usernames (recommended) |
| 867 ------------------------------------------- | 1156 --------------------------------------------------------- |
| 868 | 1157 |
| 869 A username can be created with embedded commas and < and > | 1158 A username can be created with embedded commas and < and > |
| 870 characters. Even though the < and > are usually escaped when | 1159 characters. Even though the < and > are usually escaped when |
| 871 displayed, the embedded comma makes it difficult to edit lists of | 1160 displayed, the embedded comma makes it difficult to edit lists of |
| 872 users as they are comma separated. | 1161 users as they are comma separated. |
| 875 copy the userauditor.py from the classic template into your tracker's | 1164 copy the userauditor.py from the classic template into your tracker's |
| 876 detectors directory. Otherwise merge the changes from the template | 1165 detectors directory. Otherwise merge the changes from the template |
| 877 userauditor.py. https://issues.roundup-tracker.org/issue2550921 may be | 1166 userauditor.py. https://issues.roundup-tracker.org/issue2550921 may be |
| 878 helpful. | 1167 helpful. |
| 879 | 1168 |
| 880 Consider reindexing if you use European languages | 1169 Consider reindexing if you use European languages (recommended) |
| 881 ------------------------------------------------- | 1170 --------------------------------------------------------------- |
| 882 | 1171 |
| 883 A couple of bugs dealing with incorrect indexing of European languages | 1172 A couple of bugs dealing with incorrect indexing of European languages |
| 884 (Russian and German were reported) have been fixed. Note reindexing | 1173 (Russian and German were reported) have been fixed. Note reindexing |
| 885 all your data may take a long time. See: | 1174 all your data may take a long time. See: |
| 886 https://issues.roundup-tracker.org/issue1195739 and | 1175 https://issues.roundup-tracker.org/issue1195739 and |
| 895 SATA drive. Using native indexing with sqlite took about 45 | 1184 SATA drive. Using native indexing with sqlite took about 45 |
| 896 minutes. Using whoosh took about 2 hours. Using xapian took about 6 | 1185 minutes. Using whoosh took about 2 hours. Using xapian took about 6 |
| 897 hours. All examples were with Python 2. Anecdotal evidence shows | 1186 hours. All examples were with Python 2. Anecdotal evidence shows |
| 898 Python 3 is faster, but YMMV. | 1187 Python 3 is faster, but YMMV. |
| 899 | 1188 |
| 900 Merge improvements in statusauditor.py | 1189 Merge improvements in statusauditor.py (optional) |
| 901 -------------------------------------- | 1190 ------------------------------------------------- |
| 902 | 1191 |
| 903 By default the detector statusauditor.py will change the status from | 1192 By default the detector statusauditor.py will change the status from |
| 904 "unread" to "chatting" when a second message is added to an issue. | 1193 "unread" to "chatting" when a second message is added to an issue. |
| 905 The distributed classic and jinja templates implement this feature in | 1194 The distributed classic and jinja templates implement this feature in |
| 906 their copies of ``detectors/statusauditor.py``. | 1195 their copies of ``detectors/statusauditor.py``. |
| 923 have a ``detectors/config.ini`` file. (Note this is | 1212 have a ``detectors/config.ini`` file. (Note this is |
| 924 ``detectors/config.ini`` do not confuse it with the main | 1213 ``detectors/config.ini`` do not confuse it with the main |
| 925 ``config.ini`` file at the root of the tracker home.) | 1214 ``config.ini`` file at the root of the tracker home.) |
| 926 | 1215 |
| 927 This enhancement is disabled by default. Enable it by changing the | 1216 This enhancement is disabled by default. Enable it by changing the |
| 928 value in ``detectors/config.ini`` from: | 1217 value in ``detectors/config.ini`` from:: |
| 929 | 1218 |
| 930 chatting_requires_two_users = False | 1219 chatting_requires_two_users = False |
| 931 | 1220 |
| 932 to | 1221 to:: |
| 933 | 1222 |
| 934 chatting_requires_two_users = True | 1223 chatting_requires_two_users = True |
| 935 | 1224 |
| 936 (the values ``no`` and ``yes`` can also be used). Restart the tracker | 1225 (the values ``no`` and ``yes`` can also be used). Restart the tracker |
| 937 to enable the change. | 1226 to enable the change. |
| 956 DETECTOR::STATUSAUDITOR_CHATTING_REQUIRES_TWO_USERS: 'T' | 1245 DETECTOR::STATUSAUDITOR_CHATTING_REQUIRES_TWO_USERS: 'T' |
| 957 Allowed values: yes, no | 1246 Allowed values: yes, no |
| 958 | 1247 |
| 959 to fix this set the value to ``yes`` (True) or ``no`` (False). | 1248 to fix this set the value to ``yes`` (True) or ``no`` (False). |
| 960 | 1249 |
| 961 Responsive template changes | 1250 Responsive template changes (optional) |
| 962 --------------------------- | 1251 -------------------------------------- |
| 963 | 1252 |
| 964 There have been some changes to the responsive template. You can | 1253 There have been some changes to the responsive template. You can |
| 965 diff/merge these changes into your responsive template based tracker. | 1254 diff/merge these changes into your responsive template based tracker. |
| 966 | 1255 |
| 967 Jinja template changes | 1256 Jinja template changes (required) |
| 968 ---------------------- | 1257 --------------------------------- |
| 969 | 1258 |
| 970 Auto escaping has been enabled in the jinja template engine, this | 1259 Auto escaping has been enabled in the jinja template engine, this |
| 971 means it is no longer necessary to manually escape dynamic strings | 1260 means it is no longer necessary to manually escape dynamic strings |
| 972 with "\|e", but strings that should not be escaped need to be marked | 1261 with ``|e``, but strings that should not be escaped need to be marked |
| 973 with "\|safe" (e.g. "{{ context.history()|u|safe }}"). Also, the i18n | 1262 with ``|safe`` (e.g. ``{{ context.history()|u|safe }}``). Also, the i18n |
| 974 extension has been enabled and the template has been updated to use | 1263 extension has been enabled and the template has been updated to use |
| 975 the extension for translatable text instead of explicit "i18n.gettext" | 1264 the extension for translatable text instead of explicit ``i18n.gettext`` |
| 976 calls: | 1265 calls:: |
| 977 | 1266 |
| 978 {% trans %}List of issues{% endtrans %} | 1267 {% trans %}List of issues{% endtrans %} |
| 979 | 1268 |
| 980 instead of: | 1269 instead of:: |
| 981 | 1270 |
| 982 {{ i18n.gettext('List of issues')|u }} | 1271 {{ i18n.gettext('List of issues')|u }} |
| 983 | 1272 |
| 984 The jinja template has been upgraded to use bootstrap 4.1.3 (from | 1273 The jinja template has been upgraded to use bootstrap 4.1.3 (from |
| 985 2.2.2). You can diff/merge changes into your jinja template based | 1274 2.2.2). You can diff/merge changes into your jinja template based |
| 1010 -------------------------- | 1299 -------------------------- |
| 1011 | 1300 |
| 1012 After installing the new version of roundup, you should | 1301 After installing the new version of roundup, you should |
| 1013 update the ``config.ini`` file for your tracker. To do this: | 1302 update the ``config.ini`` file for your tracker. To do this: |
| 1014 | 1303 |
| 1015 1. backup your existing ``config.ini`` file | 1304 1. backup your existing ``config.ini`` file |
| 1016 2. using the newly installed code, run:: | 1305 2. using the newly installed code, run:: |
| 1017 | 1306 |
| 1018 roundup-admin -i /path/to/tracker updateconfig config.ini.new | 1307 roundup-admin -i /path/to/tracker updateconfig config.ini.new |
| 1019 | 1308 |
| 1020 to create the file config.ini.new. Replace | 1309 to create the file config.ini.new. Replace |
| 1021 ``/path/to/tracker`` with the path to your tracker. | 1310 ``/path/to/tracker`` with the path to your tracker. |
| 1022 3. replace your tracker's config.ini with config.ini.new | 1311 3. replace your tracker's config.ini with config.ini.new |
| 1023 | 1312 |
| 1024 Using updateconfig keeps all the settings from your | 1313 Using updateconfig keeps all the settings from your |
| 1025 tracker's config.ini file and adds settings for all the new | 1314 tracker's config.ini file and adds settings for all the new |
| 1026 options. | 1315 options. |
| 1027 | 1316 |
| 1031 | 1320 |
| 1032 Read the new config.ini and configure it to enable new | 1321 Read the new config.ini and configure it to enable new |
| 1033 features. Details on using these features can be found in | 1322 features. Details on using these features can be found in |
| 1034 this section. | 1323 this section. |
| 1035 | 1324 |
| 1036 Make sure that user can view labelprop on classes (REQUIRED) | 1325 Make sure that user can view labelprop on classes (required) |
| 1037 ------------------------------------------------------------ | 1326 ------------------------------------------------------------ |
| 1038 | 1327 |
| 1039 If you have View permissions that use ```properties=...```, | 1328 If you have View permissions that use ```properties=...```, |
| 1040 make sure that the labelprop for the class is listed in the | 1329 make sure that the labelprop for the class is listed in the |
| 1041 properties list. | 1330 properties list. |
| 1064 content. | 1353 content. |
| 1065 | 1354 |
| 1066 See: https://sourceforge.net/p/roundup/mailman/message/35763294/ | 1355 See: https://sourceforge.net/p/roundup/mailman/message/35763294/ |
| 1067 for the initial discussion of the issue. | 1356 for the initial discussion of the issue. |
| 1068 | 1357 |
| 1069 Cross Site Request Forgery Detection Added | 1358 .. _cross site request forgery detection added: |
| 1070 ------------------------------------------ | 1359 |
| 1360 Cross Site Request Forgery Detection Added (recommended) | |
| 1361 -------------------------------------------------------- | |
| 1071 | 1362 |
| 1072 Roundup 1.6. supports a number of defenses against CSRF. | 1363 Roundup 1.6. supports a number of defenses against CSRF. |
| 1073 | 1364 |
| 1074 Http header verification against the tracker's ``web`` | 1365 Http header verification against the tracker's ``web`` |
| 1075 setting in the ``[tracker]`` section of config.ini for the | 1366 setting in the ``[tracker]`` section of config.ini for the |
| 1076 following headers: | 1367 following headers: |
| 1077 | 1368 |
| 1078 1. Analyze the ``Referer`` HTTP header to make sure it | 1369 1. Analyze the ``Referer`` HTTP header to make sure it |
| 1079 includes the web setting. | 1370 includes the web setting. |
| 1080 2. Analyze the ``Origin`` HTTP header to make sure the | 1371 2. Analyze the ``Origin`` HTTP header to make sure the |
| 1081 schema://host matches the web setting. | 1372 schema://host matches the web setting. |
| 1082 3. Analyze the ``X-Forwarded-Host`` header set by a proxy | 1373 3. Analyze the ``X-Forwarded-Host`` header set by a proxy |
| 1083 running in front of roundup to make sure it agrees with | 1374 running in front of roundup to make sure it agrees with |
| 1084 the host part of the web setting. | 1375 the host part of the web setting. |
| 1085 4. Analyze the ``Host`` header to make sure it agrees with | 1376 4. Analyze the ``Host`` header to make sure it agrees with |
| 1086 the host part of the web setting. This is not done if | 1377 the host part of the web setting. This is not done if |
| 1087 ``X-Forwarded-Host`` is set. | 1378 ``X-Forwarded-Host`` is set. |
| 1088 | 1379 |
| 1089 By default roundup 1.6 does not require any specific header | 1380 By default roundup 1.6 does not require any specific header |
| 1090 to be present. However at least one of the headers above | 1381 to be present. However at least one of the headers above |
| 1091 *must* pass validation checks (usually ``Host`` or | 1382 *must* pass validation checks (usually ``Host`` or |
| 1092 ``Referer``) or the submission is rejected with an error. | 1383 ``Referer``) or the submission is rejected with an error. |
| 1103 is not true the post is rejected and the user is notified. | 1394 is not true the post is rejected and the user is notified. |
| 1104 | 1395 |
| 1105 The standard context/submit templating item creates CSRF tokens by | 1396 The standard context/submit templating item creates CSRF tokens by |
| 1106 default. If you have forms using the POST method that are not using | 1397 default. If you have forms using the POST method that are not using |
| 1107 the standard submit routine, you should add the following field to all | 1398 the standard submit routine, you should add the following field to all |
| 1108 forms: | 1399 forms:: |
| 1109 | 1400 |
| 1110 <input name="@csrf" type="hidden" | 1401 <input name="@csrf" type="hidden" |
| 1111 tal:attributes="value python:utils.anti_csrf_nonce()"> | 1402 tal:attributes="value python:utils.anti_csrf_nonce()"> |
| 1112 | 1403 |
| 1113 A unique random token is generated by every call to | 1404 A unique random token is generated by every call to |
| 1114 utils.anti_csrf_nonce() and is put in a database to be | 1405 utils.anti_csrf_nonce() and is put in a database to be |
| 1115 retreived if the token is used. Token lifetimes are 2 weeks | 1406 retreived if the token is used. Token lifetimes are 2 weeks |
| 1116 by default but can be configured in config.ini. Roundup will | 1407 by default but can be configured in config.ini. Roundup will |
| 1117 automatically prune old tokens. Calling anti_csrf_nonce with | 1408 automatically prune old tokens. Calling anti_csrf_nonce with |
| 1118 an integer lifetime, for example: | 1409 an integer lifetime, for example:: |
| 1119 | 1410 |
| 1120 <input name="@csrf" type="hidden" | 1411 <input name="@csrf" type="hidden" |
| 1121 tal:attributes="value python:utils.anti_csrf_nonce(lifetime=10)"> | 1412 tal:attributes="value python:utils.anti_csrf_nonce(lifetime=10)"> |
| 1122 | 1413 |
| 1123 sets the lifetime of that nonce to 10 minutes. | 1414 sets the lifetime of that nonce to 10 minutes. |
| 1206 security issue required a directory with a specific unusual name. This | 1497 security issue required a directory with a specific unusual name. This |
| 1207 made it difficult to exploit. However allowing the use of | 1498 made it difficult to exploit. However allowing the use of |
| 1208 subdirectories to organize the templates required that it be fixed. | 1499 subdirectories to organize the templates required that it be fixed. |
| 1209 | 1500 |
| 1210 | 1501 |
| 1211 Database back end specified in config.ini (REQUIRED) | 1502 Database back end specified in config.ini (required) |
| 1212 ---------------------------------------------------- | 1503 ---------------------------------------------------- |
| 1213 | 1504 |
| 1214 The ``db/backend_name`` file is no longer used to configure the database | 1505 The ``db/backend_name`` file is no longer used to configure the database |
| 1215 backend being used for a tracker. The backend is now configured in the | 1506 backend being used for a tracker. The backend is now configured in the |
| 1216 ``config.ini`` file using the ``backend`` option located in the ``[rdbms]`` | 1507 ``config.ini`` file using the ``backend`` option located in the ``[rdbms]`` |
| 1315 # address. It must be a valid RFC2822 address or people will not be | 1606 # address. It must be a valid RFC2822 address or people will not be |
| 1316 # able to reply. | 1607 # able to reply. |
| 1317 # Default: | 1608 # Default: |
| 1318 replyto_address = | 1609 replyto_address = |
| 1319 | 1610 |
| 1320 Login from a search or after logout works better (REQUIRED) | 1611 Login from a search or after logout works better (required) |
| 1321 ----------------------------------------------------------- | 1612 ----------------------------------------------------------- |
| 1322 | 1613 |
| 1323 The login form has been improved to work with some back end code | 1614 The login form has been improved to work with some back end code |
| 1324 changes. Now when a user logs in they stay on the same page where they | 1615 changes. Now when a user logs in they stay on the same page where they |
| 1325 started the login. To make this work, you must change the tal that is | 1616 started the login. To make this work, you must change the tal that is |
| 1327 assigned to __came_from must be url encoded/quoted and be under the | 1618 assigned to __came_from must be url encoded/quoted and be under the |
| 1328 tracker's base url. If the base_url uses http, you can set the url to | 1619 tracker's base url. If the base_url uses http, you can set the url to |
| 1329 https. | 1620 https. |
| 1330 | 1621 |
| 1331 Replace the existing code in the tracker's html/page.html page that | 1622 Replace the existing code in the tracker's html/page.html page that |
| 1332 looks similar to (look for name="__came_from"):: | 1623 looks similar to (look for name="__came_from"): |
| 1333 | 1624 |
| 1334 <input type="hidden" name="__came_from" tal:attributes="value string:${request/base}${request/env/PATH_INFO}"> | 1625 .. code:: |
| 1335 | 1626 :class: big-code |
| 1336 with the following:: | 1627 |
| 1628 <input type="hidden" name="__came_from" tal:attributes="value string:${request/base}${request/env/PATH_INFO}"> | |
| 1629 | |
| 1630 with the following: | |
| 1631 | |
| 1632 .. code:: html | |
| 1633 :class: big-code | |
| 1337 | 1634 |
| 1338 <input type="hidden" name="__came_from" | 1635 <input type="hidden" name="__came_from" |
| 1339 tal:condition="exists:request/env/QUERY_STRING" | 1636 tal:condition="exists:request/env/QUERY_STRING" |
| 1340 tal:attributes="value string:${request/base}${request/env/PATH_INFO}?${request/env/QUERY_STRING}"> | 1637 tal:attributes="value string:${request/base}${request/env/PATH_INFO}?${request/env/QUERY_STRING}"> |
| 1341 <input type="hidden" name="__came_from" | 1638 <input type="hidden" name="__came_from" |
| 1377 keyword's name when creating the keyword. The new classic tracker has | 1674 keyword's name when creating the keyword. The new classic tracker has |
| 1378 a new checkbox (checked by default) that keeps you on the same page so | 1675 a new checkbox (checked by default) that keeps you on the same page so |
| 1379 you can add a new keywords one after the other. | 1676 you can add a new keywords one after the other. |
| 1380 | 1677 |
| 1381 To add this to your own tracker, add the following code (prefixed with | 1678 To add this to your own tracker, add the following code (prefixed with |
| 1382 a +) after the entry box for the new keyword in html/keyword.item.html:: | 1679 a +) after the entry box for the new keyword in html/keyword.item.html: |
| 1680 | |
| 1681 .. code:: | |
| 1682 :class: big-code | |
| 1383 | 1683 |
| 1384 <tr> | 1684 <tr> |
| 1385 <th i18n:translate="">Keyword</th> | 1685 <th i18n:translate="">Keyword</th> |
| 1386 <td tal:content="structure context/name/field">name</td> | 1686 <td tal:content="structure context/name/field">name</td> |
| 1387 + <td tal:condition="not:context/id"> | 1687 + <td tal:condition="not:context/id"> |
| 1468 A new method has been added to HTMLStringProperty called url_quote. | 1768 A new method has been added to HTMLStringProperty called url_quote. |
| 1469 The default templates have been updated to use this in the "Your | 1769 The default templates have been updated to use this in the "Your |
| 1470 Query" section of the trackers html/page.html file. You will want to | 1770 Query" section of the trackers html/page.html file. You will want to |
| 1471 change your template. Lines starting with - are the original line and | 1771 change your template. Lines starting with - are the original line and |
| 1472 you want to change it to match the line starting with the + (remove | 1772 you want to change it to match the line starting with the + (remove |
| 1473 the + from the line):: | 1773 the + from the line): |
| 1774 | |
| 1775 .. code:: | |
| 1776 :class: big-code | |
| 1474 | 1777 |
| 1475 <tal:block tal:repeat="qs request/user/queries"> | 1778 <tal:block tal:repeat="qs request/user/queries"> |
| 1476 - <a href="#" tal:attributes="href string:${qs/klass}?${qs/url}&@dispname=${qs/name}" | 1779 - <a href="#" tal:attributes="href string:${qs/klass}?${qs/url}&@dispname=${qs/name}" |
| 1477 + <a href="#" tal:attributes="href string:${qs/klass}?${qs/url}&@dispname=${qs/name/url_quote}" | 1780 + <a href="#" tal:attributes="href string:${qs/klass}?${qs/url}&@dispname=${qs/name/url_quote}" |
| 1478 tal:content="qs/name">link</a><br> | 1781 tal:content="qs/name">link</a><br> |
| 1782 self.client.add_error_message(...) | 2085 self.client.add_error_message(...) |
| 1783 | 2086 |
| 1784 The new calls escape the passed string by default and avoid XSS security | 2087 The new calls escape the passed string by default and avoid XSS security |
| 1785 issues. | 2088 issues. |
| 1786 | 2089 |
| 1787 .. index:: Upgrading; 1.4.20 to 1.4.21 | 2090 |
| 1788 | 2091 Migrating from older versions |
| 1789 Migrating from 1.4.20 to 1.4.21 | |
| 1790 =============================== | |
| 1791 | |
| 1792 The ``_generic.calendar.html`` page of the instance has been updated to include | |
| 1793 ``<meta name="robots" content="noindex, nofollow" />``. This prevents | |
| 1794 robots to follow all the links in the calendar. If you haven't modified the | |
| 1795 page on your local instance, you can simply replace it with the one in | |
| 1796 ``share/roundup/templates/classic/html/_generic.calendar.html``; if you did, | |
| 1797 you can add the tag manually. See issue2550765 and changeset a099ff2ceff3. | |
| 1798 | |
| 1799 If you are using the xml-rpc interface, there is a change | |
| 1800 in accessing it. You can not send text/xml data to any | |
| 1801 roundup url and get a response, you must use the /xmlrpc | |
| 1802 url. For example, if you used to send your xmlrpc request to: | |
| 1803 | |
| 1804 http://myroundup.com/roundup | |
| 1805 | |
| 1806 you need to change the url to read: | |
| 1807 | |
| 1808 http://myroundup.com/roundup/xmlrpc | |
| 1809 | |
| 1810 to invoke the xmlrpc handler. This allows us to send xml | |
| 1811 data to roundup for other handlers (e.g. REST, SOAP ...) | |
| 1812 in the future. | |
| 1813 | |
| 1814 | |
| 1815 .. index:: upgrading; 1.4.19 to 1.4.20 | |
| 1816 | |
| 1817 Migrating from 1.4.19 to 1.4.20 | |
| 1818 =============================== | |
| 1819 | |
| 1820 Roundup used to allow certain HTML-Tags in OK- and Error-messages. Since | |
| 1821 these messages are passed via the URL (due to roundup redirecting after | |
| 1822 an edit), we did have security-issues (see issue2550724). | |
| 1823 | |
| 1824 If you have customized the OK or Error messages in your | |
| 1825 roundup-installation and you were using features like bold or italic | |
| 1826 in the message, you will have to do without this highlighting and | |
| 1827 remove HTML tags from messages. | |
| 1828 | |
| 1829 If you were using <br> tags for multi-line messages, you now should use | |
| 1830 newlines instead, these will be replaced with <br/> during formatting. | |
| 1831 | |
| 1832 Note that the previous implementation also allowed links inside | |
| 1833 messages. Since these links could be set by an attacker, no links in | |
| 1834 roundup messages are supported anymore. This does *not* affect the | |
| 1835 "clear this message" link in OK-messages as it is generated by the | |
| 1836 template and is not part of the OK-message. | |
| 1837 | |
| 1838 If you have not modified any roundup messages, you need not do anything, | |
| 1839 the templates shipped with roundup did not use HTML tags in messages for | |
| 1840 highlighting. | |
| 1841 | |
| 1842 | |
| 1843 .. index:: upgrading; 1.4.17 to 1.4.18 | |
| 1844 | |
| 1845 Migrating from 1.4.17 to 1.4.18 | |
| 1846 =============================== | |
| 1847 | |
| 1848 There was a bug in 1.4.17 where files were unlinked from issues if a | |
| 1849 mail without attachment was received via the mail interface. The | |
| 1850 following script will list likely issues being affected by the bug. | |
| 1851 The date in the script is the date of the 1.4.17 release. If you have | |
| 1852 installed 1.4.17 later than this date, you can change the date | |
| 1853 appropriately to your installation date. Run the script in the directory | |
| 1854 of your tracker:: | |
| 1855 | |
| 1856 #!/usr/bin/python | |
| 1857 import os | |
| 1858 from roundup import instance | |
| 1859 from roundup.date import Date | |
| 1860 dir = os.getcwd () | |
| 1861 tracker = instance.open (dir) | |
| 1862 db = tracker.open ('admin') | |
| 1863 # you may want to change this to your install date to find less candidates | |
| 1864 last_release = Date('2011-05-13') | |
| 1865 affected = {} | |
| 1866 for i in db.issue.getnodeids(): | |
| 1867 for j in db.issue.history(i): | |
| 1868 if i in affected: | |
| 1869 break | |
| 1870 if j[1] < last_release or j[3] != 'set' or 'files' not in j[4]: | |
| 1871 continue | |
| 1872 for op, p in j[4]['files']: | |
| 1873 if op == '-': | |
| 1874 affected [i] = 1 | |
| 1875 break | |
| 1876 print(', '.join(sorted(affected.keys()))) | |
| 1877 | |
| 1878 To find out which files where attached before you can look in the | |
| 1879 history of the affected issue. For fixing issues you can re-attach the | |
| 1880 files in question using the "set" command of roundup-admin, e.g., if the | |
| 1881 list of files attached to an issue should be files 5, 17, 23 for issue42 | |
| 1882 you will set this using | |
| 1883 | |
| 1884 roundup-admin -i /path/to/your/tracker set issue42 files=5,17,23 | |
| 1885 | |
| 1886 .. index:: upgrading; 1.4.x to 1.4.17 | |
| 1887 | |
| 1888 Migrating from 1.4.x to 1.4.17 | |
| 1889 ============================== | |
| 1890 | |
| 1891 There is a new config-option `migrate_passwords` in section `web` to | |
| 1892 auto-migrate passwords at web-login time to a more secure storage | |
| 1893 scheme. Default for the new option is "yes" so if you don't want that | |
| 1894 passwords are auto-migrated to a more secure password scheme on user | |
| 1895 login, set this to "no" before running your tracker(s) after the | |
| 1896 upgrade. | |
| 1897 | |
| 1898 The standalone roundup-server now defaults to listening on localhost (no | |
| 1899 longer on all network interfaces). This will not affect you if you're | |
| 1900 already using a configuration file for roundup-server. If you are using | |
| 1901 an empty setting for the `host` parameter in the config-file you should | |
| 1902 explicitly put 0.0.0.0 there as the use of an empty string to specify | |
| 1903 listening to all interfaces is deprecated and will go away in a future | |
| 1904 version. If you are starting the server without a configuration file | |
| 1905 and want to explicitly listen to all network interface, you should | |
| 1906 specify the -n option with the address `0.0.0.0`. | |
| 1907 | |
| 1908 .. _new search permissions for query in 1.4.17: | |
| 1909 | |
| 1910 Searching now requires either read-permission without a check method, or | |
| 1911 you will have to add a "Search" permission for a class or a list of | |
| 1912 properties for a class (if you want to allow searching). For the classic | |
| 1913 template (or other templates derived from it) you want to add the | |
| 1914 following lines to your `schema.py` file:: | |
| 1915 | |
| 1916 p = db.security.addPermission(name='Search', klass='query') | |
| 1917 db.security.addPermissionToRole('User', p) | |
| 1918 | |
| 1919 This is needed, because for the `query` class users may view only their | |
| 1920 own queries (or public queries). This is implemented with a `check` | |
| 1921 method, therefore the default search permissions will not allow | |
| 1922 searching and you'll have to add an explicit search permission. | |
| 1923 If you have modified your schema, you can check if you're missing any | |
| 1924 search permissions with the following script, run it in your tracker | |
| 1925 directory, it will list for each Class and Property the roles that may | |
| 1926 search for this property:: | |
| 1927 | |
| 1928 #!/usr/bin/python | |
| 1929 from __future__ import print_function | |
| 1930 import os | |
| 1931 from roundup import instance | |
| 1932 | |
| 1933 tracker = instance.open(os.getcwd ()) | |
| 1934 db = tracker.open('admin') | |
| 1935 | |
| 1936 for cl in sorted(db.getclasses()): | |
| 1937 print("Class:", cl) | |
| 1938 for p in sorted(db.getclass(cl).getprops(protected=True).keys()): | |
| 1939 print(" Property:", p) | |
| 1940 roles = [] | |
| 1941 for role in sorted(db.security.role.keys()): | |
| 1942 if db.security.roleHasSearchPermission(cl,p,role): | |
| 1943 roles.append(role) | |
| 1944 print(" roles may search:", ', '.join(roles)) | |
| 1945 | |
| 1946 | |
| 1947 .. index:: upgrading; 1.4.x to 1.4.12 | |
| 1948 | |
| 1949 Migrating from 1.4.x to 1.4.12 | |
| 1950 ============================== | |
| 1951 | |
| 1952 Item creation now checks the "Create" permission instead of the "Edit" | |
| 1953 permission for individual properties. If you have modified your tracker | |
| 1954 permissions from the default distribution, you should check that | |
| 1955 "Create" permissions exist for all properties you want users to be able | |
| 1956 to create. | |
| 1957 | |
| 1958 | |
| 1959 Fixing some potential security holes | |
| 1960 ------------------------------------ | |
| 1961 | |
| 1962 Enhanced checking was added to the user registration auditor. If you | |
| 1963 run a public tracker you should update your tracker's | |
| 1964 ``detectors/userauditor.py`` using the new code from | |
| 1965 ``share/roundup/templates/classic/detectors/userauditor.py``. In most | |
| 1966 cases you may just copy the file over, but if you've made changes to | |
| 1967 the auditor in your tracker then you'll need to manually integrate | |
| 1968 the new code. | |
| 1969 | |
| 1970 Some HTML templates were found to have formatting security problems: | |
| 1971 | |
| 1972 ``html/page.html``:: | |
| 1973 | |
| 1974 -tal:replace="request/user/username">username</span></b><br> | |
| 1975 +tal:replace="python:request.user.username.plain(escape=1)">username</span></b><br> | |
| 1976 | |
| 1977 ``html/_generic.help-list.html``:: | |
| 1978 | |
| 1979 -tal:content="structure python:item[prop]"></label> | |
| 1980 +tal:content="python:item[prop]"></label> | |
| 1981 | |
| 1982 The lines marked "+" should be added and lines marked "-" should be | |
| 1983 deleted (minus the "+"/"-" signs). | |
| 1984 | |
| 1985 | |
| 1986 Some HTML interface tweaks | |
| 1987 -------------------------- | |
| 1988 | |
| 1989 You may wish to copy the ``user_utils.js`` and ``style.css` files from the | |
| 1990 source distribution ``share/roundup/templates/classic/html/`` directory to the | |
| 1991 ``html`` directory of your trackers as it includes a small improvement. | |
| 1992 | |
| 1993 If you have made local changes to those files you'll need to manually work | |
| 1994 the differences in to your versions or ignore the changes. | |
| 1995 | |
| 1996 | |
| 1997 .. index:: upgrading; 1.4.x to 1.4.11 | |
| 1998 | |
| 1999 Migrating from 1.4.x to 1.4.11 | |
| 2000 ============================== | |
| 2001 | |
| 2002 Close potential security hole | |
| 2003 ----------------------------- | |
| 2004 | |
| 2005 If your tracker has untrusted users you should examine its ``schema.py`` | |
| 2006 file and look for the section granting the "Edit" permission to your users. | |
| 2007 This should look something like:: | |
| 2008 | |
| 2009 p = db.security.addPermission(name='Edit', klass='user', check=own_record, | |
| 2010 description="User is allowed to edit their own user details") | |
| 2011 | |
| 2012 and should be modified to restrict the list of properties they are allowed | |
| 2013 to edit by adding the ``properties=`` section like:: | |
| 2014 | |
| 2015 p = db.security.addPermission(name='Edit', klass='user', check=own_record, | |
| 2016 properties=('username', 'password', 'address', 'realname', 'phone', | |
| 2017 'organisation', 'alternate_addresses', 'queries', 'timezone'), | |
| 2018 description="User is allowed to edit their own user details") | |
| 2019 | |
| 2020 Most importantly the "roles" property should not be editable - thus not | |
| 2021 appear in that list of properties. | |
| 2022 | |
| 2023 | |
| 2024 Grant the "Register" permission to the Anonymous role | |
| 2025 ----------------------------------------------------- | |
| 2026 | |
| 2027 A separate "Register" permission has been introduced to allow | |
| 2028 anonymous users to register. This means you will need to add the | |
| 2029 following to your tracker's ``schema.py`` to add the permission and | |
| 2030 assign it to the Anonymous role (replacing any previously assigned | |
| 2031 "Create user" permission for the Anonymous role):: | |
| 2032 | |
| 2033 +db.security.addPermission(name='Register', klass='user', | |
| 2034 + description='User is allowed to register new user') | |
| 2035 | |
| 2036 # Assign the appropriate permissions to the anonymous user's Anonymous | |
| 2037 # Role. Choices here are: | |
| 2038 # - Allow anonymous users to register | |
| 2039 -db.security.addPermissionToRole('Anonymous', 'Create', 'user') | |
| 2040 +db.security.addPermissionToRole('Anonymous', 'Register', 'user') | |
| 2041 | |
| 2042 The lines marked "+" should be added and lines marked "-" should be | |
| 2043 deleted (minus the "+"/"-" signs). | |
| 2044 | |
| 2045 You should also modify the ``html/page.html`` template to change the | |
| 2046 permission tested there:: | |
| 2047 | |
| 2048 -tal:condition="python:request.user.hasPermission('Create', 'user')" | |
| 2049 +tal:condition="python:request.user.hasPermission('Register', 'user')" | |
| 2050 | |
| 2051 | |
| 2052 Generic class editor may now restore retired items | |
| 2053 -------------------------------------------------- | |
| 2054 | |
| 2055 The instructions for doing so won't be present in your tracker unless you copy | |
| 2056 the ``_generic.index.html`` template from the roundup distribution in | |
| 2057 ``share/roundup/templates/classic/html`` to your tracker's ``html`` directory. | |
| 2058 | |
| 2059 | |
| 2060 .. index:: upgrading; 1.4.x to 1.4.9 | |
| 2061 | |
| 2062 Migrating from 1.4.x to 1.4.9 | |
| 2063 ============================= | 2092 ============================= |
| 2064 | 2093 |
| 2065 Customized MailGW Class | 2094 See the `historical migration <upgrading-history.html>`_ document. |
| 2066 ----------------------- | 2095 |
| 2067 | 2096 .. _`security documentation`: security-history.html |
| 2068 If you have customized the MailGW class in your tracker: The new MailGW | |
| 2069 class opens the database for each message in the method handle_message | |
| 2070 (instance.open) instead of passing the opened database as a parameter to | |
| 2071 the MailGW constructor. The old handle_message has been renamed to | |
| 2072 _handle_message. The new method opens the database and wraps the call to | |
| 2073 the old method into a try/finally. | |
| 2074 | |
| 2075 Your customized MailGW class needs to mirror this behavior. | |
| 2076 | |
| 2077 Fix the "remove" button in issue files and messages lists | |
| 2078 --------------------------------------------------------- | |
| 2079 | |
| 2080 The "remove" button(s) in the issue messages list needs to be altered. Find | |
| 2081 the following in your tracker's ``html/issue.item.html`` template:: | |
| 2082 | |
| 2083 <td> | |
| 2084 <form style="padding:0" tal:condition="context/is_edit_ok" | |
| 2085 tal:attributes="action string:issue${context/id}"> | |
| 2086 <input type="hidden" name="@remove@files" tal:attributes="value file/id"> | |
| 2087 | |
| 2088 and add ``method="POST"`` as shown below:: | |
| 2089 | |
| 2090 <td> | |
| 2091 <form style="padding:0" method="POST" tal:condition="context/is_edit_ok" | |
| 2092 tal:attributes="action string:issue${context/id}"> | |
| 2093 <input type="hidden" name="@remove@files" tal:attributes="value file/id"> | |
| 2094 | |
| 2095 Then also find:: | |
| 2096 | |
| 2097 <td> | |
| 2098 <form style="padding:0" tal:condition="context/is_edit_ok" | |
| 2099 tal:attributes="action string:issue${context/id}"> | |
| 2100 <input type="hidden" name="@remove@messages" tal:attributes="value msg/id"> | |
| 2101 | |
| 2102 and add ``method="POST"`` as shown below:: | |
| 2103 | |
| 2104 <td> | |
| 2105 <form style="padding:0" method="POST" tal:condition="context/is_edit_ok" | |
| 2106 tal:attributes="action string:issue${context/id}"> | |
| 2107 <input type="hidden" name="@remove@messages" tal:attributes="value msg/id"> | |
| 2108 | |
| 2109 | |
| 2110 Fixing the "retire" button in user management list | |
| 2111 -------------------------------------------------- | |
| 2112 | |
| 2113 Some previous versions of this upgrading document missed ``method="POST"`` | |
| 2114 in the change to the "retire" link in the user management list | |
| 2115 in section `Migrating from 1.4.x to 1.4.7`_. | |
| 2116 Make sure the change is done as listed below in this document. | |
| 2117 | |
| 2118 | |
| 2119 .. index:: upgrading; 1.4.x to 1.4.7 | |
| 2120 | |
| 2121 Migrating from 1.4.x to 1.4.7 | |
| 2122 ============================= | |
| 2123 | |
| 2124 Several security issues were addressed in this release. Some aspects of your | |
| 2125 trackers may no longer function depending on your local customisations. Core | |
| 2126 functionality that will need to be modified: | |
| 2127 | |
| 2128 Grant the "retire" permission to users for their queries | |
| 2129 -------------------------------------------------------- | |
| 2130 | |
| 2131 Users will no longer be able to retire their own queries. To remedy this you | |
| 2132 will need to add the following to your tracker's ``schema.py`` just under the | |
| 2133 line that grants them permission to edit their own queries:: | |
| 2134 | |
| 2135 p = db.security.addPermission(name='Edit', klass='query', check=edit_query, | |
| 2136 description="User is allowed to edit their queries") | |
| 2137 db.security.addPermissionToRole('User', p) | |
| 2138 + p = db.security.addPermission(name='Retire', klass='query', check=edit_query, | |
| 2139 + description="User is allowed to retire their queries") | |
| 2140 + db.security.addPermissionToRole('User', p) | |
| 2141 p = db.security.addPermission(name='Create', klass='query', | |
| 2142 description="User is allowed to create queries") | |
| 2143 db.security.addPermissionToRole('User', p) | |
| 2144 | |
| 2145 The lines marked "+" should be added, minus the "+" sign. | |
| 2146 | |
| 2147 | |
| 2148 Fix the "retire" link in the users list for admin users | |
| 2149 ------------------------------------------------------- | |
| 2150 | |
| 2151 The "retire" link found in the file ``html/user.index.html``:: | |
| 2152 | |
| 2153 <td tal:condition="context/is_edit_ok"> | |
| 2154 <a tal:attributes="href string:user${user/id}?@action=retire&@template=index" | |
| 2155 i18n:translate="">retire</a> | |
| 2156 | |
| 2157 Should be replaced with:: | |
| 2158 | |
| 2159 <td tal:condition="context/is_retire_ok"> | |
| 2160 <form style="padding:0" method="POST" | |
| 2161 tal:attributes="action string:user${user/id}"> | |
| 2162 <input type="hidden" name="@template" value="index"> | |
| 2163 <input type="hidden" name="@action" value="retire"> | |
| 2164 <input type="submit" value="retire" i18n:attributes="value"> | |
| 2165 </form> | |
| 2166 | |
| 2167 | |
| 2168 Fix for Python 2.6+ users | |
| 2169 ------------------------- | |
| 2170 | |
| 2171 If you use Python 2.6 you should edit your tracker's | |
| 2172 ``detectors/nosyreaction.py`` file to change:: | |
| 2173 | |
| 2174 import sets | |
| 2175 | |
| 2176 at the top to:: | |
| 2177 | |
| 2178 from roundup.anypy.sets_ import set | |
| 2179 | |
| 2180 and then all instances of ``sets.Set()`` to ``set()`` in the later code. | |
| 2181 | |
| 2182 | |
| 2183 | |
| 2184 Trackers currently allowing HTML file uploading | |
| 2185 ----------------------------------------------- | |
| 2186 | |
| 2187 Trackers which wish to continue to allow uploading of HTML content against issues | |
| 2188 will need to set a new configuration variable in the ``[web]`` section of the | |
| 2189 tracker's ``config.ini`` file: | |
| 2190 | |
| 2191 # Setting this option enables Roundup to serve uploaded HTML | |
| 2192 # file content *as HTML*. This is a potential security risk | |
| 2193 # and is therefore disabled by default. Set to 'yes' if you | |
| 2194 # trust *all* users uploading content to your tracker. | |
| 2195 # Allowed values: yes, no | |
| 2196 # Default: no | |
| 2197 allow_html_file = no | |
| 2198 | |
| 2199 | |
| 2200 | |
| 2201 .. index:: upgrading; 1.4.2 to 1.4.3 | |
| 2202 | |
| 2203 Migrating from 1.4.2 to 1.4.3 | |
| 2204 ============================= | |
| 2205 | |
| 2206 If you are using the MySQL backend you will need to replace some indexes | |
| 2207 that may have been created by version 1.4.2. | |
| 2208 | |
| 2209 You should to access your MySQL database directly and remove any indexes | |
| 2210 with a name ending in "_key_retired_idx". You should then re-add them with | |
| 2211 the same spec except the key column name needs a size. So an index on | |
| 2212 "_user (__retired, _name)" should become "_user (__retired, _name(255))". | |
| 2213 | |
| 2214 | |
| 2215 .. index:: upgrading; 1.4.x to 1.4.2 | |
| 2216 | |
| 2217 Migrating from 1.4.x to 1.4.2 | |
| 2218 ============================= | |
| 2219 | |
| 2220 .. index:: roundup-admin; migrate subcommand | |
| 2221 | |
| 2222 You should run the "roundup-admin migrate" command for your tracker once | |
| 2223 you've installed the latest codebase. | |
| 2224 | |
| 2225 Do this before you use the web, command-line or mail interface and before | |
| 2226 any users access the tracker. | |
| 2227 | |
| 2228 This command will respond with either "Tracker updated" (if you've not | |
| 2229 previously run it on an RDBMS backend) or "No migration action required" | |
| 2230 (if you have run it, or have used another interface to the tracker, | |
| 2231 or are using anydbm). | |
| 2232 | |
| 2233 It's safe to run this even if it's not required, so just get into the | |
| 2234 habit. | |
| 2235 | |
| 2236 | |
| 2237 .. index:: upgrading; 1.3.3 to 1.4.0 | |
| 2238 | |
| 2239 Migrating from 1.3.3 to 1.4.0 | |
| 2240 ============================= | |
| 2241 | |
| 2242 Value of the "refwd_re" tracker configuration option (section "mailgw") | |
| 2243 is treated as UTF-8 string. In previous versions, it was ISO8859-1. | |
| 2244 | |
| 2245 If you have running trackers based on the classic template, please | |
| 2246 update the messagesummary detector as follows:: | |
| 2247 | |
| 2248 --- detectors/messagesummary.py 17 Apr 2003 03:26:38 -0000 1.1 | |
| 2249 +++ detectors/messagesummary.py 3 Apr 2007 06:47:21 -0000 1.2 | |
| 2250 @@ -8,7 +8,7 @@ | |
| 2251 if newvalues.has_key('summary') or not newvalues.has_key('content'): | |
| 2252 return | |
| 2253 | |
| 2254 - summary, content = parseContent(newvalues['content'], 1, 1) | |
| 2255 + summary, content = parseContent(newvalues['content'], config=db.config) | |
| 2256 newvalues['summary'] = summary | |
| 2257 | |
| 2258 In the latest version we have added some database indexes to the | |
| 2259 SQL-backends (mysql, postgresql, sqlite) for speeding up building the | |
| 2260 roundup-index for full-text search. We recommend that you create the | |
| 2261 following database indexes on the database by hand:: | |
| 2262 | |
| 2263 CREATE INDEX words_by_id ON __words (_textid); | |
| 2264 CREATE UNIQUE INDEX __textids_by_props ON __textids (_class, _itemid, _prop); | |
| 2265 | |
| 2266 .. index:: upgrading; 1.2.x to 1.3.0 | |
| 2267 | |
| 2268 Migrating from 1.2.x to 1.3.0 | |
| 2269 ============================= | |
| 2270 | |
| 2271 1.3.0 Web interface changes | |
| 2272 --------------------------- | |
| 2273 | |
| 2274 Some of the HTML files in the "classic" and "minimal" tracker templates | |
| 2275 were changed to fix some bugs and clean them up. You may wish to compare | |
| 2276 them to the HTML files in your tracker and apply any changes. | |
| 2277 | |
| 2278 | |
| 2279 .. index:: upgrading; 1.1.2 to 1.2.0 | |
| 2280 | |
| 2281 Migrating from 1.1.2 to 1.2.0 | |
| 2282 ============================= | |
| 2283 | |
| 2284 1.2.0 Sorting and grouping by multiple properties | |
| 2285 ------------------------------------------------- | |
| 2286 | |
| 2287 Starting with this version, sorting and grouping by multiple properties | |
| 2288 is possible. This means that request.sort and request.group are now | |
| 2289 lists. This is reflected in several places: | |
| 2290 | |
| 2291 * ``renderWith`` now has list attributes for ``sort`` and ``group``, | |
| 2292 where you previously wrote:: | |
| 2293 | |
| 2294 renderWith(... sort=('-', 'activity'), group=('+', 'priority') | |
| 2295 | |
| 2296 you write now:: | |
| 2297 | |
| 2298 renderWith(... sort=[('-', 'activity')], group=[('+', 'priority')] | |
| 2299 | |
| 2300 * In templates that permit to edit sorting/grouping, request.sort and | |
| 2301 request.group are (possibly empty) lists. You can now sort and group | |
| 2302 by multiple attributes. For an example, see the classic template. You | |
| 2303 may want search for the variable ``n_sort`` which can be set to the | |
| 2304 number of sort/group properties. | |
| 2305 | |
| 2306 * Templates that diplay new headlines for each group of items with | |
| 2307 equal group properties can now use the modified ``batch.propchanged`` | |
| 2308 method that can take several properties which are checked for | |
| 2309 changes. See the example in the classic template which makes use of | |
| 2310 ``batch.propchanged``. | |
| 2311 | |
| 2312 .. index:: upgrading; 1.1.0 to 1.1.1 | |
| 2313 | |
| 2314 Migrating from 1.1.0 to 1.1.1 | |
| 2315 ============================= | |
| 2316 | |
| 2317 1.1.1 "Clear this message" | |
| 2318 -------------------------- | |
| 2319 | |
| 2320 In 1.1.1, the standard ``page.html`` template includes a "clear this message" | |
| 2321 link in the green "ok" message bar that appears after a successful edit | |
| 2322 (or other) action. | |
| 2323 | |
| 2324 To include this in your tracker, change the following in your ``page.html`` | |
| 2325 template:: | |
| 2326 | |
| 2327 <p tal:condition="options/ok_message | nothing" class="ok-message" | |
| 2328 tal:repeat="m options/ok_message" tal:content="structure m">error</p> | |
| 2329 | |
| 2330 to be:: | |
| 2331 | |
| 2332 <p tal:condition="options/ok_message | nothing" class="ok-message"> | |
| 2333 <span tal:repeat="m options/ok_message" | |
| 2334 tal:content="structure string:$m <br/ > " /> | |
| 2335 <a class="form-small" tal:attributes="href request/current_url" | |
| 2336 i18n:translate="">clear this message</a> | |
| 2337 </p> | |
| 2338 | |
| 2339 | |
| 2340 If you implemented the "clear this message" in your 1.1.0 tracker, then you | |
| 2341 should change it to the above and it will work much better! | |
| 2342 | |
| 2343 | |
| 2344 .. index:: upgrading; 1.0.x to 1.1.0 | |
| 2345 | |
| 2346 Migrating from 1.0.x to 1.1.0 | |
| 2347 ============================= | |
| 2348 | |
| 2349 1.1 Login "For Session Only" | |
| 2350 ---------------------------- | |
| 2351 | |
| 2352 In 1.1, web logins are alive for the length of a session only, *unless* you | |
| 2353 add the following to the login form in your tracker's ``page.html``:: | |
| 2354 | |
| 2355 <input type="checkbox" name="remember" id="remember"> | |
| 2356 <label for="remember" i18n:translate="">Remember me?</label><br> | |
| 2357 | |
| 2358 See the classic tracker ``page.html`` if you're unsure where this should | |
| 2359 go. | |
| 2360 | |
| 2361 | |
| 2362 1.1 Query Display Name | |
| 2363 ---------------------- | |
| 2364 | |
| 2365 The ``dispname`` web variable has been renamed ``@dispname`` to avoid | |
| 2366 clashing with other variables of the same name. If you are using the | |
| 2367 display name feature, you will need to edit your tracker's ``page.html`` | |
| 2368 and ``issue.index.html`` pages to change ``dispname`` to ``@dispname``. | |
| 2369 | |
| 2370 A side-effect of this change is that the renderWith method used in the | |
| 2371 ``home.html`` page may now take a dispname argument. | |
| 2372 | |
| 2373 | |
| 2374 1.1 "Clear this message" | |
| 2375 ------------------------ | |
| 2376 | |
| 2377 In 1.1, the standard ``page.html`` template includes a "clear this message" | |
| 2378 link in the green "ok" message bar that appears after a successful edit | |
| 2379 (or other) action. | |
| 2380 | |
| 2381 To include this in your tracker, change the following in your ``page.html`` | |
| 2382 template:: | |
| 2383 | |
| 2384 <p tal:condition="options/ok_message | nothing" class="ok-message" | |
| 2385 tal:repeat="m options/ok_message" tal:content="structure m">error</p> | |
| 2386 | |
| 2387 to be:: | |
| 2388 | |
| 2389 <p tal:condition="options/ok_message | nothing" class="ok-message"> | |
| 2390 <span tal:repeat="m options/ok_message" | |
| 2391 tal:content="structure string:$m <br/ > " /> | |
| 2392 <a class="form-small" tal:attributes="href string:issue${context/id}" | |
| 2393 i18n:translate="">clear this message</a> | |
| 2394 </p> | |
| 2395 | |
| 2396 | |
| 2397 .. index:: upgrading; 0.8.x to 1.0 | |
| 2398 | |
| 2399 Migrating from 0.8.x to 1.0 | |
| 2400 =========================== | |
| 2401 | |
| 2402 1.0 New Query Permissions | |
| 2403 ------------------------- | |
| 2404 | |
| 2405 New permissions are defined for query editing and viewing. To include these | |
| 2406 in your tracker, you need to add these lines to your tracker's | |
| 2407 ``schema.py``:: | |
| 2408 | |
| 2409 # Users should be able to edit and view their own queries. They should also | |
| 2410 # be able to view any marked as not private. They should not be able to | |
| 2411 # edit others' queries, even if they're not private | |
| 2412 def view_query(db, userid, itemid): | |
| 2413 private_for = db.query.get(itemid, 'private_for') | |
| 2414 if not private_for: return True | |
| 2415 return userid == private_for | |
| 2416 def edit_query(db, userid, itemid): | |
| 2417 return userid == db.query.get(itemid, 'creator') | |
| 2418 p = db.security.addPermission(name='View', klass='query', check=view_query, | |
| 2419 description="User is allowed to view their own and public queries") | |
| 2420 db.security.addPermissionToRole('User', p) | |
| 2421 p = db.security.addPermission(name='Edit', klass='query', check=edit_query, | |
| 2422 description="User is allowed to edit their queries") | |
| 2423 db.security.addPermissionToRole('User', p) | |
| 2424 p = db.security.addPermission(name='Create', klass='query', | |
| 2425 description="User is allowed to create queries") | |
| 2426 db.security.addPermissionToRole('User', p) | |
| 2427 | |
| 2428 and then remove 'query' from the line:: | |
| 2429 | |
| 2430 # Assign the access and edit Permissions for issue, file and message | |
| 2431 # to regular users now | |
| 2432 for cl in 'issue', 'file', 'msg', 'query', 'keyword': | |
| 2433 | |
| 2434 so it looks like:: | |
| 2435 | |
| 2436 for cl in 'issue', 'file', 'msg', 'keyword': | |
| 2437 | |
| 2438 | |
| 2439 .. index:: upgrading; 0.8.0 to 0.8.3 | |
| 2440 | |
| 2441 Migrating from 0.8.0 to 0.8.3 | |
| 2442 ============================= | |
| 2443 | |
| 2444 0.8.3 Nosy Handling Changes | |
| 2445 --------------------------- | |
| 2446 | |
| 2447 A change was made to fix a bug in the ``nosyreaction.py`` standard | |
| 2448 detector. To incorporate this fix in your trackers, you will need to copy | |
| 2449 the ``nosyreaction.py`` file from the ``templates/classic/detectors`` | |
| 2450 directory of the source to your tracker's ``templates`` directory. | |
| 2451 | |
| 2452 If you have modified the ``nosyreaction.py`` file from the standard | |
| 2453 version, you will need to roll your changes into the new file. | |
| 2454 | |
| 2455 | |
| 2456 .. index:: upgrading; 0.7.1 to 0.8.0 | |
| 2457 | |
| 2458 Migrating from 0.7.1 to 0.8.0 | |
| 2459 ============================= | |
| 2460 | |
| 2461 You *must* fully uninstall previous Roundup version before installing | |
| 2462 Roundup 0.8.0. If you don't do that, ``roundup-admin install`` | |
| 2463 command may fail to function properly. | |
| 2464 | |
| 2465 0.8.0 Backend changes | |
| 2466 --------------------- | |
| 2467 | |
| 2468 Backends 'bsddb' and 'bsddb3' are removed. If you are using one of these, | |
| 2469 you *must* migrate to another backend before upgrading. | |
| 2470 | |
| 2471 | |
| 2472 0.8.0 API changes | |
| 2473 ----------------- | |
| 2474 | |
| 2475 Class.safeget() was removed from the API. Test your item ids before calling | |
| 2476 Class.get() instead. | |
| 2477 | |
| 2478 | |
| 2479 0.8.0 New tracker layout | |
| 2480 ------------------------ | |
| 2481 | |
| 2482 The ``config.py`` file has been replaced by ``config.ini``. You may use the | |
| 2483 roundup-admin command "genconfig" to generate a new config file:: | |
| 2484 | |
| 2485 roundup-admin genconfig <tracker home>/config.ini | |
| 2486 | |
| 2487 and modify the values therein based on the contents of your old config.py. | |
| 2488 In most cases, the names of the config variables are the same. | |
| 2489 | |
| 2490 The ``select_db.py`` file has been replaced by a file in the ``db`` | |
| 2491 directory called ``backend_name``. As you might guess, this file contains | |
| 2492 just the name of the backend. To figure what the contents of yours should | |
| 2493 be, use the following table: | |
| 2494 | |
| 2495 ================================ ========================= | |
| 2496 ``select_db.py`` contents ``backend_name`` contents | |
| 2497 ================================ ========================= | |
| 2498 from back_anydbm import ... anydbm | |
| 2499 from back_metakit import ... metakit | |
| 2500 from back_sqlite import ... sqlite | |
| 2501 from back_mysql import ... mysql | |
| 2502 from back_postgresql import ... postgresql | |
| 2503 ================================ ========================= | |
| 2504 | |
| 2505 The ``dbinit.py`` file has been split into two new files, | |
| 2506 ``initial_data.py`` and ``schema.py``. The contents of this file are: | |
| 2507 | |
| 2508 ``initial_data.py`` | |
| 2509 You don't need one of these as your tracker is already initialised. | |
| 2510 | |
| 2511 ``schema.py`` | |
| 2512 Copy the body of the ``def open(name=None)`` function from your old | |
| 2513 tracker's ``dbinit.py`` file to this file. As the lines you're copying | |
| 2514 aren't part of a function definition anymore, one level of indentation | |
| 2515 needs to be removed (remove only the leading four spaces on each | |
| 2516 line). | |
| 2517 | |
| 2518 The first few lines -- those starting with ``from roundup.hyperdb | |
| 2519 import ...`` and the ``db = Database(config, name)`` line -- don't | |
| 2520 need to be copied. Neither do the last few lines -- those starting | |
| 2521 with ``import detectors``, down to ``return db`` inclusive. | |
| 2522 | |
| 2523 You may remove the ``__init__.py`` module from the "detectors" directory as | |
| 2524 it is no longer used. | |
| 2525 | |
| 2526 There's a new way to write extension code for Roundup. If you have code in | |
| 2527 an ``interfaces.py`` file you should move it. See the `customisation | |
| 2528 documentation`_ for information about how extensions are now written. | |
| 2529 Note that some older trackers may use ``interfaces.py`` to customise the | |
| 2530 mail gateway behaviour. You will need to keep your ``interfaces.py`` file | |
| 2531 if this is the case. | |
| 2532 | |
| 2533 | |
| 2534 0.8.0 Permissions Changes | |
| 2535 ------------------------- | |
| 2536 | |
| 2537 The creation of a new item in the user interfaces is now controlled by the | |
| 2538 "Create" Permission. You will need to add an assignment of this Permission | |
| 2539 to your users who are allowed to create items. The most common form of this | |
| 2540 is the following in your ``schema.py`` added just under the current | |
| 2541 assignation of the Edit Permission:: | |
| 2542 | |
| 2543 for cl in 'issue', 'file', 'msg', 'query', 'keyword': | |
| 2544 p = db.security.getPermission('Create', cl) | |
| 2545 db.security.addPermissionToRole('User', p) | |
| 2546 | |
| 2547 You will need to explicitly let anonymous users access the web interface so | |
| 2548 that regular users are able to see the login form. Note that almost all | |
| 2549 trackers will need this Permission. The only situation where it's not | |
| 2550 required is in a tracker that uses an HTTP Basic Authenticated front-end. | |
| 2551 It's enabled by adding to your ``schema.py``:: | |
| 2552 | |
| 2553 p = db.security.getPermission('Web Access') | |
| 2554 db.security.addPermissionToRole('Anonymous', p) | |
| 2555 | |
| 2556 Finally, you will need to enable permission for your users to edit their | |
| 2557 own details by adding the following to ``schema.py``:: | |
| 2558 | |
| 2559 # Users should be able to edit their own details. Note that this | |
| 2560 # permission is limited to only the situation where the Viewed or | |
| 2561 # Edited item is their own. | |
| 2562 def own_record(db, userid, itemid): | |
| 2563 '''Determine whether the userid matches the item being accessed.''' | |
| 2564 return userid == itemid | |
| 2565 p = db.security.addPermission(name='View', klass='user', check=own_record, | |
| 2566 description="User is allowed to view their own user details") | |
| 2567 p = db.security.addPermission(name='Edit', klass='user', check=own_record, | |
| 2568 description="User is allowed to edit their own user details") | |
| 2569 db.security.addPermissionToRole('User', p) | |
| 2570 | |
| 2571 | |
| 2572 0.8.0 Use of TemplatingUtils | |
| 2573 ---------------------------- | |
| 2574 | |
| 2575 If you used custom python functions in TemplatingUtils, they must | |
| 2576 be moved from interfaces.py to a new file in the ``extensions`` directory. | |
| 2577 | |
| 2578 Each Function that should be available through TAL needs to be defined | |
| 2579 as a toplevel function in the newly created file. Furthermore you | |
| 2580 add an inititialization function, that registers the functions with the | |
| 2581 tracker. | |
| 2582 | |
| 2583 If you find this too tedious, donfu wrote an automatic init function that | |
| 2584 takes an existing TemplatingUtils class, and registers all class methods | |
| 2585 that do not start with an underscore. The following hack should be placed | |
| 2586 in the ``extensions`` directory alongside other extensions:: | |
| 2587 | |
| 2588 class TemplatingUtils: | |
| 2589 # copy from interfaces.py | |
| 2590 | |
| 2591 def init(tracker): | |
| 2592 util = TemplatingUtils() | |
| 2593 | |
| 2594 def setClient(tu): | |
| 2595 util.client = tu.client | |
| 2596 return util | |
| 2597 | |
| 2598 def execUtil(name): | |
| 2599 return lambda tu, *args, **kwargs: \ | |
| 2600 getattr(setClient(tu), name)(*args, **kwargs) | |
| 2601 | |
| 2602 for name in dir(util): | |
| 2603 if callable(getattr(util, name)) and not name.startswith('_'): | |
| 2604 tracker.registerUtil(name, execUtil(name)) | |
| 2605 | |
| 2606 | |
| 2607 0.8.0 Logging Configuration | |
| 2608 --------------------------- | |
| 2609 | |
| 2610 See the `administration guide`_ for information about configuring the new | |
| 2611 logging implemented in 0.8.0. | |
| 2612 | |
| 2613 | |
| 2614 .. index:: upgrading; 0.7.2 to 0.7.3 | |
| 2615 | |
| 2616 Migrating from 0.7.2 to 0.7.3 | |
| 2617 ============================= | |
| 2618 | |
| 2619 0.7.3 Configuration | |
| 2620 ------------------- | |
| 2621 | |
| 2622 If you choose, you may specify the directory from which static files are | |
| 2623 served (those which use the URL component ``@@file``). Currently the | |
| 2624 directory defaults to the ``TEMPLATES`` configuration variable. You may | |
| 2625 define a new variable, ``STATIC_FILES`` which overrides this value for | |
| 2626 static files. | |
| 2627 | |
| 2628 | |
| 2629 .. index:: upgrading; 0.7.0 to 0.7.2 | |
| 2630 | |
| 2631 Migrating from 0.7.0 to 0.7.2 | |
| 2632 ============================= | |
| 2633 | |
| 2634 0.7.2 DEFAULT_TIMEZONE is now required | |
| 2635 -------------------------------------- | |
| 2636 | |
| 2637 The DEFAULT_TIMEZONE configuration variable is now required. Add the | |
| 2638 following to your tracker's ``config.py`` file:: | |
| 2639 | |
| 2640 # You may specify a different default timezone, for use when users do not | |
| 2641 # choose their own in their settings. | |
| 2642 DEFAULT_TIMEZONE = 0 # specify as numeric hour offest | |
| 2643 | |
| 2644 .. index:: upgrading; 0.7.0 to 0.7.1 | |
| 2645 | |
| 2646 Migrating from 0.7.0 to 0.7.1 | |
| 2647 ============================= | |
| 2648 | |
| 2649 0.7.1 Permission assignments | |
| 2650 ---------------------------- | |
| 2651 | |
| 2652 If you allow anonymous access to your tracker, you might need to assign | |
| 2653 some additional View (or Edit if your tracker is that open) permissions | |
| 2654 to the "anonymous" user. To do so, find the code in your ``dbinit.py`` that | |
| 2655 says:: | |
| 2656 | |
| 2657 for cl in 'issue', 'file', 'msg', 'query', 'keyword': | |
| 2658 p = db.security.getPermission('View', cl) | |
| 2659 db.security.addPermissionToRole('User', p) | |
| 2660 p = db.security.getPermission('Edit', cl) | |
| 2661 db.security.addPermissionToRole('User', p) | |
| 2662 for cl in 'priority', 'status': | |
| 2663 p = db.security.getPermission('View', cl) | |
| 2664 db.security.addPermissionToRole('User', p) | |
| 2665 | |
| 2666 Add add a line:: | |
| 2667 | |
| 2668 db.security.addPermissionToRole('Anonymous', p) | |
| 2669 | |
| 2670 next to the existing ``'User'`` lines for the Permissions you wish to | |
| 2671 assign to the anonymous user. | |
| 2672 | |
| 2673 | |
| 2674 .. index:: upgrading; versions earlier than 0.7 | |
| 2675 | |
| 2676 Migrating from 0.6 to 0.7 | |
| 2677 ========================= | |
| 2678 | |
| 2679 0.7.0 Permission assignments | |
| 2680 ---------------------------- | |
| 2681 | |
| 2682 Due to a change in the rendering of web widgets, permissions are now | |
| 2683 checked on Classes where they previously weren't (this is a good thing). | |
| 2684 | |
| 2685 You will need to add some additional Permission assignments for your | |
| 2686 regular users, or some displays will break. After the following in your | |
| 2687 tracker's ``dbinit.py``:: | |
| 2688 | |
| 2689 # Assign the access and edit Permissions for issue, file and message | |
| 2690 # to regular users now | |
| 2691 for cl in 'issue', 'file', 'msg', 'query', 'keyword': | |
| 2692 p = db.security.getPermission('View', cl) | |
| 2693 db.security.addPermissionToRole('User', p) | |
| 2694 p = db.security.getPermission('Edit', cl) | |
| 2695 db.security.addPermissionToRole('User', p) | |
| 2696 | |
| 2697 add:: | |
| 2698 | |
| 2699 for cl in 'priority', 'status': | |
| 2700 p = db.security.getPermission('View', cl) | |
| 2701 db.security.addPermissionToRole('User', p) | |
| 2702 | |
| 2703 | |
| 2704 0.7.0 Getting the current user id | |
| 2705 --------------------------------- | |
| 2706 | |
| 2707 The Database.curuserid attribute has been removed. | |
| 2708 | |
| 2709 Any code referencing this attribute should be replaced with a | |
| 2710 call to Database.getuid(). | |
| 2711 | |
| 2712 | |
| 2713 0.7.0 ZRoundup changes | |
| 2714 ---------------------- | |
| 2715 | |
| 2716 The templates in your tracker's html directory will need updating if you | |
| 2717 wish to use ZRoundup. If you've not modified those files (or some of them), | |
| 2718 you may just copy the new versions from the Roundup source in the | |
| 2719 templates/classic/html directory. | |
| 2720 | |
| 2721 If you have modified the html files, then you'll need to manually edit them | |
| 2722 to change all occurances of special form variables from using the colon ":" | |
| 2723 special character to the at "@" special character. That is, variables such | |
| 2724 as:: | |
| 2725 | |
| 2726 :action :required :template :remove:messages ... | |
| 2727 | |
| 2728 should become:: | |
| 2729 | |
| 2730 @action @required @template @remove@messages ... | |
| 2731 | |
| 2732 Note that ``tal:`` statements are unaffected. So are TAL expression type | |
| 2733 prefixes such as ``python:`` and ``string:``. Please ask on the | |
| 2734 roundup-users mailing list for help if you're unsure. | |
| 2735 | |
| 2736 | |
| 2737 0.7.0 Edit collision detection | |
| 2738 ------------------------------ | |
| 2739 | |
| 2740 Roundup now detects collisions with editing in the web interface (that is, | |
| 2741 two people editing the same item at the same time). | |
| 2742 | |
| 2743 You must copy the ``_generic.collision.html`` file from Roundup source in | |
| 2744 the ``templates/classic/html`` directory. to your tracker's ``html`` | |
| 2745 directory. | |
| 2746 | |
| 2747 | |
| 2748 Migrating from 0.6.x to 0.6.3 | |
| 2749 ============================= | |
| 2750 | |
| 2751 0.6.3 Configuration | |
| 2752 ------------------- | |
| 2753 | |
| 2754 You will need to copy the file:: | |
| 2755 | |
| 2756 templates/classic/detectors/__init__.py | |
| 2757 | |
| 2758 to your tracker's ``detectors`` directory, replacing the one already there. | |
| 2759 This fixes a couple of bugs in that file. | |
| 2760 | |
| 2761 | |
| 2762 | |
| 2763 Migrating from 0.5 to 0.6 | |
| 2764 ========================= | |
| 2765 | |
| 2766 | |
| 2767 0.6.0 Configuration | |
| 2768 ------------------- | |
| 2769 | |
| 2770 Introduced EMAIL_FROM_TAG config variable. This value is inserted into | |
| 2771 the From: line of nosy email. If the sending user is "Foo Bar", the | |
| 2772 From: line is usually:: | |
| 2773 | |
| 2774 "Foo Bar" <issue_tracker@tracker.example> | |
| 2775 | |
| 2776 the EMAIL_FROM_TAG goes inside the "Foo Bar" quotes like so:: | |
| 2777 | |
| 2778 "Foo Bar EMAIL_FROM_TAG" <issue_tracker@tracker.example> | |
| 2779 | |
| 2780 I've altered the mechanism in the detectors __init__.py module so that it | |
| 2781 doesn't cross-import detectors from other trackers (if you run more than one | |
| 2782 in a single roundup-server). This change means that you'll need to copy the | |
| 2783 __init__.py from roundup/templates/classic/detectors/__init__.py to your | |
| 2784 <tracker home>/detectors/__init__.py. Don't worry, the "classic" __init__ is a | |
| 2785 one-size-fits-all, so it'll work even if you've added/removed detectors. | |
| 2786 | |
| 2787 0.6.0 Templating changes | |
| 2788 ------------------------ | |
| 2789 | |
| 2790 The ``user.item`` template (in the tracker home "templates" directory) | |
| 2791 needs to have the following hidden variable added to its form (between the | |
| 2792 ``<form...>`` and ``</form>`` tags:: | |
| 2793 | |
| 2794 <input type="hidden" name=":template" value="item"> | |
| 2795 | |
| 2796 | |
| 2797 0.6.0 Form handling changes | |
| 2798 --------------------------- | |
| 2799 | |
| 2800 Roundup's form handling capabilities have been significantly expanded. This | |
| 2801 should not affect users of 0.5 installations - but if you find you're | |
| 2802 getting errors from form submissions, please ask for help on the Roundup | |
| 2803 users mailing list: | |
| 2804 | |
| 2805 https://sourceforge.net/projects/roundup/lists/roundup-users | |
| 2806 | |
| 2807 See the customisation doc section on `Form Values`__ for documentation of the | |
| 2808 new form variables possible. | |
| 2809 | |
| 2810 __ customizing.html#form-values | |
| 2811 | |
| 2812 | |
| 2813 0.6.0 Multilingual character set support | |
| 2814 ---------------------------------------- | |
| 2815 | |
| 2816 Added internationalization support. This is done via encoding all data | |
| 2817 stored in roundup database to utf-8 (unicode encoding). To support utf-8 in | |
| 2818 web interface you should add the folowing line to your tracker's html/page | |
| 2819 and html/_generic.help files inside <head> tag:: | |
| 2820 | |
| 2821 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
| 2822 | |
| 2823 Since latin characters in utf-8 have the same codes as in ASCII table, this | |
| 2824 modification is optional for users who use only plain latin characters. | |
| 2825 | |
| 2826 After this modification, you will be able to see and enter any world | |
| 2827 character via web interface. Data received via mail interface also converted | |
| 2828 to utf-8, however only new messages will be converted. If your roundup | |
| 2829 database contains some of non-ASCII characters in one of 8-bit encoding, | |
| 2830 they will not be visible in new unicode environment. Some of such data (e.g. | |
| 2831 user names, keywords, etc) can be edited by administrator, the others | |
| 2832 (e.g. messages' contents) is not editable via web interface. Currently there | |
| 2833 is no tool for converting such data, the only solution is to close | |
| 2834 appropriate old issues and create new ones with the same content. | |
| 2835 | |
| 2836 | |
| 2837 0.6.0 User timezone support | |
| 2838 --------------------------- | |
| 2839 | |
| 2840 From version 0.6.0 roundup supports displaying of Date data in user' local | |
| 2841 timezone if he/she has provided timezone information. To make it possible | |
| 2842 some modification to tracker's schema and HTML templates are required. | |
| 2843 First you must add string property 'timezone' to user class in dbinit.py | |
| 2844 like this:: | |
| 2845 | |
| 2846 user = Class(db, "user", | |
| 2847 username=String(), password=Password(), | |
| 2848 address=String(), realname=String(), | |
| 2849 phone=String(), organisation=String(), | |
| 2850 alternate_addresses=String(), | |
| 2851 queries=Multilink('query'), roles=String(), | |
| 2852 timezone=String()) | |
| 2853 | |
| 2854 And second - html interface. Add following lines to | |
| 2855 $TRACKER_HOME/html/user.item template:: | |
| 2856 | |
| 2857 <tr> | |
| 2858 <th>Timezone</th> | |
| 2859 <td tal:content="structure context/timezone/field">timezone</td> | |
| 2860 </tr> | |
| 2861 | |
| 2862 After that all users should be able to provide their timezone information. | |
| 2863 Timezone should be a positive or negative integer - offset from GMT. | |
| 2864 | |
| 2865 After providing timezone, roundup will show all dates values, found in web | |
| 2866 and mail interfaces in local time. It will also accept any Date info in | |
| 2867 local time, convert and store it in GMT. | |
| 2868 | |
| 2869 | |
| 2870 0.6.0 Search page structure | |
| 2871 --------------------------- | |
| 2872 | |
| 2873 In order to accomodate query editing the search page has been restructured. If | |
| 2874 you want to provide your users with query editing, you should update your | |
| 2875 search page using the macros detailed in the customisation doc section | |
| 2876 `Searching on categories`__. | |
| 2877 | |
| 2878 __ customizing.html#searching-on-categories | |
| 2879 | |
| 2880 Also, the url field in the query class no longer starts with a '?'. You'll need | |
| 2881 to remove this question mark from the url field to support queries. There's | |
| 2882 a script in the "tools" directory called ``migrate-queries.py`` that should | |
| 2883 automatically change any existing queries for you. As always, make a backup | |
| 2884 of your database before running such a script. | |
| 2885 | |
| 2886 | |
| 2887 0.6.0 Notes for metakit backend users | |
| 2888 ------------------------------------- | |
| 2889 | |
| 2890 Roundup 0.6.0 introduced searching on ranges of dates and intervals. To | |
| 2891 support it, some modifications to interval storing routine were made. So if | |
| 2892 your tracker uses metakit backend and your db schema contains intervals | |
| 2893 property, searches on that property will not be accurate for db items that | |
| 2894 was stored before roundup' upgrade. However all new records should be | |
| 2895 searchable on intervals. | |
| 2896 | |
| 2897 It is possible to convert your database to new format: you can export and | |
| 2898 import back all your data (consult "Migrating backends" in "Maintenance" | |
| 2899 documentation). After this operation all your interval properties should | |
| 2900 become searchable. | |
| 2901 | |
| 2902 Users of backends others than metakit should not worry about this issue. | |
| 2903 | |
| 2904 | |
| 2905 Migrating from 0.4.x to 0.5.0 | |
| 2906 ============================= | |
| 2907 | |
| 2908 This has been a fairly major revision of Roundup: | |
| 2909 | |
| 2910 1. Brand new, much more powerful, flexible, tasty and nutritious templating. | |
| 2911 Unfortunately, this means all your current templates are useless. Hopefully | |
| 2912 the new documentation and examples will be enough to help you make the | |
| 2913 transition. Please don't hesitate to ask on roundup-users for help (or | |
| 2914 complete conversions if you're completely stuck)! | |
| 2915 2. The database backed got a lot more flexible, allowing Metakit and SQL | |
| 2916 databases! The only decent SQL database implemented at present is sqlite, | |
| 2917 but others shouldn't be a whole lot more work. | |
| 2918 3. A brand new, highly flexible and much more robust security system including | |
| 2919 a system of Permissions, Roles and Role assignments to users. You may now | |
| 2920 define your own Permissions that may be checked in CGI transactions. | |
| 2921 4. Journalling has been made less storage-hungry, so has been turned on | |
| 2922 by default *except* for author, recipient and nosy link/unlink events. You | |
| 2923 are advised to turn it off in your trackers too. | |
| 2924 5. We've changed the terminology from "instance" to "tracker", to ease the | |
| 2925 learning curve/impact for new users. | |
| 2926 6. Because of the above changes, the tracker configuration has seen some | |
| 2927 major changes. See below for the details. | |
| 2928 | |
| 2929 Please, **back up your database** before you start the migration process. This | |
| 2930 is as simple as copying the "db" directory and all its contents from your | |
| 2931 tracker to somewhere safe. | |
| 2932 | |
| 2933 | |
| 2934 0.5.0 Configuration | |
| 2935 ------------------- | |
| 2936 | |
| 2937 First up, rename your ``instance_config.py`` file to just ``config.py``. | |
| 2938 | |
| 2939 Then edit your tracker's ``__init__.py`` module. It'll currently look | |
| 2940 like this:: | |
| 2941 | |
| 2942 from instance_config import * | |
| 2943 try: | |
| 2944 from dbinit import * | |
| 2945 except ImportError: | |
| 2946 pass # in installdir (probably :) | |
| 2947 from interfaces import * | |
| 2948 | |
| 2949 and it needs to be:: | |
| 2950 | |
| 2951 import config | |
| 2952 from dbinit import open, init | |
| 2953 from interfaces import Client, MailGW | |
| 2954 | |
| 2955 Due to the new templating having a top-level ``page`` that defines links for | |
| 2956 searching, indexes, adding items etc, the following variables are no longer | |
| 2957 used: | |
| 2958 | |
| 2959 - HEADER_INDEX_LINKS | |
| 2960 - HEADER_ADD_LINKS | |
| 2961 - HEADER_SEARCH_LINKS | |
| 2962 - SEARCH_FILTERS | |
| 2963 - DEFAULT_INDEX | |
| 2964 - UNASSIGNED_INDEX | |
| 2965 - USER_INDEX | |
| 2966 - ISSUE_FILTER | |
| 2967 | |
| 2968 The new security implementation will require additions to the dbinit module, | |
| 2969 but also removes the need for the following tracker config variables: | |
| 2970 | |
| 2971 - ANONYMOUS_ACCESS | |
| 2972 - ANONYMOUS_REGISTER | |
| 2973 | |
| 2974 but requires two new variables which define the Roles assigned to users who | |
| 2975 register through the web and e-mail interfaces: | |
| 2976 | |
| 2977 - NEW_WEB_USER_ROLES | |
| 2978 - NEW_EMAIL_USER_ROLES | |
| 2979 | |
| 2980 in both cases, 'User' is a good initial setting. To emulate | |
| 2981 ``ANONYMOUS_ACCESS='deny'``, remove all "View" Permissions from the | |
| 2982 "Anonymous" Role. To emulate ``ANONYMOUS_REGISTER='deny'``, remove the "Web | |
| 2983 Registration" and/or the "Email Registration" Permission from the "Anonymous" | |
| 2984 Role. See the section on customising security in the `customisation | |
| 2985 documentation`_ for more information. | |
| 2986 | |
| 2987 Finally, the following config variables have been renamed to make more sense: | |
| 2988 | |
| 2989 - INSTANCE_HOME -> TRACKER_HOME | |
| 2990 - INSTANCE_NAME -> TRACKER_NAME | |
| 2991 - ISSUE_TRACKER_WEB -> TRACKER_WEB | |
| 2992 - ISSUE_TRACKER_EMAIL -> TRACKER_EMAIL | |
| 2993 | |
| 2994 | |
| 2995 0.5.0 Schema Specification | |
| 2996 -------------------------- | |
| 2997 | |
| 2998 0.5.0 Database backend changes | |
| 2999 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 3000 | |
| 3001 Your select_db module in your tracker has changed a fair bit. Where it used | |
| 3002 to contain:: | |
| 3003 | |
| 3004 # WARNING: DO NOT EDIT THIS FILE!!! | |
| 3005 from roundup.backends.back_anydbm import Database | |
| 3006 | |
| 3007 it must now contain:: | |
| 3008 | |
| 3009 # WARNING: DO NOT EDIT THIS FILE!!! | |
| 3010 from roundup.backends.back_anydbm import Database, Class, FileClass, IssueClass | |
| 3011 | |
| 3012 Yes, I realise the irony of the "DO NOT EDIT THIS FILE" statement :) | |
| 3013 Note the addition of the Class, FileClass, IssueClass imports. These are very | |
| 3014 important, as they're going to make the next change work too. You now need to | |
| 3015 modify the top of the dbinit module in your tracker from:: | |
| 3016 | |
| 3017 import instance_config | |
| 3018 from roundup import roundupdb | |
| 3019 from select_db import Database | |
| 3020 | |
| 3021 from roundup.roundupdb import Class, FileClass | |
| 3022 | |
| 3023 class Database(roundupdb.Database, select_db.Database): | |
| 3024 ''' Creates a hybrid database from: | |
| 3025 . the selected database back-end from select_db | |
| 3026 . the roundup extensions from roundupdb | |
| 3027 ''' | |
| 3028 pass | |
| 3029 | |
| 3030 class IssueClass(roundupdb.IssueClass): | |
| 3031 ''' issues need the email information | |
| 3032 ''' | |
| 3033 pass | |
| 3034 | |
| 3035 to:: | |
| 3036 | |
| 3037 import config | |
| 3038 from select_db import Database, Class, FileClass, IssueClass | |
| 3039 | |
| 3040 Yes, remove the Database and IssueClass definitions and those other imports. | |
| 3041 They're not needed any more! | |
| 3042 | |
| 3043 Look for places in dbinit.py where ``instance_config`` is used too, and | |
| 3044 rename them ``config``. | |
| 3045 | |
| 3046 | |
| 3047 0.5.0 Journalling changes | |
| 3048 ~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 3049 | |
| 3050 Journalling has been optimised for storage. Journalling of links has been | |
| 3051 turned back on by default. If your tracker has a large user base, you may wish | |
| 3052 to turn off journalling of nosy list, message author and message recipient | |
| 3053 link and unlink events. You do this by adding ``do_journal='no'`` to the Class | |
| 3054 initialisation in your dbinit. For example, your *msg* class initialisation | |
| 3055 probably looks like this:: | |
| 3056 | |
| 3057 msg = FileClass(db, "msg", | |
| 3058 author=Link("user"), recipients=Multilink("user"), | |
| 3059 date=Date(), summary=String(), | |
| 3060 files=Multilink("file"), | |
| 3061 messageid=String(), inreplyto=String()) | |
| 3062 | |
| 3063 to turn off journalling of author and recipient link events, add | |
| 3064 ``do_journal='no'`` to the ``author=Link("user")`` part of the statement, | |
| 3065 like so:: | |
| 3066 | |
| 3067 msg = FileClass(db, "msg", | |
| 3068 author=Link("user", do_journal='no'), | |
| 3069 recipients=Multilink("user", do_journal='no'), | |
| 3070 date=Date(), summary=String(), | |
| 3071 files=Multilink("file"), | |
| 3072 messageid=String(), inreplyto=String()) | |
| 3073 | |
| 3074 Nosy list link event journalling is actually turned off by default now. If you | |
| 3075 want to turn it on, change to your issue class' nosy list, change its | |
| 3076 definition from:: | |
| 3077 | |
| 3078 issue = IssueClass(db, "issue", | |
| 3079 assignedto=Link("user"), topic=Multilink("keyword"), | |
| 3080 priority=Link("priority"), status=Link("status")) | |
| 3081 | |
| 3082 to:: | |
| 3083 | |
| 3084 issue = IssueClass(db, "issue", nosy=Multilink("user", do_journal='yes'), | |
| 3085 assignedto=Link("user"), topic=Multilink("keyword"), | |
| 3086 priority=Link("priority"), status=Link("status")) | |
| 3087 | |
| 3088 noting that your definition of the nosy Multilink will override the normal one. | |
| 3089 | |
| 3090 | |
| 3091 0.5.0 User schema changes | |
| 3092 ~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 3093 | |
| 3094 Users have two more properties, "queries" and "roles". You'll have something | |
| 3095 like this in your dbinit module now:: | |
| 3096 | |
| 3097 user = Class(db, "user", | |
| 3098 username=String(), password=Password(), | |
| 3099 address=String(), realname=String(), | |
| 3100 phone=String(), organisation=String(), | |
| 3101 alternate_addresses=String()) | |
| 3102 user.setkey("username") | |
| 3103 | |
| 3104 and you'll need to add the new properties and the new "query" class to it | |
| 3105 like so:: | |
| 3106 | |
| 3107 query = Class(db, "query", | |
| 3108 klass=String(), name=String(), | |
| 3109 url=String()) | |
| 3110 query.setkey("name") | |
| 3111 | |
| 3112 # Note: roles is a comma-separated string of Role names | |
| 3113 user = Class(db, "user", | |
| 3114 username=String(), password=Password(), | |
| 3115 address=String(), realname=String(), | |
| 3116 phone=String(), organisation=String(), | |
| 3117 alternate_addresses=String(), | |
| 3118 queries=Multilink('query'), roles=String()) | |
| 3119 user.setkey("username") | |
| 3120 | |
| 3121 The "queries" property is used to store off the user's favourite database | |
| 3122 queries. The "roles" property is explained below in `0.5.0 Security | |
| 3123 Settings`_. | |
| 3124 | |
| 3125 | |
| 3126 0.5.0 Security Settings | |
| 3127 ~~~~~~~~~~~~~~~~~~~~~~~ | |
| 3128 | |
| 3129 See the `security documentation`_ for an explanation of how the new security | |
| 3130 system works. In a nutshell though, the security is handled as a four step | |
| 3131 process: | |
| 3132 | |
| 3133 1. Permissions are defined as having a name and optionally a hyperdb class | |
| 3134 they're specific to, | |
| 3135 2. Roles are defined that have one or more Permissions, | |
| 3136 3. Users are assigned Roles in their "roles" property, and finally | |
| 3137 4. Roundup checks that users have appropriate Permissions at appropriate times | |
| 3138 (like editing issues). | |
| 3139 | |
| 3140 Your tracker dbinit module's *open* function now has to define any | |
| 3141 Permissions that are specific to your tracker, and also the assignment | |
| 3142 of Permissions to Roles. At the moment, your open function | |
| 3143 ends with:: | |
| 3144 | |
| 3145 import detectors | |
| 3146 detectors.init(db) | |
| 3147 | |
| 3148 return db | |
| 3149 | |
| 3150 and what we need to do is insert some commands that will set up the security | |
| 3151 parameters. Right above the ``import detectors`` line, you'll want to insert | |
| 3152 these lines:: | |
| 3153 | |
| 3154 # | |
| 3155 # SECURITY SETTINGS | |
| 3156 # | |
| 3157 # new permissions for this schema | |
| 3158 for cl in 'issue', 'file', 'msg', 'user': | |
| 3159 db.security.addPermission(name="Edit", klass=cl, | |
| 3160 description="User is allowed to edit "+cl) | |
| 3161 db.security.addPermission(name="View", klass=cl, | |
| 3162 description="User is allowed to access "+cl) | |
| 3163 | |
| 3164 # Assign the access and edit permissions for issue, file and message | |
| 3165 # to regular users now | |
| 3166 for cl in 'issue', 'file', 'msg': | |
| 3167 p = db.security.getPermission('View', cl) | |
| 3168 db.security.addPermissionToRole('User', p) | |
| 3169 p = db.security.getPermission('Edit', cl) | |
| 3170 db.security.addPermissionToRole('User', p) | |
| 3171 # and give the regular users access to the web and email interface | |
| 3172 p = db.security.getPermission('Web Access') | |
| 3173 db.security.addPermissionToRole('User', p) | |
| 3174 p = db.security.getPermission('Email Access') | |
| 3175 db.security.addPermissionToRole('User', p) | |
| 3176 | |
| 3177 # May users view other user information? Comment these lines out | |
| 3178 # if you don't want them to | |
| 3179 p = db.security.getPermission('View', 'user') | |
| 3180 db.security.addPermissionToRole('User', p) | |
| 3181 | |
| 3182 # Assign the appropriate permissions to the anonymous user's Anonymous | |
| 3183 # Role. Choices here are: | |
| 3184 # - Allow anonymous users to register through the web | |
| 3185 p = db.security.getPermission('Web Registration') | |
| 3186 db.security.addPermissionToRole('Anonymous', p) | |
| 3187 # - Allow anonymous (new) users to register through the email gateway | |
| 3188 p = db.security.getPermission('Email Registration') | |
| 3189 db.security.addPermissionToRole('Anonymous', p) | |
| 3190 # - Allow anonymous users access to the "issue" class of data | |
| 3191 # Note: this also grants access to related information like files, | |
| 3192 # messages, statuses etc that are linked to issues | |
| 3193 #p = db.security.getPermission('View', 'issue') | |
| 3194 #db.security.addPermissionToRole('Anonymous', p) | |
| 3195 # - Allow anonymous users access to edit the "issue" class of data | |
| 3196 # Note: this also grants access to create related information like | |
| 3197 # files and messages etc that are linked to issues | |
| 3198 #p = db.security.getPermission('Edit', 'issue') | |
| 3199 #db.security.addPermissionToRole('Anonymous', p) | |
| 3200 | |
| 3201 # oh, g'wan, let anonymous access the web interface too | |
| 3202 p = db.security.getPermission('Web Access') | |
| 3203 db.security.addPermissionToRole('Anonymous', p) | |
| 3204 | |
| 3205 Note in the comments there the places where you might change the permissions | |
| 3206 to restrict users or grant users more access. If you've created additional | |
| 3207 classes that users should be able to edit and view, then you should add them | |
| 3208 to the "new permissions for this schema" section at the start of the security | |
| 3209 block. Then add them to the "Assign the access and edit permissions" section | |
| 3210 too, so people actually have the new Permission you've created. | |
| 3211 | |
| 3212 One final change is needed that finishes off the security system's | |
| 3213 initialisation. We need to add a call to ``db.post_init()`` at the end of the | |
| 3214 dbinit open() function. Add it like this:: | |
| 3215 | |
| 3216 import detectors | |
| 3217 detectors.init(db) | |
| 3218 | |
| 3219 # schema is set up - run any post-initialisation | |
| 3220 db.post_init() | |
| 3221 return db | |
| 3222 | |
| 3223 You may verify the setup of Permissions and Roles using the new | |
| 3224 "``roundup-admin security``" command. | |
| 3225 | |
| 3226 | |
| 3227 0.5.0 User changes | |
| 3228 ~~~~~~~~~~~~~~~~~~ | |
| 3229 | |
| 3230 To support all those schema changes, you'll need to massage your user database | |
| 3231 a little too, to: | |
| 3232 | |
| 3233 1. make sure there's an "anonymous" user - this user is mandatory now and is | |
| 3234 the one that unknown users are logged in as. | |
| 3235 2. make sure all users have at least one Role. | |
| 3236 | |
| 3237 If you don't have the "anonymous" user, create it now with the command:: | |
| 3238 | |
| 3239 roundup-admin create user username=anonymous roles=Anonymous | |
| 3240 | |
| 3241 making sure the capitalisation is the same as above. Once you've done that, | |
| 3242 you'll need to set the roles property on all users to a reasonable default. | |
| 3243 The admin user should get "Admin", the anonymous user "Anonymous" | |
| 3244 and all other users "User". The ``fixroles.py`` script in the tools directory | |
| 3245 will do this. Run it like so (where python is your python 2+ binary):: | |
| 3246 | |
| 3247 python tools/fixroles.py -i <tracker home> fixroles | |
| 3248 | |
| 3249 | |
| 3250 | |
| 3251 0.5.0 CGI interface changes | |
| 3252 --------------------------- | |
| 3253 | |
| 3254 The CGI interface code was completely reorganised and largely rewritten. The | |
| 3255 end result is that this section of your tracker interfaces module will need | |
| 3256 changing from:: | |
| 3257 | |
| 3258 from roundup import cgi_client, mailgw | |
| 3259 from roundup.i18n import _ | |
| 3260 | |
| 3261 class Client(cgi_client.Client): | |
| 3262 ''' derives basic CGI implementation from the standard module, | |
| 3263 with any specific extensions | |
| 3264 ''' | |
| 3265 pass | |
| 3266 | |
| 3267 to:: | |
| 3268 | |
| 3269 from roundup import mailgw | |
| 3270 from roundup.cgi import client | |
| 3271 | |
| 3272 class Client(client.Client): | |
| 3273 ''' derives basic CGI implementation from the standard module, | |
| 3274 with any specific extensions | |
| 3275 ''' | |
| 3276 pass | |
| 3277 | |
| 3278 You will also need to install the new version of roundup.cgi from the source | |
| 3279 cgi-bin directory if you're using it. | |
| 3280 | |
| 3281 | |
| 3282 0.5.0 HTML templating | |
| 3283 --------------------- | |
| 3284 | |
| 3285 You'll want to make a backup of your current tracker html directory. You | |
| 3286 should then copy the html directory from the Roundup source "classic" template | |
| 3287 and modify it according to your local schema changes. | |
| 3288 | |
| 3289 If you need help with the new templating system, please ask questions on the | |
| 3290 roundup-users mailing list (available through the roundup web page on | |
| 3291 sourceforge, https://www.roundup-tracker.org/. | |
| 3292 | |
| 3293 | |
| 3294 0.5.0 Detectors | |
| 3295 --------------- | |
| 3296 | |
| 3297 The nosy reactor has been updated to handle the tracker not having an | |
| 3298 "assignedto" property on issues. You may want to copy it into your tracker's | |
| 3299 detectors directory. Chances are you've already fixed it though :) | |
| 3300 | |
| 3301 | |
| 3302 Migrating from 0.4.1 to 0.4.2 | |
| 3303 ============================= | |
| 3304 | |
| 3305 0.4.2 Configuration | |
| 3306 ------------------- | |
| 3307 The USER_INDEX definition introduced in 0.4.1 was too restrictive in its | |
| 3308 allowing replacement of 'assignedto' with the user's userid. Users must change | |
| 3309 the None value of 'assignedto' to 'CURRENT USER' (the string, in quotes) for | |
| 3310 the replacement behaviour to occur now. | |
| 3311 | |
| 3312 The new configuration variables are: | |
| 3313 | |
| 3314 - EMAIL_KEEP_QUOTED_TEXT | |
| 3315 - EMAIL_LEAVE_BODY_UNCHANGED | |
| 3316 - ADD_RECIPIENTS_TO_NOSY | |
| 3317 | |
| 3318 See the sample configuration files in:: | |
| 3319 | |
| 3320 <roundup source>/roundup/templates/classic/instance_config.py | |
| 3321 | |
| 3322 and:: | |
| 3323 | |
| 3324 <roundup source>/roundup/templates/extended/instance_config.py | |
| 3325 | |
| 3326 and the `customisation documentation`_ for information on how they're used. | |
| 3327 | |
| 3328 | |
| 3329 0.4.2 Changes to detectors | |
| 3330 -------------------------- | |
| 3331 You will need to copy the detectors from the distribution into your instance | |
| 3332 home "detectors" directory. If you used the classic schema, the detectors | |
| 3333 are in:: | |
| 3334 | |
| 3335 <roundup source>/roundup/templates/classic/detectors/ | |
| 3336 | |
| 3337 If you used the extended schema, the detectors are in:: | |
| 3338 | |
| 3339 <roundup source>/roundup/templates/extended/detectors/ | |
| 3340 | |
| 3341 The change means that schema-specific code has been removed from the | |
| 3342 mail gateway and cgi interface and made into auditors: | |
| 3343 | |
| 3344 - nosyreactor.py has now got an updatenosy auditor which updates the nosy | |
| 3345 list with author, recipient and assignedto information. | |
| 3346 - statusauditor.py makes the unread or resolved -> chatting changes and | |
| 3347 presets the status of an issue to unread. | |
| 3348 | |
| 3349 There's also a bug or two fixed in the nosyreactor code. | |
| 3350 | |
| 3351 0.4.2 HTML templating changes | |
| 3352 ----------------------------- | |
| 3353 The link() htmltemplate function now has a "showid" option for links and | |
| 3354 multilinks. When true, it only displays the linked item id as the anchor | |
| 3355 text. The link value is displayed as a tooltip using the title anchor | |
| 3356 attribute. To use in eg. the superseder field, have something like this:: | |
| 3357 | |
| 3358 <td> | |
| 3359 <display call="field('superseder', showid=1)"> | |
| 3360 <display call="classhelp('issue', 'id,title', label='list', width=500)"> | |
| 3361 <property name="superseder"> | |
| 3362 <br>View: <display call="link('superseder', showid=1)"> | |
| 3363 </property> | |
| 3364 </td> | |
| 3365 | |
| 3366 The stylesheets have been cleaned up too. You may want to use the newer | |
| 3367 versions in:: | |
| 3368 | |
| 3369 <roundup source>/roundup/templates/<template>/html/default.css | |
| 3370 | |
| 3371 | |
| 3372 | |
| 3373 Migrating from 0.4.0 to 0.4.1 | |
| 3374 ============================= | |
| 3375 | |
| 3376 0.4.1 Files storage | |
| 3377 ------------------- | |
| 3378 | |
| 3379 Messages and files from newly created issues will be put into subdierectories | |
| 3380 in thousands e.g. msg123 will be put into files/msg/0/msg123, file2003 | |
| 3381 will go into files/file/2/file2003. Previous messages are still found, but | |
| 3382 could be put into this structure. | |
| 3383 | |
| 3384 0.4.1 Configuration | |
| 3385 ------------------- | |
| 3386 | |
| 3387 To allow more fine-grained access control, the variable used to check | |
| 3388 permission to auto-register users in the mail gateway is now called | |
| 3389 ANONYMOUS_REGISTER_MAIL rather than overloading ANONYMOUS_REGISTER. If the | |
| 3390 variable doesn't exist, then ANONYMOUS_REGISTER is tested as before. | |
| 3391 | |
| 3392 Configuring the links in the web header is now easier too. The following | |
| 3393 variables have been added to the classic instance_config.py:: | |
| 3394 | |
| 3395 HEADER_INDEX_LINKS - defines the "index" links to be made available | |
| 3396 HEADER_ADD_LINKS - defines the "add" links | |
| 3397 DEFAULT_INDEX - specifies the index view for DEFAULT | |
| 3398 UNASSIGNED_INDEX - specifies the index view for UNASSIGNED | |
| 3399 USER_INDEX - specifies the index view for USER | |
| 3400 | |
| 3401 See the <roundup source>/roundup/templates/classic/instance_config.py for more | |
| 3402 information - including how the variables are to be set up. Most users will | |
| 3403 just be able to copy the variables from the source to their instance home. If | |
| 3404 you've modified the header by changing the source of the interfaces.py file in | |
| 3405 the instance home, you'll need to remove that customisation and move it into | |
| 3406 the appropriate variables in instance_config.py. | |
| 3407 | |
| 3408 The extended schema has similar variables added too - see the source for more | |
| 3409 info. | |
| 3410 | |
| 3411 0.4.1 Alternate E-Mail Addresses | |
| 3412 -------------------------------- | |
| 3413 | |
| 3414 If you add the property "alternate_addresses" to your user class, your users | |
| 3415 will be able to register alternate email addresses that they may use to | |
| 3416 communicate with roundup as. All email from roundup will continue to be sent | |
| 3417 to their primary address. | |
| 3418 | |
| 3419 If you have not edited the dbinit.py file in your instance home directory, | |
| 3420 you may simply copy the new dbinit.py file from the core code. If you used | |
| 3421 the classic schema, the interfaces file is in:: | |
| 3422 | |
| 3423 <roundup source>/roundup/templates/classic/dbinit.py | |
| 3424 | |
| 3425 If you used the extended schema, the file is in:: | |
| 3426 | |
| 3427 <roundup source>/roundup/templates/extended/dbinit.py | |
| 3428 | |
| 3429 If you have modified your dbinit.py file, you need to edit the dbinit.py | |
| 3430 file in your instance home directory. Find the lines which define the user | |
| 3431 class:: | |
| 3432 | |
| 3433 user = Class(db, "msg", | |
| 3434 username=String(), password=Password(), | |
| 3435 address=String(), realname=String(), | |
| 3436 phone=String(), organisation=String(), | |
| 3437 alternate_addresses=String()) | |
| 3438 | |
| 3439 You will also want to add the property to the user's details page. The | |
| 3440 template for this is the "user.item" file in your instance home "html" | |
| 3441 directory. Similar to above, you may copy the file from the roundup source if | |
| 3442 you haven't modified it. Otherwise, add the following to the template:: | |
| 3443 | |
| 3444 <display call="multiline('alternate_addresses')"> | |
| 3445 | |
| 3446 with appropriate labelling etc. See the standard template for an idea. | |
| 3447 | |
| 3448 | |
| 3449 | |
| 3450 Migrating from 0.3.x to 0.4.0 | |
| 3451 ============================= | |
| 3452 | |
| 3453 0.4.0 Message-ID and In-Reply-To addition | |
| 3454 ----------------------------------------- | |
| 3455 0.4.0 adds the tracking of messages by message-id and allows threading | |
| 3456 using in-reply-to. Most e-mail clients support threading using this | |
| 3457 feature, and we hope to add support for it to the web gateway. If you | |
| 3458 have not edited the dbinit.py file in your instance home directory, you may | |
| 3459 simply copy the new dbinit.py file from the core code. If you used the | |
| 3460 classic schema, the interfaces file is in:: | |
| 3461 | |
| 3462 <roundup source>/roundup/templates/classic/dbinit.py | |
| 3463 | |
| 3464 If you used the extended schema, the file is in:: | |
| 3465 | |
| 3466 <roundup source>/roundup/templates/extended/dbinit.py | |
| 3467 | |
| 3468 If you have modified your dbinit.py file, you need to edit the dbinit.py | |
| 3469 file in your instance home directory. Find the lines which define the msg | |
| 3470 class:: | |
| 3471 | |
| 3472 msg = FileClass(db, "msg", | |
| 3473 author=Link("user"), recipients=Multilink("user"), | |
| 3474 date=Date(), summary=String(), | |
| 3475 files=Multilink("file")) | |
| 3476 | |
| 3477 and add the messageid and inreplyto properties like so:: | |
| 3478 | |
| 3479 msg = FileClass(db, "msg", | |
| 3480 author=Link("user"), recipients=Multilink("user"), | |
| 3481 date=Date(), summary=String(), | |
| 3482 files=Multilink("file"), | |
| 3483 messageid=String(), inreplyto=String()) | |
| 3484 | |
| 3485 Also, configuration is being cleaned up. This means that your dbinit.py will | |
| 3486 also need to be changed in the open function. If you haven't changed your | |
| 3487 dbinit.py, the above copy will be enough. If you have, you'll need to change | |
| 3488 the line (round line 50):: | |
| 3489 | |
| 3490 db = Database(instance_config.DATABASE, name) | |
| 3491 | |
| 3492 to:: | |
| 3493 | |
| 3494 db = Database(instance_config, name) | |
| 3495 | |
| 3496 | |
| 3497 0.4.0 Configuration | |
| 3498 -------------------- | |
| 3499 ``TRACKER_NAME`` and ``EMAIL_SIGNATURE_POSITION`` have been added to the | |
| 3500 instance_config.py. The simplest solution is to copy the default values | |
| 3501 from template in the core source. | |
| 3502 | |
| 3503 The mail gateway now checks ``ANONYMOUS_REGISTER`` to see if unknown users | |
| 3504 are to be automatically registered with the tracker. If it is set to "deny" | |
| 3505 then unknown users will not have access. If it is set to "allow" they will be | |
| 3506 automatically registered with the tracker. | |
| 3507 | |
| 3508 | |
| 3509 0.4.0 CGI script roundup.cgi | |
| 3510 ---------------------------- | |
| 3511 The CGI script has been updated with some features and a bugfix, so you should | |
| 3512 copy it from the roundup cgi-bin source directory again. Make sure you update | |
| 3513 the ROUNDUP_INSTANCE_HOMES after the copy. | |
| 3514 | |
| 3515 | |
| 3516 0.4.0 Nosy reactor | |
| 3517 ------------------ | |
| 3518 The nosy reactor has also changed - copy the nosyreactor.py file from the core | |
| 3519 source:: | |
| 3520 | |
| 3521 <roundup source>/roundup/templates/<template>/detectors/nosyreactor.py | |
| 3522 | |
| 3523 to your instance home "detectors" directory. | |
| 3524 | |
| 3525 | |
| 3526 0.4.0 HTML templating | |
| 3527 --------------------- | |
| 3528 The field() function was incorrectly implemented - links and multilinks now | |
| 3529 display as text fields when rendered using field(). To display a menu (drop- | |
| 3530 down or select box) you need to use the menu() function. | |
| 3531 | |
| 3532 | |
| 3533 | |
| 3534 Migrating from 0.2.x to 0.3.x | |
| 3535 ============================= | |
| 3536 | |
| 3537 0.3.x Cookie Authentication changes | |
| 3538 ----------------------------------- | |
| 3539 0.3.0 introduces cookie authentication - you will need to copy the | |
| 3540 interfaces.py file from the roundup source to your instance home to enable | |
| 3541 authentication. If you used the classic schema, the interfaces file is in:: | |
| 3542 | |
| 3543 <roundup source>/roundup/templates/classic/interfaces.py | |
| 3544 | |
| 3545 If you used the extended schema, the file is in:: | |
| 3546 | |
| 3547 <roundup source>/roundup/templates/extended/interfaces.py | |
| 3548 | |
| 3549 If you have modified your interfaces.Client class, you will need to take | |
| 3550 note of the login/logout functionality provided in roundup.cgi_client.Client | |
| 3551 (classic schema) or roundup.cgi_client.ExtendedClient (extended schema) and | |
| 3552 modify your instance code apropriately. | |
| 3553 | |
| 3554 | |
| 3555 0.3.x Password encoding | |
| 3556 ----------------------- | |
| 3557 This release also introduces encoding of passwords in the database. If you | |
| 3558 have not edited the dbinit.py file in your instance home directory, you may | |
| 3559 simply copy the new dbinit.py file from the core code. If you used the | |
| 3560 classic schema, the interfaces file is in:: | |
| 3561 | |
| 3562 <roundup source>/roundup/templates/classic/dbinit.py | |
| 3563 | |
| 3564 If you used the extended schema, the file is in:: | |
| 3565 | |
| 3566 <roundup source>/roundup/templates/extended/dbinit.py | |
| 3567 | |
| 3568 | |
| 3569 If you have modified your dbinit.py file, you may use encoded passwords: | |
| 3570 | |
| 3571 1. Edit the dbinit.py file in your instance home directory | |
| 3572 a. At the first code line of the open() function:: | |
| 3573 | |
| 3574 from roundup.hyperdb import String, Date, Link, Multilink | |
| 3575 | |
| 3576 alter to include Password, as so:: | |
| 3577 | |
| 3578 from roundup.hyperdb import String, Password, Date, Link, Multilink | |
| 3579 | |
| 3580 b. Where the password property is defined (around line 66):: | |
| 3581 | |
| 3582 user = Class(db, "user", | |
| 3583 username=String(), password=String(), | |
| 3584 address=String(), realname=String(), | |
| 3585 phone=String(), organisation=String()) | |
| 3586 user.setkey("username") | |
| 3587 | |
| 3588 alter the "password=String()" to "password=Password()":: | |
| 3589 | |
| 3590 user = Class(db, "user", | |
| 3591 username=String(), password=Password(), | |
| 3592 address=String(), realname=String(), | |
| 3593 phone=String(), organisation=String()) | |
| 3594 user.setkey("username") | |
| 3595 | |
| 3596 2. Any existing passwords in the database will remain cleartext until they | |
| 3597 are edited. It is recommended that at a minimum the admin password be | |
| 3598 changed immediately:: | |
| 3599 | |
| 3600 roundup-admin -i <instance home> set user1 password=<new password> | |
| 3601 | |
| 3602 | |
| 3603 0.3.x Configuration | |
| 3604 ------------------- | |
| 3605 FILTER_POSITION, ANONYMOUS_ACCESS, ANONYMOUS_REGISTER have been added to | |
| 3606 the instance_config.py. Simplest solution is to copy the default values from | |
| 3607 template in the core source. | |
| 3608 | |
| 3609 MESSAGES_TO_AUTHOR has been added to the IssueClass in dbinit.py. Set to 'yes' | |
| 3610 to send nosy messages to the author. Default behaviour is to not send nosy | |
| 3611 messages to the author. You will need to add MESSAGES_TO_AUTHOR to your | |
| 3612 dbinit.py in your instance home. | |
| 3613 | |
| 3614 | |
| 3615 0.3.x CGI script roundup.cgi | |
| 3616 ---------------------------- | |
| 3617 There have been some structural changes to the roundup.cgi script - you will | |
| 3618 need to install it again from the cgi-bin directory of the source | |
| 3619 distribution. Make sure you update the ROUNDUP_INSTANCE_HOMES after the | |
| 3620 copy. | |
| 3621 | |
| 3622 | |
| 3623 .. _`customisation documentation`: customizing.html | |
| 3624 .. _`security documentation`: security.html | |
| 3625 .. _`administration guide`: admin_guide.html | 2097 .. _`administration guide`: admin_guide.html |
| 3626 .. _`xmlrpc guide`: xmlrpc.html | 2098 .. _`xmlrpc guide`: xmlrpc.html |
| 3627 .. _FTS5 full-text search engine: https://www.sqlite.org/fts5.html | 2099 .. _FTS5 full-text search engine: https://www.sqlite.org/fts5.html |
| 3628 .. _PostgreSQL's full text search: https://www.postgresql.org/docs/current/textsearch.html | 2100 .. _PostgreSQL's full text search: https://www.postgresql.org/docs/current/textsearch.html |
| 3629 .. _`administration guide notes on native-fts`: admin_guide.html#configuring-native-fts-full-text-search | 2101 .. _`administration guide notes on native-fts`: admin_guide.html#configuring-native-fts-full-text-search |
| 3630 .. _Configuring Compression: admin_guide.html#configuring-compression | 2102 .. _Configuring Compression: admin_guide.html#configuring-compression |
| 3631 .. _Software Upgrade: admin_guide.html#software-upgrade | 2103 .. _Software Upgrade: admin_guide.html#software-upgrade |
| 2104 .. _new search permissions for query in 1.4.17: | |
| 2105 upgrading-history.html#new-search-permissions-for-query-in-1-4-17 |
