Code

a1bd77f9f18ad0cc0b9017c2ac9a51b780178edd
[roundup.git] / doc / upgrading.txt
1 ======================================
2 Upgrading to newer versions of Roundup
3 ======================================
5 Please read each section carefully and edit your tracker home files
6 accordingly. Note that there is information about upgrade procedures in the
7 `administration guide`_.
9 If a specific version transition isn't mentioned here (eg. 0.6.7 to 0.6.8)
10 then you don't need to do anything. If you're upgrading from 0.5.6 to
11 0.6.8 though, you'll need to check the "0.5 to 0.6" and "0.6.x to 0.6.3"
12 steps.
14 .. contents::
16 Migrating from 1.4.x to 1.4.17
17 ==============================
19 There is a new config-option 'migrate_passwords' in section 'web' to
20 auto-migrate passwords at web-login time to a more secure storage
21 scheme. Default for the new option is "yes" so if you don't want that
22 passwords are auto-migrated to a more secure password scheme on user
23 login, set this to "no" before running your tracker(s) after the
24 upgrade.
26 Searching now requires either read-permission without a check method, or
27 you will have to add a "Search" permission for a class or a list of
28 properties for a class (if you want to allow searching). For the classic
29 template (or other templates derived from it) you want to add the
30 following lines to your `schema.py` file::
32   p = db.security.addPermission(name='Search', klass='query')
33   db.security.addPermissionToRole('User', p)
35 This is needed, because for the `query` class users may view only their
36 own queries (or public queries). This is implemented with a `check`
37 method, therefore the default search permissions will not allow
38 searching and you'll have to add an explicit search permission.
39 If you have modified your schema, you can check if you're missing any
40 search permissions with the following script, run it in your tracker
41 directory, it will list for each Class and Property the roles that may
42 search for this property::
44     #!/usr/bin/python
45     import os
46     from roundup import instance
47     
48     tracker = instance.open(os.getcwd ())
49     db = tracker.open('admin')
50     
51     for cl in sorted(db.getclasses()):
52         print "Class:", cl
53         for p in sorted(db.getclass(cl).properties.keys()):
54             print "    Property:", p
55             roles = []
56             for role in sorted(db.security.role.iterkeys()):
57                 if db.security.roleHasSearchPermission(cl,p,role):
58                     roles.append(role)
59             print "        roles may search:", ', '.join(roles)
62 Migrating from 1.4.x to 1.4.12
63 ==============================
65 Item creation now checks the "Create" permission instead of the "Edit"
66 permission for individual properties. If you have modified your tracker
67 permissions from the default distribution, you should check that
68 "Create" permissions exist for all properties you want users to be able
69 to create.
72 Fixing some potential security holes
73 ------------------------------------
75 Enhanced checking was added to the user registration auditor. If you
76 run a public tracker you should update your tracker's
77 ``detectors/userauditor.py`` using the new code from
78 ``share/roundup/templates/classic/detectors/userauditor.py``. In most
79 cases you may just copy the file over, but if you've made changes to
80 the auditor in your tracker then you'll need to manually integrate
81 the new code.
83 Some HTML templates were found to have formatting security problems:
85 ``html/page.html``::
87   -tal:replace="request/user/username">username</span></b><br>
88   +tal:replace="python:request.user.username.plain(escape=1)">username</span></b><br>
90 ``html/_generic.help-list.html``::
92   -tal:content="structure python:item[prop]"></label>
93   +tal:content="python:item[prop]"></label>
95 The lines marked "+" should be added and lines marked "-" should be
96 deleted (minus the "+"/"-" signs).
99 Some HTML interface tweaks
100 --------------------------
102 You may wish to copy the ``user_utils.js`` and ``style.css` files from the
103 source distribution ``share/roundup/templates/classic/html/`` directory to the
104 ``html`` directory of your trackers as it includes a small improvement.
106 If you have made local changes to those files you'll need to manually work
107 the differences in to your versions or ignore the changes.
110 Migrating from 1.4.x to 1.4.11
111 ==============================
113 Close potential security hole
114 -----------------------------
116 If your tracker has untrusted users you should examine its ``schema.py``
117 file and look for the section granting the "Edit" permission to your users.
118 This should look something like::
120     p = db.security.addPermission(name='Edit', klass='user', check=own_record,
121         description="User is allowed to edit their own user details")
123 and should be modified to restrict the list of properties they are allowed
124 to edit by adding the ``properties=`` section like::
126     p = db.security.addPermission(name='Edit', klass='user', check=own_record,
127         properties=('username', 'password', 'address', 'realname', 'phone',
128             'organisation', 'alternate_addresses', 'queries', 'timezone'),
129         description="User is allowed to edit their own user details")
131 Most importantly the "roles" property should not be editable - thus not
132 appear in that list of properties.
135 Grant the "Register" permission to the Anonymous role
136 -----------------------------------------------------
138 A separate "Register" permission has been introduced to allow
139 anonymous users to register. This means you will need to add the
140 following to your tracker's ``schema.py`` to add the permission and
141 assign it to the Anonymous role (replacing any previously assigned
142 "Create user" permission for the Anonymous role)::
144   +db.security.addPermission(name='Register', klass='user',
145   +     description='User is allowed to register new user')
146  
147    # Assign the appropriate permissions to the anonymous user's Anonymous
148    # Role. Choices here are:
149    # - Allow anonymous users to register
150   -db.security.addPermissionToRole('Anonymous', 'Create', 'user')
151   +db.security.addPermissionToRole('Anonymous', 'Register', 'user')
153 The lines marked "+" should be added and lines marked "-" should be
154 deleted (minus the "+"/"-" signs).
156 You should also modify the ``html/page.html`` template to change the
157 permission tested there::
159    -tal:condition="python:request.user.hasPermission('Create', 'user')"
160    +tal:condition="python:request.user.hasPermission('Register', 'user')"
163 Generic class editor may now restore retired items
164 --------------------------------------------------
166 The instructions for doing so won't be present in your tracker unless you copy
167 the ``_generic.index.html`` template from the roundup distribution in
168 ``share/roundup/templates/classic/html`` to your tracker's ``html`` directory.
171 Migrating from 1.4.x to 1.4.9
172 =============================
174 Customized MailGW Class
175 -----------------------
177 If you have customized the MailGW class in your tracker: The new MailGW
178 class opens the database for each message in the method handle_message
179 (instance.open) instead of passing the opened database as a parameter to
180 the MailGW constructor. The old handle_message has been renamed to
181 _handle_message. The new method opens the database and wraps the call to
182 the old method into a try/finally.
184 Your customized MailGW class needs to mirror this behavior.
186 Fix the "remove" button in issue files and messages lists
187 ---------------------------------------------------------
189 The "remove" button(s) in the issue messages list needs to be altered. Find
190 the following in your tracker's ``html/issue.item.html`` template::
192   <td>
193    <form style="padding:0" tal:condition="context/is_edit_ok"
194          tal:attributes="action string:issue${context/id}">
195     <input type="hidden" name="@remove@files" tal:attributes="value file/id">
197 and add ``method="POST"`` as shown below::
199   <td>
200    <form style="padding:0" method="POST" tal:condition="context/is_edit_ok"
201          tal:attributes="action string:issue${context/id}">
202     <input type="hidden" name="@remove@files" tal:attributes="value file/id">
204 Then also find::
206   <td>
207    <form style="padding:0" tal:condition="context/is_edit_ok"
208          tal:attributes="action string:issue${context/id}">
209     <input type="hidden" name="@remove@messages" tal:attributes="value msg/id">
211 and add ``method="POST"`` as shown below::
213   <td>
214    <form style="padding:0" method="POST" tal:condition="context/is_edit_ok"
215          tal:attributes="action string:issue${context/id}">
216     <input type="hidden" name="@remove@messages" tal:attributes="value msg/id">
219 Fixing the "retire" button in user management list
220 --------------------------------------------------
222 If you made the change to the "reture" link in the user management list as
223 listed below in `Migrating from 1.4.x to 1.4.7`_ then you'll need to fix that
224 change by adding ``method="POST"`` to the ``<form>`` tag::
226      <form style="padding:0" method="POST"
227            tal:attributes="action string:user${user/id}">
228       <input type="hidden" name="@template" value="index">
229       <input type="hidden" name="@action" value="retire">
230       <input type="submit" value="retire" i18n:attributes="value">
231      </form>
234 Migrating from 1.4.x to 1.4.7
235 =============================
237 Several security issues were addressed in this release. Some aspects of your
238 trackers may no longer function depending on your local customisations. Core
239 functionality that will need to be modified:
241 Grant the "retire" permission to users for their queries
242 --------------------------------------------------------
244 Users will no longer be able to retire their own queries. To remedy this you
245 will need to add the following to your tracker's ``schema.py`` just under the
246 line that grants them permission to edit their own queries::
248    p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
249       description="User is allowed to edit their queries")
250    db.security.addPermissionToRole('User', p)
251  + p = db.security.addPermission(name='Retire', klass='query', check=edit_query,
252  +    description="User is allowed to retire their queries")
253  + db.security.addPermissionToRole('User', p)
254    p = db.security.addPermission(name='Create', klass='query',
255       description="User is allowed to create queries")
256    db.security.addPermissionToRole('User', p)
258 The lines marked "+" should be added, minus the "+" sign.
261 Fix the "retire" link in the users list for admin users
262 -------------------------------------------------------
264 The "retire" link found in the file ``html/user.index.html``::
266   <td tal:condition="context/is_edit_ok">
267    <a tal:attributes="href string:user${user/id}?@action=retire&@template=index"
268     i18n:translate="">retire</a>
270 Should be replaced with::
272   <td tal:condition="context/is_retire_ok">
273      <form style="padding:0" method="POST"
274            tal:attributes="action string:user${user/id}">
275       <input type="hidden" name="@template" value="index">
276       <input type="hidden" name="@action" value="retire">
277       <input type="submit" value="retire" i18n:attributes="value">
278      </form>
281 Fix for Python 2.6+ users
282 -------------------------
284 If you use Python 2.6 you should edit your tracker's
285 ``detectors/nosyreaction.py`` file to change::
287    import sets
289 at the top to::
291    from roundup.anypy.sets_ import set
293 and then all instances of ``sets.Set()`` to ``set()`` in the later code.
297 Trackers currently allowing HTML file uploading
298 -----------------------------------------------
300 Trackers which wish to continue to allow uploading of HTML content against issues
301 will need to set a new configuration variable in the ``[web]`` section of the
302 tracker's ``config.ini`` file:
304    # Setting this option enables Roundup to serve uploaded HTML
305    # file content *as HTML*. This is a potential security risk
306    # and is therefore disabled by default. Set to 'yes' if you
307    # trust *all* users uploading content to your tracker.
308    # Allowed values: yes, no
309    # Default: no
310    allow_html_file = no
314 Migrating from 1.4.2 to 1.4.3
315 =============================
317 If you are using the MySQL backend you will need to replace some indexes
318 that may have been created by version 1.4.2.
320 You should to access your MySQL database directly and remove any indexes
321 with a name ending in "_key_retired_idx". You should then re-add them with
322 the same spec except the key column name needs a size. So an index on
323 "_user (__retired, _name)" should become "_user (__retired, _name(255))".
326 Migrating from 1.4.x to 1.4.2
327 =============================
329 You should run the "roundup-admin migrate" command for your tracker once
330 you've installed the latest codebase. 
332 Do this before you use the web, command-line or mail interface and before
333 any users access the tracker.
335 This command will respond with either "Tracker updated" (if you've not
336 previously run it on an RDBMS backend) or "No migration action required"
337 (if you have run it, or have used another interface to the tracker,
338 or are using anydbm).
340 It's safe to run this even if it's not required, so just get into the
341 habit.
344 Migrating from 1.3.3 to 1.4.0
345 =============================
347 Value of the "refwd_re" tracker configuration option (section "mailgw")
348 is treated as UTF-8 string.  In previous versions, it was ISO8859-1.
350 If you have running trackers based on the classic template, please
351 update the messagesummary detector as follows::
353     --- detectors/messagesummary.py 17 Apr 2003 03:26:38 -0000      1.1
354     +++ detectors/messagesummary.py 3 Apr 2007 06:47:21 -0000       1.2
355     @@ -8,7 +8,7 @@
356      if newvalues.has_key('summary') or not newvalues.has_key('content'):
357          return
359     -    summary, content = parseContent(newvalues['content'], 1, 1)
360     +    summary, content = parseContent(newvalues['content'], config=db.config)
361      newvalues['summary'] = summary
363 In the latest version we have added some database indexes to the
364 SQL-backends (mysql, postgresql, sqlite) for speeding up building the
365 roundup-index for full-text search. We recommend that you create the
366 following database indexes on the database by hand::
368  CREATE INDEX words_by_id ON __words (_textid);
369  CREATE UNIQUE INDEX __textids_by_props ON __textids (_class, _itemid, _prop);
371 Migrating from 1.2.x to 1.3.0
372 =============================
374 1.3.0 Web interface changes
375 ---------------------------
377 Some of the HTML files in the "classic" and "minimal" tracker templates
378 were changed to fix some bugs and clean them up. You may wish to compare
379 them to the HTML files in your tracker and apply any changes.
382 Migrating from 1.1.2 to 1.2.0
383 =============================
385 1.2.0 Sorting and grouping by multiple properties
386 -------------------------------------------------
388 Starting with this version, sorting and grouping by multiple properties
389 is possible. This means that request.sort and request.group are now
390 lists. This is reflected in several places:
392  * ``renderWith`` now has list attributes for ``sort`` and ``group``,
393    where you previously wrote::
394    
395     renderWith(... sort=('-', 'activity'), group=('+', 'priority')
397    you write now::
399     renderWith(... sort=[('-', 'activity')], group=[('+', 'priority')]
401  * In templates that permit to edit sorting/grouping, request.sort and
402    request.group are (possibly empty) lists. You can now sort and group
403    by multiple attributes. For an example, see the classic template. You
404    may want search for the variable ``n_sort`` which can be set to the
405    number of sort/group properties.
407  * Templates that diplay new headlines for each group of items with
408    equal group properties can now use the modified ``batch.propchanged``
409    method that can take several properties which are checked for
410    changes. See the example in the classic template which makes use of
411    ``batch.propchanged``.
413 Migrating from 1.1.0 to 1.1.1
414 =============================
416 1.1.1 "Clear this message"
417 --------------------------
419 In 1.1.1, the standard ``page.html`` template includes a "clear this message"
420 link in the green "ok" message bar that appears after a successful edit
421 (or other) action.
423 To include this in your tracker, change the following in your ``page.html``
424 template::
426  <p tal:condition="options/ok_message | nothing" class="ok-message"
427     tal:repeat="m options/ok_message" tal:content="structure m">error</p>
429 to be::
431  <p tal:condition="options/ok_message | nothing" class="ok-message">
432    <span tal:repeat="m options/ok_message"
433       tal:content="structure string:$m <br/ > " />
434     <a class="form-small" tal:attributes="href request/current_url"
435        i18n:translate="">clear this message</a>
436  </p>
439 If you implemented the "clear this message" in your 1.1.0 tracker, then you
440 should change it to the above and it will work much better!
443 Migrating from 1.0.x to 1.1.0
444 =============================
446 1.1 Login "For Session Only"
447 ----------------------------
449 In 1.1, web logins are alive for the length of a session only, *unless* you
450 add the following to the login form in your tracker's ``page.html``::
452     <input type="checkbox" name="remember" id="remember">
453     <label for="remember" i18n:translate="">Remember me?</label><br>
455 See the classic tracker ``page.html`` if you're unsure where this should
456 go.
459 1.1 Query Display Name
460 ----------------------
462 The ``dispname`` web variable has been renamed ``@dispname`` to avoid
463 clashing with other variables of the same name. If you are using the
464 display name feature, you will need to edit your tracker's ``page.html``
465 and ``issue.index.html`` pages to change ``dispname`` to ``@dispname``.
467 A side-effect of this change is that the renderWith method used in the
468 ``home.html`` page may now take a dispname argument.
471 1.1 "Clear this message"
472 ------------------------
474 In 1.1, the standard ``page.html`` template includes a "clear this message"
475 link in the green "ok" message bar that appears after a successful edit
476 (or other) action.
478 To include this in your tracker, change the following in your ``page.html``
479 template::
481  <p tal:condition="options/ok_message | nothing" class="ok-message"
482     tal:repeat="m options/ok_message" tal:content="structure m">error</p>
484 to be::
486  <p tal:condition="options/ok_message | nothing" class="ok-message">
487    <span tal:repeat="m options/ok_message"
488       tal:content="structure string:$m <br/ > " />
489     <a class="form-small" tal:attributes="href string:issue${context/id}"
490        i18n:translate="">clear this message</a>
491  </p>
494 Migrating from 0.8.x to 1.0
495 ===========================
497 1.0 New Query Permissions
498 -------------------------
500 New permissions are defined for query editing and viewing. To include these
501 in your tracker, you need to add these lines to your tracker's
502 ``schema.py``::
504  # Users should be able to edit and view their own queries. They should also
505  # be able to view any marked as not private. They should not be able to
506  # edit others' queries, even if they're not private
507  def view_query(db, userid, itemid):
508      private_for = db.query.get(itemid, 'private_for')
509      if not private_for: return True
510      return userid == private_for
511  def edit_query(db, userid, itemid):
512      return userid == db.query.get(itemid, 'creator')
513  p = db.security.addPermission(name='View', klass='query', check=view_query,
514      description="User is allowed to view their own and public queries")
515  db.security.addPermissionToRole('User', p)
516  p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
517      description="User is allowed to edit their queries")
518  db.security.addPermissionToRole('User', p)
519  p = db.security.addPermission(name='Create', klass='query',
520      description="User is allowed to create queries")
521  db.security.addPermissionToRole('User', p)
523 and then remove 'query' from the line::
525  # Assign the access and edit Permissions for issue, file and message
526  # to regular users now
527  for cl in 'issue', 'file', 'msg', 'query', 'keyword':
529 so it looks like::
531  for cl in 'issue', 'file', 'msg', 'keyword':
534 Migrating from 0.8.0 to 0.8.3
535 =============================
537 0.8.3 Nosy Handling Changes
538 ---------------------------
540 A change was made to fix a bug in the ``nosyreaction.py`` standard
541 detector. To incorporate this fix in your trackers, you will need to copy
542 the ``nosyreaction.py`` file from the ``templates/classic/detectors``
543 directory of the source to your tracker's ``templates`` directory.
545 If you have modified the ``nosyreaction.py`` file from the standard
546 version, you will need to roll your changes into the new file.
549 Migrating from 0.7.1 to 0.8.0
550 =============================
552 You *must* fully uninstall previous Roundup version before installing
553 Roundup 0.8.0.  If you don't do that, ``roundup-admin install``
554 command may fail to function properly.
556 0.8.0 Backend changes
557 ---------------------
559 Backends 'bsddb' and 'bsddb3' are removed.  If you are using one of these,
560 you *must* migrate to another backend before upgrading.
563 0.8.0 API changes
564 -----------------
566 Class.safeget() was removed from the API. Test your item ids before calling
567 Class.get() instead.
570 0.8.0 New tracker layout
571 ------------------------
573 The ``config.py`` file has been replaced by ``config.ini``. You may use the
574 roundup-admin command "genconfig" to generate a new config file::
576   roundup-admin genconfig <tracker home>/config.ini
578 and modify the values therein based on the contents of your old config.py.
579 In most cases, the names of the config variables are the same.
581 The ``select_db.py`` file has been replaced by a file in the ``db``
582 directory called ``backend_name``. As you might guess, this file contains
583 just the name of the backend. To figure what the contents of yours should
584 be, use the following table:
586   ================================ =========================
587   ``select_db.py`` contents        ``backend_name`` contents
588   ================================ =========================
589   from back_anydbm import ...      anydbm
590   from back_metakit import ...     metakit
591   from back_sqlite import ...      sqlite
592   from back_mysql import ...       mysql
593   from back_postgresql import ...  postgresql
594   ================================ =========================
596 The ``dbinit.py`` file has been split into two new files,
597 ``initial_data.py`` and ``schema.py``. The contents of this file are:
599 ``initial_data.py``
600   You don't need one of these as your tracker is already initialised.
602 ``schema.py``
603   Copy the body of the ``def open(name=None)`` function from your old
604   tracker's ``dbinit.py`` file to this file. As the lines you're copying
605   aren't part of a function definition anymore, one level of indentation
606   needs to be removed (remove only the leading four spaces on each
607   line). 
609   The first few lines -- those starting with ``from roundup.hyperdb
610   import ...`` and the ``db = Database(config, name)`` line -- don't
611   need to be copied. Neither do the last few lines -- those starting
612   with ``import detectors``, down to ``return db`` inclusive.
614 You may remove the ``__init__.py`` module from the "detectors" directory as
615 it is no longer used.
617 There's a new way to write extension code for Roundup. If you have code in
618 an ``interfaces.py`` file you should move it. See the `customisation
619 documentation`_ for information about how extensions are now written.
620 Note that some older trackers may use ``interfaces.py`` to customise the
621 mail gateway behaviour. You will need to keep your ``interfaces.py`` file
622 if this is the case.
625 0.8.0 Permissions Changes
626 -------------------------
628 The creation of a new item in the user interfaces is now controlled by the
629 "Create" Permission. You will need to add an assignment of this Permission
630 to your users who are allowed to create items. The most common form of this
631 is the following in your ``schema.py`` added just under the current
632 assignation of the Edit Permission::
634     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
635         p = db.security.getPermission('Create', cl)
636         db.security.addPermissionToRole('User', p)
638 You will need to explicitly let anonymous users access the web interface so
639 that regular users are able to see the login form. Note that almost all
640 trackers will need this Permission. The only situation where it's not
641 required is in a tracker that uses an HTTP Basic Authenticated front-end.
642 It's enabled by adding to your ``schema.py``::
644     p = db.security.getPermission('Web Access')
645     db.security.addPermissionToRole('Anonymous', p)
647 Finally, you will need to enable permission for your users to edit their
648 own details by adding the following to ``schema.py``::
650     # Users should be able to edit their own details. Note that this
651     # permission is limited to only the situation where the Viewed or
652     # Edited item is their own.
653     def own_record(db, userid, itemid):
654         '''Determine whether the userid matches the item being accessed.'''
655         return userid == itemid
656     p = db.security.addPermission(name='View', klass='user', check=own_record,
657         description="User is allowed to view their own user details")
658     p = db.security.addPermission(name='Edit', klass='user', check=own_record,
659         description="User is allowed to edit their own user details")
660     db.security.addPermissionToRole('User', p)
663 0.8.0 Use of TemplatingUtils
664 ----------------------------
666 If you used custom python functions in TemplatingUtils, they must
667 be moved from interfaces.py to a new file in the ``extensions`` directory. 
669 Each Function that should be available through TAL needs to be defined
670 as a toplevel function in the newly created file. Furthermore you
671 add an inititialization function, that registers the functions with the 
672 tracker.
674 If you find this too tedious, donfu wrote an automatic init function that
675 takes an existing TemplatingUtils class, and registers all class methods
676 that do not start with an underscore. The following hack should be placed
677 in the ``extensions`` directory alongside other extensions::
679     class TemplatingUtils:
680          # copy from interfaces.py
682     def init(tracker):
683          util = TemplatingUtils()
685          def setClient(tu):
686              util.client = tu.client
687              return util
689          def execUtil(name):
690              return lambda tu, *args, **kwargs: \
691                      getattr(setClient(tu), name)(*args, **kwargs)
693          for name in dir(util):
694              if callable(getattr(util, name)) and not name.startswith('_'):
695                   tracker.registerUtil(name, execUtil(name))
698 0.8.0 Logging Configuration
699 ---------------------------
701 See the `administration guide`_ for information about configuring the new
702 logging implemented in 0.8.0.
705 Migrating from 0.7.2 to 0.7.3
706 =============================
708 0.7.3 Configuration
709 -------------------
711 If you choose, you may specify the directory from which static files are
712 served (those which use the URL component ``@@file``). Currently the
713 directory defaults to the ``TEMPLATES`` configuration variable. You may
714 define a new variable, ``STATIC_FILES`` which overrides this value for
715 static files.
718 Migrating from 0.7.0 to 0.7.2
719 =============================
721 0.7.2 DEFAULT_TIMEZONE is now required
722 --------------------------------------
724 The DEFAULT_TIMEZONE configuration variable is now required. Add the
725 following to your tracker's ``config.py`` file::
727     # You may specify a different default timezone, for use when users do not
728     # choose their own in their settings.
729     DEFAULT_TIMEZONE = 0            # specify as numeric hour offest
732 Migrating from 0.7.0 to 0.7.1
733 =============================
735 0.7.1 Permission assignments
736 ----------------------------
738 If you allow anonymous access to your tracker, you might need to assign
739 some additional View (or Edit if your tracker is that open) permissions
740 to the "anonymous" user. To do so, find the code in your ``dbinit.py`` that
741 says::
743     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
744         p = db.security.getPermission('View', cl)
745         db.security.addPermissionToRole('User', p)
746         p = db.security.getPermission('Edit', cl)
747         db.security.addPermissionToRole('User', p)
748     for cl in 'priority', 'status':
749         p = db.security.getPermission('View', cl)
750         db.security.addPermissionToRole('User', p)
752 Add add a line::
754         db.security.addPermissionToRole('Anonymous', p)
756 next to the existing ``'User'`` lines for the Permissions you wish to
757 assign to the anonymous user.
760 Migrating from 0.6 to 0.7
761 =========================
763 0.7.0 Permission assignments
764 ----------------------------
766 Due to a change in the rendering of web widgets, permissions are now
767 checked on Classes where they previously weren't (this is a good thing).
769 You will need to add some additional Permission assignments for your
770 regular users, or some displays will break. After the following in your 
771 tracker's ``dbinit.py``::
773     # Assign the access and edit Permissions for issue, file and message
774     # to regular users now
775     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
776         p = db.security.getPermission('View', cl)
777         db.security.addPermissionToRole('User', p)
778         p = db.security.getPermission('Edit', cl)
779         db.security.addPermissionToRole('User', p)
781 add::
783     for cl in 'priority', 'status':
784         p = db.security.getPermission('View', cl)
785         db.security.addPermissionToRole('User', p)
788 0.7.0 Getting the current user id
789 ---------------------------------
791 The Database.curuserid attribute has been removed.
793 Any code referencing this attribute should be replaced with a
794 call to Database.getuid().
797 0.7.0 ZRoundup changes
798 ----------------------
800 The templates in your tracker's html directory will need updating if you
801 wish to use ZRoundup. If you've not modified those files (or some of them),
802 you may just copy the new versions from the Roundup source in the
803 templates/classic/html directory.
805 If you have modified the html files, then you'll need to manually edit them
806 to change all occurances of special form variables from using the colon ":"
807 special character to the at "@" special character. That is, variables such
808 as::
810   :action :required :template :remove:messages ...
812 should become::
814   @action @required @template @remove@messages ...
816 Note that ``tal:`` statements are unaffected. So are TAL expression type
817 prefixes such as ``python:`` and ``string:``. Please ask on the
818 roundup-users mailing list for help if you're unsure.
821 0.7.0 Edit collision detection
822 ------------------------------
824 Roundup now detects collisions with editing in the web interface (that is,
825 two people editing the same item at the same time).
827 You must copy the ``_generic.collision.html`` file from Roundup source in
828 the ``templates/classic/html`` directory. to your tracker's ``html``
829 directory.
832 Migrating from 0.6.x to 0.6.3
833 =============================
835 0.6.3 Configuration
836 -------------------
838 You will need to copy the file::
840   templates/classic/detectors/__init__.py
842 to your tracker's ``detectors`` directory, replacing the one already there.
843 This fixes a couple of bugs in that file.
847 Migrating from 0.5 to 0.6
848 =========================
851 0.6.0 Configuration
852 -------------------
854 Introduced EMAIL_FROM_TAG config variable. This value is inserted into
855 the From: line of nosy email. If the sending user is "Foo Bar", the
856 From: line is usually::
858      "Foo Bar" <issue_tracker@tracker.example>
860 the EMAIL_FROM_TAG goes inside the "Foo Bar" quotes like so::
862      "Foo Bar EMAIL_FROM_TAG" <issue_tracker@tracker.example>
864 I've altered the mechanism in the detectors __init__.py module so that it
865 doesn't cross-import detectors from other trackers (if you run more than one
866 in a single roundup-server). This change means that you'll need to copy the
867 __init__.py from roundup/templates/classic/detectors/__init__.py to your
868 <tracker home>/detectors/__init__.py. Don't worry, the "classic" __init__ is a
869 one-size-fits-all, so it'll work even if you've added/removed detectors.
871 0.6.0 Templating changes
872 ------------------------
874 The ``user.item`` template (in the tracker home "templates" directory)
875 needs to have the following hidden variable added to its form (between the
876 ``<form...>`` and ``</form>`` tags::
878   <input type="hidden" name=":template" value="item">
881 0.6.0 Form handling changes
882 ---------------------------
884 Roundup's form handling capabilities have been significantly expanded. This
885 should not affect users of 0.5 installations - but if you find you're
886 getting errors from form submissions, please ask for help on the Roundup
887 users mailing list:
889   http://lists.sourceforge.net/lists/listinfo/roundup-users
891 See the customisation doc section on `Form Values`__ for documentation of the
892 new form variables possible.
894 __ customizing.html#form-values
897 0.6.0 Multilingual character set support
898 ----------------------------------------
900 Added internationalization support. This is done via encoding all data
901 stored in roundup database to utf-8 (unicode encoding). To support utf-8 in
902 web interface you should add the folowing line to your tracker's html/page
903 and html/_generic.help files inside <head> tag::
904   
905     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
907 Since latin characters in utf-8 have the same codes as in ASCII table, this
908 modification is optional for users who use only plain latin characters. 
910 After this modification, you will be able to see and enter any world
911 character via web interface. Data received via mail interface also converted
912 to utf-8, however only new messages will be converted. If your roundup
913 database contains some of non-ASCII characters in one of 8-bit encoding,
914 they will not be visible in new unicode environment. Some of such data (e.g.
915 user names, keywords, etc)  can be edited by administrator, the others
916 (e.g. messages' contents) is not editable via web interface. Currently there
917 is no tool for converting such data, the only solution is to close
918 appropriate old issues and create new ones with the same content.
921 0.6.0 User timezone support
922 ---------------------------
924 From version 0.6.0 roundup supports displaying of Date data in user' local
925 timezone if he/she has provided timezone information. To make it possible
926 some modification to tracker's schema and HTML templates are required.
927 First you must add string property 'timezone' to user class in dbinit.py
928 like this::
929   
930     user = Class(db, "user", 
931                     username=String(),   password=Password(),
932                     address=String(),    realname=String(), 
933                     phone=String(),      organisation=String(),
934                     alternate_addresses=String(),
935                     queries=Multilink('query'), roles=String(),
936                     timezone=String())
937   
938 And second - html interface. Add following lines to
939 $TRACKER_HOME/html/user.item template::
940   
941      <tr>
942       <th>Timezone</th>
943       <td tal:content="structure context/timezone/field">timezone</td>
944      </tr>
946 After that all users should be able to provide their timezone information.
947 Timezone should be a positive or negative integer - offset from GMT.
949 After providing timezone, roundup will show all dates values, found in web
950 and mail interfaces in local time. It will also accept any Date info in
951 local time, convert and store it in GMT.
954 0.6.0 Search page structure
955 ---------------------------
957 In order to accomodate query editing the search page has been restructured. If
958 you want to provide your users with query editing, you should update your
959 search page using the macros detailed in the customisation doc section
960 `Searching on categories`__.
962 __ customizing.html#searching-on-categories
964 Also, the url field in the query class no longer starts with a '?'. You'll need
965 to remove this question mark from the url field to support queries. There's
966 a script in the "tools" directory called ``migrate-queries.py`` that should
967 automatically change any existing queries for you. As always, make a backup
968 of your database before running such a script.
971 0.6.0 Notes for metakit backend users
972 -------------------------------------
974 Roundup 0.6.0 introduced searching on ranges of dates and intervals. To
975 support it, some modifications to interval storing routine were made. So if
976 your tracker uses metakit backend and your db schema contains intervals
977 property, searches on that property will not be accurate for db items that
978 was stored before roundup' upgrade. However all new records should be
979 searchable on intervals.
981 It is possible to convert your database to new format: you can export and
982 import back all your data (consult "Migrating backends" in "Maintenance"
983 documentation). After this operation all your interval properties should
984 become searchable.
986 Users of backends others than metakit should not worry about this issue.
989 Migrating from 0.4.x to 0.5.0
990 =============================
992 This has been a fairly major revision of Roundup:
994 1. Brand new, much more powerful, flexible, tasty and nutritious templating.
995    Unfortunately, this means all your current templates are useless. Hopefully
996    the new documentation and examples will be enough to help you make the
997    transition. Please don't hesitate to ask on roundup-users for help (or
998    complete conversions if you're completely stuck)!
999 2. The database backed got a lot more flexible, allowing Metakit and SQL
1000    databases! The only decent SQL database implemented at present is sqlite,
1001    but others shouldn't be a whole lot more work.
1002 3. A brand new, highly flexible and much more robust security system including
1003    a system of Permissions, Roles and Role assignments to users. You may now
1004    define your own Permissions that may be checked in CGI transactions.
1005 4. Journalling has been made less storage-hungry, so has been turned on
1006    by default *except* for author, recipient and nosy link/unlink events. You
1007    are advised to turn it off in your trackers too.
1008 5. We've changed the terminology from "instance" to "tracker", to ease the
1009    learning curve/impact for new users.
1010 6. Because of the above changes, the tracker configuration has seen some
1011    major changes. See below for the details.
1013 Please, **back up your database** before you start the migration process. This
1014 is as simple as copying the "db" directory and all its contents from your
1015 tracker to somewhere safe.
1018 0.5.0 Configuration
1019 -------------------
1021 First up, rename your ``instance_config.py`` file to just ``config.py``.
1023 Then edit your tracker's ``__init__.py`` module. It'll currently look
1024 like this::
1026  from instance_config import *
1027  try:
1028      from dbinit import *
1029  except ImportError:
1030      pass # in installdir (probably :)
1031  from interfaces import *
1033 and it needs to be::
1035  import config
1036  from dbinit import open, init
1037  from interfaces import Client, MailGW
1039 Due to the new templating having a top-level ``page`` that defines links for
1040 searching, indexes, adding items etc, the following variables are no longer
1041 used:
1043 - HEADER_INDEX_LINKS
1044 - HEADER_ADD_LINKS
1045 - HEADER_SEARCH_LINKS
1046 - SEARCH_FILTERS
1047 - DEFAULT_INDEX
1048 - UNASSIGNED_INDEX
1049 - USER_INDEX
1050 - ISSUE_FILTER
1052 The new security implementation will require additions to the dbinit module,
1053 but also removes the need for the following tracker config variables:
1055 - ANONYMOUS_ACCESS
1056 - ANONYMOUS_REGISTER
1058 but requires two new variables which define the Roles assigned to users who
1059 register through the web and e-mail interfaces:
1061 - NEW_WEB_USER_ROLES
1062 - NEW_EMAIL_USER_ROLES
1064 in both cases, 'User' is a good initial setting. To emulate
1065 ``ANONYMOUS_ACCESS='deny'``, remove all "View" Permissions from the
1066 "Anonymous" Role. To emulate ``ANONYMOUS_REGISTER='deny'``, remove the "Web
1067 Registration" and/or the "Email Registration" Permission from the "Anonymous"
1068 Role. See the section on customising security in the `customisation
1069 documentation`_ for more information.
1071 Finally, the following config variables have been renamed to make more sense:
1073 - INSTANCE_HOME -> TRACKER_HOME
1074 - INSTANCE_NAME -> TRACKER_NAME
1075 - ISSUE_TRACKER_WEB -> TRACKER_WEB
1076 - ISSUE_TRACKER_EMAIL -> TRACKER_EMAIL
1079 0.5.0 Schema Specification
1080 --------------------------
1082 0.5.0 Database backend changes
1083 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1085 Your select_db module in your tracker has changed a fair bit. Where it used
1086 to contain::
1088  # WARNING: DO NOT EDIT THIS FILE!!!
1089  from roundup.backends.back_anydbm import Database
1091 it must now contain::
1093  # WARNING: DO NOT EDIT THIS FILE!!!
1094  from roundup.backends.back_anydbm import Database, Class, FileClass, IssueClass
1096 Yes, I realise the irony of the "DO NOT EDIT THIS FILE" statement :)
1097 Note the addition of the Class, FileClass, IssueClass imports. These are very
1098 important, as they're going to make the next change work too. You now need to
1099 modify the top of the dbinit module in your tracker from::
1101  import instance_config
1102  from roundup import roundupdb
1103  from select_db import Database
1105  from roundup.roundupdb import Class, FileClass
1107  class Database(roundupdb.Database, select_db.Database):
1108      ''' Creates a hybrid database from:
1109           . the selected database back-end from select_db
1110           . the roundup extensions from roundupdb
1111      '''
1112      pass
1114  class IssueClass(roundupdb.IssueClass):
1115      ''' issues need the email information
1116      '''
1117      pass
1119 to::
1121  import config
1122  from select_db import Database, Class, FileClass, IssueClass
1124 Yes, remove the Database and IssueClass definitions and those other imports.
1125 They're not needed any more!
1127 Look for places in dbinit.py where ``instance_config`` is used too, and
1128 rename them ``config``.
1131 0.5.0 Journalling changes
1132 ~~~~~~~~~~~~~~~~~~~~~~~~~
1134 Journalling has been optimised for storage. Journalling of links has been
1135 turned back on by default. If your tracker has a large user base, you may wish
1136 to turn off journalling of nosy list, message author and message recipient
1137 link and unlink events. You do this by adding ``do_journal='no'`` to the Class
1138 initialisation in your dbinit. For example, your *msg* class initialisation
1139 probably looks like this::
1141     msg = FileClass(db, "msg",
1142                     author=Link("user"), recipients=Multilink("user"),
1143                     date=Date(),         summary=String(),
1144                     files=Multilink("file"),
1145                     messageid=String(),  inreplyto=String())
1147 to turn off journalling of author and recipient link events, add
1148 ``do_journal='no'`` to the ``author=Link("user")`` part of the statement,
1149 like so::
1151     msg = FileClass(db, "msg",
1152                     author=Link("user", do_journal='no'),
1153                     recipients=Multilink("user", do_journal='no'),
1154                     date=Date(),         summary=String(),
1155                     files=Multilink("file"),
1156                     messageid=String(),  inreplyto=String())
1158 Nosy list link event journalling is actually turned off by default now. If you
1159 want to turn it on, change to your issue class' nosy list, change its
1160 definition from::
1162     issue = IssueClass(db, "issue",
1163                     assignedto=Link("user"), topic=Multilink("keyword"),
1164                     priority=Link("priority"), status=Link("status"))
1166 to::
1168     issue = IssueClass(db, "issue", nosy=Multilink("user", do_journal='yes'),
1169                     assignedto=Link("user"), topic=Multilink("keyword"),
1170                     priority=Link("priority"), status=Link("status"))
1172 noting that your definition of the nosy Multilink will override the normal one.
1175 0.5.0 User schema changes
1176 ~~~~~~~~~~~~~~~~~~~~~~~~~
1178 Users have two more properties, "queries" and "roles". You'll have something
1179 like this in your dbinit module now::
1181     user = Class(db, "user",
1182                     username=String(),   password=Password(),
1183                     address=String(),    realname=String(),
1184                     phone=String(),      organisation=String(),
1185                     alternate_addresses=String())
1186     user.setkey("username")
1188 and you'll need to add the new properties and the new "query" class to it
1189 like so::
1191     query = Class(db, "query",
1192                     klass=String(),     name=String(),
1193                     url=String())
1194     query.setkey("name")
1196     # Note: roles is a comma-separated string of Role names
1197     user = Class(db, "user",
1198                     username=String(),   password=Password(),
1199                     address=String(),    realname=String(),
1200                     phone=String(),      organisation=String(),
1201                     alternate_addresses=String(),
1202                     queries=Multilink('query'), roles=String())
1203     user.setkey("username")
1205 The "queries" property is used to store off the user's favourite database
1206 queries. The "roles" property is explained below in `0.5.0 Security
1207 Settings`_.
1210 0.5.0 Security Settings
1211 ~~~~~~~~~~~~~~~~~~~~~~~
1213 See the `security documentation`_ for an explanation of how the new security
1214 system works. In a nutshell though, the security is handled as a four step
1215 process:
1217 1. Permissions are defined as having a name and optionally a hyperdb class
1218    they're specific to,
1219 2. Roles are defined that have one or more Permissions,
1220 3. Users are assigned Roles in their "roles" property, and finally
1221 4. Roundup checks that users have appropriate Permissions at appropriate times
1222    (like editing issues).
1224 Your tracker dbinit module's *open* function now has to define any
1225 Permissions that are specific to your tracker, and also the assignment
1226 of Permissions to Roles. At the moment, your open function
1227 ends with::
1229     import detectors
1230     detectors.init(db)
1232     return db
1234 and what we need to do is insert some commands that will set up the security
1235 parameters. Right above the ``import detectors`` line, you'll want to insert
1236 these lines::
1238     #
1239     # SECURITY SETTINGS
1240     #
1241     # new permissions for this schema
1242     for cl in 'issue', 'file', 'msg', 'user':
1243         db.security.addPermission(name="Edit", klass=cl,
1244             description="User is allowed to edit "+cl)
1245         db.security.addPermission(name="View", klass=cl,
1246             description="User is allowed to access "+cl)
1248     # Assign the access and edit permissions for issue, file and message
1249     # to regular users now
1250     for cl in 'issue', 'file', 'msg':
1251         p = db.security.getPermission('View', cl)
1252         db.security.addPermissionToRole('User', p)
1253         p = db.security.getPermission('Edit', cl)
1254         db.security.addPermissionToRole('User', p)
1255     # and give the regular users access to the web and email interface
1256     p = db.security.getPermission('Web Access')
1257     db.security.addPermissionToRole('User', p)
1258     p = db.security.getPermission('Email Access')
1259     db.security.addPermissionToRole('User', p)
1261     # May users view other user information? Comment these lines out
1262     # if you don't want them to
1263     p = db.security.getPermission('View', 'user')
1264     db.security.addPermissionToRole('User', p)
1266     # Assign the appropriate permissions to the anonymous user's Anonymous
1267     # Role. Choices here are:
1268     # - Allow anonymous users to register through the web
1269     p = db.security.getPermission('Web Registration')
1270     db.security.addPermissionToRole('Anonymous', p)
1271     # - Allow anonymous (new) users to register through the email gateway
1272     p = db.security.getPermission('Email Registration')
1273     db.security.addPermissionToRole('Anonymous', p)
1274     # - Allow anonymous users access to the "issue" class of data
1275     #   Note: this also grants access to related information like files,
1276     #         messages, statuses etc that are linked to issues
1277     #p = db.security.getPermission('View', 'issue')
1278     #db.security.addPermissionToRole('Anonymous', p)
1279     # - Allow anonymous users access to edit the "issue" class of data
1280     #   Note: this also grants access to create related information like
1281     #         files and messages etc that are linked to issues
1282     #p = db.security.getPermission('Edit', 'issue')
1283     #db.security.addPermissionToRole('Anonymous', p)
1285     # oh, g'wan, let anonymous access the web interface too
1286     p = db.security.getPermission('Web Access')
1287     db.security.addPermissionToRole('Anonymous', p)
1289 Note in the comments there the places where you might change the permissions
1290 to restrict users or grant users more access. If you've created additional
1291 classes that users should be able to edit and view, then you should add them
1292 to the "new permissions for this schema" section at the start of the security
1293 block. Then add them to the "Assign the access and edit permissions" section
1294 too, so people actually have the new Permission you've created.
1296 One final change is needed that finishes off the security system's
1297 initialisation. We need to add a call to ``db.post_init()`` at the end of the
1298 dbinit open() function. Add it like this::
1300     import detectors
1301     detectors.init(db)
1303     # schema is set up - run any post-initialisation
1304     db.post_init()
1305     return db
1307 You may verify the setup of Permissions and Roles using the new
1308 "``roundup-admin security``" command.
1311 0.5.0 User changes
1312 ~~~~~~~~~~~~~~~~~~
1314 To support all those schema changes, you'll need to massage your user database
1315 a little too, to:
1317 1. make sure there's an "anonymous" user - this user is mandatory now and is
1318    the one that unknown users are logged in as.
1319 2. make sure all users have at least one Role.
1321 If you don't have the "anonymous" user, create it now with the command::
1323   roundup-admin create user username=anonymous roles=Anonymous
1325 making sure the capitalisation is the same as above. Once you've done that,
1326 you'll need to set the roles property on all users to a reasonable default.
1327 The admin user should get "Admin", the anonymous user "Anonymous"
1328 and all other users "User". The ``fixroles.py`` script in the tools directory
1329 will do this. Run it like so (where python is your python 2+ binary)::
1331   python tools/fixroles.py -i <tracker home> fixroles
1335 0.5.0 CGI interface changes
1336 ---------------------------
1338 The CGI interface code was completely reorganised and largely rewritten. The
1339 end result is that this section of your tracker interfaces module will need
1340 changing from::
1342  from roundup import cgi_client, mailgw
1343  from roundup.i18n import _
1344  
1345  class Client(cgi_client.Client):
1346      ''' derives basic CGI implementation from the standard module,
1347          with any specific extensions
1348      '''
1349      pass
1351 to::
1353  from roundup import mailgw
1354  from roundup.cgi import client
1355  
1356  class Client(client.Client): 
1357      ''' derives basic CGI implementation from the standard module,
1358          with any specific extensions
1359      '''
1360      pass
1362 You will also need to install the new version of roundup.cgi from the source
1363 cgi-bin directory if you're using it.
1366 0.5.0 HTML templating
1367 ---------------------
1369 You'll want to make a backup of your current tracker html directory. You
1370 should then copy the html directory from the Roundup source "classic" template
1371 and modify it according to your local schema changes.
1373 If you need help with the new templating system, please ask questions on the
1374 roundup-users mailing list (available through the roundup project page on
1375 sourceforge, http://roundup.sf.net/)
1378 0.5.0 Detectors
1379 ---------------
1381 The nosy reactor has been updated to handle the tracker not having an
1382 "assignedto" property on issues. You may want to copy it into your tracker's
1383 detectors directory. Chances are you've already fixed it though :)
1386 Migrating from 0.4.1 to 0.4.2
1387 =============================
1389 0.4.2 Configuration
1390 -------------------
1391 The USER_INDEX definition introduced in 0.4.1 was too restrictive in its
1392 allowing replacement of 'assignedto' with the user's userid. Users must change
1393 the None value of 'assignedto' to 'CURRENT USER' (the string, in quotes) for
1394 the replacement behaviour to occur now.
1396 The new configuration variables are:
1398 - EMAIL_KEEP_QUOTED_TEXT 
1399 - EMAIL_LEAVE_BODY_UNCHANGED
1400 - ADD_RECIPIENTS_TO_NOSY
1402 See the sample configuration files in::
1404  <roundup source>/roundup/templates/classic/instance_config.py
1406 and::
1408  <roundup source>/roundup/templates/extended/instance_config.py
1410 and the `customisation documentation`_ for information on how they're used.
1413 0.4.2 Changes to detectors
1414 --------------------------
1415 You will need to copy the detectors from the distribution into your instance
1416 home "detectors" directory. If you used the classic schema, the detectors
1417 are in::
1419  <roundup source>/roundup/templates/classic/detectors/
1421 If you used the extended schema, the detectors are in::
1423  <roundup source>/roundup/templates/extended/detectors/
1425 The change means that schema-specific code has been removed from the
1426 mail gateway and cgi interface and made into auditors:
1428 - nosyreactor.py has now got an updatenosy auditor which updates the nosy
1429   list with author, recipient and assignedto information.
1430 - statusauditor.py makes the unread or resolved -> chatting changes and
1431   presets the status of an issue to unread.
1433 There's also a bug or two fixed in the nosyreactor code.
1435 0.4.2 HTML templating changes
1436 -----------------------------
1437 The link() htmltemplate function now has a "showid" option for links and
1438 multilinks. When true, it only displays the linked item id as the anchor
1439 text. The link value is displayed as a tooltip using the title anchor
1440 attribute. To use in eg. the superseder field, have something like this::
1442    <td>
1443     <display call="field('superseder', showid=1)">
1444     <display call="classhelp('issue', 'id,title', label='list', width=500)">
1445     <property name="superseder">
1446      <br>View: <display call="link('superseder', showid=1)">
1447     </property>
1448    </td>
1450 The stylesheets have been cleaned up too. You may want to use the newer
1451 versions in::
1453  <roundup source>/roundup/templates/<template>/html/default.css
1457 Migrating from 0.4.0 to 0.4.1
1458 =============================
1460 0.4.1 Files storage
1461 -------------------
1463 Messages and files from newly created issues will be put into subdierectories
1464 in thousands e.g. msg123 will be put into files/msg/0/msg123, file2003
1465 will go into files/file/2/file2003. Previous messages are still found, but
1466 could be put into this structure.
1468 0.4.1 Configuration
1469 -------------------
1471 To allow more fine-grained access control, the variable used to check
1472 permission to auto-register users in the mail gateway is now called
1473 ANONYMOUS_REGISTER_MAIL rather than overloading ANONYMOUS_REGISTER. If the
1474 variable doesn't exist, then ANONYMOUS_REGISTER is tested as before.
1476 Configuring the links in the web header is now easier too. The following
1477 variables have been added to the classic instance_config.py::
1479   HEADER_INDEX_LINKS   - defines the "index" links to be made available
1480   HEADER_ADD_LINKS     - defines the "add" links
1481   DEFAULT_INDEX        - specifies the index view for DEFAULT
1482   UNASSIGNED_INDEX     - specifies the index view for UNASSIGNED
1483   USER_INDEX           - specifies the index view for USER
1485 See the <roundup source>/roundup/templates/classic/instance_config.py for more
1486 information - including how the variables are to be set up. Most users will
1487 just be able to copy the variables from the source to their instance home. If
1488 you've modified the header by changing the source of the interfaces.py file in
1489 the instance home, you'll need to remove that customisation and move it into
1490 the appropriate variables in instance_config.py.
1492 The extended schema has similar variables added too - see the source for more
1493 info.
1495 0.4.1 Alternate E-Mail Addresses
1496 --------------------------------
1498 If you add the property "alternate_addresses" to your user class, your users
1499 will be able to register alternate email addresses that they may use to
1500 communicate with roundup as. All email from roundup will continue to be sent
1501 to their primary address.
1503 If you have not edited the dbinit.py file in your instance home directory,
1504 you may simply copy the new dbinit.py file from the core code. If you used
1505 the classic schema, the interfaces file is in::
1507  <roundup source>/roundup/templates/classic/dbinit.py
1509 If you used the extended schema, the file is in::
1511  <roundup source>/roundup/templates/extended/dbinit.py 
1513 If you have modified your dbinit.py file, you need to edit the dbinit.py
1514 file in your instance home directory. Find the lines which define the user
1515 class::
1517     user = Class(db, "msg",
1518                     username=String(),   password=Password(),
1519                     address=String(),    realname=String(), 
1520                     phone=String(),      organisation=String(),
1521                     alternate_addresses=String())
1523 You will also want to add the property to the user's details page. The
1524 template for this is the "user.item" file in your instance home "html"
1525 directory. Similar to above, you may copy the file from the roundup source if
1526 you haven't modified it. Otherwise, add the following to the template::
1528    <display call="multiline('alternate_addresses')">
1530 with appropriate labelling etc. See the standard template for an idea.
1534 Migrating from 0.3.x to 0.4.0
1535 =============================
1537 0.4.0 Message-ID and In-Reply-To addition
1538 -----------------------------------------
1539 0.4.0 adds the tracking of messages by message-id and allows threading
1540 using in-reply-to. Most e-mail clients support threading using this
1541 feature, and we hope to add support for it to the web gateway. If you
1542 have not edited the dbinit.py file in your instance home directory, you may
1543 simply copy the new dbinit.py file from the core code. If you used the
1544 classic schema, the interfaces file is in::
1546  <roundup source>/roundup/templates/classic/dbinit.py
1548 If you used the extended schema, the file is in::
1550  <roundup source>/roundup/templates/extended/dbinit.py 
1552 If you have modified your dbinit.py file, you need to edit the dbinit.py
1553 file in your instance home directory. Find the lines which define the msg
1554 class::
1556     msg = FileClass(db, "msg",
1557                     author=Link("user"), recipients=Multilink("user"),
1558                     date=Date(),         summary=String(),
1559                     files=Multilink("file"))
1561 and add the messageid and inreplyto properties like so::
1563     msg = FileClass(db, "msg",
1564                     author=Link("user"), recipients=Multilink("user"),
1565                     date=Date(),         summary=String(),
1566                     files=Multilink("file"),
1567                     messageid=String(),  inreplyto=String())
1569 Also, configuration is being cleaned up. This means that your dbinit.py will
1570 also need to be changed in the open function. If you haven't changed your
1571 dbinit.py, the above copy will be enough. If you have, you'll need to change
1572 the line (round line 50)::
1574     db = Database(instance_config.DATABASE, name)
1576 to::
1578     db = Database(instance_config, name)
1581 0.4.0 Configuration
1582 --------------------
1583 ``TRACKER_NAME`` and ``EMAIL_SIGNATURE_POSITION`` have been added to the
1584 instance_config.py. The simplest solution is to copy the default values
1585 from template in the core source.
1587 The mail gateway now checks ``ANONYMOUS_REGISTER`` to see if unknown users
1588 are to be automatically registered with the tracker. If it is set to "deny"
1589 then unknown users will not have access. If it is set to "allow" they will be
1590 automatically registered with the tracker.
1593 0.4.0 CGI script roundup.cgi
1594 ----------------------------
1595 The CGI script has been updated with some features and a bugfix, so you should
1596 copy it from the roundup cgi-bin source directory again. Make sure you update
1597 the ROUNDUP_INSTANCE_HOMES after the copy.
1600 0.4.0 Nosy reactor
1601 ------------------
1602 The nosy reactor has also changed - copy the nosyreactor.py file from the core
1603 source::
1605    <roundup source>/roundup/templates/<template>/detectors/nosyreactor.py
1607 to your instance home "detectors" directory.
1610 0.4.0 HTML templating
1611 ---------------------
1612 The field() function was incorrectly implemented - links and multilinks now
1613 display as text fields when rendered using field(). To display a menu (drop-
1614 down or select box) you need to use the menu() function.
1618 Migrating from 0.2.x to 0.3.x
1619 =============================
1621 0.3.x Cookie Authentication changes
1622 -----------------------------------
1623 0.3.0 introduces cookie authentication - you will need to copy the
1624 interfaces.py file from the roundup source to your instance home to enable
1625 authentication. If you used the classic schema, the interfaces file is in::
1627  <roundup source>/roundup/templates/classic/interfaces.py
1629 If you used the extended schema, the file is in::
1631  <roundup source>/roundup/templates/extended/interfaces.py
1633 If you have modified your interfaces.Client class, you will need to take
1634 note of the login/logout functionality provided in roundup.cgi_client.Client
1635 (classic schema) or roundup.cgi_client.ExtendedClient (extended schema) and
1636 modify your instance code apropriately.
1639 0.3.x Password encoding
1640 -----------------------
1641 This release also introduces encoding of passwords in the database. If you
1642 have not edited the dbinit.py file in your instance home directory, you may
1643 simply copy the new dbinit.py file from the core code. If you used the
1644 classic schema, the interfaces file is in::
1646  <roundup source>/roundup/templates/classic/dbinit.py
1648 If you used the extended schema, the file is in::
1650  <roundup source>/roundup/templates/extended/dbinit.py
1653 If you have modified your dbinit.py file, you may use encoded passwords:
1655 1. Edit the dbinit.py file in your instance home directory
1656    a. At the first code line of the open() function::
1658        from roundup.hyperdb import String, Date, Link, Multilink
1660       alter to include Password, as so::
1662        from roundup.hyperdb import String, Password, Date, Link, Multilink
1664    b. Where the password property is defined (around line 66)::
1666        user = Class(db, "user", 
1667                        username=String(),   password=String(),
1668                        address=String(),    realname=String(), 
1669                        phone=String(),      organisation=String())
1670        user.setkey("username")
1672       alter the "password=String()" to "password=Password()"::
1674        user = Class(db, "user", 
1675                        username=String(),   password=Password(),
1676                        address=String(),    realname=String(), 
1677                        phone=String(),      organisation=String())
1678        user.setkey("username")
1680 2. Any existing passwords in the database will remain cleartext until they
1681    are edited. It is recommended that at a minimum the admin password be
1682    changed immediately::
1684       roundup-admin -i <instance home> set user1 password=<new password>
1687 0.3.x Configuration
1688 -------------------
1689 FILTER_POSITION, ANONYMOUS_ACCESS, ANONYMOUS_REGISTER have been added to
1690 the instance_config.py. Simplest solution is to copy the default values from
1691 template in the core source.
1693 MESSAGES_TO_AUTHOR has been added to the IssueClass in dbinit.py. Set to 'yes'
1694 to send nosy messages to the author. Default behaviour is to not send nosy
1695 messages to the author. You will need to add MESSAGES_TO_AUTHOR to your
1696 dbinit.py in your instance home.
1699 0.3.x CGI script roundup.cgi
1700 ----------------------------
1701 There have been some structural changes to the roundup.cgi script - you will
1702 need to install it again from the cgi-bin directory of the source
1703 distribution. Make sure you update the ROUNDUP_INSTANCE_HOMES after the
1704 copy.
1707 .. _`customisation documentation`: customizing.html
1708 .. _`security documentation`: security.html
1709 .. _`administration guide`: admin_guide.html