.. meta:: :description: Critical documentation for upgrading the Roundup Issue Tracker. Actions that must be taken when upgrading from one version to another are documented here. .. index:: Upgrading ====================================== Upgrading to newer versions of Roundup ====================================== Please read each section carefully and edit the files in your tracker home accordingly. Note that there is information about upgrade procedures in the `administration guide`_ in the `Software Upgrade`_ section. If a specific version transition isn't mentioned here (e.g. 0.6.7 to 0.6.8) then you don't need to do anything. If you're upgrading from 0.5.6 to 0.6.8 though, you'll need to apply the "0.5 to 0.6" and "0.6.x to 0.6.3" steps. General steps: 1. Make note of your current Roundup version. 2. Take your Roundup installation offline (web, email, cron scripts, roundup-admin etc.) 3. Backup your Roundup instance 4. Install the new version of Roundup (preferably in a new virtual environment) 5. Make version specific changes as described below for each version transition. If you are starting at 1.5.0 and installing to 2.3.0, you need to make the changes for **all** versions starting at 1.5 and ending at 2.3. E.G. 1.5.0 -> 1.5.1, 1.5.1 -> 1.6.0, ..., 2.1.0 -> 2.2.0, 2.2.0 -> 2.3.0. 6. Run ``roundup-admin -i migrate`` using the newer version of Roundup for the instance you are upgrading. This will update the database if it is required. 7. Bring your Roundup instance back online 8. Test Repeat for each tracker instance. .. note:: The v1.5.x releases of Roundup were the last to support Python v2.5 and v2.6. Starting with the v1.6 releases of Roundup Python version 2.7 that is newer than 2.7.2 is required to run Roundup. Starting with Roundup version 2.0.0 we also support Python 3 versions newer than 3.6. Recent release notes have the following labels: * **required** - Roundup will not work properly if these steps are not done * **recommended** - Roundup will still work, but these steps can cause security or stability issues if not done. * **optional** - new features or changes to existing features you might want to use * **info** - important possibly visible changes in how things operate If you use virtual environments for your installation, you can run trackers with different versions of Roundup. So you can have one tracker using version 2.2.0 and another tracker using version 1.6.1. This allows you to upgrade trackers one at a time rather than having to upgrade all your trackers at once. Note that downgrading may require restoring your database to an earlier version, so make sure you backed up your database. .. note:: This file only includes versions released in the last 10 years. If you are upgrading from an older version, start with the changes in the `historical migration `_ document. .. admonition:: Python 2 Support If you are running Roundup under Python 2, you should make plans to switch to Python 3. Release 2.4.0 (Jul 2024) is the last release to officially support Python 2. The next non-patch release scheduled for 2025 will mark 5 years since Roundup supported Python 3. .. admonition:: XHTML Support Deprecation Notice If you are running a tracker where the ``html_version`` setting in ``config.ini`` is ``xhtml``, you should plan to change your templates to use html (HTML5). If you are affected by this, please send email to the roundup-users mailing list (roundup-users at lists.sourceforge.net). Version 2.3.0 is the last version to support XHTML. Contents: .. contents:: :local: .. index:: Upgrading; 2.4.0 to 2.5.0 Migrating from 2.4.0 to 2.5.0 ============================= Deprecation Notices (info) -------------------------- Support for SQLite version 2 has been removed in 2.5.0. Support for the `PySQLite `_ library has been removed in 2.5.0. Only the Python supplied sqlite3 library will be supported. Update responsive template _generic.404.html and query.item.html (recommended) ------------------------------------------------------------------------------ This only applies if your tracker is based on the responsive template. Check the TEMPLATE-INFO.txt file in your tracker home. The template name is the first component of the ``Name`` field. For example a Name like:: Name: responsive-bugtracker is based on the responsive template. If the Name doesn't start with ``responsive`` no changes are needed. The ``_generic.404.html`` and ``query.item.html`` templates will crash when displayed because a missing macro is called. Change:: to:: at the top of both files. The icing macro used in other tracker templates was renamed to frame in this tracker template. Update userauditor.py detector (recommended) -------------------------------------------- When using the REST interface, setting the address property of the user to the same value it currently has resulted in an error. If you have not changed your userauditor, you can copy one from any of the supplied templates in the ``detectors/userauditor.py`` file. Use ``roundup-admin templates`` to find a list of template directories. If you have changed your userauditor from the stock version, apply the following diff:: raise ValueError('Email address syntax is invalid "%s"'%address) check_main = db.user.stringFind(address=address) + # allow user to set same address via rest + if check_main: + check_main = nodeid not in check_main + # make sure none of the alts are owned by anyone other than us (x!=nodeid) add the lines marked with ``+`` in the file in the location after check_main is assigned. Modify config.ini password_pbkdf2_default_rounds setting (recommended) ---------------------------------------------------------------------- The method for hashing and storing passwords has been updated to use PBKDF2 with SHA512 hash. This change was first introduced in Roundup 2.3 and is now the standard. If you previously added code in interfaces.py for a `PBKDF2 upgrade`_ to enable PBKDF2S5, you can remove that code now. SHA512 is a more secure hash, it requires fewer rounds to ensure safety. The older PBKDF2-SHA1 needed around 2 million rounds. You should update the ``password_pbkdf2_default_rounds`` setting in ``config.ini`` to 250000. This value is higher than the OWASP recommendation of 210000 from three years ago. If you don’t make this change, logins will be slow, especially for REST or XMLRPC calls. See `PBKDF2 upgrade`_ for details on how to test the algorithm's speed. We do not recommend reverting to the older SHA1 PBKDF2. If you have to do so due to a slow CPU, you can add the following to your tracker's ``interfaces.py``:: from roundup.password import Password ## Use PBDKF2 (PBKDF2-SHA1) as default hash for passwords. # That scheme is at the start of the deprecated_schemes list and ha # to be removed. Password.default_scheme = Password.deprecated_schemes.pop(0) # Add PBKDF2S5 (PBKDF2-SHA512) as a valid scheme. Passwords # using it will be rehashed to use PBDKF2. Password.experimental_schemes[0] = "PBKDF2S5" If you proceed with this, you should set ``password_pbkdf2_default_rounds`` to 2 million or more rounds to keep your hashed password database secure in case it gets stolen. Defusedxml support improves XMLRPC security (optional) ------------------------------------------------------ This release adds support for the defusedxml_ module. If it is installed it will be automatically used. The default xmlrpc module in the standard library has known issues when parsing crafted XML. It can take a lot of CPU time and consume large amounts of memory with small payloads. When the XMLRPC endpoint is used without defusedxml, it will log a warning to the log file. The log entry can be disabled by adding:: from roundup.cgi import client client.WARN_FOR_MISSING_DEFUSEDXML = False to the ``interfaces.py`` file in the tracker home. (Create the file if it is missing.) XMLRPC access is enabled by default in the classic and other trackers. Upgrading to defusedxml is considered optional because the XMLRPC endpoint can be disabled in the tracker's ``config.ini``. Also ``Xmlrpc Access`` can be removed from the ``Users`` role by commenting out a line in ``schema.py``. If you have enabled the xmlrpc endpoint, you should install defusedxml. .. _defusedxml: https://pypi.org/project/defusedxml/ Use native date inputs (optional) --------------------------------- Roundup now uses native date or datetime-local inputs for Date() properties. These inputs take the place of the text input and calendar popup from earlier Roundup versions. Modern browsers come with a built-in calendar for date selection, so the ``(cal)`` calendar link is no longer needed. These native inputs show the date based on the browser's locale and translate terms into the local language. If you do nothing, simple uses of the field() method will generate date inputs to allow selection of a date. Input fields for Date() properties will not have the ``(cal)`` link anymore. Complex uses will not be upgraded and will operate like earlier Roundup versions. To upgrade all date properties, there are four changes to make: 1. Replace ``field`` calls with ``field_time`` where needed. 2. Remove the format argument from field() calls on Date() properties. 3. Remove popcal() calls. 4. Include datecopy.js in page.html. Use field_time() where needed ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The format used by ``field`` does not include hours, minutes or seconds. If your users need to enter times, you should change these calls to use ``field_time``. The arguments are the same as for field. Remove format argument ~~~~~~~~~~~~~~~~~~~~~~ Speaking of arguments, avoid setting the date format if you want to use native date inputs. The date value needs a specific format for date or datetime-local inputs. If you include the `format` argument in the `field` method, it should be removed. The `field` method uses the format ``%Y-%m-%d``. The ``field_time`` method uses the format ``%Y-%m-%dT%H:%M:%S``. If you use these exact formats, Roundup will accept them and use a native date input. .. highlight:: text If you use an format that doesn't match, you will see a text input and a logged warning message like:: Format '%Y-%m' prevents use of modern date input. Remove format from field() call in template test.item. Using text input. .. highlight:: default The log message will appear if your logging level is set to WARNING or lower. (Refer to your tracker's :ref:`config.ini logging section ` for details on logging levels.) If you want to use a text input for a specific date format, you can add ``type="text"`` to the field() argument list to suppress the warning. By default using a format argument will show the popup calendar link. You can disable the link by setting ``popcal=False`` in the field() call. If you have:: tal:content="structure python:context.duedate.field( placeholder='YYYY-MM, format='%Y-%m')" changing it to:: tal:content="structure python:context.duedate.field( type='text', placeholder='YYYY-MM, format='%Y-%m', popcal=False)" will generate the input as in Roundup 2.4 or earlier without a popcal link. If you are using a path expression like:: tal:content="context/duedate/field" change it to:: tal:content="structure python:context.duedate.field( type='text')" to get the input from before Roundup 2.5 with a popcal link. Remove popcal ~~~~~~~~~~~~~ If you use the ``popcal()`` method directly in your templates, you can remove them. The browser's native date selection calendar can be used instead. Add copy/paste/edit on double-click using datecopy.js ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There is no way to copy/paste using a native datetime-local or date input. With the datecopy.js file installed, double-clicking on the input turns it into a normal text input with the ability to copy, paste, or manually edit the date. To set this up, take either ``datecopy.js`` or the smaller version, ``datecopy.min.js``, from the ``html`` folder of the classic tracker template. Put the file in the ``html`` folder of your tracker home. After you install the datecopy file, you can add the script directly to a page using:: or get the file in a separate download using a regular script tag:: You can place these at the end of ``page.html`` just before the close body ```` tag. This is the method used in the classic template. This forces the file to be run for every page even those that don't have any date inputs. However, it is cached after the first download. Alternatively you can inline or link to it using a script tag only on pages that will have a date input. For example ``issue.item.html``. There is no support for activating text mode using the keyboard. Tablet/touch support is mixed. Chrome supports double-tap to activate text mode input. Firefox does not. Change in REST response for invalid CORS requests (info) -------------------------------------------------------- CORS_ preflight requests that are missing required headers can now result in either a 403 or 400 error code. If you permit anonymous users to access the REST interface, a 400 error may still occur. Previously, only a 400 error was given. This change is not expected to create issues since the client will recognize both codes it as an error response, and the CORS request will still fail. More secure session cookie handling (info) ------------------------------------------ This affects you if you are accessing a tracker via https. The name for the cookie that you get when logging into the web interface has a new name. When upgrading to Roundup 2.5 all users will have to to log in again. The cookie now has a ``__Secure-`` prefix to prevent it from being exposed/used over http. If your tracker is using the unencrypted http protocol, nothing has changed. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#cookie_prefixes for details on this security measure. Invalid accept header now prevents operation (info) --------------------------------------------------- In earlier versions, the rest interface checked for an incorrect "Accept" header, "@apiver", or the ".json" mime type only after processing the request. This would lead to a 406 error, but the requested change would still be completed. In this release, the validation of the output format and version occurs before any database changes are made. Now, all errors related to the data format (mime type, API version) will return 406 errors, where some previously resulted in 400 errors. New method for registering templating utils (info) -------------------------------------------------- If you are building a template utility function that needs access to: * the database * the client instance * the form the user submitted you had to pass these objects from the template using the ``db``, ``request.client`` or ``request.form`` arguments. A new method for registering a template utility has been added. If you use the ``instance`` object's ``registerUtilMethod()`` to register a utility function, you do not need to pass these arguments. The function is called as a method and the first argument is a ``client`` instance from which the database (client.db), form (client.form). You can find an example in :ref:`dynamic_csp`. .. index:: Upgrading; 2.3.0 to 2.4.0 Migrating from 2.3.0 to 2.4.0 ============================= Update your ``config.ini`` (required) ------------------------------------- Upgrade tracker's config.ini file. Use:: roundup-admin -i /path/to/tracker updateconfig newconfig.ini to generate a new ini file preserving all your settings. You can then merge any local comments from the tracker's ``config.ini`` to ``newconfig.ini`` and replace ``config.ini`` with ``newconfig.ini``. ``updateconfig`` will tell you if it is changing old default values or if a value must be changed manually. This will insert the bad API login rate limiting settings. Also if you have ``html_version`` set to ``xhtml``, you will get an error. .. _CVE-2024-39124: Fix for CVE-2024-39124 in help/calendar popups (recommended) ------------------------------------------------------------ Classhelper components accessed via URL using ``@template=help``, ``@template=calendar`` or other template frame in the classhelper can run JavaScript embedded in the URL. If user clicks on a malicious URL that: * arrives in an email, * is embedded in a note left on a ticket [#markdown-note]_, * left on some other web page the JavaScript code will be executed. This vulnerability seems to be limited to manually crafted URL's. It has not been generated by using Roundup's mechanism for generating classhelper URLs. The files that need to be changed to fix this depend on the template used to create the tracker. Check the TEMPLATE-INFO.txt file in your tracker home. The template name is the first component of the ``Name`` field. For example trackers with Names like:: Name: classic-bugtracker Name: devel-mytracker were derived from the ``classic`` and ``devel`` templates respectively. If your tracker is derived from the jinja2 template, you may not be affected as it doesn't provide classhelpers by default. If you aren't sure which tracker template was used to create your tracker home, check the ``html/help.html`` file for the word ``Javascript``. If your help.html is missing the word ``Javascript``, follow the directions for the classic template. If you have not modified the original tracker html templates, you can copy replacement files from the new templates supplied with release 2.4.0. If you install 2.4.0 in a `new virtual environment `_, you can use the command ``roundup-admin templates`` to find the installation path of the default templates. If your template was based on the classic template, replace the following files in your tracker: * html/_generic.calendar.html * html/_generic.help-list.html * html/_generic.help-submit.html * html/_generic.help.html * html/user.help-search.html * html/user.help.html If your template was based on the minimal template, replace the following files in your tracker: * html/_generic.calendar.html * html/_generic.help.html If your template was based on the responsive or devel templates, replace the following files in your tracker: * html/_generic.calendar.html * html/_generic.help-submit.html * html/help.html * html/user.help-search.html * html/user.help.html As an example, assume Roundup's virtual environment is ``/tools/roundup``. The classic tracker's default template will be in ``/tools/roundup/share/roundup/templates/classic``. Copy ``/tools/roundup/share/roundup/templates/classic/html/_generic.calendar.html`` to ``html/_generic.calendar.html`` in your tracker's home directory. Repeat for every one of the files that needs to be replaced. If you have made local changes to your popup/classhelper files or have created new help templates based on the existing ones, don't copy the default files. Instead, follow the directions below to modify each file as needed for your template. In the examples below, your script tag may differ. For example it could include:: tal:attributes="nonce request/client/client_nonce" If it does, keep the differences. You want to make changes to remove the structure option but keep the rest of the valid attributes. Most files have a small script that sets a few variables from the settings in the URL. You should change::