comparison doc/upgrading.txt @ 7281:194093011cb7

Move upgrade directions for version < 1.5.0 to history document The upgrading doc is huge. Most people don't need docs more than 10 years old. Move docs for versions less than 1.5.0 (July 2013) to upgrading-history.txt. Probably could cut this back to 5 years (1.6.0 release in 2018) but lets go with 10 for now.
author John Rouillard <rouilj@ieee.org>
date Tue, 25 Apr 2023 17:24:32 -0400
parents 41b2a0e12899
children c3b0fd62b0b8
comparison
equal deleted inserted replaced
7280:2a735d785836 7281:194093011cb7
1967 self.client.add_error_message(...) 1967 self.client.add_error_message(...)
1968 1968
1969 The new calls escape the passed string by default and avoid XSS security 1969 The new calls escape the passed string by default and avoid XSS security
1970 issues. 1970 issues.
1971 1971
1972 .. index:: Upgrading; 1.4.20 to 1.4.21
1973
1974 Migrating from 1.4.20 to 1.4.21
1975 ===============================
1976
1977 The ``_generic.calendar.html`` page of the instance has been updated to include
1978 ``<meta name="robots" content="noindex, nofollow" />``. This prevents
1979 robots to follow all the links in the calendar. If you haven't modified the
1980 page on your local instance, you can simply replace it with the one in
1981 ``share/roundup/templates/classic/html/_generic.calendar.html``; if you did,
1982 you can add the tag manually. See issue2550765 and changeset a099ff2ceff3.
1983
1984 If you are using the xml-rpc interface, there is a change
1985 in accessing it. You can not send text/xml data to any
1986 roundup url and get a response, you must use the /xmlrpc
1987 url. For example, if you used to send your xmlrpc request to:
1988
1989 \http://myroundup.com/roundup
1990
1991 you need to change the url to read:
1992
1993 \http://myroundup.com/roundup/xmlrpc
1994
1995 to invoke the xmlrpc handler. This allows us to send xml
1996 data to roundup for other handlers (e.g. REST, SOAP ...)
1997 in the future.
1998
1999
2000 .. index:: upgrading; 1.4.19 to 1.4.20
2001
2002 Migrating from 1.4.19 to 1.4.20
2003 ===============================
2004
2005 Roundup used to allow certain HTML-Tags in OK- and Error-messages. Since
2006 these messages are passed via the URL (due to roundup redirecting after
2007 an edit), we did have security-issues (see issue2550724).
2008
2009 If you have customized the OK or Error messages in your
2010 roundup-installation and you were using features like bold or italic
2011 in the message, you will have to do without this highlighting and
2012 remove HTML tags from messages.
2013
2014 If you were using <br> tags for multi-line messages, you now should use
2015 newlines instead, these will be replaced with <br/> during formatting.
2016
2017 Note that the previous implementation also allowed links inside
2018 messages. Since these links could be set by an attacker, no links in
2019 roundup messages are supported anymore. This does *not* affect the
2020 "clear this message" link in OK-messages as it is generated by the
2021 template and is not part of the OK-message.
2022
2023 If you have not modified any roundup messages, you need not do anything,
2024 the templates shipped with roundup did not use HTML tags in messages for
2025 highlighting.
2026
2027
2028 .. index:: upgrading; 1.4.17 to 1.4.18
2029
2030 Migrating from 1.4.17 to 1.4.18
2031 ===============================
2032
2033 There was a bug in 1.4.17 where files were unlinked from issues if a
2034 mail without attachment was received via the mail interface. The
2035 following script will list likely issues being affected by the bug.
2036 The date in the script is the date of the 1.4.17 release. If you have
2037 installed 1.4.17 later than this date, you can change the date
2038 appropriately to your installation date. Run the script in the directory
2039 of your tracker::
2040
2041 #!/usr/bin/python
2042 import os
2043 from roundup import instance
2044 from roundup.date import Date
2045 dir = os.getcwd ()
2046 tracker = instance.open (dir)
2047 db = tracker.open ('admin')
2048 # you may want to change this to your install date to find less candidates
2049 last_release = Date('2011-05-13')
2050 affected = {}
2051 for i in db.issue.getnodeids():
2052 for j in db.issue.history(i):
2053 if i in affected:
2054 break
2055 if j[1] < last_release or j[3] != 'set' or 'files' not in j[4]:
2056 continue
2057 for op, p in j[4]['files']:
2058 if op == '-':
2059 affected [i] = 1
2060 break
2061 print(', '.join(sorted(affected.keys())))
2062
2063 To find out which files where attached before you can look in the
2064 history of the affected issue. For fixing issues you can re-attach the
2065 files in question using the "set" command of roundup-admin, e.g., if the
2066 list of files attached to an issue should be files 5, 17, 23 for issue42
2067 you will set this using
2068
2069 roundup-admin -i /path/to/your/tracker set issue42 files=5,17,23
2070
2071 .. index:: upgrading; 1.4.x to 1.4.17
2072
2073 Migrating from 1.4.x to 1.4.17
2074 ==============================
2075
2076 There is a new config-option `migrate_passwords` in section `web` to
2077 auto-migrate passwords at web-login time to a more secure storage
2078 scheme. Default for the new option is "yes" so if you don't want that
2079 passwords are auto-migrated to a more secure password scheme on user
2080 login, set this to "no" before running your tracker(s) after the
2081 upgrade.
2082
2083 The standalone roundup-server now defaults to listening on localhost (no
2084 longer on all network interfaces). This will not affect you if you're
2085 already using a configuration file for roundup-server. If you are using
2086 an empty setting for the `host` parameter in the config-file you should
2087 explicitly put 0.0.0.0 there as the use of an empty string to specify
2088 listening to all interfaces is deprecated and will go away in a future
2089 version. If you are starting the server without a configuration file
2090 and want to explicitly listen to all network interface, you should
2091 specify the -n option with the address `0.0.0.0`.
2092
2093 .. _new search permissions for query in 1.4.17:
2094
2095 Searching now requires either read-permission without a check method, or
2096 you will have to add a "Search" permission for a class or a list of
2097 properties for a class (if you want to allow searching). For the classic
2098 template (or other templates derived from it) you want to add the
2099 following lines to your `schema.py` file::
2100
2101 p = db.security.addPermission(name='Search', klass='query')
2102 db.security.addPermissionToRole('User', p)
2103
2104 This is needed, because for the `query` class users may view only their
2105 own queries (or public queries). This is implemented with a `check`
2106 method, therefore the default search permissions will not allow
2107 searching and you'll have to add an explicit search permission.
2108 If you have modified your schema, you can check if you're missing any
2109 search permissions with the following script, run it in your tracker
2110 directory, it will list for each Class and Property the roles that may
2111 search for this property::
2112
2113 #!/usr/bin/python
2114 from __future__ import print_function
2115 import os
2116 from roundup import instance
2117
2118 tracker = instance.open(os.getcwd ())
2119 db = tracker.open('admin')
2120
2121 for cl in sorted(db.getclasses()):
2122 print("Class:", cl)
2123 for p in sorted(db.getclass(cl).getprops(protected=True).keys()):
2124 print(" Property:", p)
2125 roles = []
2126 for role in sorted(db.security.role.keys()):
2127 if db.security.roleHasSearchPermission(cl,p,role):
2128 roles.append(role)
2129 print(" roles may search:", ', '.join(roles))
2130
2131
2132 .. index:: upgrading; 1.4.x to 1.4.12
2133
2134 Migrating from 1.4.x to 1.4.12
2135 ==============================
2136
2137 Item creation now checks the "Create" permission instead of the "Edit"
2138 permission for individual properties. If you have modified your tracker
2139 permissions from the default distribution, you should check that
2140 "Create" permissions exist for all properties you want users to be able
2141 to create.
2142
2143
2144 Fixing some potential security holes
2145 ------------------------------------
2146
2147 Enhanced checking was added to the user registration auditor. If you
2148 run a public tracker you should update your tracker's
2149 ``detectors/userauditor.py`` using the new code from
2150 ``share/roundup/templates/classic/detectors/userauditor.py``. In most
2151 cases you may just copy the file over, but if you've made changes to
2152 the auditor in your tracker then you'll need to manually integrate
2153 the new code.
2154
2155 Some HTML templates were found to have formatting security problems:
2156
2157 ``html/page.html``::
2158
2159 -tal:replace="request/user/username">username</span></b><br>
2160 +tal:replace="python:request.user.username.plain(escape=1)">username</span></b><br>
2161
2162 ``html/_generic.help-list.html``::
2163
2164 -tal:content="structure python:item[prop]"></label>
2165 +tal:content="python:item[prop]"></label>
2166
2167 The lines marked "+" should be added and lines marked "-" should be
2168 deleted (minus the "+"/"-" signs).
2169
2170
2171 Some HTML interface tweaks
2172 --------------------------
2173
2174 You may wish to copy the ``user_utils.js`` and ``style.css` files from the
2175 source distribution ``share/roundup/templates/classic/html/`` directory to the
2176 ``html`` directory of your trackers as it includes a small improvement.
2177
2178 If you have made local changes to those files you'll need to manually work
2179 the differences in to your versions or ignore the changes.
2180
2181
2182 .. index:: upgrading; 1.4.x to 1.4.11
2183
2184 Migrating from 1.4.x to 1.4.11
2185 ==============================
2186
2187 Close potential security hole
2188 -----------------------------
2189
2190 If your tracker has untrusted users you should examine its ``schema.py``
2191 file and look for the section granting the "Edit" permission to your users.
2192 This should look something like::
2193
2194 p = db.security.addPermission(name='Edit', klass='user', check=own_record,
2195 description="User is allowed to edit their own user details")
2196
2197 and should be modified to restrict the list of properties they are allowed
2198 to edit by adding the ``properties=`` section like::
2199
2200 p = db.security.addPermission(name='Edit', klass='user', check=own_record,
2201 properties=('username', 'password', 'address', 'realname', 'phone',
2202 'organisation', 'alternate_addresses', 'queries', 'timezone'),
2203 description="User is allowed to edit their own user details")
2204
2205 Most importantly the "roles" property should not be editable - thus not
2206 appear in that list of properties.
2207
2208
2209 Grant the "Register" permission to the Anonymous role
2210 -----------------------------------------------------
2211
2212 A separate "Register" permission has been introduced to allow
2213 anonymous users to register. This means you will need to add the
2214 following to your tracker's ``schema.py`` to add the permission and
2215 assign it to the Anonymous role (replacing any previously assigned
2216 "Create user" permission for the Anonymous role)::
2217
2218 +db.security.addPermission(name='Register', klass='user',
2219 + description='User is allowed to register new user')
2220
2221 # Assign the appropriate permissions to the anonymous user's Anonymous
2222 # Role. Choices here are:
2223 # - Allow anonymous users to register
2224 -db.security.addPermissionToRole('Anonymous', 'Create', 'user')
2225 +db.security.addPermissionToRole('Anonymous', 'Register', 'user')
2226
2227 The lines marked "+" should be added and lines marked "-" should be
2228 deleted (minus the "+"/"-" signs).
2229
2230 You should also modify the ``html/page.html`` template to change the
2231 permission tested there::
2232
2233 -tal:condition="python:request.user.hasPermission('Create', 'user')"
2234 +tal:condition="python:request.user.hasPermission('Register', 'user')"
2235
2236
2237 Generic class editor may now restore retired items
2238 --------------------------------------------------
2239
2240 The instructions for doing so won't be present in your tracker unless you copy
2241 the ``_generic.index.html`` template from the roundup distribution in
2242 ``share/roundup/templates/classic/html`` to your tracker's ``html`` directory.
2243
2244
2245 .. index:: upgrading; 1.4.x to 1.4.9
2246
2247 Migrating from 1.4.x to 1.4.9
2248 =============================
2249
2250 Customized MailGW Class
2251 -----------------------
2252
2253 If you have customized the MailGW class in your tracker: The new MailGW
2254 class opens the database for each message in the method handle_message
2255 (instance.open) instead of passing the opened database as a parameter to
2256 the MailGW constructor. The old handle_message has been renamed to
2257 _handle_message. The new method opens the database and wraps the call to
2258 the old method into a try/finally.
2259
2260 Your customized MailGW class needs to mirror this behavior.
2261
2262 Fix the "remove" button in issue files and messages lists
2263 ---------------------------------------------------------
2264
2265 The "remove" button(s) in the issue messages list needs to be altered. Find
2266 the following in your tracker's ``html/issue.item.html`` template::
2267
2268 <td>
2269 <form style="padding:0" tal:condition="context/is_edit_ok"
2270 tal:attributes="action string:issue${context/id}">
2271 <input type="hidden" name="@remove@files" tal:attributes="value file/id">
2272
2273 and add ``method="POST"`` as shown below::
2274
2275 <td>
2276 <form style="padding:0" method="POST" tal:condition="context/is_edit_ok"
2277 tal:attributes="action string:issue${context/id}">
2278 <input type="hidden" name="@remove@files" tal:attributes="value file/id">
2279
2280 Then also find::
2281
2282 <td>
2283 <form style="padding:0" tal:condition="context/is_edit_ok"
2284 tal:attributes="action string:issue${context/id}">
2285 <input type="hidden" name="@remove@messages" tal:attributes="value msg/id">
2286
2287 and add ``method="POST"`` as shown below::
2288
2289 <td>
2290 <form style="padding:0" method="POST" tal:condition="context/is_edit_ok"
2291 tal:attributes="action string:issue${context/id}">
2292 <input type="hidden" name="@remove@messages" tal:attributes="value msg/id">
2293
2294
2295 Fixing the "retire" button in user management list
2296 --------------------------------------------------
2297
2298 Some previous versions of this upgrading document missed ``method="POST"``
2299 in the change to the "retire" link in the user management list
2300 in section `Migrating from 1.4.x to 1.4.7`_.
2301 Make sure the change is done as listed below in this document.
2302
2303
2304 .. index:: upgrading; 1.4.x to 1.4.7
2305
2306 Migrating from 1.4.x to 1.4.7
2307 =============================
2308
2309 Several security issues were addressed in this release. Some aspects of your
2310 trackers may no longer function depending on your local customisations. Core
2311 functionality that will need to be modified:
2312
2313 Grant the "retire" permission to users for their queries
2314 --------------------------------------------------------
2315
2316 Users will no longer be able to retire their own queries. To remedy this you
2317 will need to add the following to your tracker's ``schema.py`` just under the
2318 line that grants them permission to edit their own queries::
2319
2320 p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
2321 description="User is allowed to edit their queries")
2322 db.security.addPermissionToRole('User', p)
2323 + p = db.security.addPermission(name='Retire', klass='query', check=edit_query,
2324 + description="User is allowed to retire their queries")
2325 + db.security.addPermissionToRole('User', p)
2326 p = db.security.addPermission(name='Create', klass='query',
2327 description="User is allowed to create queries")
2328 db.security.addPermissionToRole('User', p)
2329
2330 The lines marked "+" should be added, minus the "+" sign.
2331
2332
2333 Fix the "retire" link in the users list for admin users
2334 -------------------------------------------------------
2335
2336 The "retire" link found in the file ``html/user.index.html``::
2337
2338 <td tal:condition="context/is_edit_ok">
2339 <a tal:attributes="href string:user${user/id}?@action=retire&@template=index"
2340 i18n:translate="">retire</a>
2341
2342 Should be replaced with::
2343
2344 <td tal:condition="context/is_retire_ok">
2345 <form style="padding:0" method="POST"
2346 tal:attributes="action string:user${user/id}">
2347 <input type="hidden" name="@template" value="index">
2348 <input type="hidden" name="@action" value="retire">
2349 <input type="submit" value="retire" i18n:attributes="value">
2350 </form>
2351
2352
2353 Fix for Python 2.6+ users
2354 -------------------------
2355
2356 If you use Python 2.6 you should edit your tracker's
2357 ``detectors/nosyreaction.py`` file to change::
2358
2359 import sets
2360
2361 at the top to::
2362
2363 from roundup.anypy.sets_ import set
2364
2365 and then all instances of ``sets.Set()`` to ``set()`` in the later code.
2366
2367
2368
2369 Trackers currently allowing HTML file uploading
2370 -----------------------------------------------
2371
2372 Trackers which wish to continue to allow uploading of HTML content against issues
2373 will need to set a new configuration variable in the ``[web]`` section of the
2374 tracker's ``config.ini`` file:
2375
2376 # Setting this option enables Roundup to serve uploaded HTML
2377 # file content *as HTML*. This is a potential security risk
2378 # and is therefore disabled by default. Set to 'yes' if you
2379 # trust *all* users uploading content to your tracker.
2380 # Allowed values: yes, no
2381 # Default: no
2382 allow_html_file = no
2383
2384
2385
2386 .. index:: upgrading; 1.4.2 to 1.4.3
2387
2388 Migrating from 1.4.2 to 1.4.3
2389 =============================
2390
2391 If you are using the MySQL backend you will need to replace some indexes
2392 that may have been created by version 1.4.2.
2393
2394 You should to access your MySQL database directly and remove any indexes
2395 with a name ending in "_key_retired_idx". You should then re-add them with
2396 the same spec except the key column name needs a size. So an index on
2397 "_user (__retired, _name)" should become "_user (__retired, _name(255))".
2398
2399
2400 .. index:: upgrading; 1.4.x to 1.4.2
2401
2402 Migrating from 1.4.x to 1.4.2
2403 =============================
2404
2405 .. index:: roundup-admin; migrate subcommand
2406
2407 You should run the "roundup-admin migrate" command for your tracker once
2408 you've installed the latest codebase.
2409
2410 Do this before you use the web, command-line or mail interface and before
2411 any users access the tracker.
2412
2413 This command will respond with either "Tracker updated" (if you've not
2414 previously run it on an RDBMS backend) or "No migration action required"
2415 (if you have run it, or have used another interface to the tracker,
2416 or are using anydbm).
2417
2418 It's safe to run this even if it's not required, so just get into the
2419 habit.
2420
2421
2422 .. index:: upgrading; 1.3.3 to 1.4.0
2423
2424 Migrating from 1.3.3 to 1.4.0
2425 =============================
2426
2427 Value of the "refwd_re" tracker configuration option (section "mailgw")
2428 is treated as UTF-8 string. In previous versions, it was ISO8859-1.
2429
2430 If you have running trackers based on the classic template, please
2431 update the messagesummary detector as follows::
2432
2433 --- detectors/messagesummary.py 17 Apr 2003 03:26:38 -0000 1.1
2434 +++ detectors/messagesummary.py 3 Apr 2007 06:47:21 -0000 1.2
2435 @@ -8,7 +8,7 @@
2436 if newvalues.has_key('summary') or not newvalues.has_key('content'):
2437 return
2438
2439 - summary, content = parseContent(newvalues['content'], 1, 1)
2440 + summary, content = parseContent(newvalues['content'], config=db.config)
2441 newvalues['summary'] = summary
2442
2443 In the latest version we have added some database indexes to the
2444 SQL-backends (mysql, postgresql, sqlite) for speeding up building the
2445 roundup-index for full-text search. We recommend that you create the
2446 following database indexes on the database by hand::
2447
2448 CREATE INDEX words_by_id ON __words (_textid);
2449 CREATE UNIQUE INDEX __textids_by_props ON __textids (_class, _itemid, _prop);
2450
2451 .. index:: upgrading; 1.2.x to 1.3.0
2452
2453 Migrating from 1.2.x to 1.3.0
2454 =============================
2455
2456 1.3.0 Web interface changes
2457 ---------------------------
2458
2459 Some of the HTML files in the "classic" and "minimal" tracker templates
2460 were changed to fix some bugs and clean them up. You may wish to compare
2461 them to the HTML files in your tracker and apply any changes.
2462
2463
2464 .. index:: upgrading; 1.1.2 to 1.2.0
2465
2466 Migrating from 1.1.2 to 1.2.0
2467 =============================
2468
2469 1.2.0 Sorting and grouping by multiple properties
2470 -------------------------------------------------
2471
2472 Starting with this version, sorting and grouping by multiple properties
2473 is possible. This means that request.sort and request.group are now
2474 lists. This is reflected in several places:
2475
2476 * ``renderWith`` now has list attributes for ``sort`` and ``group``,
2477 where you previously wrote::
2478
2479 renderWith(... sort=('-', 'activity'), group=('+', 'priority')
2480
2481 you write now::
2482
2483 renderWith(... sort=[('-', 'activity')], group=[('+', 'priority')]
2484
2485 * In templates that permit to edit sorting/grouping, request.sort and
2486 request.group are (possibly empty) lists. You can now sort and group
2487 by multiple attributes. For an example, see the classic template. You
2488 may want search for the variable ``n_sort`` which can be set to the
2489 number of sort/group properties.
2490
2491 * Templates that diplay new headlines for each group of items with
2492 equal group properties can now use the modified ``batch.propchanged``
2493 method that can take several properties which are checked for
2494 changes. See the example in the classic template which makes use of
2495 ``batch.propchanged``.
2496
2497 .. index:: upgrading; 1.1.0 to 1.1.1
2498
2499 Migrating from 1.1.0 to 1.1.1
2500 =============================
2501
2502 1.1.1 "Clear this message"
2503 --------------------------
2504
2505 In 1.1.1, the standard ``page.html`` template includes a "clear this message"
2506 link in the green "ok" message bar that appears after a successful edit
2507 (or other) action.
2508
2509 To include this in your tracker, change the following in your ``page.html``
2510 template::
2511
2512 <p tal:condition="options/ok_message | nothing" class="ok-message"
2513 tal:repeat="m options/ok_message" tal:content="structure m">error</p>
2514
2515 to be::
2516
2517 <p tal:condition="options/ok_message | nothing" class="ok-message">
2518 <span tal:repeat="m options/ok_message"
2519 tal:content="structure string:$m <br/ > " />
2520 <a class="form-small" tal:attributes="href request/current_url"
2521 i18n:translate="">clear this message</a>
2522 </p>
2523
2524
2525 If you implemented the "clear this message" in your 1.1.0 tracker, then you
2526 should change it to the above and it will work much better!
2527
2528
2529 .. index:: upgrading; 1.0.x to 1.1.0
2530
2531 Migrating from 1.0.x to 1.1.0
2532 =============================
2533
2534 1.1 Login "For Session Only"
2535 ----------------------------
2536
2537 In 1.1, web logins are alive for the length of a session only, *unless* you
2538 add the following to the login form in your tracker's ``page.html``::
2539
2540 <input type="checkbox" name="remember" id="remember">
2541 <label for="remember" i18n:translate="">Remember me?</label><br>
2542
2543 See the classic tracker ``page.html`` if you're unsure where this should
2544 go.
2545
2546
2547 1.1 Query Display Name
2548 ----------------------
2549
2550 The ``dispname`` web variable has been renamed ``@dispname`` to avoid
2551 clashing with other variables of the same name. If you are using the
2552 display name feature, you will need to edit your tracker's ``page.html``
2553 and ``issue.index.html`` pages to change ``dispname`` to ``@dispname``.
2554
2555 A side-effect of this change is that the renderWith method used in the
2556 ``home.html`` page may now take a dispname argument.
2557
2558
2559 1.1 "Clear this message"
2560 ------------------------
2561
2562 In 1.1, the standard ``page.html`` template includes a "clear this message"
2563 link in the green "ok" message bar that appears after a successful edit
2564 (or other) action.
2565
2566 To include this in your tracker, change the following in your ``page.html``
2567 template::
2568
2569 <p tal:condition="options/ok_message | nothing" class="ok-message"
2570 tal:repeat="m options/ok_message" tal:content="structure m">error</p>
2571
2572 to be::
2573
2574 <p tal:condition="options/ok_message | nothing" class="ok-message">
2575 <span tal:repeat="m options/ok_message"
2576 tal:content="structure string:$m <br/ > " />
2577 <a class="form-small" tal:attributes="href string:issue${context/id}"
2578 i18n:translate="">clear this message</a>
2579 </p>
2580
2581
2582 .. index:: upgrading; 0.8.x to 1.0
2583
2584 Migrating from 0.8.x to 1.0
2585 ===========================
2586
2587 1.0 New Query Permissions
2588 -------------------------
2589
2590 New permissions are defined for query editing and viewing. To include these
2591 in your tracker, you need to add these lines to your tracker's
2592 ``schema.py``::
2593
2594 # Users should be able to edit and view their own queries. They should also
2595 # be able to view any marked as not private. They should not be able to
2596 # edit others' queries, even if they're not private
2597 def view_query(db, userid, itemid):
2598 private_for = db.query.get(itemid, 'private_for')
2599 if not private_for: return True
2600 return userid == private_for
2601 def edit_query(db, userid, itemid):
2602 return userid == db.query.get(itemid, 'creator')
2603 p = db.security.addPermission(name='View', klass='query', check=view_query,
2604 description="User is allowed to view their own and public queries")
2605 db.security.addPermissionToRole('User', p)
2606 p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
2607 description="User is allowed to edit their queries")
2608 db.security.addPermissionToRole('User', p)
2609 p = db.security.addPermission(name='Create', klass='query',
2610 description="User is allowed to create queries")
2611 db.security.addPermissionToRole('User', p)
2612
2613 and then remove 'query' from the line::
2614
2615 # Assign the access and edit Permissions for issue, file and message
2616 # to regular users now
2617 for cl in 'issue', 'file', 'msg', 'query', 'keyword':
2618
2619 so it looks like::
2620
2621 for cl in 'issue', 'file', 'msg', 'keyword':
2622
2623
2624 .. index:: upgrading; 0.8.0 to 0.8.3
2625
2626 Migrating from 0.8.0 to 0.8.3
2627 =============================
2628
2629 0.8.3 Nosy Handling Changes
2630 ---------------------------
2631
2632 A change was made to fix a bug in the ``nosyreaction.py`` standard
2633 detector. To incorporate this fix in your trackers, you will need to copy
2634 the ``nosyreaction.py`` file from the ``templates/classic/detectors``
2635 directory of the source to your tracker's ``templates`` directory.
2636
2637 If you have modified the ``nosyreaction.py`` file from the standard
2638 version, you will need to roll your changes into the new file.
2639
2640
2641 .. index:: upgrading; 0.7.1 to 0.8.0
2642
2643 Migrating from 0.7.1 to 0.8.0
2644 =============================
2645
2646 You *must* fully uninstall previous Roundup version before installing
2647 Roundup 0.8.0. If you don't do that, ``roundup-admin install``
2648 command may fail to function properly.
2649
2650 0.8.0 Backend changes
2651 ---------------------
2652
2653 Backends 'bsddb' and 'bsddb3' are removed. If you are using one of these,
2654 you *must* migrate to another backend before upgrading.
2655
2656
2657 0.8.0 API changes
2658 -----------------
2659
2660 Class.safeget() was removed from the API. Test your item ids before calling
2661 Class.get() instead.
2662
2663
2664 0.8.0 New tracker layout
2665 ------------------------
2666
2667 The ``config.py`` file has been replaced by ``config.ini``. You may use the
2668 roundup-admin command "genconfig" to generate a new config file::
2669
2670 roundup-admin genconfig <tracker home>/config.ini
2671
2672 and modify the values therein based on the contents of your old config.py.
2673 In most cases, the names of the config variables are the same.
2674
2675 The ``select_db.py`` file has been replaced by a file in the ``db``
2676 directory called ``backend_name``. As you might guess, this file contains
2677 just the name of the backend. To figure what the contents of yours should
2678 be, use the following table:
2679
2680 ================================ =========================
2681 ``select_db.py`` contents ``backend_name`` contents
2682 ================================ =========================
2683 from back_anydbm import ... anydbm
2684 from back_metakit import ... metakit
2685 from back_sqlite import ... sqlite
2686 from back_mysql import ... mysql
2687 from back_postgresql import ... postgresql
2688 ================================ =========================
2689
2690 The ``dbinit.py`` file has been split into two new files,
2691 ``initial_data.py`` and ``schema.py``. The contents of this file are:
2692
2693 ``initial_data.py``
2694 You don't need one of these as your tracker is already initialised.
2695
2696 ``schema.py``
2697 Copy the body of the ``def open(name=None)`` function from your old
2698 tracker's ``dbinit.py`` file to this file. As the lines you're copying
2699 aren't part of a function definition anymore, one level of indentation
2700 needs to be removed (remove only the leading four spaces on each
2701 line).
2702
2703 The first few lines -- those starting with ``from roundup.hyperdb
2704 import ...`` and the ``db = Database(config, name)`` line -- don't
2705 need to be copied. Neither do the last few lines -- those starting
2706 with ``import detectors``, down to ``return db`` inclusive.
2707
2708 You may remove the ``__init__.py`` module from the "detectors" directory as
2709 it is no longer used.
2710
2711 There's a new way to write extension code for Roundup. If you have code in
2712 an ``interfaces.py`` file you should move it. See the `customisation
2713 documentation`_ for information about how extensions are now written.
2714 Note that some older trackers may use ``interfaces.py`` to customise the
2715 mail gateway behaviour. You will need to keep your ``interfaces.py`` file
2716 if this is the case.
2717
2718
2719 0.8.0 Permissions Changes
2720 -------------------------
2721
2722 The creation of a new item in the user interfaces is now controlled by the
2723 "Create" Permission. You will need to add an assignment of this Permission
2724 to your users who are allowed to create items. The most common form of this
2725 is the following in your ``schema.py`` added just under the current
2726 assignation of the Edit Permission::
2727
2728 for cl in 'issue', 'file', 'msg', 'query', 'keyword':
2729 p = db.security.getPermission('Create', cl)
2730 db.security.addPermissionToRole('User', p)
2731
2732 You will need to explicitly let anonymous users access the web interface so
2733 that regular users are able to see the login form. Note that almost all
2734 trackers will need this Permission. The only situation where it's not
2735 required is in a tracker that uses an HTTP Basic Authenticated front-end.
2736 It's enabled by adding to your ``schema.py``::
2737
2738 p = db.security.getPermission('Web Access')
2739 db.security.addPermissionToRole('Anonymous', p)
2740
2741 Finally, you will need to enable permission for your users to edit their
2742 own details by adding the following to ``schema.py``::
2743
2744 # Users should be able to edit their own details. Note that this
2745 # permission is limited to only the situation where the Viewed or
2746 # Edited item is their own.
2747 def own_record(db, userid, itemid):
2748 '''Determine whether the userid matches the item being accessed.'''
2749 return userid == itemid
2750 p = db.security.addPermission(name='View', klass='user', check=own_record,
2751 description="User is allowed to view their own user details")
2752 p = db.security.addPermission(name='Edit', klass='user', check=own_record,
2753 description="User is allowed to edit their own user details")
2754 db.security.addPermissionToRole('User', p)
2755
2756
2757 0.8.0 Use of TemplatingUtils
2758 ----------------------------
2759
2760 If you used custom python functions in TemplatingUtils, they must
2761 be moved from interfaces.py to a new file in the ``extensions`` directory.
2762
2763 Each Function that should be available through TAL needs to be defined
2764 as a toplevel function in the newly created file. Furthermore you
2765 add an inititialization function, that registers the functions with the
2766 tracker.
2767
2768 If you find this too tedious, donfu wrote an automatic init function that
2769 takes an existing TemplatingUtils class, and registers all class methods
2770 that do not start with an underscore. The following hack should be placed
2771 in the ``extensions`` directory alongside other extensions::
2772
2773 class TemplatingUtils:
2774 # copy from interfaces.py
2775
2776 def init(tracker):
2777 util = TemplatingUtils()
2778
2779 def setClient(tu):
2780 util.client = tu.client
2781 return util
2782
2783 def execUtil(name):
2784 return lambda tu, *args, **kwargs: \
2785 getattr(setClient(tu), name)(*args, **kwargs)
2786
2787 for name in dir(util):
2788 if callable(getattr(util, name)) and not name.startswith('_'):
2789 tracker.registerUtil(name, execUtil(name))
2790
2791
2792 0.8.0 Logging Configuration
2793 ---------------------------
2794
2795 See the `administration guide`_ for information about configuring the new
2796 logging implemented in 0.8.0.
2797
2798
2799 .. index:: upgrading; 0.7.2 to 0.7.3
2800
2801 Migrating from 0.7.2 to 0.7.3
2802 =============================
2803
2804 0.7.3 Configuration
2805 -------------------
2806
2807 If you choose, you may specify the directory from which static files are
2808 served (those which use the URL component ``@@file``). Currently the
2809 directory defaults to the ``TEMPLATES`` configuration variable. You may
2810 define a new variable, ``STATIC_FILES`` which overrides this value for
2811 static files.
2812
2813
2814 .. index:: upgrading; 0.7.0 to 0.7.2
2815
2816 Migrating from 0.7.0 to 0.7.2
2817 =============================
2818
2819 0.7.2 DEFAULT_TIMEZONE is now required
2820 --------------------------------------
2821
2822 The DEFAULT_TIMEZONE configuration variable is now required. Add the
2823 following to your tracker's ``config.py`` file::
2824
2825 # You may specify a different default timezone, for use when users do not
2826 # choose their own in their settings.
2827 DEFAULT_TIMEZONE = 0 # specify as numeric hour offest
2828
2829 .. index:: upgrading; 0.7.0 to 0.7.1
2830
2831 Migrating from 0.7.0 to 0.7.1
2832 =============================
2833
2834 0.7.1 Permission assignments
2835 ----------------------------
2836
2837 If you allow anonymous access to your tracker, you might need to assign
2838 some additional View (or Edit if your tracker is that open) permissions
2839 to the "anonymous" user. To do so, find the code in your ``dbinit.py`` that
2840 says::
2841
2842 for cl in 'issue', 'file', 'msg', 'query', 'keyword':
2843 p = db.security.getPermission('View', cl)
2844 db.security.addPermissionToRole('User', p)
2845 p = db.security.getPermission('Edit', cl)
2846 db.security.addPermissionToRole('User', p)
2847 for cl in 'priority', 'status':
2848 p = db.security.getPermission('View', cl)
2849 db.security.addPermissionToRole('User', p)
2850
2851 Add add a line::
2852
2853 db.security.addPermissionToRole('Anonymous', p)
2854
2855 next to the existing ``'User'`` lines for the Permissions you wish to
2856 assign to the anonymous user.
2857
2858
2859 .. index:: upgrading; versions earlier than 0.7
2860
2861 Migrating from 0.6 to 0.7
2862 =========================
2863
2864 0.7.0 Permission assignments
2865 ----------------------------
2866
2867 Due to a change in the rendering of web widgets, permissions are now
2868 checked on Classes where they previously weren't (this is a good thing).
2869
2870 You will need to add some additional Permission assignments for your
2871 regular users, or some displays will break. After the following in your
2872 tracker's ``dbinit.py``::
2873
2874 # Assign the access and edit Permissions for issue, file and message
2875 # to regular users now
2876 for cl in 'issue', 'file', 'msg', 'query', 'keyword':
2877 p = db.security.getPermission('View', cl)
2878 db.security.addPermissionToRole('User', p)
2879 p = db.security.getPermission('Edit', cl)
2880 db.security.addPermissionToRole('User', p)
2881
2882 add::
2883
2884 for cl in 'priority', 'status':
2885 p = db.security.getPermission('View', cl)
2886 db.security.addPermissionToRole('User', p)
2887
2888
2889 0.7.0 Getting the current user id
2890 ---------------------------------
2891
2892 The Database.curuserid attribute has been removed.
2893
2894 Any code referencing this attribute should be replaced with a
2895 call to Database.getuid().
2896
2897
2898 0.7.0 ZRoundup changes
2899 ----------------------
2900
2901 The templates in your tracker's html directory will need updating if you
2902 wish to use ZRoundup. If you've not modified those files (or some of them),
2903 you may just copy the new versions from the Roundup source in the
2904 templates/classic/html directory.
2905
2906 If you have modified the html files, then you'll need to manually edit them
2907 to change all occurances of special form variables from using the colon ":"
2908 special character to the at "@" special character. That is, variables such
2909 as::
2910
2911 :action :required :template :remove:messages ...
2912
2913 should become::
2914
2915 @action @required @template @remove@messages ...
2916
2917 Note that ``tal:`` statements are unaffected. So are TAL expression type
2918 prefixes such as ``python:`` and ``string:``. Please ask on the
2919 roundup-users mailing list for help if you're unsure.
2920
2921
2922 0.7.0 Edit collision detection
2923 ------------------------------
2924
2925 Roundup now detects collisions with editing in the web interface (that is,
2926 two people editing the same item at the same time).
2927
2928 You must copy the ``_generic.collision.html`` file from Roundup source in
2929 the ``templates/classic/html`` directory. to your tracker's ``html``
2930 directory.
2931
2932
2933 Migrating from 0.6.x to 0.6.3
2934 =============================
2935
2936 0.6.3 Configuration
2937 -------------------
2938
2939 You will need to copy the file::
2940
2941 templates/classic/detectors/__init__.py
2942
2943 to your tracker's ``detectors`` directory, replacing the one already there.
2944 This fixes a couple of bugs in that file.
2945
2946
2947
2948 Migrating from 0.5 to 0.6
2949 =========================
2950
2951
2952 0.6.0 Configuration
2953 -------------------
2954
2955 Introduced EMAIL_FROM_TAG config variable. This value is inserted into
2956 the From: line of nosy email. If the sending user is "Foo Bar", the
2957 From: line is usually::
2958
2959 "Foo Bar" <issue_tracker@tracker.example>
2960
2961 the EMAIL_FROM_TAG goes inside the "Foo Bar" quotes like so::
2962
2963 "Foo Bar EMAIL_FROM_TAG" <issue_tracker@tracker.example>
2964
2965 I've altered the mechanism in the detectors __init__.py module so that it
2966 doesn't cross-import detectors from other trackers (if you run more than one
2967 in a single roundup-server). This change means that you'll need to copy the
2968 __init__.py from roundup/templates/classic/detectors/__init__.py to your
2969 <tracker home>/detectors/__init__.py. Don't worry, the "classic" __init__ is a
2970 one-size-fits-all, so it'll work even if you've added/removed detectors.
2971
2972 0.6.0 Templating changes
2973 ------------------------
2974
2975 The ``user.item`` template (in the tracker home "templates" directory)
2976 needs to have the following hidden variable added to its form (between the
2977 ``<form...>`` and ``</form>`` tags::
2978
2979 <input type="hidden" name=":template" value="item">
2980
2981
2982 0.6.0 Form handling changes
2983 ---------------------------
2984
2985 Roundup's form handling capabilities have been significantly expanded. This
2986 should not affect users of 0.5 installations - but if you find you're
2987 getting errors from form submissions, please ask for help on the Roundup
2988 users mailing list:
2989
2990 https://sourceforge.net/projects/roundup/lists/roundup-users
2991
2992 See the customisation doc section on `Form Values`__ for documentation of the
2993 new form variables possible.
2994
2995 __ customizing.html#form-values
2996
2997
2998 0.6.0 Multilingual character set support
2999 ----------------------------------------
3000
3001 Added internationalization support. This is done via encoding all data
3002 stored in roundup database to utf-8 (unicode encoding). To support utf-8 in
3003 web interface you should add the folowing line to your tracker's html/page
3004 and html/_generic.help files inside <head> tag::
3005
3006 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
3007
3008 Since latin characters in utf-8 have the same codes as in ASCII table, this
3009 modification is optional for users who use only plain latin characters.
3010
3011 After this modification, you will be able to see and enter any world
3012 character via web interface. Data received via mail interface also converted
3013 to utf-8, however only new messages will be converted. If your roundup
3014 database contains some of non-ASCII characters in one of 8-bit encoding,
3015 they will not be visible in new unicode environment. Some of such data (e.g.
3016 user names, keywords, etc) can be edited by administrator, the others
3017 (e.g. messages' contents) is not editable via web interface. Currently there
3018 is no tool for converting such data, the only solution is to close
3019 appropriate old issues and create new ones with the same content.
3020
3021
3022 0.6.0 User timezone support
3023 ---------------------------
3024
3025 From version 0.6.0 roundup supports displaying of Date data in user' local
3026 timezone if he/she has provided timezone information. To make it possible
3027 some modification to tracker's schema and HTML templates are required.
3028 First you must add string property 'timezone' to user class in dbinit.py
3029 like this::
3030
3031 user = Class(db, "user",
3032 username=String(), password=Password(),
3033 address=String(), realname=String(),
3034 phone=String(), organisation=String(),
3035 alternate_addresses=String(),
3036 queries=Multilink('query'), roles=String(),
3037 timezone=String())
3038
3039 And second - html interface. Add following lines to
3040 $TRACKER_HOME/html/user.item template::
3041
3042 <tr>
3043 <th>Timezone</th>
3044 <td tal:content="structure context/timezone/field">timezone</td>
3045 </tr>
3046
3047 After that all users should be able to provide their timezone information.
3048 Timezone should be a positive or negative integer - offset from GMT.
3049
3050 After providing timezone, roundup will show all dates values, found in web
3051 and mail interfaces in local time. It will also accept any Date info in
3052 local time, convert and store it in GMT.
3053
3054
3055 0.6.0 Search page structure
3056 ---------------------------
3057
3058 In order to accomodate query editing the search page has been restructured. If
3059 you want to provide your users with query editing, you should update your
3060 search page using the macros detailed in the customisation doc section
3061 `Searching on categories`__.
3062
3063 __ customizing.html#searching-on-categories
3064
3065 Also, the url field in the query class no longer starts with a '?'. You'll need
3066 to remove this question mark from the url field to support queries. There's
3067 a script in the "tools" directory called ``migrate-queries.py`` that should
3068 automatically change any existing queries for you. As always, make a backup
3069 of your database before running such a script.
3070
3071
3072 0.6.0 Notes for metakit backend users
3073 -------------------------------------
3074
3075 Roundup 0.6.0 introduced searching on ranges of dates and intervals. To
3076 support it, some modifications to interval storing routine were made. So if
3077 your tracker uses metakit backend and your db schema contains intervals
3078 property, searches on that property will not be accurate for db items that
3079 was stored before roundup' upgrade. However all new records should be
3080 searchable on intervals.
3081
3082 It is possible to convert your database to new format: you can export and
3083 import back all your data (consult "Migrating backends" in "Maintenance"
3084 documentation). After this operation all your interval properties should
3085 become searchable.
3086
3087 Users of backends others than metakit should not worry about this issue.
3088
3089
3090 Migrating from 0.4.x to 0.5.0
3091 =============================
3092
3093 This has been a fairly major revision of Roundup:
3094
3095 1. Brand new, much more powerful, flexible, tasty and nutritious templating.
3096 Unfortunately, this means all your current templates are useless. Hopefully
3097 the new documentation and examples will be enough to help you make the
3098 transition. Please don't hesitate to ask on roundup-users for help (or
3099 complete conversions if you're completely stuck)!
3100 2. The database backed got a lot more flexible, allowing Metakit and SQL
3101 databases! The only decent SQL database implemented at present is sqlite,
3102 but others shouldn't be a whole lot more work.
3103 3. A brand new, highly flexible and much more robust security system including
3104 a system of Permissions, Roles and Role assignments to users. You may now
3105 define your own Permissions that may be checked in CGI transactions.
3106 4. Journalling has been made less storage-hungry, so has been turned on
3107 by default *except* for author, recipient and nosy link/unlink events. You
3108 are advised to turn it off in your trackers too.
3109 5. We've changed the terminology from "instance" to "tracker", to ease the
3110 learning curve/impact for new users.
3111 6. Because of the above changes, the tracker configuration has seen some
3112 major changes. See below for the details.
3113
3114 Please, **back up your database** before you start the migration process. This
3115 is as simple as copying the "db" directory and all its contents from your
3116 tracker to somewhere safe.
3117
3118
3119 0.5.0 Configuration
3120 -------------------
3121
3122 First up, rename your ``instance_config.py`` file to just ``config.py``.
3123
3124 Then edit your tracker's ``__init__.py`` module. It'll currently look
3125 like this::
3126
3127 from instance_config import *
3128 try:
3129 from dbinit import *
3130 except ImportError:
3131 pass # in installdir (probably :)
3132 from interfaces import *
3133
3134 and it needs to be::
3135
3136 import config
3137 from dbinit import open, init
3138 from interfaces import Client, MailGW
3139
3140 Due to the new templating having a top-level ``page`` that defines links for
3141 searching, indexes, adding items etc, the following variables are no longer
3142 used:
3143
3144 - HEADER_INDEX_LINKS
3145 - HEADER_ADD_LINKS
3146 - HEADER_SEARCH_LINKS
3147 - SEARCH_FILTERS
3148 - DEFAULT_INDEX
3149 - UNASSIGNED_INDEX
3150 - USER_INDEX
3151 - ISSUE_FILTER
3152
3153 The new security implementation will require additions to the dbinit module,
3154 but also removes the need for the following tracker config variables:
3155
3156 - ANONYMOUS_ACCESS
3157 - ANONYMOUS_REGISTER
3158
3159 but requires two new variables which define the Roles assigned to users who
3160 register through the web and e-mail interfaces:
3161
3162 - NEW_WEB_USER_ROLES
3163 - NEW_EMAIL_USER_ROLES
3164
3165 in both cases, 'User' is a good initial setting. To emulate
3166 ``ANONYMOUS_ACCESS='deny'``, remove all "View" Permissions from the
3167 "Anonymous" Role. To emulate ``ANONYMOUS_REGISTER='deny'``, remove the "Web
3168 Registration" and/or the "Email Registration" Permission from the "Anonymous"
3169 Role. See the section on customising security in the `customisation
3170 documentation`_ for more information.
3171
3172 Finally, the following config variables have been renamed to make more sense:
3173
3174 - INSTANCE_HOME -> TRACKER_HOME
3175 - INSTANCE_NAME -> TRACKER_NAME
3176 - ISSUE_TRACKER_WEB -> TRACKER_WEB
3177 - ISSUE_TRACKER_EMAIL -> TRACKER_EMAIL
3178
3179
3180 0.5.0 Schema Specification
3181 --------------------------
3182
3183 0.5.0 Database backend changes
3184 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3185
3186 Your select_db module in your tracker has changed a fair bit. Where it used
3187 to contain::
3188
3189 # WARNING: DO NOT EDIT THIS FILE!!!
3190 from roundup.backends.back_anydbm import Database
3191
3192 it must now contain::
3193
3194 # WARNING: DO NOT EDIT THIS FILE!!!
3195 from roundup.backends.back_anydbm import Database, Class, FileClass, IssueClass
3196
3197 Yes, I realise the irony of the "DO NOT EDIT THIS FILE" statement :)
3198 Note the addition of the Class, FileClass, IssueClass imports. These are very
3199 important, as they're going to make the next change work too. You now need to
3200 modify the top of the dbinit module in your tracker from::
3201
3202 import instance_config
3203 from roundup import roundupdb
3204 from select_db import Database
3205
3206 from roundup.roundupdb import Class, FileClass
3207
3208 class Database(roundupdb.Database, select_db.Database):
3209 ''' Creates a hybrid database from:
3210 . the selected database back-end from select_db
3211 . the roundup extensions from roundupdb
3212 '''
3213 pass
3214
3215 class IssueClass(roundupdb.IssueClass):
3216 ''' issues need the email information
3217 '''
3218 pass
3219
3220 to::
3221
3222 import config
3223 from select_db import Database, Class, FileClass, IssueClass
3224
3225 Yes, remove the Database and IssueClass definitions and those other imports.
3226 They're not needed any more!
3227
3228 Look for places in dbinit.py where ``instance_config`` is used too, and
3229 rename them ``config``.
3230
3231
3232 0.5.0 Journalling changes
3233 ~~~~~~~~~~~~~~~~~~~~~~~~~
3234
3235 Journalling has been optimised for storage. Journalling of links has been
3236 turned back on by default. If your tracker has a large user base, you may wish
3237 to turn off journalling of nosy list, message author and message recipient
3238 link and unlink events. You do this by adding ``do_journal='no'`` to the Class
3239 initialisation in your dbinit. For example, your *msg* class initialisation
3240 probably looks like this::
3241
3242 msg = FileClass(db, "msg",
3243 author=Link("user"), recipients=Multilink("user"),
3244 date=Date(), summary=String(),
3245 files=Multilink("file"),
3246 messageid=String(), inreplyto=String())
3247
3248 to turn off journalling of author and recipient link events, add
3249 ``do_journal='no'`` to the ``author=Link("user")`` part of the statement,
3250 like so::
3251
3252 msg = FileClass(db, "msg",
3253 author=Link("user", do_journal='no'),
3254 recipients=Multilink("user", do_journal='no'),
3255 date=Date(), summary=String(),
3256 files=Multilink("file"),
3257 messageid=String(), inreplyto=String())
3258
3259 Nosy list link event journalling is actually turned off by default now. If you
3260 want to turn it on, change to your issue class' nosy list, change its
3261 definition from::
3262
3263 issue = IssueClass(db, "issue",
3264 assignedto=Link("user"), topic=Multilink("keyword"),
3265 priority=Link("priority"), status=Link("status"))
3266
3267 to::
3268
3269 issue = IssueClass(db, "issue", nosy=Multilink("user", do_journal='yes'),
3270 assignedto=Link("user"), topic=Multilink("keyword"),
3271 priority=Link("priority"), status=Link("status"))
3272
3273 noting that your definition of the nosy Multilink will override the normal one.
3274
3275
3276 0.5.0 User schema changes
3277 ~~~~~~~~~~~~~~~~~~~~~~~~~
3278
3279 Users have two more properties, "queries" and "roles". You'll have something
3280 like this in your dbinit module now::
3281
3282 user = Class(db, "user",
3283 username=String(), password=Password(),
3284 address=String(), realname=String(),
3285 phone=String(), organisation=String(),
3286 alternate_addresses=String())
3287 user.setkey("username")
3288
3289 and you'll need to add the new properties and the new "query" class to it
3290 like so::
3291
3292 query = Class(db, "query",
3293 klass=String(), name=String(),
3294 url=String())
3295 query.setkey("name")
3296
3297 # Note: roles is a comma-separated string of Role names
3298 user = Class(db, "user",
3299 username=String(), password=Password(),
3300 address=String(), realname=String(),
3301 phone=String(), organisation=String(),
3302 alternate_addresses=String(),
3303 queries=Multilink('query'), roles=String())
3304 user.setkey("username")
3305
3306 The "queries" property is used to store off the user's favourite database
3307 queries. The "roles" property is explained below in `0.5.0 Security
3308 Settings`_.
3309
3310
3311 0.5.0 Security Settings
3312 ~~~~~~~~~~~~~~~~~~~~~~~
3313
3314 See the `security documentation`_ for an explanation of how the new security
3315 system works. In a nutshell though, the security is handled as a four step
3316 process:
3317
3318 1. Permissions are defined as having a name and optionally a hyperdb class
3319 they're specific to,
3320 2. Roles are defined that have one or more Permissions,
3321 3. Users are assigned Roles in their "roles" property, and finally
3322 4. Roundup checks that users have appropriate Permissions at appropriate times
3323 (like editing issues).
3324
3325 Your tracker dbinit module's *open* function now has to define any
3326 Permissions that are specific to your tracker, and also the assignment
3327 of Permissions to Roles. At the moment, your open function
3328 ends with::
3329
3330 import detectors
3331 detectors.init(db)
3332
3333 return db
3334
3335 and what we need to do is insert some commands that will set up the security
3336 parameters. Right above the ``import detectors`` line, you'll want to insert
3337 these lines::
3338
3339 #
3340 # SECURITY SETTINGS
3341 #
3342 # new permissions for this schema
3343 for cl in 'issue', 'file', 'msg', 'user':
3344 db.security.addPermission(name="Edit", klass=cl,
3345 description="User is allowed to edit "+cl)
3346 db.security.addPermission(name="View", klass=cl,
3347 description="User is allowed to access "+cl)
3348
3349 # Assign the access and edit permissions for issue, file and message
3350 # to regular users now
3351 for cl in 'issue', 'file', 'msg':
3352 p = db.security.getPermission('View', cl)
3353 db.security.addPermissionToRole('User', p)
3354 p = db.security.getPermission('Edit', cl)
3355 db.security.addPermissionToRole('User', p)
3356 # and give the regular users access to the web and email interface
3357 p = db.security.getPermission('Web Access')
3358 db.security.addPermissionToRole('User', p)
3359 p = db.security.getPermission('Email Access')
3360 db.security.addPermissionToRole('User', p)
3361
3362 # May users view other user information? Comment these lines out
3363 # if you don't want them to
3364 p = db.security.getPermission('View', 'user')
3365 db.security.addPermissionToRole('User', p)
3366
3367 # Assign the appropriate permissions to the anonymous user's Anonymous
3368 # Role. Choices here are:
3369 # - Allow anonymous users to register through the web
3370 p = db.security.getPermission('Web Registration')
3371 db.security.addPermissionToRole('Anonymous', p)
3372 # - Allow anonymous (new) users to register through the email gateway
3373 p = db.security.getPermission('Email Registration')
3374 db.security.addPermissionToRole('Anonymous', p)
3375 # - Allow anonymous users access to the "issue" class of data
3376 # Note: this also grants access to related information like files,
3377 # messages, statuses etc that are linked to issues
3378 #p = db.security.getPermission('View', 'issue')
3379 #db.security.addPermissionToRole('Anonymous', p)
3380 # - Allow anonymous users access to edit the "issue" class of data
3381 # Note: this also grants access to create related information like
3382 # files and messages etc that are linked to issues
3383 #p = db.security.getPermission('Edit', 'issue')
3384 #db.security.addPermissionToRole('Anonymous', p)
3385
3386 # oh, g'wan, let anonymous access the web interface too
3387 p = db.security.getPermission('Web Access')
3388 db.security.addPermissionToRole('Anonymous', p)
3389
3390 Note in the comments there the places where you might change the permissions
3391 to restrict users or grant users more access. If you've created additional
3392 classes that users should be able to edit and view, then you should add them
3393 to the "new permissions for this schema" section at the start of the security
3394 block. Then add them to the "Assign the access and edit permissions" section
3395 too, so people actually have the new Permission you've created.
3396
3397 One final change is needed that finishes off the security system's
3398 initialisation. We need to add a call to ``db.post_init()`` at the end of the
3399 dbinit open() function. Add it like this::
3400
3401 import detectors
3402 detectors.init(db)
3403
3404 # schema is set up - run any post-initialisation
3405 db.post_init()
3406 return db
3407
3408 You may verify the setup of Permissions and Roles using the new
3409 "``roundup-admin security``" command.
3410
3411
3412 0.5.0 User changes
3413 ~~~~~~~~~~~~~~~~~~
3414
3415 To support all those schema changes, you'll need to massage your user database
3416 a little too, to:
3417
3418 1. make sure there's an "anonymous" user - this user is mandatory now and is
3419 the one that unknown users are logged in as.
3420 2. make sure all users have at least one Role.
3421
3422 If you don't have the "anonymous" user, create it now with the command::
3423
3424 roundup-admin create user username=anonymous roles=Anonymous
3425
3426 making sure the capitalisation is the same as above. Once you've done that,
3427 you'll need to set the roles property on all users to a reasonable default.
3428 The admin user should get "Admin", the anonymous user "Anonymous"
3429 and all other users "User". The ``fixroles.py`` script in the tools directory
3430 will do this. Run it like so (where python is your python 2+ binary)::
3431
3432 python tools/fixroles.py -i <tracker home> fixroles
3433
3434
3435
3436 0.5.0 CGI interface changes
3437 ---------------------------
3438
3439 The CGI interface code was completely reorganised and largely rewritten. The
3440 end result is that this section of your tracker interfaces module will need
3441 changing from::
3442
3443 from roundup import cgi_client, mailgw
3444 from roundup.i18n import _
3445
3446 class Client(cgi_client.Client):
3447 ''' derives basic CGI implementation from the standard module,
3448 with any specific extensions
3449 '''
3450 pass
3451
3452 to::
3453
3454 from roundup import mailgw
3455 from roundup.cgi import client
3456
3457 class Client(client.Client):
3458 ''' derives basic CGI implementation from the standard module,
3459 with any specific extensions
3460 '''
3461 pass
3462
3463 You will also need to install the new version of roundup.cgi from the source
3464 cgi-bin directory if you're using it.
3465
3466
3467 0.5.0 HTML templating
3468 ---------------------
3469
3470 You'll want to make a backup of your current tracker html directory. You
3471 should then copy the html directory from the Roundup source "classic" template
3472 and modify it according to your local schema changes.
3473
3474 If you need help with the new templating system, please ask questions on the
3475 roundup-users mailing list (available through the roundup web page on
3476 sourceforge, https://www.roundup-tracker.org/.
3477
3478
3479 0.5.0 Detectors
3480 ---------------
3481
3482 The nosy reactor has been updated to handle the tracker not having an
3483 "assignedto" property on issues. You may want to copy it into your tracker's
3484 detectors directory. Chances are you've already fixed it though :)
3485
3486
3487 Migrating from 0.4.1 to 0.4.2
3488 =============================
3489
3490 0.4.2 Configuration
3491 -------------------
3492 The USER_INDEX definition introduced in 0.4.1 was too restrictive in its
3493 allowing replacement of 'assignedto' with the user's userid. Users must change
3494 the None value of 'assignedto' to 'CURRENT USER' (the string, in quotes) for
3495 the replacement behaviour to occur now.
3496
3497 The new configuration variables are:
3498
3499 - EMAIL_KEEP_QUOTED_TEXT
3500 - EMAIL_LEAVE_BODY_UNCHANGED
3501 - ADD_RECIPIENTS_TO_NOSY
3502
3503 See the sample configuration files in::
3504
3505 <roundup source>/roundup/templates/classic/instance_config.py
3506
3507 and::
3508
3509 <roundup source>/roundup/templates/extended/instance_config.py
3510
3511 and the `customisation documentation`_ for information on how they're used.
3512
3513
3514 0.4.2 Changes to detectors
3515 --------------------------
3516 You will need to copy the detectors from the distribution into your instance
3517 home "detectors" directory. If you used the classic schema, the detectors
3518 are in::
3519
3520 <roundup source>/roundup/templates/classic/detectors/
3521
3522 If you used the extended schema, the detectors are in::
3523
3524 <roundup source>/roundup/templates/extended/detectors/
3525
3526 The change means that schema-specific code has been removed from the
3527 mail gateway and cgi interface and made into auditors:
3528
3529 - nosyreactor.py has now got an updatenosy auditor which updates the nosy
3530 list with author, recipient and assignedto information.
3531 - statusauditor.py makes the unread or resolved -> chatting changes and
3532 presets the status of an issue to unread.
3533
3534 There's also a bug or two fixed in the nosyreactor code.
3535
3536 0.4.2 HTML templating changes
3537 -----------------------------
3538 The link() htmltemplate function now has a "showid" option for links and
3539 multilinks. When true, it only displays the linked item id as the anchor
3540 text. The link value is displayed as a tooltip using the title anchor
3541 attribute. To use in eg. the superseder field, have something like this::
3542
3543 <td>
3544 <display call="field('superseder', showid=1)">
3545 <display call="classhelp('issue', 'id,title', label='list', width=500)">
3546 <property name="superseder">
3547 <br>View: <display call="link('superseder', showid=1)">
3548 </property>
3549 </td>
3550
3551 The stylesheets have been cleaned up too. You may want to use the newer
3552 versions in::
3553
3554 <roundup source>/roundup/templates/<template>/html/default.css
3555
3556
3557
3558 Migrating from 0.4.0 to 0.4.1
3559 =============================
3560
3561 0.4.1 Files storage
3562 -------------------
3563
3564 Messages and files from newly created issues will be put into subdierectories
3565 in thousands e.g. msg123 will be put into files/msg/0/msg123, file2003
3566 will go into files/file/2/file2003. Previous messages are still found, but
3567 could be put into this structure.
3568
3569 0.4.1 Configuration
3570 -------------------
3571
3572 To allow more fine-grained access control, the variable used to check
3573 permission to auto-register users in the mail gateway is now called
3574 ANONYMOUS_REGISTER_MAIL rather than overloading ANONYMOUS_REGISTER. If the
3575 variable doesn't exist, then ANONYMOUS_REGISTER is tested as before.
3576
3577 Configuring the links in the web header is now easier too. The following
3578 variables have been added to the classic instance_config.py::
3579
3580 HEADER_INDEX_LINKS - defines the "index" links to be made available
3581 HEADER_ADD_LINKS - defines the "add" links
3582 DEFAULT_INDEX - specifies the index view for DEFAULT
3583 UNASSIGNED_INDEX - specifies the index view for UNASSIGNED
3584 USER_INDEX - specifies the index view for USER
3585
3586 See the <roundup source>/roundup/templates/classic/instance_config.py for more
3587 information - including how the variables are to be set up. Most users will
3588 just be able to copy the variables from the source to their instance home. If
3589 you've modified the header by changing the source of the interfaces.py file in
3590 the instance home, you'll need to remove that customisation and move it into
3591 the appropriate variables in instance_config.py.
3592
3593 The extended schema has similar variables added too - see the source for more
3594 info.
3595
3596 0.4.1 Alternate E-Mail Addresses
3597 --------------------------------
3598
3599 If you add the property "alternate_addresses" to your user class, your users
3600 will be able to register alternate email addresses that they may use to
3601 communicate with roundup as. All email from roundup will continue to be sent
3602 to their primary address.
3603
3604 If you have not edited the dbinit.py file in your instance home directory,
3605 you may simply copy the new dbinit.py file from the core code. If you used
3606 the classic schema, the interfaces file is in::
3607
3608 <roundup source>/roundup/templates/classic/dbinit.py
3609
3610 If you used the extended schema, the file is in::
3611
3612 <roundup source>/roundup/templates/extended/dbinit.py
3613
3614 If you have modified your dbinit.py file, you need to edit the dbinit.py
3615 file in your instance home directory. Find the lines which define the user
3616 class::
3617
3618 user = Class(db, "msg",
3619 username=String(), password=Password(),
3620 address=String(), realname=String(),
3621 phone=String(), organisation=String(),
3622 alternate_addresses=String())
3623
3624 You will also want to add the property to the user's details page. The
3625 template for this is the "user.item" file in your instance home "html"
3626 directory. Similar to above, you may copy the file from the roundup source if
3627 you haven't modified it. Otherwise, add the following to the template::
3628
3629 <display call="multiline('alternate_addresses')">
3630
3631 with appropriate labelling etc. See the standard template for an idea.
3632
3633
3634
3635 Migrating from 0.3.x to 0.4.0
3636 =============================
3637
3638 0.4.0 Message-ID and In-Reply-To addition
3639 -----------------------------------------
3640 0.4.0 adds the tracking of messages by message-id and allows threading
3641 using in-reply-to. Most e-mail clients support threading using this
3642 feature, and we hope to add support for it to the web gateway. If you
3643 have not edited the dbinit.py file in your instance home directory, you may
3644 simply copy the new dbinit.py file from the core code. If you used the
3645 classic schema, the interfaces file is in::
3646
3647 <roundup source>/roundup/templates/classic/dbinit.py
3648
3649 If you used the extended schema, the file is in::
3650
3651 <roundup source>/roundup/templates/extended/dbinit.py
3652
3653 If you have modified your dbinit.py file, you need to edit the dbinit.py
3654 file in your instance home directory. Find the lines which define the msg
3655 class::
3656
3657 msg = FileClass(db, "msg",
3658 author=Link("user"), recipients=Multilink("user"),
3659 date=Date(), summary=String(),
3660 files=Multilink("file"))
3661
3662 and add the messageid and inreplyto properties like so::
3663
3664 msg = FileClass(db, "msg",
3665 author=Link("user"), recipients=Multilink("user"),
3666 date=Date(), summary=String(),
3667 files=Multilink("file"),
3668 messageid=String(), inreplyto=String())
3669
3670 Also, configuration is being cleaned up. This means that your dbinit.py will
3671 also need to be changed in the open function. If you haven't changed your
3672 dbinit.py, the above copy will be enough. If you have, you'll need to change
3673 the line (round line 50)::
3674
3675 db = Database(instance_config.DATABASE, name)
3676
3677 to::
3678
3679 db = Database(instance_config, name)
3680
3681
3682 0.4.0 Configuration
3683 --------------------
3684 ``TRACKER_NAME`` and ``EMAIL_SIGNATURE_POSITION`` have been added to the
3685 instance_config.py. The simplest solution is to copy the default values
3686 from template in the core source.
3687
3688 The mail gateway now checks ``ANONYMOUS_REGISTER`` to see if unknown users
3689 are to be automatically registered with the tracker. If it is set to "deny"
3690 then unknown users will not have access. If it is set to "allow" they will be
3691 automatically registered with the tracker.
3692
3693
3694 0.4.0 CGI script roundup.cgi
3695 ----------------------------
3696 The CGI script has been updated with some features and a bugfix, so you should
3697 copy it from the roundup cgi-bin source directory again. Make sure you update
3698 the ROUNDUP_INSTANCE_HOMES after the copy.
3699
3700
3701 0.4.0 Nosy reactor
3702 ------------------
3703 The nosy reactor has also changed - copy the nosyreactor.py file from the core
3704 source::
3705
3706 <roundup source>/roundup/templates/<template>/detectors/nosyreactor.py
3707
3708 to your instance home "detectors" directory.
3709
3710
3711 0.4.0 HTML templating
3712 ---------------------
3713 The field() function was incorrectly implemented - links and multilinks now
3714 display as text fields when rendered using field(). To display a menu (drop-
3715 down or select box) you need to use the menu() function.
3716
3717
3718
3719 Migrating from 0.2.x to 0.3.x
3720 =============================
3721
3722 0.3.x Cookie Authentication changes
3723 -----------------------------------
3724 0.3.0 introduces cookie authentication - you will need to copy the
3725 interfaces.py file from the roundup source to your instance home to enable
3726 authentication. If you used the classic schema, the interfaces file is in::
3727
3728 <roundup source>/roundup/templates/classic/interfaces.py
3729
3730 If you used the extended schema, the file is in::
3731
3732 <roundup source>/roundup/templates/extended/interfaces.py
3733
3734 If you have modified your interfaces.Client class, you will need to take
3735 note of the login/logout functionality provided in roundup.cgi_client.Client
3736 (classic schema) or roundup.cgi_client.ExtendedClient (extended schema) and
3737 modify your instance code apropriately.
3738
3739
3740 0.3.x Password encoding
3741 -----------------------
3742 This release also introduces encoding of passwords in the database. If you
3743 have not edited the dbinit.py file in your instance home directory, you may
3744 simply copy the new dbinit.py file from the core code. If you used the
3745 classic schema, the interfaces file is in::
3746
3747 <roundup source>/roundup/templates/classic/dbinit.py
3748
3749 If you used the extended schema, the file is in::
3750
3751 <roundup source>/roundup/templates/extended/dbinit.py
3752
3753
3754 If you have modified your dbinit.py file, you may use encoded passwords:
3755
3756 1. Edit the dbinit.py file in your instance home directory
3757 a. At the first code line of the open() function::
3758
3759 from roundup.hyperdb import String, Date, Link, Multilink
3760
3761 alter to include Password, as so::
3762
3763 from roundup.hyperdb import String, Password, Date, Link, Multilink
3764
3765 b. Where the password property is defined (around line 66)::
3766
3767 user = Class(db, "user",
3768 username=String(), password=String(),
3769 address=String(), realname=String(),
3770 phone=String(), organisation=String())
3771 user.setkey("username")
3772
3773 alter the "password=String()" to "password=Password()"::
3774
3775 user = Class(db, "user",
3776 username=String(), password=Password(),
3777 address=String(), realname=String(),
3778 phone=String(), organisation=String())
3779 user.setkey("username")
3780
3781 2. Any existing passwords in the database will remain cleartext until they
3782 are edited. It is recommended that at a minimum the admin password be
3783 changed immediately::
3784
3785 roundup-admin -i <instance home> set user1 password=<new password>
3786
3787
3788 0.3.x Configuration
3789 -------------------
3790 FILTER_POSITION, ANONYMOUS_ACCESS, ANONYMOUS_REGISTER have been added to
3791 the instance_config.py. Simplest solution is to copy the default values from
3792 template in the core source.
3793
3794 MESSAGES_TO_AUTHOR has been added to the IssueClass in dbinit.py. Set to 'yes'
3795 to send nosy messages to the author. Default behaviour is to not send nosy
3796 messages to the author. You will need to add MESSAGES_TO_AUTHOR to your
3797 dbinit.py in your instance home.
3798
3799
3800 0.3.x CGI script roundup.cgi
3801 ----------------------------
3802 There have been some structural changes to the roundup.cgi script - you will
3803 need to install it again from the cgi-bin directory of the source
3804 distribution. Make sure you update the ROUNDUP_INSTANCE_HOMES after the
3805 copy.
3806
3807
3808 .. _`customisation documentation`: customizing.html 1972 .. _`customisation documentation`: customizing.html
3809 .. _`security documentation`: security-history.html 1973 .. _`security documentation`: security-history.html
3810 .. _`administration guide`: admin_guide.html 1974 .. _`administration guide`: admin_guide.html
3811 .. _`xmlrpc guide`: xmlrpc.html 1975 .. _`xmlrpc guide`: xmlrpc.html
3812 .. _FTS5 full-text search engine: https://www.sqlite.org/fts5.html 1976 .. _FTS5 full-text search engine: https://www.sqlite.org/fts5.html
3813 .. _PostgreSQL's full text search: https://www.postgresql.org/docs/current/textsearch.html 1977 .. _PostgreSQL's full text search: https://www.postgresql.org/docs/current/textsearch.html
3814 .. _`administration guide notes on native-fts`: admin_guide.html#configuring-native-fts-full-text-search 1978 .. _`administration guide notes on native-fts`: admin_guide.html#configuring-native-fts-full-text-search
3815 .. _Configuring Compression: admin_guide.html#configuring-compression 1979 .. _Configuring Compression: admin_guide.html#configuring-compression
3816 .. _Software Upgrade: admin_guide.html#software-upgrade 1980 .. _Software Upgrade: admin_guide.html#software-upgrade
1981 .. _new search permissions for query in 1.4.17:
1982 upgrading-history.html#new-search-permissions-for-query-in-1-4-17

Roundup Issue Tracker: http://roundup-tracker.org/