Code

- release preparation
[roundup.git] / doc / upgrading.txt
index 925cf34d9deb18a827c91f185d9efd470090106a..eb0a68c9a0d9ea601fbc93c6790a2c2935d8c168 100644 (file)
@@ -6,95 +6,810 @@ 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.
+
 .. contents::
 
+Migrating from 1.4.16 to 1.4.17
+===============================
+
+There was a bug in 1.4.16 where files were unlinked from issues if a
+mail without attachment was received via the mail interface. The
+following script will list likely issues being affected by the bug.
+The date in the script is the date of the 1.4.16 release. If you have
+installed 1.4.16 later than this date, you can change the date
+appropriately to your installation date. Run the script in the directory
+of your tracker.
+
+#!/usr/bin/python
+import os
+from roundup import instance
+from roundup.date import Date
+dir     = os.getcwd ()
+tracker = instance.open (dir)
+db      = tracker.open ('admin')
+# you may want to change this to your install date to find less candidates
+last_release = Date('2011-05-13')
+affected = {}
+for i in db.issue.getnodeids():
+    for j in db.issue.history(i):
+        if i in affected:
+            break
+        if j[1] < last_release or j[3] != 'set' or 'files' not in j[4]:
+            continue
+        for op, p in j[4]['files']:
+            if op == '-':
+                affected [i] = 1
+                break
+print ', '.join(sorted(affected.iterkeys()))
+
+To find out which files where attached before you can look in the
+history of the affected issue.  For fixing issues you can re-attach the
+files in question using the "set" command of roundup-admin, e.g., if the
+list of files attached to an issue should be files 5, 17, 23 for issue42
+you will set this using
+
+roundup-admin -i /path/to/your/tracker set issue42 files=5,17,23
+
+Migrating from 1.4.x to 1.4.17
+==============================
+
+There is a new config-option `migrate_passwords` in section `web` to
+auto-migrate passwords at web-login time to a more secure storage
+scheme. Default for the new option is "yes" so if you don't want that
+passwords are auto-migrated to a more secure password scheme on user
+login, set this to "no" before running your tracker(s) after the
+upgrade.
+
+The standalone roundup-server now defaults to listening on localhost (no
+longer on all network interfaces). This will not affect you if you're
+already using a configuration file for roundup-server. If you are using
+an empty setting for the `host` parameter in the config-file you should
+explicitly put 0.0.0.0 there as the use of an empty string to specify
+listening to all interfaces is deprecated and will go away in a future
+version.  If you are starting the server without a configuration file
+and want to explicitly listen to all network interface, you should
+specify the -n option with the address `0.0.0.0`.
+
+Searching now requires either read-permission without a check method, or
+you will have to add a "Search" permission for a class or a list of
+properties for a class (if you want to allow searching). For the classic
+template (or other templates derived from it) you want to add the
+following lines to your `schema.py` file::
+
+  p = db.security.addPermission(name='Search', klass='query')
+  db.security.addPermissionToRole('User', p)
+
+This is needed, because for the `query` class users may view only their
+own queries (or public queries). This is implemented with a `check`
+method, therefore the default search permissions will not allow
+searching and you'll have to add an explicit search permission.
+If you have modified your schema, you can check if you're missing any
+search permissions with the following script, run it in your tracker
+directory, it will list for each Class and Property the roles that may
+search for this property::
+
+    #!/usr/bin/python
+    import os
+    from roundup import instance
+    
+    tracker = instance.open(os.getcwd ())
+    db = tracker.open('admin')
+    
+    for cl in sorted(db.getclasses()):
+        print "Class:", cl
+        for p in sorted(db.getclass(cl).properties.keys()):
+            print "    Property:", p
+            roles = []
+            for role in sorted(db.security.role.iterkeys()):
+                if db.security.roleHasSearchPermission(cl,p,role):
+                    roles.append(role)
+            print "        roles may search:", ', '.join(roles)
+
+
+Migrating from 1.4.x to 1.4.12
+==============================
+
+Item creation now checks the "Create" permission instead of the "Edit"
+permission for individual properties. If you have modified your tracker
+permissions from the default distribution, you should check that
+"Create" permissions exist for all properties you want users to be able
+to create.
+
+
+Fixing some potential security holes
+------------------------------------
 
+Enhanced checking was added to the user registration auditor. If you
+run a public tracker you should update your tracker's
+``detectors/userauditor.py`` using the new code from
+``share/roundup/templates/classic/detectors/userauditor.py``. In most
+cases you may just copy the file over, but if you've made changes to
+the auditor in your tracker then you'll need to manually integrate
+the new code.
 
-Migrating from 0.7 to 0.8
-=========================
+Some HTML templates were found to have formatting security problems:
 
+``html/page.html``::
 
-0.8.0 Added filereactor detector
---------------------------------
+  -tal:replace="request/user/username">username</span></b><br>
+  +tal:replace="python:request.user.username.plain(escape=1)">username</span></b><br>
+
+``html/_generic.help-list.html``::
+
+  -tal:content="structure python:item[prop]"></label>
+  +tal:content="python:item[prop]"></label>
+
+The lines marked "+" should be added and lines marked "-" should be
+deleted (minus the "+"/"-" signs).
+
+
+Some HTML interface tweaks
+--------------------------
+
+You may wish to copy the ``user_utils.js`` and ``style.css` files from the
+source distribution ``share/roundup/templates/classic/html/`` directory to the
+``html`` directory of your trackers as it includes a small improvement.
+
+If you have made local changes to those files you'll need to manually work
+the differences in to your versions or ignore the changes.
+
+
+Migrating from 1.4.x to 1.4.11
+==============================
+
+Close potential security hole
+-----------------------------
+
+If your tracker has untrusted users you should examine its ``schema.py``
+file and look for the section granting the "Edit" permission to your users.
+This should look something like::
+
+    p = db.security.addPermission(name='Edit', klass='user', check=own_record,
+        description="User is allowed to edit their own user details")
+
+and should be modified to restrict the list of properties they are allowed
+to edit by adding the ``properties=`` section like::
+
+    p = db.security.addPermission(name='Edit', klass='user', check=own_record,
+        properties=('username', 'password', 'address', 'realname', 'phone',
+            'organisation', 'alternate_addresses', 'queries', 'timezone'),
+        description="User is allowed to edit their own user details")
+
+Most importantly the "roles" property should not be editable - thus not
+appear in that list of properties.
+
+
+Grant the "Register" permission to the Anonymous role
+-----------------------------------------------------
+
+A separate "Register" permission has been introduced to allow
+anonymous users to register. This means you will need to add the
+following to your tracker's ``schema.py`` to add the permission and
+assign it to the Anonymous role (replacing any previously assigned
+"Create user" permission for the Anonymous role)::
+
+  +db.security.addPermission(name='Register', klass='user',
+  +     description='User is allowed to register new user')
+   # Assign the appropriate permissions to the anonymous user's Anonymous
+   # Role. Choices here are:
+   # - Allow anonymous users to register
+  -db.security.addPermissionToRole('Anonymous', 'Create', 'user')
+  +db.security.addPermissionToRole('Anonymous', 'Register', 'user')
+
+The lines marked "+" should be added and lines marked "-" should be
+deleted (minus the "+"/"-" signs).
+
+You should also modify the ``html/page.html`` template to change the
+permission tested there::
+
+   -tal:condition="python:request.user.hasPermission('Create', 'user')"
+   +tal:condition="python:request.user.hasPermission('Register', 'user')"
+
+
+Generic class editor may now restore retired items
+--------------------------------------------------
+
+The instructions for doing so won't be present in your tracker unless you copy
+the ``_generic.index.html`` template from the roundup distribution in
+``share/roundup/templates/classic/html`` to your tracker's ``html`` directory.
+
+
+Migrating from 1.4.x to 1.4.9
+=============================
+
+Customized MailGW Class
+-----------------------
+
+If you have customized the MailGW class in your tracker: The new MailGW
+class opens the database for each message in the method handle_message
+(instance.open) instead of passing the opened database as a parameter to
+the MailGW constructor. The old handle_message has been renamed to
+_handle_message. The new method opens the database and wraps the call to
+the old method into a try/finally.
+
+Your customized MailGW class needs to mirror this behavior.
+
+Fix the "remove" button in issue files and messages lists
+---------------------------------------------------------
+
+The "remove" button(s) in the issue messages list needs to be altered. Find
+the following in your tracker's ``html/issue.item.html`` template::
+
+  <td>
+   <form style="padding:0" tal:condition="context/is_edit_ok"
+         tal:attributes="action string:issue${context/id}">
+    <input type="hidden" name="@remove@files" tal:attributes="value file/id">
+
+and add ``method="POST"`` as shown below::
+
+  <td>
+   <form style="padding:0" method="POST" tal:condition="context/is_edit_ok"
+         tal:attributes="action string:issue${context/id}">
+    <input type="hidden" name="@remove@files" tal:attributes="value file/id">
+
+Then also find::
+
+  <td>
+   <form style="padding:0" tal:condition="context/is_edit_ok"
+         tal:attributes="action string:issue${context/id}">
+    <input type="hidden" name="@remove@messages" tal:attributes="value msg/id">
+
+and add ``method="POST"`` as shown below::
+
+  <td>
+   <form style="padding:0" method="POST" tal:condition="context/is_edit_ok"
+         tal:attributes="action string:issue${context/id}">
+    <input type="hidden" name="@remove@messages" tal:attributes="value msg/id">
+
+
+Fixing the "retire" button in user management list
+--------------------------------------------------
+
+If you made the change to the "reture" link in the user management list as
+listed below in `Migrating from 1.4.x to 1.4.7`_ then you'll need to fix that
+change by adding ``method="POST"`` to the ``<form>`` tag::
+
+     <form style="padding:0" method="POST"
+           tal:attributes="action string:user${user/id}">
+      <input type="hidden" name="@template" value="index">
+      <input type="hidden" name="@action" value="retire">
+      <input type="submit" value="retire" i18n:attributes="value">
+     </form>
+
+
+Migrating from 1.4.x to 1.4.7
+=============================
+
+Several security issues were addressed in this release. Some aspects of your
+trackers may no longer function depending on your local customisations. Core
+functionality that will need to be modified:
+
+Grant the "retire" permission to users for their queries
+--------------------------------------------------------
+
+Users will no longer be able to retire their own queries. To remedy this you
+will need to add the following to your tracker's ``schema.py`` just under the
+line that grants them permission to edit their own queries::
+
+   p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
+      description="User is allowed to edit their queries")
+   db.security.addPermissionToRole('User', p)
+ + p = db.security.addPermission(name='Retire', klass='query', check=edit_query,
+ +    description="User is allowed to retire their queries")
+ + db.security.addPermissionToRole('User', p)
+   p = db.security.addPermission(name='Create', klass='query',
+      description="User is allowed to create queries")
+   db.security.addPermissionToRole('User', p)
+
+The lines marked "+" should be added, minus the "+" sign.
 
-This reactor is not installed by default, but rather can be found in the source
-directory, under the detectors/ directory.
 
-In it, it contains a workaround for an Internet Explorer limitation, regarding
-.eml and .mht files. It is tested to work with both Internet Explorer 6 and
-Mozilla's Firefox. 
+Fix the "retire" link in the users list for admin users
+-------------------------------------------------------
 
-Read the description inside of the reactor itself, for more information.
+The "retire" link found in the file ``html/user.index.html``::
 
+  <td tal:condition="context/is_edit_ok">
+   <a tal:attributes="href string:user${user/id}?@action=retire&@template=index"
+    i18n:translate="">retire</a>
 
-0.8.0 Added Dispatcher role
+Should be replaced with::
+
+  <td tal:condition="context/is_retire_ok">
+     <form style="padding:0" method="POST"
+           tal:attributes="action string:user${user/id}">
+      <input type="hidden" name="@template" value="index">
+      <input type="hidden" name="@action" value="retire">
+      <input type="submit" value="retire" i18n:attributes="value">
+     </form>
+
+
+Fix for Python 2.6+ users
+-------------------------
+
+If you use Python 2.6 you should edit your tracker's
+``detectors/nosyreaction.py`` file to change::
+
+   import sets
+
+at the top to::
+
+   from roundup.anypy.sets_ import set
+
+and then all instances of ``sets.Set()`` to ``set()`` in the later code.
+
+
+
+Trackers currently allowing HTML file uploading
+-----------------------------------------------
+
+Trackers which wish to continue to allow uploading of HTML content against issues
+will need to set a new configuration variable in the ``[web]`` section of the
+tracker's ``config.ini`` file:
+
+   # Setting this option enables Roundup to serve uploaded HTML
+   # file content *as HTML*. This is a potential security risk
+   # and is therefore disabled by default. Set to 'yes' if you
+   # trust *all* users uploading content to your tracker.
+   # Allowed values: yes, no
+   # Default: no
+   allow_html_file = no
+
+
+
+Migrating from 1.4.2 to 1.4.3
+=============================
+
+If you are using the MySQL backend you will need to replace some indexes
+that may have been created by version 1.4.2.
+
+You should to access your MySQL database directly and remove any indexes
+with a name ending in "_key_retired_idx". You should then re-add them with
+the same spec except the key column name needs a size. So an index on
+"_user (__retired, _name)" should become "_user (__retired, _name(255))".
+
+
+Migrating from 1.4.x to 1.4.2
+=============================
+
+You should run the "roundup-admin migrate" command for your tracker once
+you've installed the latest codebase. 
+
+Do this before you use the web, command-line or mail interface and before
+any users access the tracker.
+
+This command will respond with either "Tracker updated" (if you've not
+previously run it on an RDBMS backend) or "No migration action required"
+(if you have run it, or have used another interface to the tracker,
+or are using anydbm).
+
+It's safe to run this even if it's not required, so just get into the
+habit.
+
+
+Migrating from 1.3.3 to 1.4.0
+=============================
+
+Value of the "refwd_re" tracker configuration option (section "mailgw")
+is treated as UTF-8 string.  In previous versions, it was ISO8859-1.
+
+If you have running trackers based on the classic template, please
+update the messagesummary detector as follows::
+
+    --- detectors/messagesummary.py 17 Apr 2003 03:26:38 -0000      1.1
+    +++ detectors/messagesummary.py 3 Apr 2007 06:47:21 -0000       1.2
+    @@ -8,7 +8,7 @@
+     if newvalues.has_key('summary') or not newvalues.has_key('content'):
+         return
+
+    -    summary, content = parseContent(newvalues['content'], 1, 1)
+    +    summary, content = parseContent(newvalues['content'], config=db.config)
+     newvalues['summary'] = summary
+
+In the latest version we have added some database indexes to the
+SQL-backends (mysql, postgresql, sqlite) for speeding up building the
+roundup-index for full-text search. We recommend that you create the
+following database indexes on the database by hand::
+
+ CREATE INDEX words_by_id ON __words (_textid);
+ CREATE UNIQUE INDEX __textids_by_props ON __textids (_class, _itemid, _prop);
+
+Migrating from 1.2.x to 1.3.0
+=============================
+
+1.3.0 Web interface changes
 ---------------------------
 
-A new config option has been added. There is a 'role' that can be filled, 
-that of the 'dispatcher'. This person acts as a central sentinel for issues
-coming into the system. You can configure it so that all e-mail error messages
-get bounced to them, them and the user in question, or just the user (default).
+Some of the HTML files in the "classic" and "minimal" tracker templates
+were changed to fix some bugs and clean them up. You may wish to compare
+them to the HTML files in your tracker and apply any changes.
 
-To toggle these switches, look at the new classic and minimal config.py's,
-specifically:
 
+Migrating from 1.1.2 to 1.2.0
+=============================
 
-# The 'dispatcher' is a role that can get notified of new items to the database.
-DISPATCHER_EMAIL = ADMIN_EMAIL
+1.2.0 Sorting and grouping by multiple properties
+-------------------------------------------------
 
-...
+Starting with this version, sorting and grouping by multiple properties
+is possible. This means that request.sort and request.group are now
+lists. This is reflected in several places:
 
+ * ``renderWith`` now has list attributes for ``sort`` and ``group``,
+   where you previously wrote::
+   
+    renderWith(... sort=('-', 'activity'), group=('+', 'priority')
 
-# Send error messages to the dispatcher, user, or both?
-# If 'dispatcher', error message notifications will only be sent to the dispatcher.
-# If 'user',       error message notifications will only be sent to the user.
-# If 'both',       error message notifications will be sent to both individuals.
-ERROR_MESSAGES_TO = 'user'
+   you write now::
 
-Migrating from 0.6 to 0.7
-=========================
+    renderWith(... sort=[('-', 'activity')], group=[('+', 'priority')]
 
-0.7.0 Added CSV export action
------------------------------
+ * In templates that permit to edit sorting/grouping, request.sort and
+   request.group are (possibly empty) lists. You can now sort and group
+   by multiple attributes. For an example, see the classic template. You
+   may want search for the variable ``n_sort`` which can be set to the
+   number of sort/group properties.
+
+ * Templates that diplay new headlines for each group of items with
+   equal group properties can now use the modified ``batch.propchanged``
+   method that can take several properties which are checked for
+   changes. See the example in the classic template which makes use of
+   ``batch.propchanged``.
+
+Migrating from 1.1.0 to 1.1.1
+=============================
+
+1.1.1 "Clear this message"
+--------------------------
 
-A new action has been added which exports the current index page or search
-result as a comma-separated-value (CSV) file.
+In 1.1.1, the standard ``page.html`` template includes a "clear this message"
+link in the green "ok" message bar that appears after a successful edit
+(or other) action.
 
-To use it, add this to your "index" templates:
+To include this in your tracker, change the following in your ``page.html``
+template::
 
-<a tal:attributes="href python:request.indexargs_url('issue',
-            {'@action':'csv_export'})">Download as CSV</a>
+ <p tal:condition="options/ok_message | nothing" class="ok-message"
+    tal:repeat="m options/ok_message" tal:content="structure m">error</p>
 
-Making sure that the ``'issue'`` part matches the class name of the page
-you're editing.
+to be::
 
+ <p tal:condition="options/ok_message | nothing" class="ok-message">
+   <span tal:repeat="m options/ok_message"
+      tal:content="structure string:$m <br/ > " />
+    <a class="form-small" tal:attributes="href request/current_url"
+       i18n:translate="">clear this message</a>
+ </p>
 
-0.7.0 Typed columns in MySQL backend
-------------------------------------
 
-The MySQL (and Postgresql for that matter) backend now creates tables with
-appropriate column datatypes (not just varchar).
+If you implemented the "clear this message" in your 1.1.0 tracker, then you
+should change it to the above and it will work much better!
 
-Your database will be automatically migrated to use the new schemas, but
-it will take time. It's probably a good idea to make sure you do this as
-part of the upgrade when users are not expected to be using the system.
 
+Migrating from 1.0.x to 1.1.0
+=============================
+
+1.1 Login "For Session Only"
+----------------------------
+
+In 1.1, web logins are alive for the length of a session only, *unless* you
+add the following to the login form in your tracker's ``page.html``::
 
-0.7.0 Permission setup
+    <input type="checkbox" name="remember" id="remember">
+    <label for="remember" i18n:translate="">Remember me?</label><br>
+
+See the classic tracker ``page.html`` if you're unsure where this should
+go.
+
+
+1.1 Query Display Name
 ----------------------
 
-0.7 automatically sets up the Edit and View Permissions for all classes,
-thus you don't need to do so. Feel free to remove the code::
+The ``dispname`` web variable has been renamed ``@dispname`` to avoid
+clashing with other variables of the same name. If you are using the
+display name feature, you will need to edit your tracker's ``page.html``
+and ``issue.index.html`` pages to change ``dispname`` to ``@dispname``.
 
-    # Add new Permissions for this schema
-    for cl in 'issue', 'file', 'msg', 'user', 'query', 'keyword':
-        db.security.addPermission(name="Edit", klass=cl,
-            description="User is allowed to edit "+cl)
-        db.security.addPermission(name="View", klass=cl,
-            description="User is allowed to access "+cl)
+A side-effect of this change is that the renderWith method used in the
+``home.html`` page may now take a dispname argument.
 
-from your ``dbinit.py``.
 
+1.1 "Clear this message"
+------------------------
+
+In 1.1, the standard ``page.html`` template includes a "clear this message"
+link in the green "ok" message bar that appears after a successful edit
+(or other) action.
+
+To include this in your tracker, change the following in your ``page.html``
+template::
+
+ <p tal:condition="options/ok_message | nothing" class="ok-message"
+    tal:repeat="m options/ok_message" tal:content="structure m">error</p>
+
+to be::
+
+ <p tal:condition="options/ok_message | nothing" class="ok-message">
+   <span tal:repeat="m options/ok_message"
+      tal:content="structure string:$m <br/ > " />
+    <a class="form-small" tal:attributes="href string:issue${context/id}"
+       i18n:translate="">clear this message</a>
+ </p>
+
+
+Migrating from 0.8.x to 1.0
+===========================
+
+1.0 New Query Permissions
+-------------------------
+
+New permissions are defined for query editing and viewing. To include these
+in your tracker, you need to add these lines to your tracker's
+``schema.py``::
+
+ # Users should be able to edit and view their own queries. They should also
+ # be able to view any marked as not private. They should not be able to
+ # edit others' queries, even if they're not private
+ def view_query(db, userid, itemid):
+     private_for = db.query.get(itemid, 'private_for')
+     if not private_for: return True
+     return userid == private_for
+ def edit_query(db, userid, itemid):
+     return userid == db.query.get(itemid, 'creator')
+ p = db.security.addPermission(name='View', klass='query', check=view_query,
+     description="User is allowed to view their own and public queries")
+ db.security.addPermissionToRole('User', p)
+ p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
+     description="User is allowed to edit their queries")
+ db.security.addPermissionToRole('User', p)
+ p = db.security.addPermission(name='Create', klass='query',
+     description="User is allowed to create queries")
+ db.security.addPermissionToRole('User', p)
+
+and then remove 'query' from the line::
+
+ # Assign the access and edit Permissions for issue, file and message
+ # to regular users now
+ for cl in 'issue', 'file', 'msg', 'query', 'keyword':
+
+so it looks like::
+
+ for cl in 'issue', 'file', 'msg', 'keyword':
+
+
+Migrating from 0.8.0 to 0.8.3
+=============================
+
+0.8.3 Nosy Handling Changes
+---------------------------
+
+A change was made to fix a bug in the ``nosyreaction.py`` standard
+detector. To incorporate this fix in your trackers, you will need to copy
+the ``nosyreaction.py`` file from the ``templates/classic/detectors``
+directory of the source to your tracker's ``templates`` directory.
+
+If you have modified the ``nosyreaction.py`` file from the standard
+version, you will need to roll your changes into the new file.
+
+
+Migrating from 0.7.1 to 0.8.0
+=============================
+
+You *must* fully uninstall previous Roundup version before installing
+Roundup 0.8.0.  If you don't do that, ``roundup-admin install``
+command may fail to function properly.
+
+0.8.0 Backend changes
+---------------------
+
+Backends 'bsddb' and 'bsddb3' are removed.  If you are using one of these,
+you *must* migrate to another backend before upgrading.
+
+
+0.8.0 API changes
+-----------------
+
+Class.safeget() was removed from the API. Test your item ids before calling
+Class.get() instead.
+
+
+0.8.0 New tracker layout
+------------------------
+
+The ``config.py`` file has been replaced by ``config.ini``. You may use the
+roundup-admin command "genconfig" to generate a new config file::
+
+  roundup-admin genconfig <tracker home>/config.ini
+
+and modify the values therein based on the contents of your old config.py.
+In most cases, the names of the config variables are the same.
+
+The ``select_db.py`` file has been replaced by a file in the ``db``
+directory called ``backend_name``. As you might guess, this file contains
+just the name of the backend. To figure what the contents of yours should
+be, use the following table:
+
+  ================================ =========================
+  ``select_db.py`` contents        ``backend_name`` contents
+  ================================ =========================
+  from back_anydbm import ...      anydbm
+  from back_metakit import ...     metakit
+  from back_sqlite import ...      sqlite
+  from back_mysql import ...       mysql
+  from back_postgresql import ...  postgresql
+  ================================ =========================
+
+The ``dbinit.py`` file has been split into two new files,
+``initial_data.py`` and ``schema.py``. The contents of this file are:
+
+``initial_data.py``
+  You don't need one of these as your tracker is already initialised.
+
+``schema.py``
+  Copy the body of the ``def open(name=None)`` function from your old
+  tracker's ``dbinit.py`` file to this file. As the lines you're copying
+  aren't part of a function definition anymore, one level of indentation
+  needs to be removed (remove only the leading four spaces on each
+  line). 
+
+  The first few lines -- those starting with ``from roundup.hyperdb
+  import ...`` and the ``db = Database(config, name)`` line -- don't
+  need to be copied. Neither do the last few lines -- those starting
+  with ``import detectors``, down to ``return db`` inclusive.
+
+You may remove the ``__init__.py`` module from the "detectors" directory as
+it is no longer used.
+
+There's a new way to write extension code for Roundup. If you have code in
+an ``interfaces.py`` file you should move it. See the `customisation
+documentation`_ for information about how extensions are now written.
+Note that some older trackers may use ``interfaces.py`` to customise the
+mail gateway behaviour. You will need to keep your ``interfaces.py`` file
+if this is the case.
+
+
+0.8.0 Permissions Changes
+-------------------------
+
+The creation of a new item in the user interfaces is now controlled by the
+"Create" Permission. You will need to add an assignment of this Permission
+to your users who are allowed to create items. The most common form of this
+is the following in your ``schema.py`` added just under the current
+assignation of the Edit Permission::
+
+    for cl in 'issue', 'file', 'msg', 'query', 'keyword':
+        p = db.security.getPermission('Create', cl)
+        db.security.addPermissionToRole('User', p)
+
+You will need to explicitly let anonymous users access the web interface so
+that regular users are able to see the login form. Note that almost all
+trackers will need this Permission. The only situation where it's not
+required is in a tracker that uses an HTTP Basic Authenticated front-end.
+It's enabled by adding to your ``schema.py``::
+
+    p = db.security.getPermission('Web Access')
+    db.security.addPermissionToRole('Anonymous', p)
+
+Finally, you will need to enable permission for your users to edit their
+own details by adding the following to ``schema.py``::
+
+    # Users should be able to edit their own details. Note that this
+    # permission is limited to only the situation where the Viewed or
+    # Edited item is their own.
+    def own_record(db, userid, itemid):
+        '''Determine whether the userid matches the item being accessed.'''
+        return userid == itemid
+    p = db.security.addPermission(name='View', klass='user', check=own_record,
+        description="User is allowed to view their own user details")
+    p = db.security.addPermission(name='Edit', klass='user', check=own_record,
+        description="User is allowed to edit their own user details")
+    db.security.addPermissionToRole('User', p)
+
+
+0.8.0 Use of TemplatingUtils
+----------------------------
+
+If you used custom python functions in TemplatingUtils, they must
+be moved from interfaces.py to a new file in the ``extensions`` directory. 
+
+Each Function that should be available through TAL needs to be defined
+as a toplevel function in the newly created file. Furthermore you
+add an inititialization function, that registers the functions with the 
+tracker.
+
+If you find this too tedious, donfu wrote an automatic init function that
+takes an existing TemplatingUtils class, and registers all class methods
+that do not start with an underscore. The following hack should be placed
+in the ``extensions`` directory alongside other extensions::
+
+    class TemplatingUtils:
+         # copy from interfaces.py
+
+    def init(tracker):
+         util = TemplatingUtils()
+
+         def setClient(tu):
+             util.client = tu.client
+             return util
+
+         def execUtil(name):
+             return lambda tu, *args, **kwargs: \
+                     getattr(setClient(tu), name)(*args, **kwargs)
+
+         for name in dir(util):
+             if callable(getattr(util, name)) and not name.startswith('_'):
+                  tracker.registerUtil(name, execUtil(name))
+
+
+0.8.0 Logging Configuration
+---------------------------
+
+See the `administration guide`_ for information about configuring the new
+logging implemented in 0.8.0.
+
+
+Migrating from 0.7.2 to 0.7.3
+=============================
+
+0.7.3 Configuration
+-------------------
+
+If you choose, you may specify the directory from which static files are
+served (those which use the URL component ``@@file``). Currently the
+directory defaults to the ``TEMPLATES`` configuration variable. You may
+define a new variable, ``STATIC_FILES`` which overrides this value for
+static files.
+
+
+Migrating from 0.7.0 to 0.7.2
+=============================
+
+0.7.2 DEFAULT_TIMEZONE is now required
+--------------------------------------
+
+The DEFAULT_TIMEZONE configuration variable is now required. Add the
+following to your tracker's ``config.py`` file::
+
+    # You may specify a different default timezone, for use when users do not
+    # choose their own in their settings.
+    DEFAULT_TIMEZONE = 0            # specify as numeric hour offest
+
+
+Migrating from 0.7.0 to 0.7.1
+=============================
+
+0.7.1 Permission assignments
+----------------------------
+
+If you allow anonymous access to your tracker, you might need to assign
+some additional View (or Edit if your tracker is that open) permissions
+to the "anonymous" user. To do so, find the code in your ``dbinit.py`` that
+says::
+
+    for cl in 'issue', 'file', 'msg', 'query', 'keyword':
+        p = db.security.getPermission('View', cl)
+        db.security.addPermissionToRole('User', p)
+        p = db.security.getPermission('Edit', cl)
+        db.security.addPermissionToRole('User', p)
+    for cl in 'priority', 'status':
+        p = db.security.getPermission('View', cl)
+        db.security.addPermissionToRole('User', p)
+
+Add add a line::
+
+        db.security.addPermissionToRole('Anonymous', p)
+
+next to the existing ``'User'`` lines for the Permissions you wish to
+assign to the anonymous user.
+
+
+Migrating from 0.6 to 0.7
+=========================
 
 0.7.0 Permission assignments
 ----------------------------
@@ -121,43 +836,13 @@ add::
         db.security.addPermissionToRole('User', p)
 
 
-0.7.0 New "actor" property
---------------------------
-
-Roundup's database has a new per-item property "actor" which reflects the
-user performing the last "actvitiy". See the classic template for ways to
-integrate this new property into your interface.
-
-The property will be automatically added to your existing database.
-
-
-0.7.0 Extending the cgi interface
----------------------------------
-
-Before 0.7.0 adding or extending web actions was done by overriding or adding
-methods on the Client class. Though this approach still works to provide
-backwards compatibility, it is recommended you upgrade to the new approach, as
-described in the `Defining new web actions`__ section of the customization
-documentation. You might also want to take a look at the `Using an external
-password validation source`__ example.
-
-__ customizing.html#defining-new-web-actions
-__ customizing.html#using-an-external-password-validation-source
-
-
 0.7.0 Getting the current user id
 ---------------------------------
 
-Removed Database.curuserid attribute. Any code referencing this attribute
-should be replaced with a call to Database.getuid().
+The Database.curuserid attribute has been removed.
 
-
-0.7.0 Email character set
--------------------------
-
-The default character set for sending email is UTF-8 (ie. Unicode). If you
-have users whose email clients can't handle UTF-8 (eg. Eudora) then you
-will need to edit the new config.py variable ``EMAIL_CHARSET``.
+Any code referencing this attribute should be replaced with a
+call to Database.getuid().
 
 
 0.7.0 ZRoundup changes
@@ -175,7 +860,7 @@ as::
 
   :action :required :template :remove:messages ...
 
-should become:
+should become::
 
   @action @required @template @remove@messages ...
 
@@ -184,6 +869,17 @@ prefixes such as ``python:`` and ``string:``. Please ask on the
 roundup-users mailing list for help if you're unsure.
 
 
+0.7.0 Edit collision detection
+------------------------------
+
+Roundup now detects collisions with editing in the web interface (that is,
+two people editing the same item at the same time).
+
+You must copy the ``_generic.collision.html`` file from Roundup source in
+the ``templates/classic/html`` directory. to your tracker's ``html``
+directory.
+
+
 Migrating from 0.6.x to 0.6.3
 =============================
 
@@ -1061,4 +1757,4 @@ copy.
 
 .. _`customisation documentation`: customizing.html
 .. _`security documentation`: security.html
-.. _`administration guide`: admin.html
+.. _`administration guide`: admin_guide.html