====================================== Upgrading to newer versions of Roundup ====================================== Please read each section carefully and edit your tracker home files accordingly. Note that there is information about upgrade procedures in the `administration guide`_. If a specific version transition isn't mentioned here (eg. 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 check the "0.5 to 0.6" and "0.6.x to 0.6.3" steps. **IMPORTANT** The v1.5.x releases of Roundup will be the last to support Python v2.5. Support for Python v2.5 and v2.66 will be dropped with the v1.6 release of Roundup. Roundup 1.6 and newer require Python v2.7. Contents: .. contents:: :local: Migrating from 1.5.1 to 1.6.0 ============================= Make sure that user can view labelprop on classes (REQUIRED) ------------------------------------------------------------ If you have View permissions that use ```properties=...```, make sure that the labelprop for the class is listed in the properties list. The first one of these that exists must must be in the list: 1. the property set by a call to setlabelprop for the class 2. the key of the class (as set by setkey()) 3. the "name" property (if it exists) 4. the "title" property (if it exists) if none of those apply, you must allow * the "id" property E.G. If your class does a setlabelprop("foo") you must include "foo" in the properties list even if the class has name or title properties. See: http://www.roundup-tracker.org/docs/customizing.html#setlabelprop-property for further details on the labelprop. If you don't do this, you will find that multilinks (and possibly links) may not be displayed properly. E.G. templates that iterate over a mutlilink field (with tal:repeat for example) may not show any content. See: https://sourceforge.net/p/roundup/mailman/message/35763294/ for the initial discussion of the issue. Cross Site Request Forgery Detection Added ------------------------------------------ Roundup 1.6. supports a number of defenses against CSRF. Http header verification against the tracker's ``web`` setting in the ``[tracker]`` section of config.ini for the following headers: # Analyze the ``Referer`` HTTP header to make sure it includes the web setting. # Analyse the ``Origin`` HTTP header to make sure the schema://host matches the web setting. # Analyze the ``X-Forwarded-Host`` header set by a proxy running in front of roundup to make sure it agrees with the host part of the web setting. # Analyze the ``Host`` header to make sure it agrees with the host part of the web setting. This is not done if ``X-Forwarded-Host`` is set. By default roundup 1.6 does not require any specific header to be present. However at least one of the headers above *must* pass validation checks (usually ``Host`` or ``Referer``) or the submission is rejected with an error. If any header fails validation, the submission is rejected. (Note the user's form keeps all the data they entered if it was rejected.) Also the admin can include unique csrf tokens for all forms submitted using the POST method. (Delete and put methods are also included, but not currently used by roundup.) The csrf token (nonce) is tied to the user's session. When the user submits the form and nonce, the nonce is checked to make sure it was issued to the user and the same session. If this is not true the post is rejected and the user is notified. The standard context/submit templating item creates CSRF tokens by default. If you have forms using the POST method that are not using the standard submit routine, you should add the following field to all forms: A unique random token is generated by every call to utils.anti_csrf_nonce() and is put in a database to be retreived if the token is used. Token lifetimes are 2 weeks by default but can be configured in config.ini. Roundup will automatically prune old tokens. Calling anti_csrf_nonce with an integer lifetime, for example sets the lifetime of that nonce to 10 minutes. If you want to change the default settings, you have to update the web section in your tracker's config.ini's. To do this backup your existing config.ini. Run: roundup-admin -i /path/to/tracker genconfig config.ini.new to create a new config.ini in the file config.ini.new. Then merge the new csrf settings into your tracker's config. Look for settings that start with csrf. The config.ini.new file includes detailed descriptions of the settings. In general one of four values can be set for these settings. The default is ``yes``, which validates the header or nonce and blocks access if the validation fails. If the field/header is missing it allows access. Setting these fields to ``required`` blocks access if the header/nonce is missing. It is recommended that you change your templates so every form that is not submitted via GET has an @csrf field. Then change the csrf_enforce_token setting to 'required'. Errors and Troubleshooting ~~~~~~~~~~~~~~~~~~~~~~~~~~ If you see the @csrf nonce in the URL, you have added the value to a form that uses the GET method. You should remove the @csrf token from these forms as it is not needed. If you get an error: AttributeError: 'list' object has no attribute 'value' in handle_csrf, you have more than one @csrf token for the form. This usually occurs because the form uses the standard context/submit element but you also added an explicit @csrf statement. Simply remove the @csrf element for that form. Support for SameSite cookie option for session cookie ----------------------------------------------------- Support for serving the session cookie using the SameSite cookie option has been added. By default it is set to lax to provide a better user experience. But this can be changes to strict or the option can be removed entirely. Using the process for merging config.ini changes described in `Cross Site Request Forgery Detection Added`_ you can add the ``samesite_cookie_setting`` to the ``[web]`` section of the config file. Fix for path traversal changes template resolution -------------------------------------------------- The templates in the tracker's html subdirectory must not be symbolic links that lead outside of the html directory. If you don't use symbolic links for templates in your html subdirectory you don't have to make any changes. Otherwise you need to replace the symbolic links with hard links to the files or replace the symbolic links with the files. This is a side effect of fixing a path traversal security issue. The security issue required a directory with a specific unusual name. This made it difficult to exploit. However allowing the use of subdirectories to organize the templates required that it be fixed. Database back end specified in config.ini (REQUIRED) ---------------------------------------------------- The ``db/backend_name`` file is no longer used to configure the database backend being used for a tracker. The backend is now configured in the ``config.ini`` file using the ``backend`` option located in the ``[rdbms]`` section. For example if ``db/backend_name`` file contains ``sqlite``, a new entry in the tracker's ``config.ini`` will need to be created:: [rdbms] ... # Database backend. # Default: backend = sqlite Once the ``config.ini`` file has been updated with the new ``backend`` option, you can safely delete the ``db/backend_name`` file. Note: the ``backend_name`` file may be located in a directory other than ``db/`` if you have configured the ``database`` option in the ``[main]`` section of the ``config.ini`` file to be something other than ``db``. New config file option 'indexer' added -------------------------------------- With support for the Whoosh indexer, a new config file option has been added. You can force Roundup to use a particular text indexer by setting this value in the [main] section of the tracker's ``config.ini`` file (usually placed right before indexer_stopwords):: [main] ... # Force Roundup to use a particular text indexer. # If no indexer is supplied, the first available indexer # will be used in the following order: # Possible values: xapian, whoosh, native (internal). indexer = Stemming improved in Xapian Indexer ----------------------------------- Stemming allows a search for "silent" also match silently. The Porter stemmer in Xapian works with lowercase English text. In this release we lowercase the documents as they are put into the indexer. This means capitalization is not preserved, but produces more hits by using the stemmer. You will need to do a roundup-admin reindex if you are using the Xapian full text indexer on your tracker. New config file option 'replyto_address' added ---------------------------------------------- A new config file option has been added to let you control the Reply-To header on nosy messages. Edit your tracker's ``config.ini`` and place the following after the email entry in the tracker section:: [tracker] ... # Controls the reply-to header address used when sending # nosy messages. # If the value is unset (default) the roundup tracker's # email address (above) is used. # If set to "AUTHOR" then the primary email address of the # author of the change will be used as the reply-to # address. This allows email exchanges to occur outside of # the view of roundup and exposes the address of the person # who updated the issue, but it could be useful in some # unusual circumstances. # If set to some other value, the value is used as the reply-to # address. It must be a valid RFC2822 address or people will not be # able to reply. # Default: replyto_address = Login from a search or after logout works better (REQUIRED) ----------------------------------------------------------- The login form has been improved to work with some back end code changes. Now when a user logs in they stay on the same page where they started the login. To make this work, you must change the tal that is used to set the ``__came_from`` form variable. Note that the url assigned to __came_from must be url encoded/quoted and be under the tracker's base url. If the base_url uses http, you can set the url to https. Replace the existing code in the tracker's html/page.html page that looks similar to (look for name="__came_from"):: with the following:: Now search backwards for the nearest form statement before the code that sets __came_from. If it looks like::