Mercurial > p > roundup > code
changeset 8544:e738377b4ffe
feature: add detector that prevents file content changes by Admin and other users.
New detector and upgrading announcement. Also example of stripping
content editing from the User role.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Tue, 24 Mar 2026 22:11:27 -0400 |
| parents | 1ffa1f42e1da |
| children | 695399dea532 |
| files | CHANGES.txt detectors/README.txt detectors/immutable_file_contents.py doc/upgrading.txt |
| diffstat | 4 files changed, 73 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/CHANGES.txt Tue Mar 24 21:30:47 2026 -0400 +++ b/CHANGES.txt Tue Mar 24 22:11:27 2026 -0400 @@ -96,7 +96,15 @@ plain text. Faster then beautifulsoup4 and it passes the html 5 standard browser test suite. Beautifulsoup is still supported. (John Rouillard) - +- add a new detector: immutable_file_contents.py that prevents changes + to file contents. By default, the permissions assigned to FileClass + based classes (files, msgs) do not prevent editing of file contents. + While the usual HTML templates don't provide a way to modify files, + the REST interface allows changing file contents without an audit + trail. Manually driving the HTML interface (via curl for example) + also allows content changes. The new detector prevents changes to + file contents via Roundup even by a user with admin rights. + 2025-07-13 2.5.0 Fixed:
--- a/detectors/README.txt Tue Mar 24 21:30:47 2026 -0400 +++ b/detectors/README.txt Tue Mar 24 22:11:27 2026 -0400 @@ -19,6 +19,10 @@ emailauditor.py - Rename .eml files (from email multi-part bodies) to .mht so they can be downloaded/viewed in Internet Explorer. +immutable_file_contents.py - prevent changes to the contents property + of file and msg classes including by + people with the admin role. + irker.py - communicate with irkerd to allow roundtup to send announcements to an IRC channel.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/detectors/immutable_file_contents.py Tue Mar 24 22:11:27 2026 -0400 @@ -0,0 +1,22 @@ +# HTML pages don't provide a way to change the contents of a file. +# However REST does allow setting content and the HTML interface can +# be directed to update the content as well. This detector +# prevents changes to file content. + +from roundup.exceptions import UsageError + +def immutable_file_contents(db, cl, nodeid, newvalues): + ''' Prevent content changes to a file + ''' + if 'content' in newvalues: + raise UsageError("File contents are immutable. " + "Rejecting change to contents.") + + +def init(db): + """If you have other FileClass based classes add them here.""" + + # fire before changes are made + db.file.audit('set', immutable_file_contents) + db.msg.audit('set', immutable_file_contents) +
--- a/doc/upgrading.txt Tue Mar 24 21:30:47 2026 -0400 +++ b/doc/upgrading.txt Tue Mar 24 22:11:27 2026 -0400 @@ -303,6 +303,44 @@ There have been some internal refactorings and improvements in the REST code that will make it a bit faster. +Make File Contents Immutable for Everybody (optional) +----------------------------------------------------- + +The HTML based interface for files and messages doesn't provide a way +to change file content. However it is possible for privileged people +to modify the content via the web. In most cases, this change will not +be recorded in the audit log. It can be detected by looking at the +change time of the file. Then compare it to the change time of files +before and after it. Since files are created in order, the file +``msg50`` should have a change timestamp after ``msg49`` and before +``msg51``. + +The 2.6.0 release includes an immutable_file_contents.py +detector. If you copy the detector into your tracker's detector +directory nobody, including users with admin rights, can change +file/msg contents via Roundup. Changes to files would have to be +done by logging into the Roundup server and editing the files +locally. + +For non-admin user's the following edit permission for FileClass based +classes will prevent regular users from changing file content via +Roundup. Remove the existing ``Edit`` permission from your FileClass +based classes. Then add your classname to the loop. The permission +strips ``content`` from the list of editable properties and permits +editing of the other properties:: + + for cl in 'file', 'msg': + properties = list(x for x in + db.getclass(cl).getprops(protected=False).keys() + if x != 'content') + + file_edit_perm = db.security.addPermission( + name='Edit', klass=cl, + properties=properties, + description="User is allowed to edit all %s props except content" % cl) + + db.security.addPermissionToRole('User', file_edit_perm) + .. index:: Upgrading; 2.4.0 to 2.5.0 Migrating from 2.4.0 to 2.5.0
