Mercurial > p > roundup > code
comparison doc/upgrading.txt @ 8416:370689471a08 issue2550923_computed_property
merge from default branch accumulated changes since Nov 2023
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Sun, 17 Aug 2025 16:12:25 -0400 |
| parents | 0663a7bcef6c |
| children | 94eed885e958 |
comparison
equal
deleted
inserted
replaced
| 7693:78585199552a | 8416:370689471a08 |
|---|---|
| 1 .. meta:: | 1 .. meta:: |
| 2 :description: | 2 :description: |
| 3 Critical documentation for upgrading the Roundup Issue | 3 Critical documentation for upgrading the Roundup Issue |
| 4 Tracker. Actions that must 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 |
| 31 each version transition. If you are starting at 1.5.0 | 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** | 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. | 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, | 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. | 35 2.2.0 -> 2.3.0. |
| 36 6. Run ``roundup-admin -i <tracker_home> migrate`` using the newer | 36 6. Run ``roundup-admin -i <tracker_home> migrate`` using |
| 37 version of Roundup for **all** the trackers you have | 37 the newer version of Roundup for the instance you are |
| 38 upgraded. This will update the database if it is required. | 38 upgrading. This will update the database if it is |
| 39 required. | |
| 39 7. Bring your Roundup instance back online | 40 7. Bring your Roundup instance back online |
| 40 8. Test | 41 8. Test |
| 42 | |
| 43 Repeat for each tracker instance. | |
| 41 | 44 |
| 42 .. note:: | 45 .. note:: |
| 43 The v1.5.x releases of Roundup were the last to support | 46 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 | 47 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 | 48 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 | 49 Roundup. Starting with Roundup version 2.0.0 we also support Python 3 |
| 47 versions newer than 3.6. | 50 versions newer than 3.6. Roundup version 2.5 supports Python |
| 51 3.7 and newer. | |
| 48 | 52 |
| 49 Recent release notes have the following labels: | 53 Recent release notes have the following labels: |
| 50 | 54 |
| 51 * required - Roundup will not work properly if these steps are not done | 55 * **required** - Roundup will not work properly if these steps are not done |
| 52 * recommended - Roundup will still work, but these steps can cause | 56 * **recommended** - Roundup will still work, but these steps can cause |
| 53 security or stability issues if not done. | 57 security or stability issues if not done. |
| 54 * optional - new features or changes to existing features you might | 58 * **optional** - new features or changes to existing features you might |
| 55 want to use | 59 want to use |
| 56 * info - important possibly visible changes in how things operate | 60 * **info** - important possibly visible changes in how things operate |
| 57 | 61 |
| 58 If you use virtual environments for your installation, you can run | 62 If you use virtual environments for your installation, you |
| 59 trackers with different versions of Roundup. So you can have one tracker | 63 can run trackers with different versions of Roundup. So you |
| 60 using version 2.2.0 and another tracker using version 1.6.1. This | 64 can have one tracker using version 2.2.0 and another tracker |
| 61 allows you to upgrade trackers one at a time rather than having to | 65 using version 1.6.1. This allows you to upgrade trackers one |
| 62 upgrade all your trackers at once. | 66 at a time rather than having to upgrade all your trackers at |
| 67 once. Note that downgrading may require restoring your | |
| 68 database to an earlier version, so make sure you backed up | |
| 69 your database. | |
| 63 | 70 |
| 64 .. note:: | 71 .. note:: |
| 65 | 72 |
| 66 This file only includes versions released in the last 10 | 73 This file only includes versions released in the last 10 |
| 67 years. If you are upgrading from an older version, start with the | 74 years. If you are upgrading from an older version, start with the |
| 69 document. | 76 document. |
| 70 | 77 |
| 71 .. admonition:: Python 2 Support | 78 .. admonition:: Python 2 Support |
| 72 | 79 |
| 73 If you are running Roundup under Python 2, you should make plans to | 80 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 | 81 switch to Python 3. Release 2.4.0 (Jul 2024) is the last release to |
| 75 used for developing Roundup are dropping support for Python 2. Also | 82 officially support Python 2. The next non-patch release scheduled |
| 76 optional packages are dropping Python 2 support. As a result Python 2 | 83 for 2025 will mark 5 years since Roundup supported Python 3. |
| 77 may not be supported for many more release cycles. | |
| 78 | 84 |
| 79 .. admonition:: XHTML Support Deprecation Notice | 85 .. admonition:: XHTML Support Deprecation Notice |
| 80 | 86 |
| 81 If you are running a tracker where the ``html_version`` setting in | 87 If you are running a tracker where the ``html_version`` setting in |
| 82 ``config.ini`` is ``xhtml``, you should plan to change your | 88 ``config.ini`` is ``xhtml``, you should plan to change your |
| 83 templates to use html (HTML5). If you are affected by this, please | 89 templates to use html (HTML5). If you are affected by this, please |
| 84 send email to the roundup-users mailing list (roundup-users at | 90 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 | 91 lists.sourceforge.net). Version 2.3.0 is the last version to support |
| 86 version to support XHTML. | 92 XHTML. |
| 87 | 93 |
| 88 Contents: | 94 .. raw:: html |
| 95 | |
| 96 <details> | |
| 97 <summary>Contents:</summary> | |
| 89 | 98 |
| 90 .. contents:: | 99 .. contents:: |
| 91 :local: | 100 :local: |
| 92 | 101 |
| 93 .. index:: Upgrading; 2.2.0 to 2.3.0 | 102 .. raw:: html |
| 103 | |
| 104 </details> | |
| 105 | |
| 106 .. index:: Upgrading; 2.5.0 to 2.6.0 | |
| 107 | |
| 108 Migrating from 2.5.0 to 2.6.0 | |
| 109 ============================= | |
| 110 | |
| 111 Support authorized changes in your tracker (optional) | |
| 112 ----------------------------------------------------- | |
| 113 | |
| 114 An auditor can require change verification with user's password. | |
| 115 | |
| 116 When changing sensitive information (e.g. passwords) it is | |
| 117 useful to ask for a validated authorization. This makes sure | |
| 118 that the user is present by typing their password. | |
| 119 | |
| 120 You can add this to your auditors using the example | |
| 121 :ref:`sensitive_changes`. | |
| 122 | |
| 123 To use this, you must copy ``_generic.reauth.html`` into your | |
| 124 tracker's html subdirectory. See the classic template directory for a | |
| 125 copy. If you are using jinja2, see the jinja2 template directory. | |
| 126 Then you can raise a Reauth exception and have the proper page | |
| 127 displayed. | |
| 128 | |
| 129 Also javascript *MUST* be turned on if this is used with a file | |
| 130 input. If JavaScript is not turned on, attached files are lost during | |
| 131 the reauth step. Information from other types of inputs (password, | |
| 132 date, text etc.) do not need JavaScript to work. | |
| 133 | |
| 134 See :ref:`Confirming the User` in the reference manual for details. | |
| 135 | |
| 136 .. index:: Upgrading; 2.4.0 to 2.5.0 | |
| 137 | |
| 138 Migrating from 2.4.0 to 2.5.0 | |
| 139 ============================= | |
| 140 | |
| 141 .. _CVE-2025-53865: | |
| 142 | |
| 143 XSS security issue with devel and responsive templates (recommended) | |
| 144 -------------------------------------------------------------------- | |
| 145 | |
| 146 There are actually two different issues under this heading. | |
| 147 | |
| 148 1. incorrect use of the ``structure`` keyword with | |
| 149 ``tal:content`` | |
| 150 2. use of ``tal:replace`` on unsafe input | |
| 151 | |
| 152 See the `security page for a link to CVE-2025-53865 | |
| 153 <security.html#cve-announcements>`_. | |
| 154 | |
| 155 In the discussion below, the :term:`html directory` means one or | |
| 156 more directories listed in the ``templates`` key of your | |
| 157 tracker's ``config.ini`` file. | |
| 158 | |
| 159 These directions can be used to solve the XSS security issue with | |
| 160 any version of Roundup. Even if you used a classic or minimal | |
| 161 template, you should check your trackers for these issues. The | |
| 162 classic template fixed most of these many years ago, but the | |
| 163 updates were not made to the devel and responsive templates. No | |
| 164 report of similar issues with the jinja template has been seen. | |
| 165 | |
| 166 Incorrect use of structure in templates | |
| 167 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 168 | |
| 169 The devel and responsive templates prior to Roundup 2.5 used this | |
| 170 construct:: | |
| 171 | |
| 172 tal:content="structure context/MUMBLE/plain" | |
| 173 | |
| 174 Where ``MUMBLE`` is a property of your issues (e.g. title). | |
| 175 | |
| 176 This construct allows a URL with a carefully crafted query | |
| 177 parameter to execute arbitrary JavaScript. | |
| 178 | |
| 179 You should check all your trackers. The classic template has not | |
| 180 used this construct since at least 2009, but your tracker's | |
| 181 templates may use the offending construct anyway. | |
| 182 | |
| 183 This fix will apply if your tracker is based on the responsive or | |
| 184 devel template. Check the TEMPLATE-INFO.txt file in your tracker | |
| 185 home. The template name is the first component of the ``Name`` | |
| 186 field. For example a Name like:: | |
| 187 | |
| 188 Name: responsive-bugtracker | |
| 189 | |
| 190 Name: devel-bugtracker | |
| 191 | |
| 192 shows that tracker is based on the responsive or devel templates. | |
| 193 | |
| 194 .. _cve-2025-53865-fixed: | |
| 195 | |
| 196 To fix this, remove the ``structure`` declaration when it is used | |
| 197 with a plain representation. So fixing the code by replacing the | |
| 198 example above with:: | |
| 199 | |
| 200 tal:content="context/MUMBLE/plain" | |
| 201 | |
| 202 prevents the attack. | |
| 203 | |
| 204 To check for this issue, search for ``structure`` followed by | |
| 205 ``/plain`` in all your html templates. If you are on a Linux/Unix | |
| 206 system you can search the html subdirectory of your tracker with | |
| 207 the following:: | |
| 208 | |
| 209 grep 'structure.*/plain' *.html | |
| 210 | |
| 211 which should return any lines with issues. | |
| 212 | |
| 213 .. warning:: | |
| 214 | |
| 215 Backup the files in the ``html`` subdirectory of your tracker | |
| 216 in case an edit goes wrong. | |
| 217 | |
| 218 As an example, you could fix this issue using the GNU sed | |
| 219 command:: | |
| 220 | |
| 221 sed -i.bak -e '/structure.*\/plain/s/structure.//' *.html | |
| 222 | |
| 223 to edit the files in place and remove the structure keyword. It | |
| 224 will create a ``.bak`` file with the original contents of the | |
| 225 file. If your templates were changed, this might still miss some | |
| 226 entries. If you are on windows, some text editors support search | |
| 227 and replace using a regular expression. | |
| 228 | |
| 229 If the construct is split across lines:: | |
| 230 | |
| 231 tal:content="structure | |
| 232 context/MUMBLE/plain" | |
| 233 | |
| 234 the commands above will miss the construct. So you should also | |
| 235 search the html files using ``grep /plain *.html`` and verify | |
| 236 that all of the ``context/MUMBLE/plain`` include ``tal:content`` | |
| 237 as in the `fixed example above <#cve-2025-53865-fixed>`_. Any | |
| 238 lines that have ``context/MUMBLE/plain`` without ``tal:content=`` | |
| 239 before it need to be manually verified/fixed. | |
| 240 | |
| 241 The distributed devel and responsive templates do not split the | |
| 242 construct across lines, but if you changed the files it may be | |
| 243 split. | |
| 244 | |
| 245 tal:replace used with unsafe input | |
| 246 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 247 | |
| 248 The problem was caused by the following markup:: | |
| 249 | |
| 250 <span tal:replace="context/MUMBLE" /> | |
| 251 | |
| 252 in the head of the ``bug.item.html``, ``task.item.html`` and | |
| 253 other files in the devel and responsive templates. | |
| 254 | |
| 255 This was fixed many years ago in the classic template's | |
| 256 ``index.item.html``. The classic template replaces the above | |
| 257 construct with:: | |
| 258 | |
| 259 <tal:x tal:content="context/MUMBLE" /> | |
| 260 | |
| 261 ``tal:content`` explicitly escapes the result unless the | |
| 262 ``structure`` directive is used. ``tal:replace`` expects the | |
| 263 result to be safe and usable in an HTML context. | |
| 264 | |
| 265 TAL drops any tags that it doesn't know about from the output. | |
| 266 ``<tal:x tal:content="..." />`` results in the value of the | |
| 267 content expression without a surrounding html tag. (Effectively | |
| 268 replacing the construct.) | |
| 269 | |
| 270 The following diff for ``bug.item.html`` in the devel template | |
| 271 shows the change to make things safe (remove lines starting with | |
| 272 ``-`` and add lines staring with ``+``):: | |
| 273 | |
| 274 <tal:block metal:use-macro="templates/page/macros/frame"> | |
| 275 <title metal:fill-slot="head_title"> | |
| 276 <tal:block condition="context/id" i18n:translate="" | |
| 277 - >Bug <span tal:replace="context/id" i18n:name="id" | |
| 278 - />: <span tal:replace="context/title" i18n:name="title" | |
| 279 - /> - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker" | |
| 280 + >Bug <tal:x tal:content="context/id" i18n:name="id" | |
| 281 + />: <tal:x tal:content="context/title" i18n:name="title" | |
| 282 + /> - <tal:x tal:content="config/TRACKER_NAME" i18n:name="tracker" | |
| 283 /></tal:block> | |
| 284 <tal:block condition="not:context/id" i18n:translate="" | |
| 285 >New Bug report - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker" | |
| 286 | |
| 287 A similar change was applied in the following html files in the | |
| 288 devel or responsive templates: | |
| 289 | |
| 290 .. rst-class:: multicol | |
| 291 | |
| 292 * _generic.collision.html | |
| 293 * bug.item.html | |
| 294 * keyword.item.html | |
| 295 * milestone.item.html | |
| 296 * msg.item.html | |
| 297 * task.item.html | |
| 298 * user.item.html | |
| 299 | |
| 300 Also ``page.html`` should be changed from:: | |
| 301 | |
| 302 <p class="label"><b tal:replace="request/user/username">username</b></p> | |
| 303 | |
| 304 to:: | |
| 305 | |
| 306 <p class="label"><b tal:replace="python:request.user.username.plain(escape=1)">username</b></p> | |
| 307 | |
| 308 The code audit found the ``tal:replace`` construct is used with | |
| 309 ``context/id`` and ``context/designator`` paths. The references | |
| 310 to these paths have been changed to use ``tal:x`` in the classic | |
| 311 template's ``msg.item.html`` file and the classic and minimal | |
| 312 template's ``_generic.collision.html`` file. | |
| 313 | |
| 314 These paths are critical to navigation in Roundup and are set | |
| 315 from the path part of the URL. Roundup's URL path validation | |
| 316 makes it unlikely that an attacker could exploit them. If you | |
| 317 wish you can change your templates or copy the corresponding | |
| 318 files from the template if you haven't made local changes. | |
| 319 | |
| 320 Also you may have used copies of these insecure templates | |
| 321 elsewhere in your tracker (e.g. to create a feature class). To | |
| 322 find other possible issues you can use the command:: | |
| 323 | |
| 324 grep -r "tal:replace=" *.html | |
| 325 | |
| 326 in your tracker's :term:`html directory`. Check each occurrence | |
| 327 and if needed, change it to the safer form. You should consider | |
| 328 any reference to ``context`` to be under the user's (attacker's) | |
| 329 control. Also ``db`` (excluding ``db/config``) and ``request`` | |
| 330 references that use user supplied content | |
| 331 (e.g. ``request/user/username`` above) should be changed to | |
| 332 ``tal:x`` form | |
| 333 | |
| 334 .. comment: | |
| 335 As part of the analysis, the following command was used to find | |
| 336 potentially vulnerable stuff in the templates. Each grep -v was | |
| 337 removed to display items in that category and they were checked:: | |
| 338 | |
| 339 grep -r 'tal:replace' . | grep -v 'replace="batch' | \ | |
| 340 grep -v 'replace="config' | grep -v 'replace="db/config' | \ | |
| 341 grep -v 'replace="structure' | grep -v 'replace="python:' | \ | |
| 342 grep -v 'replace="request/' | |
| 343 | |
| 344 | |
| 345 context/id, context/designator: | |
| 346 assume safe if used in an class.item.html page as the page | |
| 347 wouldn't be shown if they weren't valid numbers/designators. | |
| 348 | |
| 349 Might not be ok referenced in a _generic fallback page though. | |
| 350 | |
| 351 config, db/config, batch, nothing: | |
| 352 should be safe as they are not under user control | |
| 353 | |
| 354 request/classname (python:request._classname), request/template: | |
| 355 should be safe as they are needed to navigate to a display page, | |
| 356 so if they are invalid nothing will be displayed. | |
| 357 | |
| 358 utils, python: | |
| 359 assume it's written correctly and is safe (could use some new | |
| 360 tests for the shipped utility functions). The intent of these | |
| 361 can be to deliver blocks of <script> or other html markup. | |
| 362 | |
| 363 db, request: | |
| 364 might be dangerous when accessing user supplied values. | |
| 365 | |
| 366 request/user/username: | |
| 367 Escape these. If the username is an XSS issue, an attacker could | |
| 368 use it to compromise a user. | |
| 369 | |
| 370 request/dispname: | |
| 371 should be quoted and is by the existing python: code. | |
| 372 | |
| 373 Open question: why does there have to be an error generated by the | |
| 374 url @sort=1. Without invalid sort param, the exploit url doesn't | |
| 375 work and the context appears to use the database's title not the one | |
| 376 in the url. Also its not positional @sort=1 can appear anywhere in | |
| 377 the url. | |
| 378 | |
| 379 Deprecation Notices (required) | |
| 380 ------------------------------ | |
| 381 | |
| 382 * Support for SQLite version 2 has been removed in 2.5.0. | |
| 383 * Support for the `PySQLite <https://github.com/ghaering/pysqlite>`_ | |
| 384 library has been removed in 2.5.0. Only the Python supplied | |
| 385 sqlite3 library is supported. | |
| 386 * Roundup 2.5.0 supports Python 3.7 or newer. (It is not tested | |
| 387 on Python 3.6. It may work but we don't support it.) | |
| 388 | |
| 389 Update responsive template _generic.404.html and query.item.html (recommended) | |
| 390 ------------------------------------------------------------------------------ | |
| 391 | |
| 392 This only applies if your tracker is based on the responsive | |
| 393 template. Check the TEMPLATE-INFO.txt file in your tracker | |
| 394 home. The template name is the first component of the ``Name`` | |
| 395 field. For example a Name like:: | |
| 396 | |
| 397 Name: responsive-bugtracker | |
| 398 | |
| 399 is based on the responsive template. If the Name doesn't start with | |
| 400 ``responsive`` no changes are needed. | |
| 401 | |
| 402 The ``_generic.404.html`` and ``query.item.html`` templates will crash | |
| 403 when displayed because a missing macro is called. Change:: | |
| 404 | |
| 405 <tal:block metal:use-macro="templates/page/macros/icing"> | |
| 406 | |
| 407 to:: | |
| 408 | |
| 409 <tal:block metal:use-macro="templates/page/macros/frame"> | |
| 410 | |
| 411 at the top of both files. The icing macro used in other tracker | |
| 412 templates was renamed to frame in this tracker template. | |
| 413 | |
| 414 Update userauditor.py detector (recommended) | |
| 415 -------------------------------------------- | |
| 416 | |
| 417 When using the REST interface, setting the address property of the | |
| 418 user to the same value it currently has resulted in an error. | |
| 419 | |
| 420 If you have not changed your userauditor, you can copy one from any of | |
| 421 the supplied templates in the ``detectors/userauditor.py`` file. Use | |
| 422 ``roundup-admin templates`` to find a list of template directories. | |
| 423 | |
| 424 If you have changed your userauditor from the stock version, apply the | |
| 425 following diff:: | |
| 426 | |
| 427 raise ValueError('Email address syntax is invalid | |
| 428 "%s"'%address) | |
| 429 | |
| 430 check_main = db.user.stringFind(address=address) | |
| 431 + # allow user to set same address via rest | |
| 432 + if check_main: | |
| 433 + check_main = nodeid not in check_main | |
| 434 + | |
| 435 # make sure none of the alts are owned by anyone other than us (x!=nodeid) | |
| 436 | |
| 437 add the lines marked with ``+`` in the file in the location after | |
| 438 check_main is assigned. | |
| 439 | |
| 440 Modify config.ini password_pbkdf2_default_rounds setting (recommended) | |
| 441 ---------------------------------------------------------------------- | |
| 442 | |
| 443 The method for hashing and storing passwords has been updated to use | |
| 444 PBKDF2 with SHA512 hash. This change was first introduced in Roundup | |
| 445 2.3 and is now the standard. If you previously added code in | |
| 446 interfaces.py for a `PBKDF2 upgrade`_ to enable PBKDF2S5, you can | |
| 447 remove that code now. | |
| 448 | |
| 449 SHA512 is a more secure hash, it requires fewer rounds to ensure | |
| 450 safety. The older PBKDF2-SHA1 needed around 2 million rounds. | |
| 451 | |
| 452 You should update the ``password_pbkdf2_default_rounds`` setting in | |
| 453 ``config.ini`` to 250000. This value is higher than the OWASP | |
| 454 recommendation of 210000 from three years ago. If you don’t make this | |
| 455 change, logins will be slow, especially for REST or XMLRPC calls. | |
| 456 | |
| 457 See `PBKDF2 upgrade`_ for details on how to test the algorithm's | |
| 458 speed. We do not recommend reverting to the older SHA1 PBKDF2. If you | |
| 459 have to do so due to a slow CPU, you can add the following to your | |
| 460 tracker's ``interfaces.py``:: | |
| 461 | |
| 462 from roundup.password import Password | |
| 463 ## Use PBDKF2 (PBKDF2-SHA1) as default hash for passwords. | |
| 464 # That scheme is at the start of the deprecated_schemes list and ha | |
| 465 # to be removed. | |
| 466 Password.default_scheme = Password.deprecated_schemes.pop(0) | |
| 467 # Add PBKDF2S5 (PBKDF2-SHA512) as a valid scheme. Passwords | |
| 468 # using it will be rehashed to use PBDKF2. | |
| 469 Password.experimental_schemes.insert(0, "PBKDF2S5") | |
| 470 | |
| 471 If you proceed with this, you should set | |
| 472 ``password_pbkdf2_default_rounds`` to 2 million or more rounds to keep | |
| 473 your hashed password database secure in case it gets stolen. | |
| 474 | |
| 475 Defusedxml support improves XMLRPC security (optional) | |
| 476 ------------------------------------------------------ | |
| 477 | |
| 478 This release adds support for the defusedxml_ module. If it is | |
| 479 installed it will be automatically used. The default xmlrpc module in | |
| 480 the standard library has known issues when parsing crafted XML. It can | |
| 481 take a lot of CPU time and consume large amounts of memory with small | |
| 482 payloads. | |
| 483 | |
| 484 When the XMLRPC endpoint is used without defusedxml, it will log a | |
| 485 warning to the log file. The log entry can be disabled by adding:: | |
| 486 | |
| 487 | |
| 488 from roundup.cgi import client | |
| 489 client.WARN_FOR_MISSING_DEFUSEDXML = False | |
| 490 | |
| 491 to the ``interfaces.py`` file in the tracker home. (Create the file if | |
| 492 it is missing.) | |
| 493 | |
| 494 XMLRPC access is enabled by default in the classic and other trackers. | |
| 495 Upgrading to defusedxml is considered optional because the XMLRPC | |
| 496 endpoint can be disabled in the tracker's ``config.ini``. Also | |
| 497 ``Xmlrpc Access`` can be removed from the ``Users`` role by commenting | |
| 498 out a line in ``schema.py``. | |
| 499 | |
| 500 If you have enabled the xmlrpc endpoint, you should install | |
| 501 defusedxml. | |
| 502 | |
| 503 .. _defusedxml: https://pypi.org/project/defusedxml/ | |
| 504 | |
| 505 Enable use of native date inputs (optional) | |
| 506 ------------------------------------------- | |
| 507 | |
| 508 Roundup now can use native ``date`` or ``datetime-local`` inputs for | |
| 509 ``Date()`` properties. These inputs take the place of the text input and | |
| 510 calendar popup from earlier Roundup versions. Modern browsers come with | |
| 511 a built-in calendar for date selection, so the ``(cal)`` calendar link | |
| 512 is no longer needed. These native inputs show the date based on the | |
| 513 browser's locale and translate terms into the local language. | |
| 514 | |
| 515 Note that the date format is tied to the language setting in most | |
| 516 browsers, with some browsers you need special configurations to make the | |
| 517 browser use the operating system date format. | |
| 518 | |
| 519 By default the old input mechanism (using type=text inputs) is used. | |
| 520 To enable native date input you need to set the config variable :: | |
| 521 | |
| 522 use_browser_date_input = yes | |
| 523 | |
| 524 in section ``[web]`` in the ``config.ini`` file. | |
| 525 | |
| 526 If native date input is used, simple uses of the ``field()`` method will | |
| 527 generate ``datetime-local`` inputs to allow selection of a date and time. | |
| 528 Input fields for ``Date()`` properties will not have the ``(cal)`` link | |
| 529 anymore. If fields should only use a date (without time) you can specify | |
| 530 the parameter ``display_time=no`` in ``schema.py`` for a ``Date()`` | |
| 531 property (the default is ``yes``). This will use ``date`` inputs in the | |
| 532 generated html to select a date only. If you need this only for a single | |
| 533 date, the ``field()`` method now has a boolean parameter | |
| 534 ``display_time`` (which by default is set to the ``display_time`` | |
| 535 parameter of ``Date()``) | |
| 536 | |
| 537 Complex uses using a ``format`` specification in ``field()`` will not be | |
| 538 upgraded and will operate like earlier Roundup versions. In addition the | |
| 539 ``format`` can now also be specified in the ``Date()`` constructor. | |
| 540 | |
| 541 To upgrade all date properties, there are five changes to make: | |
| 542 | |
| 543 1. Configure ``use_browser_date_input = yes`` in section ``[web]`` in | |
| 544 ``config.ini`` | |
| 545 | |
| 546 2. Optionally add ``display_time = no`` in the schema for Date() | |
| 547 properties that should have no time displayed | |
| 548 | |
| 549 3. Remove the format argument from field() calls on Date() | |
| 550 properties. | |
| 551 | |
| 552 4. Remove popcal() calls. | |
| 553 | |
| 554 5. Include datecopy.js in page.html. | |
| 555 | |
| 556 The ``display_time`` option | |
| 557 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 558 | |
| 559 Both the ``Date()`` constructor and the ``field`` call take a | |
| 560 ``display_time`` option which by default is ``yes`` in the ``Date()`` | |
| 561 constructor and ``True`` in ``field``. The ``display_time`` setting of | |
| 562 ``Date()`` is inherited by the html property, so it doesn't need to be | |
| 563 specified in each ``field()`` call for this property. | |
| 564 | |
| 565 When ``display_time`` is off, the date field does not include hours, | |
| 566 minutes or seconds. | |
| 567 | |
| 568 Remove format argument | |
| 569 ~~~~~~~~~~~~~~~~~~~~~~ | |
| 570 | |
| 571 Speaking of arguments, avoid setting the date ``format`` if you want to | |
| 572 use native date inputs. If you include the `format` argument in the | |
| 573 `field` method, it should be removed. | |
| 574 | |
| 575 By default using a format argument will show the | |
| 576 popup calendar link. You can disable the link by setting | |
| 577 ``popcal=False`` in the field() call. If you have:: | |
| 578 | |
| 579 tal:content="structure python:context.duedate.field( | |
| 580 placeholder='YYYY-MM, format='%Y-%m')" | |
| 581 | |
| 582 changing it to:: | |
| 583 | |
| 584 tal:content="structure python:context.duedate.field( | |
| 585 placeholder='YYYY-MM, format='%Y-%m', | |
| 586 popcal=False)" | |
| 587 | |
| 588 will generate the input as in Roundup 2.4 or earlier without a | |
| 589 popcal link. | |
| 590 | |
| 591 Remove popcal | |
| 592 ~~~~~~~~~~~~~ | |
| 593 | |
| 594 if you have enabled date input types in the configuration and you | |
| 595 use the ``popcal()`` method directly in your templates, you | |
| 596 should remove them. The browser's native date selection calendar should | |
| 597 be used instead. | |
| 598 | |
| 599 Add copy/paste/edit on double-click using datecopy.js | |
| 600 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 601 | |
| 602 When using date input types, | |
| 603 there is no way to copy/paste using a native ``datetime-local`` or | |
| 604 ``date`` input. With the ``datecopy.js`` file installed, double-clicking | |
| 605 on the input turns it into a normal text input with the ability | |
| 606 to copy, paste, or manually edit the date. | |
| 607 | |
| 608 To set this up, take either ``datecopy.js`` or the smaller | |
| 609 version, ``datecopy.min.js``, from the ``html`` folder of the | |
| 610 classic tracker template. Put the file in the ``html`` folder of | |
| 611 your tracker home. | |
| 612 | |
| 613 After you install the datecopy file, you can add the script | |
| 614 directly to a page using:: | |
| 615 | |
| 616 <script tal:attributes="nonce request/client/client_nonce" | |
| 617 tal:content="structure python:utils.readfile('datecopy.min.js')"> | |
| 618 </script> | |
| 619 | |
| 620 or get the file in a separate download using a regular script | |
| 621 tag:: | |
| 622 | |
| 623 <script type="text/javascript" src="@@file/datecopy.js"> | |
| 624 </script> | |
| 625 | |
| 626 You can place these at the end of ``page.html`` just before the | |
| 627 close body ``</body>`` tag. This is the method used in the | |
| 628 classic template. This forces the file to be run for every page | |
| 629 even those that don't have any date inputs. However, it is cached | |
| 630 after the first download. | |
| 631 | |
| 632 Alternatively you can inline or link to it using a script tag | |
| 633 only on pages that will have a date input. For example | |
| 634 ``issue.item.html``. | |
| 635 | |
| 636 There is no support for activating text mode using the | |
| 637 keyboard. Tablet/touch support is mixed. Chrome supports | |
| 638 double-tap to activate text mode input. Firefox does not. | |
| 639 | |
| 640 Enable native number inputs for Number() and Integer() (optional) | |
| 641 ----------------------------------------------------------------- | |
| 642 | |
| 643 Roundup's ``field()`` method for properties of type ``Number()`` or | |
| 644 ``Integer()`` can use a native browser number input by default. | |
| 645 | |
| 646 This is configurable for *all* ``Number()`` and ``Integer()`` properties | |
| 647 with the config option ``use_browser_number_input`` in section ``[web]``. | |
| 648 | |
| 649 You can use the old style text inputs for individual fields | |
| 650 by calling the field method with ``type="text"``. | |
| 651 | |
| 652 Note that the ``Integer()`` type also uses ``step="1"`` by default to | |
| 653 add a stepper control and try to constrain the input to | |
| 654 integers. This can be overridden by passing a new step | |
| 655 (e.g. ``step="50"``) to the ``field()`` method. | |
| 656 | |
| 657 This is an experiment and maybe changed based on feedback. | |
| 658 | |
| 659 Change in REST response for invalid CORS requests (info) | |
| 660 -------------------------------------------------------- | |
| 661 | |
| 662 CORS_ preflight requests that are missing required headers can | |
| 663 now result in either a 403 or 400 error code. If you permit | |
| 664 anonymous users to access the REST interface, a 400 error may | |
| 665 still occur. Previously, only a 400 error was given. This change | |
| 666 is not expected to create issues since the client will recognize | |
| 667 both codes it as an error response, and the CORS request will | |
| 668 still fail. | |
| 669 | |
| 670 More secure session cookie handling (info) | |
| 671 ------------------------------------------ | |
| 672 | |
| 673 This affects you if you are accessing a tracker via https. The name | |
| 674 for the cookie that you get when logging into the web interface has a | |
| 675 new name. When upgrading to Roundup 2.5 all users will have to to log | |
| 676 in again. The cookie now has a ``__Secure-`` prefix to prevent it | |
| 677 from being exposed/used over http. | |
| 678 | |
| 679 If your tracker is using the unencrypted http protocol, nothing has | |
| 680 changed. | |
| 681 | |
| 682 See | |
| 683 https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#cookie_prefixes | |
| 684 for details on this security measure. | |
| 685 | |
| 686 Invalid accept header now prevents operation (info) | |
| 687 --------------------------------------------------- | |
| 688 | |
| 689 In earlier versions, the rest interface checked for an incorrect | |
| 690 "Accept" header, "@apiver", or the ".json" mime type only after | |
| 691 processing the request. This would lead to a 406 error, but the | |
| 692 requested change would still be completed. | |
| 693 | |
| 694 In this release, the validation of the output format and version | |
| 695 occurs before any database changes are made. Now, all errors related | |
| 696 to the data format (mime type, API version) will return 406 errors, | |
| 697 where some previously resulted in 400 errors. | |
| 698 | |
| 699 New method for registering templating utils (info) | |
| 700 -------------------------------------------------- | |
| 701 | |
| 702 If you are building a template utility function that needs access | |
| 703 to: | |
| 704 | |
| 705 * the database | |
| 706 * the client instance | |
| 707 * the form the user submitted | |
| 708 | |
| 709 you had to pass these objects from the template using the ``db``, | |
| 710 ``request.client`` or ``request.form`` arguments. | |
| 711 | |
| 712 A new method for registering a template utility has been added. If you | |
| 713 use the ``instance`` object's ``registerUtilMethod()`` to register a | |
| 714 utility function, you do not need to pass these arguments. The | |
| 715 function is called as a method and the first argument is a | |
| 716 TemplatingUtils (tu) instance from which the client object | |
| 717 (tu.client), the database (tu.client.db), form (tu.client.form), | |
| 718 request (tu.client.request), the translator for the current language | |
| 719 (tu._) and any functions (tu.X) you registered using | |
| 720 ``registerUtil()`` are available. | |
| 721 | |
| 722 You can find an example in :ref:`dynamic_csp`. | |
| 723 | |
| 724 Directions for installing gpg (optional) | |
| 725 ---------------------------------------- | |
| 726 | |
| 727 In this release a new version of the gpg module was needed for Ubuntu | |
| 728 24.04 and python 3.13. Paul Schwabauer produced a new version of the | |
| 729 gpg module. However it is only on the test instance of pypi. If you | |
| 730 run into issues installing gpg with pip, you can use:: | |
| 731 | |
| 732 pip install --index-url https://test.pypi.org/simple/ \ | |
| 733 --extra-index-url https://pypi.org/simple gpg; | |
| 734 | |
| 735 to installed version 2.0 of gpg from test.pypi.org obtaining it's | |
| 736 requirements from pypi.org. | |
| 737 | |
| 738 When `issue2551368 <https://issues.roundup-tracker.org/issue2551368>`_ | |
| 739 is closed, you should be able to use ``pip install gpg`` again. | |
| 740 | |
| 741 .. index:: Upgrading; 2.3.0 to 2.4.0 | |
| 94 | 742 |
| 95 Migrating from 2.3.0 to 2.4.0 | 743 Migrating from 2.3.0 to 2.4.0 |
| 96 ============================= | 744 ============================= |
| 97 | 745 |
| 98 Update your ``config.ini`` (required) | 746 Update your ``config.ini`` (required) |
| 110 ``updateconfig`` will tell you if it is changing old default | 758 ``updateconfig`` will tell you if it is changing old default |
| 111 values or if a value must be changed manually. | 759 values or if a value must be changed manually. |
| 112 | 760 |
| 113 This will insert the bad API login rate limiting settings. | 761 This will insert the bad API login rate limiting settings. |
| 114 | 762 |
| 763 Also if you have ``html_version`` set to ``xhtml``, you will get | |
| 764 an error. | |
| 765 | |
| 766 .. _CVE-2024-39124: | |
| 767 | |
| 768 Fix for CVE-2024-39124 in help/calendar popups (recommended) | |
| 769 ------------------------------------------------------------ | |
| 770 | |
| 771 Classhelper components accessed via URL using ``@template=help``, | |
| 772 ``@template=calendar`` or other template frame in the classhelper | |
| 773 can run JavaScript embedded in the URL. If user clicks on a | |
| 774 malicious URL that: | |
| 775 | |
| 776 * arrives in an email, | |
| 777 * is embedded in a note left on a ticket [#markdown-note]_, | |
| 778 * left on some other web page | |
| 779 | |
| 780 the JavaScript code will be executed. This vulnerability seems to | |
| 781 be limited to manually crafted URL's. It has not been generated | |
| 782 by using Roundup's mechanism for generating classhelper URLs. | |
| 783 | |
| 784 The files that need to be changed to fix this depend on the | |
| 785 template used to create the tracker. Check the | |
| 786 TEMPLATE-INFO.txt file in your tracker home. The template | |
| 787 name is the first component of the ``Name`` field. For | |
| 788 example trackers with Names like:: | |
| 789 | |
| 790 Name: classic-bugtracker | |
| 791 | |
| 792 Name: devel-mytracker | |
| 793 | |
| 794 were derived from the ``classic`` and ``devel`` templates | |
| 795 respectively. If your tracker is derived from the jinja2 | |
| 796 template, you may not be affected as it doesn't provide | |
| 797 classhelpers by default. If you aren't sure which tracker | |
| 798 template was used to create your tracker home, check the | |
| 799 ``html/help.html`` file for the word ``Javascript``. If your | |
| 800 help.html is missing the word ``Javascript``, follow the | |
| 801 directions for the classic template. | |
| 802 | |
| 803 If you have not modified the original tracker html | |
| 804 templates, you can copy replacement files from the new | |
| 805 templates supplied with release 2.4.0. If you install 2.4.0 | |
| 806 in a `new virtual environment | |
| 807 <installation.html#standard-installation>`_, you can use the | |
| 808 command ``roundup-admin templates`` to find the installation | |
| 809 path of the default templates. | |
| 810 | |
| 811 If your template was based on the classic template, replace the | |
| 812 following files in your tracker: | |
| 813 | |
| 814 * html/_generic.calendar.html | |
| 815 * html/_generic.help-list.html | |
| 816 * html/_generic.help-submit.html | |
| 817 * html/_generic.help.html | |
| 818 * html/user.help-search.html | |
| 819 * html/user.help.html | |
| 820 | |
| 821 If your template was based on the minimal template, replace the | |
| 822 following files in your tracker: | |
| 823 | |
| 824 * html/_generic.calendar.html | |
| 825 * html/_generic.help.html | |
| 826 | |
| 827 If your template was based on the responsive or devel templates, | |
| 828 replace the following files in your tracker: | |
| 829 | |
| 830 * html/_generic.calendar.html | |
| 831 * html/_generic.help-submit.html | |
| 832 * html/help.html | |
| 833 * html/user.help-search.html | |
| 834 * html/user.help.html | |
| 835 | |
| 836 As an example, assume Roundup's virtual environment is | |
| 837 ``/tools/roundup``. The classic tracker's default template will | |
| 838 be in ``/tools/roundup/share/roundup/templates/classic``. | |
| 839 Copy | |
| 840 ``/tools/roundup/share/roundup/templates/classic/html/_generic.calendar.html`` | |
| 841 to ``html/_generic.calendar.html`` in your tracker's home | |
| 842 directory. Repeat for every one of the files that needs to | |
| 843 be replaced. | |
| 844 | |
| 845 If you have made local changes to your popup/classhelper | |
| 846 files or have created new help templates based on the | |
| 847 existing ones, don't copy the default files. Instead, follow | |
| 848 the directions below to modify each file as needed for your | |
| 849 template. | |
| 850 | |
| 851 In the examples below, your script tag may differ. For | |
| 852 example it could include:: | |
| 853 | |
| 854 tal:attributes="nonce request/client/client_nonce" | |
| 855 | |
| 856 If it does, keep the differences. You want to make changes | |
| 857 to remove the structure option but keep the rest of the | |
| 858 valid attributes. | |
| 859 | |
| 860 Most files have a small script that sets a few variables | |
| 861 from the settings in the URL. You should change:: | |
| 862 | |
| 863 <script language="Javascript" type="text/javascript" | |
| 864 tal:content="structure string: | |
| 865 // this is the name of the field in the original form that we're working on | |
| 866 form = window.opener.document.${request/form/form/value}; | |
| 867 field = '${request/form/property/value}';"> | |
| 868 | |
| 869 to:: | |
| 870 | |
| 871 <script language="Javascript" type="text/javascript" | |
| 872 tal:content="string: | |
| 873 // this is the name of the field in the original form that we're working on | |
| 874 form = window.opener.document.${request/form/form/value}; | |
| 875 field = '${request/form/property/value}';"> | |
| 876 | |
| 877 by removing the ``structure`` keyword from the tal:content | |
| 878 block. This will html escape the settings in the URL. This | |
| 879 neutralizes an attempt to execute JavaScript by manipulating | |
| 880 the URL. Most of the files use code similar to this. | |
| 881 | |
| 882 A few files have more extensive JavaScript embedded in the same | |
| 883 script tag. To handle this you should split it into two scripts | |
| 884 and encode the replaced strings. For example, change:: | |
| 885 | |
| 886 <script language="Javascript" type="text/javascript" | |
| 887 tal:content="structure string:<!-- | |
| 888 // this is the name of the field in the original form that we're working on | |
| 889 form = parent.opener.document.${request/form/form/value}; | |
| 890 callingform=form | |
| 891 field = '${request/form/property/value}'; | |
| 892 var listform = null | |
| 893 function listPresent() { | |
| 894 return document.frm_help.cb_listpresent.checked | |
| 895 [more code skipped] | |
| 896 | |
| 897 to:: | |
| 898 | |
| 899 <script language="Javascript" type="text/javascript" | |
| 900 tal:content="string: | |
| 901 // this is the name of the field in the original form that we're working on | |
| 902 form = parent.opener.document.${request/form/form/value}; | |
| 903 callingform=form | |
| 904 field = '${request/form/property/value}';"> | |
| 905 </script> | |
| 906 <script language="Javascript" type="text/javascript" | |
| 907 tal:content="string: | |
| 908 var listform = null | |
| 909 function listPresent() { | |
| 910 return document.frm_help.cb_listpresent.checked | |
| 911 [...] | |
| 912 | |
| 913 modifying the original by: | |
| 914 | |
| 915 1. removing the ``structure`` keyword and the HTML comment | |
| 916 marker ``<!--``. This encodes the replaced strings. | |
| 917 2. adding ``">`` at the end of the line that sets ``field`` closes | |
| 918 the script tag. | |
| 919 3. adding:: | |
| 920 | |
| 921 </script> | |
| 922 <script language="Javascript" type="text/javascript" | |
| 923 tal:content="string: | |
| 924 | |
| 925 after the line used in step 2, to ends the first script and | |
| 926 starts a new script. | |
| 927 | |
| 928 Just removing the ``structure`` directive is enough to fix the | |
| 929 bug. Splitting the large script into two parts: | |
| 930 | |
| 931 1. one that has replaced strings with values taken from the URL | |
| 932 2. one that has no replaced strings | |
| 933 | |
| 934 allows use of ``structure`` on the script with no replaced | |
| 935 strings should it be required for your tracker. | |
| 936 | |
| 937 .. [#markdown-note] If you are using markdown formatting for your tracker's notes, | |
| 938 the user will see the markdown label rather than the long | |
| 939 (suspicious) URL. You may want to add something like:: | |
| 940 | |
| 941 a[href*=\@template]::after { | |
| 942 content: ' [' attr(href) ']'; | |
| 943 } | |
| 944 | |
| 945 to your css. This displays the URL inside square brackets if | |
| 946 the href has ``@template`` in it. It is placed after the link | |
| 947 label. | |
| 948 | |
| 949 Fix CVE in earlier versions of Roundup (recommended) | |
| 950 ---------------------------------------------------- | |
| 951 | |
| 952 If you are upgrading to version 2.4.0, you can skip this | |
| 953 section. These fixes are already present in 2.4.0. | |
| 954 | |
| 955 This section is for people who can not upgrade yet, and want | |
| 956 to fix the issues. | |
| 957 | |
| 958 .. _CVE-2024-39125: | |
| 959 | |
| 960 Referer value not escaped CVE-2024-39125 | |
| 961 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 962 | |
| 963 Malicious JavaScript inserted into a page can change the value of | |
| 964 the Referer header to include a script. If a link on that page | |
| 965 points to a Roundup tracker, that script will be executed. The | |
| 966 technique to change the header will result in a change of the URL | |
| 967 in the browser's address bar, but this is easily missed. | |
| 968 | |
| 969 Fix this by editing ``cgi/client.py``, and change:: | |
| 970 | |
| 971 except (UsageError, Unauthorised) as msg: | |
| 972 csrf_ok = False | |
| 973 self.form_wins = True | |
| 974 self._error_message = msg.args | |
| 975 | |
| 976 to:: | |
| 977 | |
| 978 except (UsageError, Unauthorised) as msg: | |
| 979 csrf_ok = False | |
| 980 self.form_wins = True | |
| 981 self.add_error_message(' '.join(msg.args)) | |
| 982 | |
| 983 This escapes the Referer value and prevents it from being | |
| 984 executed. | |
| 985 | |
| 986 .. _CVE-2024-39126: | |
| 987 | |
| 988 Stop JavaScript execution from attached files CVE-2024-39126 | |
| 989 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 990 | |
| 991 If an SVG, XML or PDF file that includes malicious JavaScript is | |
| 992 attached to an issue, downloading the file will cause the | |
| 993 JavaScript to run. | |
| 994 | |
| 995 In ``cgi/client.py`` add the Content-Security-Policy line | |
| 996 after the existing ``nosniff`` line so it looks like:: | |
| 997 | |
| 998 # exception handlers. | |
| 999 self.determine_language() | |
| 1000 self.db.i18n = self.translator | |
| 1001 self.setHeader("X-Content-Type-Options", "nosniff") | |
| 1002 self.setHeader("Content-Security-Policy", "script-src 'none'") | |
| 1003 self.serve_file(designator) | |
| 1004 | |
| 1005 (the example is reindented for display). | |
| 1006 | |
| 1007 This should prevent SVG and XML files with embedded scripts | |
| 1008 from running. | |
| 1009 | |
| 1010 If your version of Roundup is old enough that the ``nosniff`` | |
| 1011 line is missing, search for ``serve_file(designator)`` and add | |
| 1012 both setHeader lines. | |
| 1013 | |
| 1014 .. warning:: | |
| 1015 | |
| 1016 If your users use older browsers that don't support Content | |
| 1017 Security Policies (e.g. Internet Explorer), you must | |
| 1018 remove ``text/xml`` and ``image/svg`` from | |
| 1019 ``mime_type_allowlist`` as explained below for | |
| 1020 ``application/pdf``. | |
| 1021 | |
| 1022 PDF files can also embed JavaScript. Many browsers include | |
| 1023 PDF viewers that may not support disabling scripting. The | |
| 1024 safest way to handle this is to force a download of the PDF | |
| 1025 file and use a PDF viewer with scripting disabled. To force | |
| 1026 downloading, look in ``cgi/client.py`` for | |
| 1027 ``mime_type_allowlist`` and remove the line for | |
| 1028 ``application/pdf``. | |
| 1029 | |
| 1030 Version 2.4.0 allows you to `modify the mime_type_allowlist | |
| 1031 using interfaces.py | |
| 1032 <admin_guide.html#controlling-browser-handling-of-attached-files>`_. | |
| 1033 This will allow you to enable in-browser reading of PDF | |
| 1034 files when you upgrade to 2.4.0 if you wish. | |
| 1035 | |
| 1036 Note that a `Content Security Policy as documented in the admin | |
| 1037 guide | |
| 1038 <admin_guide.html#adding-a-web-content-security-policy-csp>`_ is | |
| 1039 not applied it to a direct download. This requires adding an | |
| 1040 explicit CSP header as above. | |
| 1041 | |
| 1042 .. comment: end of CVE include marker | |
| 1043 | |
| 1044 XHTML no longer supported (required) | |
| 1045 ------------------------------------ | |
| 1046 | |
| 1047 If your ``config.ini`` sets ``html_version`` to ``xhtml``, | |
| 1048 you need to change it to ``html``. Then you need to change | |
| 1049 your tracker's templates to html from xhtml. | |
| 1050 | |
| 1051 Note that the default Roundup templates use html4 so it is | |
| 1052 unlikely that your templates are xhtml based. See | |
| 1053 `issue2551323 | |
| 1054 <https://issues.roundup-tracker.org/issue2551323>`_ for | |
| 1055 details on the deprecation of xhtml. | |
| 1056 | |
| 1057 Update MySQL character set/collations (required) | |
| 1058 ------------------------------------------------ | |
| 1059 | |
| 1060 issue2551282_ and issue2551115_ discuss issues with MySQL's utf8 | |
| 1061 support. MySQL has variations on utf8 character support. This | |
| 1062 version of Roundup expects to use utf8mb4 which is a version of | |
| 1063 utf8 that covers all characters, not just the ones in the basic | |
| 1064 multilingual plane. Previous versions of Roundup used latin1 or | |
| 1065 utf8mb3 (also known as just utf8). Newer versions of MySQL are | |
| 1066 supposed to make utf8mb4 and not utf8mb3 the default. | |
| 1067 | |
| 1068 To convert your database, you need to have MySQL 8.0.11 or newer | |
| 1069 (April 2018) and a mysql client. | |
| 1070 | |
| 1071 .. warning:: | |
| 1072 | |
| 1073 This conversion can damage your database. Back up your | |
| 1074 database using mysqldump or other tools. Preferably on a quiet | |
| 1075 database. Verify that your database can be restored (or at | |
| 1076 least look up directions for restoring it). This is very | |
| 1077 important. | |
| 1078 | |
| 1079 We suggest shutting down Roundup's interfaces: | |
| 1080 | |
| 1081 * web | |
| 1082 * email | |
| 1083 * cron jobs that use Python or roundup-admin | |
| 1084 | |
| 1085 then make your backup. | |
| 1086 | |
| 1087 Then connect to your mysql instance using ``mysql`` with the | |
| 1088 information in ``config.ini``. If your tracker's ``config.ini`` | |
| 1089 includes:: | |
| 1090 | |
| 1091 name = roundupdb | |
| 1092 host = localhost | |
| 1093 user = roundupuser | |
| 1094 password = rounduppw | |
| 1095 | |
| 1096 you would run some version of:: | |
| 1097 | |
| 1098 mysql -u roundupuser --host localhost -p roundupdb | |
| 1099 | |
| 1100 and supply ``rounduppw`` when prompted. | |
| 1101 | |
| 1102 With the Roundup database quiet, convert the character set for the | |
| 1103 database and then for all the tables. To convert the tables you | |
| 1104 need a list of them. To get this run:: | |
| 1105 | |
| 1106 mysql -sN -u roundupuser --host localhost -p \ | |
| 1107 -e 'show tables;' roundupdb > /tmp/tracker.tables | |
| 1108 | |
| 1109 The ``-sN`` removes line drawing characters and column headers | |
| 1110 from the output. For each table ``<t>`` in the file, run:: | |
| 1111 | |
| 1112 ALTER TABLE `<t>` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; | |
| 1113 | |
| 1114 You can automate this conversion using sed:: | |
| 1115 | |
| 1116 sed -e 's/^/ALTER TABLE `/' \ | |
| 1117 -e 's/$/` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;/'\ | |
| 1118 /tmp/tracker.tables> /tmp/tracker.tables.sql | |
| 1119 | |
| 1120 The backticks "`" are required as some of the table names became | |
| 1121 MySQL reserved words during Roundup's lifetime. | |
| 1122 | |
| 1123 Inspect ``tracker.tables.sql`` to see if all the lines look | |
| 1124 correct. If so then we can start the conversion. | |
| 1125 | |
| 1126 First convert the character set for the database by running:: | |
| 1127 | |
| 1128 mysql -u roundupuser --host localhost -p roundupdb | |
| 1129 | |
| 1130 Then at the ``mysql>`` prompt run:: | |
| 1131 | |
| 1132 ALTER DATABASE roundupdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; | |
| 1133 | |
| 1134 you should see: ``Query OK, 1 row affected (0.01 sec)``. | |
| 1135 | |
| 1136 Now to modify all the tables run: | |
| 1137 | |
| 1138 \. /tmp/tracker.tables.sql | |
| 1139 | |
| 1140 You will see output similar to:: | |
| 1141 | |
| 1142 Query OK, 5 rows affected (0.01 sec) | |
| 1143 Records: 5 Duplicates: 0 Warnings: 0 | |
| 1144 | |
| 1145 for each table. The rows/records will depend on the number of | |
| 1146 entries in the table. This can take a while. | |
| 1147 | |
| 1148 Once you have successfully completed this, copy your tracker's | |
| 1149 config.ini to a backup file. Edit ``config.ini`` to use the defaults: | |
| 1150 | |
| 1151 * mysql_charset = utf8mb4 | |
| 1152 * mysql_collation = utf8mb4_unicode_ci | |
| 1153 * mysql_binary_collation = utf8mb4_0900_bin | |
| 1154 | |
| 1155 Also look for a ``~/.my.cnf`` for the roundup user and make sure | |
| 1156 that the settings for character set (charset) are utf8mb4 compatible. | |
| 1157 | |
| 1158 To test, run ``roundup-admin -i tracker_home`` and display an | |
| 1159 issue designator: e.g. ``display issue10``. Check that the text | |
| 1160 fields are properly displayed (e.g. title). Start the web | |
| 1161 interface and browse some issues. Again, check that the text | |
| 1162 fields display correctly, that the history at the bottom of the | |
| 1163 issues displays correctly and if you are using the default full | |
| 1164 text search, make sure that that works. | |
| 1165 | |
| 1166 If this works, bring email cron jobs etc. back online. | |
| 1167 | |
| 1168 If this fails, take down the web interface, restore the database | |
| 1169 from backup, restore the old config.ini. Then test again and | |
| 1170 reach out to the mailing list for help. | |
| 1171 | |
| 1172 We can use assistance in getting these directions corrected or | |
| 1173 enhanced. The core Roundup developers don't use MySQL for their | |
| 1174 production workloads so we count on users to help us with this. | |
| 1175 | |
| 1176 References: | |
| 1177 | |
| 1178 * https://mathiasbynens.be/notes/mysql-utf8mb4#utf8-to-utf8mb4 | |
| 1179 * https://adamhooper.medium.com/in-mysql-never-use-utf8-use-utf8mb4-11761243e434 | |
| 1180 | |
| 1181 .. _issue2551282: https://issues.roundup-tracker.org/issue2551282 | |
| 1182 .. _issue2551115: https://issues.roundup-tracker.org/issue2551115 | |
| 1183 | |
| 1184 Disable spellcheck on all password fields (recommended) | |
| 1185 ------------------------------------------------------- | |
| 1186 | |
| 1187 All tracker templates have been updated to disable spell checking on | |
| 1188 password input fields. This can help prevent exposing the password to | |
| 1189 an external server that provides spell checking for a browser. Since | |
| 1190 passwords should not be real words in any language, spell checking | |
| 1191 serves no purpose. | |
| 1192 | |
| 1193 If you have modified your template with a "show password" option you | |
| 1194 should disable spell check. | |
| 1195 | |
| 1196 To implement this in your deployed trackers, add:: | |
| 1197 | |
| 1198 spellcheck="false" | |
| 1199 | |
| 1200 to make your password inputs look like:: | |
| 1201 | |
| 1202 <input type="password" spellcheck="false" name=....> | |
| 1203 | |
| 1204 The changed files in the classic/devel/responsive templates are: | |
| 1205 | |
| 1206 .. code-block:: text | |
| 1207 | |
| 1208 html/page.html | |
| 1209 html/user.item.html | |
| 1210 | |
| 1211 and in the jinja2 template the following files were changed: | |
| 1212 | |
| 1213 .. code-block:: text | |
| 1214 | |
| 1215 html/user.item.html | |
| 1216 html/user.register.html | |
| 1217 html/layout/navigation.html | |
| 1218 | |
| 1219 Add new classhelper to your templates (optional) | |
| 1220 ------------------------------------------------ | |
| 1221 | |
| 1222 The classic classhelper invoked by the ``(list)`` link in your | |
| 1223 issue.item.html template can be greatly improved by wrapping the | |
| 1224 links with the new web-component based ``roundup-classhelper``. | |
| 1225 | |
| 1226 The new classhelper: | |
| 1227 | |
| 1228 * allows you to select items from multiple pages | |
| 1229 * is usable with a content security policy | |
| 1230 * is more easily styled | |
| 1231 | |
| 1232 To deploy it, install the required files and wrap classhelp calls | |
| 1233 in the new ``<roundup-classhelper>`` component. For example, | |
| 1234 wrap:: | |
| 1235 | |
| 1236 <span tal:condition="context/is_edit_ok" tal:replace="structure | |
| 1237 python:db.user.classhelp('username,realname,address', | |
| 1238 property='nosy', width='600'" /> | |
| 1239 | |
| 1240 so it looks like:: | |
| 1241 | |
| 1242 <roundup-classhelper | |
| 1243 data-search-with="username,phone,roles[]"> | |
| 1244 | |
| 1245 <span tal:condition="context/is_edit_ok" tal:replace="structure | |
| 1246 python:db.user.classhelp('username,realname,address', | |
| 1247 property='nosy', width='600')" /> | |
| 1248 | |
| 1249 </roundup-classhelper> | |
| 1250 | |
| 1251 to allow the user to search by: username, phone number and use a | |
| 1252 select/dropdown to search by role. Full details about the | |
| 1253 attributes and installation instructions can be found in the | |
| 1254 `classhelper documentation`_ in the admin guide. | |
| 1255 | |
| 1256 | |
| 1257 Disable performance improvement for wsgi mode (optional) | |
| 1258 -------------------------------------------------------- | |
| 1259 | |
| 1260 In Roundup version 2.2.0, an experimental feature was introduced to | |
| 1261 enhance performance while operating in wsgi mode. Initially, this | |
| 1262 feature was disabled. Over the past two years, it has been used at a | |
| 1263 few sites without any reported problems. | |
| 1264 | |
| 1265 As a result, the default setting now enables this performance | |
| 1266 improvement, encouraging a wider adoption of the feature. In the | |
| 1267 event that an undiscovered bug arises, it can still be disabled | |
| 1268 if you experience problems. To disable it, modify your wsgi | |
| 1269 startup script and add the feature_flags to the RequestDispatcher | |
| 1270 as below:: | |
| 1271 | |
| 1272 feature_flags = { "cache_tracker": False } | |
| 1273 app = RequestDispatcher(tracker_home, feature_flags=feature_flags) | |
| 1274 | |
| 1275 Then restart your wsgi instance. If you have to disable this | |
| 1276 feature, send email to the roundup-users mailing list | |
| 1277 (roundup-users at lists.sourceforge.net) so we can help you | |
| 1278 diagnose the cause and fix it for everybody. | |
| 1279 | |
| 1280 In the future, support for disabling this improvement will be removed. | |
| 1281 | |
| 115 Fix duplicate id for confirm password in user.item.html (optional) | 1282 Fix duplicate id for confirm password in user.item.html (optional) |
| 116 ------------------------------------------------------------------ | 1283 ------------------------------------------------------------------ |
| 117 | 1284 |
| 118 The TAL macro ``user_confirm_input`` at the end of ``html/page.html`` | 1285 The TAL macro ``user_confirm_input`` at the end of ``html/page.html`` |
| 119 for all templates except ``jinja2`` sets the ``id`` of the ``Confirm | 1286 for all templates except ``jinja2`` sets the ``id`` of the ``Confirm |
| 132 to:: | 1299 to:: |
| 133 | 1300 |
| 134 tal:attributes="id string:confirm_$name; name string:@confirm@$name; readonly not:edit_ok" value=""> | 1301 tal:attributes="id string:confirm_$name; name string:@confirm@$name; readonly not:edit_ok" value=""> |
| 135 | 1302 |
| 136 This will change the id to ``confirm_password``. | 1303 This will change the id to ``confirm_password``. |
| 1304 | |
| 1305 Merge changes from devel template task.index.html (optional) | |
| 1306 ------------------------------------------------------------ | |
| 1307 | |
| 1308 The devel template's ``task.index.html`` has some fields that are not | |
| 1309 defined in the schema. It looks like it was originally copied from the | |
| 1310 ``bug.index.html``. If the task index is requested without specifying | |
| 1311 the columns/fields, the template will crash trying to display | |
| 1312 ``severity`` and other fields that don't exist in the task schema. | |
| 1313 | |
| 1314 In normal use, the left hand menu for tasks always specifies valid | |
| 1315 columns so you may not see this issue. However if you remove the | |
| 1316 ``@columns`` query parameter, you can see the error. | |
| 1317 | |
| 1318 The removed columns are: severity, versions, keywords, dependencies. | |
| 1319 | |
| 1320 It is also missing the ``solves`` field which is added to match the | |
| 1321 schema. | |
| 1322 | |
| 1323 `You can see the diff in the Sourceforge web interface <https://sourceforge.net/p/roundup/code/ci/54eb12cd3be143b079809795dcb2f813f75a691c/tree/share/roundup/templates/devel/html/task.index.html?diff=c95870b2bbab822def6066498a4ef8634e76e0b3>`_. | |
| 1324 | |
| 1325 Make group headers span all columns (optional) | |
| 1326 ---------------------------------------------- | |
| 1327 | |
| 1328 In a number of index pages a version of the following TAL command | |
| 1329 appears:: | |
| 1330 | |
| 1331 <th tal:attributes="colspan python:len(request.columns)" class="group"> | |
| 1332 | |
| 1333 If the ``@columns`` parameter (aka request.columns) is not set, | |
| 1334 all columns are shown. However the group header only spans the | |
| 1335 first column. Changing this to read:: | |
| 1336 | |
| 1337 <th tal:attributes="colspan python:len(request.columns) or 100" class="group"> | |
| 1338 | |
| 1339 makes the group header span all the columns (if you have fewer | |
| 1340 than 100 columns). All of the supplied templates hae been | |
| 1341 upgraded with this change. `See issue 2551341 for details | |
| 1342 <https://issues.roundup-tracker.org/issue2551341>`_. | |
| 1343 | |
| 1344 Note the jinja2 template has the same issue, but the development | |
| 1345 team hasn't devised a solution. | |
| 1346 | |
| 1347 Use @current_user in Searches (optional) | |
| 1348 ---------------------------------------- | |
| 1349 | |
| 1350 You can create queries like: "My issues" by searching the ``creator`` | |
| 1351 property of issues for your id number. Similarly you can search for | |
| 1352 "Issues assigned to me" by searching on the ``assignedto`` property. | |
| 1353 | |
| 1354 Queries in Roundup can be shared between users. However queries like | |
| 1355 these can be shared. However for any user but they will only find | |
| 1356 issues created by/assigned to the user who created the query. | |
| 1357 | |
| 1358 This release allows you to search Links to the User class by | |
| 1359 specifying ``@current_user``. This token searches for the currently | |
| 1360 log in user. It makes searches like the above usable when shared. | |
| 1361 | |
| 1362 This only works for properties that are a Link to the user | |
| 1363 class. E.G. creator, actor, assignedto. It does not yet work for | |
| 1364 MultiLink properties (like nosy). | |
| 1365 | |
| 1366 As an example this can be deployed to the classic tracker's issue | |
| 1367 search template (issue.search.html), by replacing:: | |
| 1368 | |
| 1369 <option metal:fill-slot="extra_options" i18n:translate="" | |
| 1370 tal:attributes="value request/user/id">created by | |
| 1371 me</option> | |
| 1372 | |
| 1373 with:: | |
| 1374 | |
| 1375 <option metal:fill-slot="extra_options" value="@current_user" | |
| 1376 tal:attributes="selected python:value == '@current_user'" | |
| 1377 i18n:translate="">created by me</option> | |
| 1378 | |
| 1379 There are three places where ``value request/user/id`` is used in the | |
| 1380 classic template. Your template may have more. | |
| 1381 | |
| 1382 If you have a user with the exact username of `@current_user` they | |
| 1383 should change it. `Details can be found in issue1525113 | |
| 1384 <https://issues.roundup-tracker.org/issue1525113>`_. | |
| 1385 | |
| 1386 New PostgreSQL Settings (optional) | |
| 1387 ---------------------------------- | |
| 1388 | |
| 1389 With this release, you can specify a Postgresql database schema | |
| 1390 to use. By default Roundup creates a database when using | |
| 1391 ``roundup-admin init``. Setting the rdbms ``name`` keyword to | |
| 1392 ``roundup_database.roundup_schema`` will create and use the | |
| 1393 ``roundup_schema`` in the pre-created ``roundup_database``. See | |
| 1394 the `Roundup PostgreSQL documentation`_ for details on how to set | |
| 1395 up the roles. | |
| 1396 | |
| 1397 Also there is a new configuration keyword in the rdbms | |
| 1398 section of ``config.ini``. The ``service`` keyword allows | |
| 1399 you to define the service name for Postgres that will be | |
| 1400 looked up in the `Connection Service File`_. Any of the | |
| 1401 methods of specifying the file including by using the | |
| 1402 ``PGSERVICEFILE`` environment variable are supported. | |
| 1403 | |
| 1404 This is similar to the existing support for MySQL | |
| 1405 option/config files and groups. | |
| 1406 | |
| 1407 If you use services, any settings for the same properties | |
| 1408 (user, name, password ...) that are in the tracker's | |
| 1409 ``config.ini`` will override the service settings. So you | |
| 1410 want to leave the ``config.ini`` settings blank. E.G.:: | |
| 1411 | |
| 1412 [rdbms] | |
| 1413 name = | |
| 1414 host = | |
| 1415 port = | |
| 1416 user = | |
| 1417 password = | |
| 1418 service = roundup_roundup | |
| 1419 | |
| 1420 Setting ``service`` to ``roundup_roundup`` with | |
| 1421 the following in the service file:: | |
| 1422 | |
| 1423 [roundup_roundup] | |
| 1424 host=127.0.0.1 | |
| 1425 port=5432 | |
| 1426 user=roundup | |
| 1427 password=roundup | |
| 1428 dbname=roundup | |
| 1429 | |
| 1430 would use the roundup database with the specified | |
| 1431 credentials. It is possible to define a service that | |
| 1432 connects to a specific schema using:: | |
| 1433 | |
| 1434 options=-c search_path=roundup_service_dev | |
| 1435 | |
| 1436 Note that the first schema specified after ``search_path=`` | |
| 1437 is created and populated. The schema name | |
| 1438 (``roundup_service_dev``) must be terminated by: a comma, | |
| 1439 whitespace or end of line. | |
| 1440 | |
| 1441 You can use the command ``psql "service=db_service_name"`` | |
| 1442 to verify the settings in the connection file. Inside of | |
| 1443 ``psql`` you can verify the ``search_path`` using ``show | |
| 1444 search_path;``. | |
| 1445 | |
| 1446 .. _`Connection Service File`: https://www.postgresql.org/docs/current/libpq-pgservice.html | |
| 1447 | |
| 1448 Update for user.help-search.html (optional) | |
| 1449 ------------------------------------------- | |
| 1450 | |
| 1451 There is a bug in the template used as a search helper for the user | |
| 1452 fields (e.g. the nosy list). The ``properties`` url query argument was | |
| 1453 ignored. You can not select the displayed fields using the | |
| 1454 ``properties`` argument. This is fixed in 2.4.0. You can probably just | |
| 1455 copy the ``user.help-search.html`` from the classic tracker template. | |
| 1456 | |
| 1457 If you have modified that template, you can follow the analysis in | |
| 1458 `issue2551320 <https://issues.roundup-tracker.org/issue2551320>`_ | |
| 1459 to fix your template. | |
| 1460 | |
| 1461 Update for _generic.help.html (optional) | |
| 1462 ---------------------------------------- | |
| 1463 | |
| 1464 Using the ``_generic.help.html`` template with ``classhelper()`` to | |
| 1465 provide information on a property without selecting a property caused | |
| 1466 an error when processing the template. Using the help template with | |
| 1467 Link properties can provide description or other information that the | |
| 1468 user can use to determine the right setting. | |
| 1469 | |
| 1470 If your tracker is based on the minimal or classic tracker and you have | |
| 1471 not changed the _generic.help.html file, you can copy it into place | |
| 1472 from the template directory. | |
| 1473 | |
| 1474 | |
| 1475 Fix static_files use of '-' directory (info) | |
| 1476 -------------------------------------------- | |
| 1477 | |
| 1478 Use of the '-' directory in ``static_files`` config.ini setting now | |
| 1479 works. So it will prevent access to the html directory when using | |
| 1480 ``@@file/`` based url's. | |
| 1481 | |
| 137 | 1482 |
| 138 Bad Login Rate Limiting and Locking (info) | 1483 Bad Login Rate Limiting and Locking (info) |
| 139 ------------------------------------------ | 1484 ------------------------------------------ |
| 140 | 1485 |
| 141 Brute force logins have been rate limited in the HTML web interface | 1486 Brute force logins have been rate limited in the HTML web interface |
| 158 and its storage objects available by importing from:: | 1503 and its storage objects available by importing from:: |
| 159 | 1504 |
| 160 from roundup.anypy.cgi_ import cgi | 1505 from roundup.anypy.cgi_ import cgi |
| 161 from roundup.anypy.cgi_ import FieldStorage, MiniFieldStorage | 1506 from roundup.anypy.cgi_ import FieldStorage, MiniFieldStorage |
| 162 | 1507 |
| 163 It is unlikey that you will care unless you have done some expert | 1508 It is unlikely that you will care unless you have done some expert |
| 164 level Roundup customization. If you have, use one of the imports above | 1509 level Roundup customization. If you have, use one of the imports above |
| 165 if you plan on running on Python 3.13 (expected in 2024) or newer. | 1510 if you plan on running on Python 3.13 (expected in 2024) or newer. |
| 166 | 1511 |
| 167 Fixing PostgreSQL Out of Memory Errors when Importing Tracker (info) | 1512 Fixing PostgreSQL Out of Memory Errors when Importing Tracker (info) |
| 168 -------------------------------------------------------------------- | 1513 -------------------------------------------------------------------- |
| 175 | 1520 |
| 176 before changing your PostgreSQL configuration, try changing the pragma | 1521 before changing your PostgreSQL configuration, try changing the pragma |
| 177 ``savepoint_limit`` to a lower value. By default it is set to | 1522 ``savepoint_limit`` to a lower value. By default it is set to |
| 178 ``10000``. In some cases this may be too high. See the `administration | 1523 ``10000``. In some cases this may be too high. See the `administration |
| 179 guide`_ for further details. | 1524 guide`_ for further details. |
| 1525 | |
| 1526 roundup-admin's History Command Produces Readable Output (info) | |
| 1527 --------------------------------------------------------------- | |
| 1528 | |
| 1529 The history command of roundup-admin used to print the raw journal | |
| 1530 data. In this release the default is to produce more human readable | |
| 1531 data. The original output (not pretty printed as below) was:: | |
| 1532 | |
| 1533 [('1', <Date 2013-02-18.20:30:34.125>, '1', 'create', {}), | |
| 1534 ('1', | |
| 1535 <Date 2013-02-19.21:24:20.391>, | |
| 1536 '1', | |
| 1537 'set', | |
| 1538 {'messages': (('+', ['3']),)}), | |
| 1539 ('1', <Date 2013-02-19.21:24:24.797>, '1', 'set', {'priority': '1'}), | |
| 1540 ('1', | |
| 1541 <Date 2013-02-20.03:16:52.000>, | |
| 1542 '1', | |
| 1543 'link', | |
| 1544 ('issue', '2', 'dependson')), | |
| 1545 ('1', <Date 2013-02-21.20:51:40.750>, '1', 'link', ('issue', '2', | |
| 1546 'seealso')), | |
| 1547 ('1', | |
| 1548 <Date 2013-02-22.05:33:08.875>, | |
| 1549 '1', | |
| 1550 'set', | |
| 1551 {'dependson': (('+', ['3']),), 'private': None, 'queue': None}), | |
| 1552 ('1', | |
| 1553 <Date 2013-02-22.05:33:19.406>, | |
| 1554 '1', | |
| 1555 'set', | |
| 1556 {'dependson': (('+', ['2']),)}), | |
| 1557 ('1', | |
| 1558 <Date 2013-02-27.03:24:42.844>, | |
| 1559 '1', | |
| 1560 'unlink', | |
| 1561 ('issue', '2', 'seealso')), | |
| 1562 ... | |
| 1563 | |
| 1564 Now it produces (Each entry is on one line, lines wrapped | |
| 1565 and indented for display):: | |
| 1566 | |
| 1567 admin(2013-02-18.20:30:34) create issue | |
| 1568 admin(2013-02-19.21:24:20) set modified messages: added: msg3 | |
| 1569 admin(2013-02-19.21:24:24) set priority was critical(1) | |
| 1570 admin(2013-02-20.03:16:52) link added issue2 to dependson | |
| 1571 admin(2013-02-21.20:51:40) link added issue2 to seealso | |
| 1572 admin(2013-02-22.05:33:08) set modified dependson: added: issue3; | |
| 1573 private was None; queue was None | |
| 1574 admin(2013-02-22.05:33:19) set modified dependson: added: issue2 | |
| 1575 admin(2013-02-27.03:24:42) unlink removed issue2 from seealso | |
| 1576 ... | |
| 1577 | |
| 1578 | |
| 1579 A few things to note: set operations can either assign a property or | |
| 1580 report a modification of a multilink property. If an assignment | |
| 1581 occurs, the value reported is the **old value** that was there before | |
| 1582 the assignment. It is **not** the value that is assigned. In the | |
| 1583 example above I don't know what the current value of priority is. All | |
| 1584 I know it was set to critical when the issue was created. | |
| 1585 | |
| 1586 Modifications to multilink properties work differently. I know that | |
| 1587 ``msg3`` was present in the messages property after 2013-02-19 at | |
| 1588 21:24:20 UTC. | |
| 1589 | |
| 1590 The history command gets a new optional argument ``raw`` that produces | |
| 1591 the old style output. The old style is (marginally) more useful for | |
| 1592 script automation. | |
| 1593 | |
| 1594 Deprecation Notices (info) | |
| 1595 -------------------------- | |
| 1596 | |
| 1597 Support for SQLite version 1 has been removed in 2.4.0. | |
| 1598 | |
| 1599 Support for SQLite version 2 will be removed in 2.5.0. | |
| 1600 | |
| 1601 Support for StructuredText has been removed in 2.4.0. Support for | |
| 1602 reStructuredText remains. | |
| 1603 | |
| 1604 Support for the `PySQLite <https://github.com/ghaering/pysqlite>`_ | |
| 1605 library will be removed in 2.5.0. Only the Python supplied sqlite3 | |
| 1606 library will be supported. | |
| 180 | 1607 |
| 181 .. index:: Upgrading; 2.2.0 to 2.3.0 | 1608 .. index:: Upgrading; 2.2.0 to 2.3.0 |
| 182 | 1609 |
| 183 Migrating from 2.2.0 to 2.3.0 | 1610 Migrating from 2.2.0 to 2.3.0 |
| 184 ============================= | 1611 ============================= |
| 256 PostgreSQL database use a numeric type that | 1683 PostgreSQL database use a numeric type that |
| 257 truncates/rounds expiration timestamps. This results in | 1684 truncates/rounds expiration timestamps. This results in |
| 258 entries being purged early or late (depending on whether | 1685 entries being purged early or late (depending on whether |
| 259 it rounds up or down). The discrepancy is a couple of | 1686 it rounds up or down). The discrepancy is a couple of |
| 260 days for Mysql or a couple of minutes for PostgreSQL. | 1687 days for Mysql or a couple of minutes for PostgreSQL. |
| 261 | 1688 |
| 262 Session keys stay for a week or more and CSRF keys are | 1689 Session keys stay for a week or more and CSRF keys are |
| 263 two weeks by default. As a result, this isn't usually a | 1690 two weeks by default. As a result, this isn't usually a |
| 264 visible issue. This migration updates the numeric types | 1691 visible issue. This migration updates the numeric types |
| 265 to ones that supports more significant figures. | 1692 to ones that supports more significant figures. |
| 266 | 1693 |
| 313 | 1740 |
| 314 Update ``config.ini``'s ``password_pbkdf2_default_rounds`` (required) | 1741 Update ``config.ini``'s ``password_pbkdf2_default_rounds`` (required) |
| 315 --------------------------------------------------------------------- | 1742 --------------------------------------------------------------------- |
| 316 | 1743 |
| 317 Roundup hashes passwords using PBKDF2 with SHA1. In this release, you | 1744 Roundup hashes passwords using PBKDF2 with SHA1. In this release, you |
| 318 can `upgrade to PBKDF2-SHA512 from current PBKDF2-SHA1`. If you | 1745 can `upgrade to PBKDF2-SHA512 from current PBKDF2-SHA1 (recommended)`_. If you |
| 319 upgrade, you want to set the default rounds according to the | 1746 upgrade, you want to set the default rounds according to the |
| 320 PBKDF2-SHA512 upgrading directions. Note that this algorithm is | 1747 PBKDF2-SHA512 upgrading directions. Note that this algorithm is |
| 321 expected to be the default in a future version of Roundup. | 1748 expected to be the default in a future version of Roundup. |
| 322 | 1749 |
| 323 If you don't want to upgrade, we recommend that you increase the | 1750 If you don't want to upgrade, we recommend that you increase the |
| 383 You should find out how to make the import succeed. You may need to | 1810 You should find out how to make the import succeed. You may need to |
| 384 install an OS vendor package or some other library. | 1811 install an OS vendor package or some other library. |
| 385 | 1812 |
| 386 .. _recommended setting of 1,300,000: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#pbkdf2 | 1813 .. _recommended setting of 1,300,000: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#pbkdf2 |
| 387 | 1814 |
| 1815 .. _PBKDF2 upgrade: | |
| 1816 | |
| 388 Upgrade to PBKDF2-SHA512 from current PBKDF2-SHA1 (recommended) | 1817 Upgrade to PBKDF2-SHA512 from current PBKDF2-SHA1 (recommended) |
| 389 --------------------------------------------------------------- | 1818 --------------------------------------------------------------- |
| 390 | 1819 |
| 391 We recommend that you upgrade to using PBKDF2-SHA512 for hashing your | 1820 We recommend that you upgrade to using PBKDF2-SHA512 for hashing your |
| 392 passwords. This is a more secure method than the old PBKDF2 (with | 1821 passwords. This is a more secure method than the old PBKDF2 (with |
| 414 command line (``roundup-admin`` for example). | 1843 command line (``roundup-admin`` for example). |
| 415 | 1844 |
| 416 Change the default hashing scheme by adding the following lines to | 1845 Change the default hashing scheme by adding the following lines to |
| 417 |the interfaces.py file|_ in your tracker home:: | 1846 |the interfaces.py file|_ in your tracker home:: |
| 418 | 1847 |
| 1848 from roundup.password import Password | |
| 419 ## Use PBDKF2S5 (PBKDF2-SHA512) for passwords. Re-hash old PBDFK2 | 1849 ## Use PBDKF2S5 (PBKDF2-SHA512) for passwords. Re-hash old PBDFK2 |
| 420 # Force password with scheme PBKDF2 (SHA1) to get re-hashed | 1850 # Force password with scheme PBKDF2 (SHA1) to get re-hashed |
| 421 Password.deprecated_schemes.insert(0, Password.known_schemes[0]) | 1851 Password.deprecated_schemes.insert(0, Password.known_schemes[0]) |
| 422 # choose PBKDF2S5 as the scheme to use for rehashing. | 1852 # choose PBKDF2S5 as the scheme to use for rehashing. |
| 423 Password.default_scheme = Password.experimental_schemes[0] | 1853 Password.default_scheme = Password.experimental_schemes[0] |
| 429 | 1859 |
| 430 You can verify that PBKDF2S5 is used by default by running:: | 1860 You can verify that PBKDF2S5 is used by default by running:: |
| 431 | 1861 |
| 432 roundup-admin -i <tracker_home> perftest password rounds=250,000 | 1862 roundup-admin -i <tracker_home> perftest password rounds=250,000 |
| 433 | 1863 |
| 434 and verify that the scheme is PBKDF2S5. | 1864 and verify that the scheme is PBKDF2S5. |
| 435 | 1865 |
| 436 .. _the interfaces.py file: | 1866 .. _the interfaces.py file: |
| 437 reference.html#interfaces-py-hooking-into-the-core-of-roundup | 1867 reference.html#interfaces-py-hooking-into-the-core-of-roundup |
| 438 | 1868 |
| 439 .. |the interfaces.py file| replace:: the ``interfaces.py`` file | 1869 .. |the interfaces.py file| replace:: the ``interfaces.py`` file |
| 490 sqlite3 <tracker_home>/db/db "pragma journal_mode;" | 1920 sqlite3 <tracker_home>/db/db "pragma journal_mode;" |
| 491 | 1921 |
| 492 2. If it returns ``delete``, change it to WAL mode using:: | 1922 2. If it returns ``delete``, change it to WAL mode using:: |
| 493 | 1923 |
| 494 sqlite3 <tracker_home>/db/db "pragma journal_mode=WAL;" | 1924 sqlite3 <tracker_home>/db/db "pragma journal_mode=WAL;" |
| 495 | 1925 |
| 496 3. verify by running the command in step 1 again and you | 1926 3. verify by running the command in step 1 again and you |
| 497 should get ``wal``. | 1927 should get ``wal``. |
| 498 | 1928 |
| 499 If you are using SQLite for session and otk databases, | 1929 If you are using SQLite for session and otk databases, |
| 500 perform the same steps replacing ``db`` with ``db-session`` | 1930 perform the same steps replacing ``db`` with ``db-session`` |
| 513 | 1943 |
| 514 Change in processing allowed_api_origins setting (info) | 1944 Change in processing allowed_api_origins setting (info) |
| 515 ------------------------------------------------------- | 1945 ------------------------------------------------------- |
| 516 | 1946 |
| 517 In this release you can use both ``*`` (as the first origin) and | 1947 In this release you can use both ``*`` (as the first origin) and |
| 518 explicit origins in the `allowed_api_origins`` setting in | 1948 explicit origins in the ``allowed_api_origins`` setting in |
| 519 ``config.ini``. (Before it was only one or the other.) | 1949 ``config.ini``. (Before it was only one or the other.) |
| 520 | 1950 |
| 521 You do not need to use ``*``. If you do, it allows any client | 1951 You do not need to use ``*``. If you do, it allows any client |
| 522 anonymous (unauthenticated) access to the Roundup tracker. This | 1952 anonymous (unauthenticated) access to the Roundup tracker. This |
| 523 is the same as browsing the tracker without logging in. If they | 1953 is the same as browsing the tracker without logging in. If they |
| 626 allowed to login. Blank passwords have been allowed since 2002, but | 2056 allowed to login. Blank passwords have been allowed since 2002, but |
| 627 2022 is a different time. If you have a use case that requires a user | 2057 2022 is a different time. If you have a use case that requires a user |
| 628 to login without a password, set the ``login_empty_passwords`` setting | 2058 to login without a password, set the ``login_empty_passwords`` setting |
| 629 in the ``web`` section of ``config.ini`` to ``yes``. In | 2059 in the ``web`` section of ``config.ini`` to ``yes``. In |
| 630 general this should be left at its default value of ``no``. | 2060 general this should be left at its default value of ``no``. |
| 2061 | |
| 2062 Verify that SQLite supports FTS5 (required) | |
| 2063 ------------------------------------------- | |
| 2064 | |
| 2065 If you use SQLite as your backend, it *must* support FTS5. See the | |
| 2066 `FTS5 testing steps`_ for how to verify this. | |
| 2067 | |
| 2068 .. _FTS5 testing steps: installation.html#fts5-testing | |
| 631 | 2069 |
| 632 Check allowed_api_origins setting (optional) | 2070 Check allowed_api_origins setting (optional) |
| 633 -------------------------------------------- | 2071 -------------------------------------------- |
| 634 | 2072 |
| 635 If you are using the REST or xmlrpc api's from an origin | 2073 If you are using the REST or xmlrpc api's from an origin |
| 677 https://www.postgresql.org/docs/14/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES | 2115 https://www.postgresql.org/docs/14/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES |
| 678 can be used. The default is websearch. Prefixing the search with | 2116 can be used. The default is websearch. Prefixing the search with |
| 679 ``ts:`` enables tsquery mode. | 2117 ``ts:`` enables tsquery mode. |
| 680 | 2118 |
| 681 A list of words behaves almost the same as the default text search | 2119 A list of words behaves almost the same as the default text search |
| 682 (`native`). So the search string `fts search` will find all issues | 2120 (``native``). So the search string ``fts search`` will find all issues |
| 683 that have both of those words (an AND search) in a text-field (like | 2121 that have both of those words (an AND search) in a text-field (like |
| 684 title) or in a message (or file) attached to the issue. | 2122 title) or in a message (or file) attached to the issue. |
| 685 | 2123 |
| 686 One thing to note is that native-fts searches do not ignore words | 2124 One thing to note is that native-fts searches do not ignore words |
| 687 longer than 50 characters or less than 2 characters. Also SQLite does | 2125 longer than 50 characters or less than 2 characters. Also SQLite does |
| 968 + from html import escape | 2406 + from html import escape |
| 969 +except ImportError: | 2407 +except ImportError: |
| 970 + from cgi import escape | 2408 + from cgi import escape |
| 971 | 2409 |
| 972 try: | 2410 try: |
| 973 import pytz | 2411 import pytz |
| 974 @@ -25,7 +28,7 @@ | 2412 @@ -25,7 +28,7 @@ |
| 975 s = ' ' | 2413 s = ' ' |
| 976 if zone == value: | 2414 if zone == value: |
| 977 s = 'selected=selected ' | 2415 s = 'selected=selected ' |
| 978 - z = cgi.escape(zone) | 2416 - z = cgi.escape(zone) |
| 979 + z = escape(zone) | 2417 + z = escape(zone) |
| 980 | 2418 |
| 981 See https://issues.roundup-tracker.org/issue2551136 for more details. | 2419 See https://issues.roundup-tracker.org/issue2551136 for more details. |
| 982 | 2420 |
| 1055 will take longer but may be worth trying if the ``exporttables`` and | 2493 will take longer but may be worth trying if the ``exporttables`` and |
| 1056 ``importtables`` method fails for some reason. | 2494 ``importtables`` method fails for some reason. |
| 1057 | 2495 |
| 1058 Another way that should be faster, but is untested is to use mysql | 2496 Another way that should be faster, but is untested is to use mysql |
| 1059 dump to dump the database. | 2497 dump to dump the database. |
| 1060 https://makandracards.com/makandra/595-dumping-and-importing-from-to-mysql-in-an-utf-8-safe-way | 2498 https://makandracards.com/makandra/595-dumping-importing-mysql-utf-8-safe-way |
| 1061 recommends:: | 2499 recommends: |
| 1062 | 2500 |
| 1063 Note that when your MySQL server is not set to UTF-8 you need to do | 2501 Note that when your MySQL server is not set to UTF-8 you need to do |
| 1064 mysqldump --default-character-set=latin1 (!) to get a correctly | 2502 mysqldump --default-character-set=latin1 (!) to get a correctly |
| 1065 encoded dump. In that case you will also need to remove the SET | 2503 encoded dump. In that case you will also need to remove the SET |
| 1066 NAMES='latin1' comment at the top of the dump, so the target machine | 2504 NAMES='latin1' comment at the top of the dump, so the target machine |
| 1068 | 2506 |
| 1069 Then import the dump. Removing ``SET NAMES`` should allow the import | 2507 Then import the dump. Removing ``SET NAMES`` should allow the import |
| 1070 to use UTF-8. | 2508 to use UTF-8. |
| 1071 | 2509 |
| 1072 Please report success or issues with this conversion to the | 2510 Please report success or issues with this conversion to the |
| 1073 roundup-users AT lists.sourceforge.net mailing list. | 2511 roundup-users at lists.sourceforge.net mailing list. |
| 1074 | 2512 |
| 1075 As people report successful or unsuccessful conversions, we will update | 2513 As people report successful or unsuccessful conversions, we will update |
| 1076 the errata page at: https://wiki.roundup-tracker.org/ReleaseErrata. | 2514 the errata page at: https://wiki.roundup-tracker.org/ReleaseErrata. |
| 1077 | 2515 |
| 1078 Upgrade tracker's config.ini file (recommended) | 2516 Upgrade tracker's config.ini file (recommended) |
| 1134 processed. | 2572 processed. |
| 1135 | 2573 |
| 1136 If you do not modify the ``user.register.html`` template in your | 2574 If you do not modify the ``user.register.html`` template in your |
| 1137 tracker's html directory, you *must* set this to 0. Otherwise you will | 2575 tracker's html directory, you *must* set this to 0. Otherwise you will |
| 1138 see the error: | 2576 see the error: |
| 2577 | |
| 2578 .. code-block:: text | |
| 1139 | 2579 |
| 1140 Form is corrupted, missing: opaqueregister. | 2580 Form is corrupted, missing: opaqueregister. |
| 1141 | 2581 |
| 1142 If set to 0, the rate limit check is disabled. | 2582 If set to 0, the rate limit check is disabled. |
| 1143 | 2583 |
| 1411 this section. | 2851 this section. |
| 1412 | 2852 |
| 1413 Make sure that user can view labelprop on classes (required) | 2853 Make sure that user can view labelprop on classes (required) |
| 1414 ------------------------------------------------------------ | 2854 ------------------------------------------------------------ |
| 1415 | 2855 |
| 1416 If you have View permissions that use ```properties=...```, make sure | 2856 If you have View permissions that use ``properties=...``, make sure |
| 1417 that the `labelprop <reference.html#setlabelprop-property>`_ for the | 2857 that the `labelprop <reference.html#setlabelprop-property>`_ for the |
| 1418 class is listed in the properties list. | 2858 class is listed in the properties list. |
| 1419 | 2859 |
| 1420 The first one of these that exists must must be in the list: | 2860 The first one of these that exists must must be in the list: |
| 1421 | 2861 |
| 1526 these forms as it is not needed. | 2966 these forms as it is not needed. |
| 1527 | 2967 |
| 1528 Errors and Troubleshooting - AttributeError list object no attribute value | 2968 Errors and Troubleshooting - AttributeError list object no attribute value |
| 1529 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 2969 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 1530 If you get an error: | 2970 If you get an error: |
| 2971 | |
| 2972 .. code-block:: text | |
| 1531 | 2973 |
| 1532 AttributeError: 'list' object has no attribute 'value' | 2974 AttributeError: 'list' object has no attribute 'value' |
| 1533 | 2975 |
| 1534 in handle_csrf, you have more than one @csrf token for the form. This | 2976 in handle_csrf, you have more than one @csrf token for the form. This |
| 1535 usually occurs because the form uses the standard context/submit | 2977 usually occurs because the form uses the standard context/submit |
| 1696 # who updated the issue, but it could be useful in some | 3138 # who updated the issue, but it could be useful in some |
| 1697 # unusual circumstances. | 3139 # unusual circumstances. |
| 1698 # If set to some other value, the value is used as the reply-to | 3140 # If set to some other value, the value is used as the reply-to |
| 1699 # address. It must be a valid RFC2822 address or people will not be | 3141 # address. It must be a valid RFC2822 address or people will not be |
| 1700 # able to reply. | 3142 # able to reply. |
| 1701 # Default: | 3143 # Default: |
| 1702 replyto_address = | 3144 replyto_address = |
| 1703 | 3145 |
| 1704 Login from a search or after logout works better (required) | 3146 Login from a search or after logout works better (required) |
| 1705 ----------------------------------------------------------- | 3147 ----------------------------------------------------------- |
| 1706 | 3148 |
| 1707 The login form has been improved to work with some back end code | 3149 The login form has been improved to work with some back end code |
| 1708 changes. Now when a user logs in they stay on the same page where they | 3150 changes. Now when a user logs in they stay on the same page where they |
| 1709 started the login. To make this work, you must change the tal that is | 3151 started the login. To make this work, you must change the tal that is |
| 1710 used to set the ``__came_from`` form variable. Note that the url | 3152 used to set the ``__came_from`` form variable. Note that the url |
| 1711 assigned to __came_from must be url encoded/quoted and be under the | 3153 assigned to __came_from must be url encoded/quoted and be under the |
| 1712 tracker's base url. If the base_url uses http, you can set the url to | 3154 tracker's base url. If the base_url uses http, you can set the url to |
| 1713 https. | 3155 https. |
| 1714 | 3156 |
| 1715 Replace the existing code in the tracker's html/page.html page that | 3157 Replace the existing code in the tracker's html/page.html page that |
| 1716 looks similar to (look for name="__came_from"): | 3158 looks similar to (look for name="__came_from"): |
| 1717 | 3159 |
| 1869 :class: big-code | 3311 :class: big-code |
| 1870 | 3312 |
| 1871 <tal:block tal:repeat="qs request/user/queries"> | 3313 <tal:block tal:repeat="qs request/user/queries"> |
| 1872 - <a href="#" tal:attributes="href string:${qs/klass}?${qs/url}&@dispname=${qs/name}" | 3314 - <a href="#" tal:attributes="href string:${qs/klass}?${qs/url}&@dispname=${qs/name}" |
| 1873 + <a href="#" tal:attributes="href string:${qs/klass}?${qs/url}&@dispname=${qs/name/url_quote}" | 3315 + <a href="#" tal:attributes="href string:${qs/klass}?${qs/url}&@dispname=${qs/name/url_quote}" |
| 1874 tal:content="qs/name">link</a><br> | 3316 tal:content="qs/name">link</a><br> |
| 1875 </tal:block> | 3317 </tal:block> |
| 1876 | 3318 |
| 1877 Find the tal:repeat line that loops over all queries. Then | 3319 Find the tal:repeat line that loops over all queries. Then |
| 1878 change the value assigned to @dispname in the href attribute from | 3320 change the value assigned to @dispname in the href attribute from |
| 1879 ${qs/name} to ${qs/name/url_quote}. Note that you should *not* change | 3321 ${qs/name} to ${qs/name/url_quote}. Note that you should *not* change |
| 1993 | 3435 |
| 1994 If you haven't modified you query.item.html template, simply copy the | 3436 If you haven't modified you query.item.html template, simply copy the |
| 1995 query.item.html template from one of the above default templates to | 3437 query.item.html template from one of the above default templates to |
| 1996 your tracker's html directory. | 3438 your tracker's html directory. |
| 1997 | 3439 |
| 1998 Enhancement to check command for Permissions | 3440 Enhancement to check command for Permissions (optional) |
| 1999 -------------------------------------------- | 3441 ------------------------------------------------------- |
| 2000 | |
| 2001 A new form of check function is permitted in permission definitions. | 3442 A new form of check function is permitted in permission definitions. |
| 2002 The three argument form is still supported and will work the same | 3443 An example check function is ``own_record(db, userid, itemid)`` in the |
| 2003 as it always has (although it may be depricated in the future). | 3444 file schema.py. The three argument form is still supported and will |
| 3445 work the same as it always has (although it may be depricated in the | |
| 3446 future). | |
| 2004 | 3447 |
| 2005 If the check function is defined as:: | 3448 If the check function is defined as:: |
| 2006 | 3449 |
| 2007 check(db, userid, itemid, **ctx) | 3450 check(db, userid, itemid, **ctx) |
| 2008 | 3451 |
| 2019 | 3462 |
| 2020 This should make defining complex permissions much easier. Consider:: | 3463 This should make defining complex permissions much easier. Consider:: |
| 2021 | 3464 |
| 2022 def issue_private_access(db, userid, itemid, **ctx): | 3465 def issue_private_access(db, userid, itemid, **ctx): |
| 2023 if not db.issue.get(itemid, 'private'): | 3466 if not db.issue.get(itemid, 'private'): |
| 2024 # allow access to everything if not private | 3467 # allow access to everything if not private |
| 2025 return True | 3468 return True |
| 2026 | 3469 |
| 2027 # It is a private issue hide nosy list | 3470 # It is a private issue hide nosy list |
| 2028 # Note that the nosy property *must* be listed | 3471 # Note that the nosy property *must* be listed |
| 2029 # in permissions argument to the addPermission | 3472 # in permissions argument to the addPermission |
| 2030 # definition otherwise this check command | 3473 # definition otherwise this check command |
| 2031 # is not run. | 3474 # is not run. |
| 2032 if ctx['property'] == 'nosy': | 3475 if ctx['property'] == 'nosy': |
| 2033 return False # deny access to this property | 3476 return False # deny access to this property |
| 2034 | 3477 |
| 2035 # allow access for editing, viewing etc. of the class | 3478 # allow access for editing, viewing etc. of the class |
| 2036 return True | 3479 return True |
| 2037 | 3480 |
| 2038 | 3481 |
| 2039 e = db.security.addPermission(name='Edit', klass='issue', | 3482 e = db.security.addPermission(name='Edit', klass='issue', |
| 2040 check=issue_private_access, | 3483 check=issue_private_access, |
| 2041 properties=['nosy'], | 3484 properties=['nosy'], |
| 2042 description="Edit issue checks") | 3485 description="Edit issue checks") |
| 2043 | 3486 |
| 2044 It is suggested that you change your checks to use the ``**ctx`` | 3487 It is suggested that you change your checks to use the ``**ctx`` |
| 2045 parameter. This is expected to be the preferred form in the future. | 3488 parameter. This is expected to be the preferred form in the future. |
| 2046 You do not need to use the ``ctx`` parameter in the function if you do | 3489 You do not need to use the ``ctx`` parameter in the function if you do |
| 2047 not need it. | 3490 not need it. |
| 2048 | 3491 |
| 3492 If the new four argument form is required in the future, there will be | |
| 3493 required (not optional) directions on upgrading your schema. | |
| 3494 | |
| 2049 Changes to property permissions | 3495 Changes to property permissions |
| 2050 ------------------------------- | 3496 ------------------------------- |
| 2051 | 3497 |
| 2052 If you create a permission: | 3498 If you create a permission:: |
| 2053 | 3499 |
| 2054 db.security.addPermission(name='View', klass='user', | 3500 db.security.addPermission(name='View', klass='user', |
| 2055 properties=['theme'], check=own_record, | 3501 properties=['theme'], check=own_record, |
| 2056 description="User is allowed to view their own theme") | 3502 description="User is allowed to view their own theme") |
| 2057 | 3503 |
| 2074 page when the search is triggered. This is usually correct since the | 3520 page when the search is triggered. This is usually correct since the |
| 2075 user expects to see the results of the query. But now that | 3521 user expects to see the results of the query. But now that |
| 2076 the code properly checks for duplicate search names, the user should | 3522 the code properly checks for duplicate search names, the user should |
| 2077 stay on the search page if there is an error. To add this to your | 3523 stay on the search page if there is an error. To add this to your |
| 2078 existing issue.search.html page, add the following line after the | 3524 existing issue.search.html page, add the following line after the |
| 2079 hidden field @old-queryname: | 3525 hidden field ``@old-queryname``:: |
| 2080 | 3526 |
| 2081 <input type="hidden" name="@template" value="index|search"/> | 3527 <input type="hidden" name="@template" value="index|search"/> |
| 2082 | 3528 |
| 2083 With this addition, the index template is displayed if there is no | 3529 With this addition, the index template is displayed if there is no |
| 2084 error, and the user stays on the search template if there is an error. | 3530 error, and the user stays on the search template if there is an error. |
| 2185 ============================= | 3631 ============================= |
| 2186 | 3632 |
| 2187 See the `historical migration <upgrading-history.html>`_ document. | 3633 See the `historical migration <upgrading-history.html>`_ document. |
| 2188 | 3634 |
| 2189 .. _`security documentation`: security-history.html | 3635 .. _`security documentation`: security-history.html |
| 3636 .. _`Roundup postgresql documentation`: postgresql.html | |
| 2190 .. _`administration guide`: admin_guide.html | 3637 .. _`administration guide`: admin_guide.html |
| 2191 .. _`xmlrpc guide`: xmlrpc.html | 3638 .. _`xmlrpc guide`: xmlrpc.html |
| 2192 .. _FTS5 full-text search engine: https://www.sqlite.org/fts5.html | 3639 .. _FTS5 full-text search engine: https://www.sqlite.org/fts5.html |
| 2193 .. _PostgreSQL's full text search: https://www.postgresql.org/docs/current/textsearch.html | 3640 .. _PostgreSQL's full text search: https://www.postgresql.org/docs/current/textsearch.html |
| 2194 .. _`administration guide notes on native-fts`: admin_guide.html#configuring-native-fts-full-text-search | 3641 .. _`administration guide notes on native-fts`: admin_guide.html#configuring-native-fts-full-text-search |
| 2195 .. _Configuring Compression: admin_guide.html#configuring-compression | 3642 .. _Configuring Compression: admin_guide.html#configuring-compression |
| 3643 .. _classhelper documentation: admin_guide.html#classhelper-web-component | |
| 2196 .. _Software Upgrade: admin_guide.html#software-upgrade | 3644 .. _Software Upgrade: admin_guide.html#software-upgrade |
| 2197 .. _new search permissions for query in 1.4.17: | 3645 .. _new search permissions for query in 1.4.17: |
| 2198 upgrading-history.html#new-search-permissions-for-query-in-1-4-17 | 3646 upgrading-history.html#new-search-permissions-for-query-in-1-4-17 |
