# HG changeset patch # User Paul Boddie # Date 1383688585 -3600 # Node ID 623d4bb10f1188f4422bc90d4a4decbf574185db # Parent acba83570c3d3aad0b0d69e4b6d617229a9f195d Removed the ApprovalQueueUser, making use of a special security policy instead. diff -r acba83570c3d -r 623d4bb10f11 ApproveChangesSupport.py --- a/ApproveChangesSupport.py Tue Nov 05 22:18:45 2013 +0100 +++ b/ApproveChangesSupport.py Tue Nov 05 22:56:25 2013 +0100 @@ -2,10 +2,6 @@ """ MoinMoin - ApproveChanges library - This library relies on the existence of a user (by default - "ApprovalQueueUser") who has sufficient privileges to write pages with ACLs - to an approval queue (ACL permissions "write,admin"). - If users other than the superuser are to be able to edit pages freely, they must be present in a group (by default "ApprovedGroup"), and if they are to be allowed to review changes, they must be present in a different group (by @@ -46,9 +42,6 @@ def get_page_reviewers_group(request): return getattr(request.cfg, "reviewers_group", "PageReviewersGroup") -def get_queued_changes_user(request): - return getattr(request.cfg, "queued_changes_user", "ApprovalQueueUser") - def is_reviewer(request): return request.user.valid and ( has_member(request, get_page_reviewers_group(request), request.user.name) or \ @@ -62,9 +55,6 @@ def user_is_approved(request, username): return has_member(request, get_approved_editors_group(request), username) -def is_queued_changes_user(request): - return request.user.valid and request.user.name == get_queued_changes_user(request) - def is_queued_changes_page(request, pagename): "Return whether 'pagename' is a queued changes page by testing its name." @@ -81,16 +71,6 @@ extra_parts = directives.has_key(directive) and 2 or 1 return "/".join(page.page_name.split("/")[:-extra_parts]) -def get_user_for_saving(request): - - "Return a user that can save pages with ACLs." - - username = get_queued_changes_user(request) - - # If the user does not exist, just return the existing user. - - return get_user(request, username) or request.user - def get_user(request, username): "Return the user having the given 'username'." diff -r acba83570c3d -r 623d4bb10f11 README.txt --- a/README.txt Tue Nov 05 22:18:45 2013 +0100 +++ b/README.txt Tue Nov 05 22:56:25 2013 +0100 @@ -16,23 +16,6 @@ See pages/HelpOnApproveChanges for the documentation for this software and how to use it. -Pre-Installation Tasks ----------------------- - -Before installing the software, create a new user who will be responsible for -queuing untrusted changes. This user will be used by the software internally, -and it should never be necessary to log in manually as this user to perform -tasks. - -Adding a new user can be done using the moin program as follows: - - moin --config-dir=path-to-wikiconfig account create \ - --name=ApprovalQueueUser --email=... --password=... - -The ... values should be substituted with acceptable values. Beware that -MoinMoin insists on distinct e-mail addresses. Beware also that providing a -password on the command line can be a risk on multi-user systems. - Installation ------------ @@ -107,21 +90,8 @@ Once the event handler has been installed, all page saving operations will be affected by its operation. With no further configuration, it is most likely -that only superusers will be able to save changes to wiki pages, and even the -queuing of changes will not function properly. - -Thus, it becomes necessary to change the wiki configuration to enable the -successful queuing of changes by changing the acl_rights_before configuration -setting, adding the following rule: - - ApprovalQueueUser:write,admin - -This will let the special internal wiki user responsible for queuing changes -(see "Pre-Installation Tasks") save and define an ACL on a page saved by an -untrusted user. See the following page for more information on access control -lists (ACLs): - - http://moinmo.in/HelpOnAccessControlLists +that only superusers will be able to save changes to wiki pages, and the edits +of all other users will be queued. The configuration settings used by ApproveChanges are as follows: @@ -158,24 +128,6 @@ This gives the name of the group page holding the names of reviewers. By default, it is set to PageReviewersGroup. See "Resource Pages" above. - queued_changes_user - ------------------- - - This gives the name of the user who saves unapproved changes to approval - queues. By default, it is set to ApprovalQueueUser. - -Troubleshooting ---------------- - -When a user tries to save a page, they get the following error (or -equivalent): - - You can't change ACLs on this page since you have no admin rights on it! - -This is possibly caused by the absence of the ApprovalQueueUser (see -"Pre-Installation Tasks" above) and/or the acl_rights_before rule for that -user (see "Configuration" above). - Recommended Software -------------------- @@ -204,6 +156,9 @@ -------------------------------------------------------------- * Added user-specific approval queues. + * Removed the special ApprovalQueueUser. This user can be removed from + existing installations since the software no longer needs it to perform + the queuing of unapproved contributions. New in ApproveChanges 0.1.1 (Changes since ApproveChanges 0.1) -------------------------------------------------------------- diff -r acba83570c3d -r 623d4bb10f11 events/queue_for_review.py --- a/events/queue_for_review.py Tue Nov 05 22:18:45 2013 +0100 +++ b/events/queue_for_review.py Tue Nov 05 22:56:25 2013 +0100 @@ -11,8 +11,22 @@ from MoinMoin.PageEditor import PageEditor from MoinMoin.events import PagePreSaveEvent, Abort +from MoinMoin.security import Permissions from ApproveChangesSupport import * +class SpecialPermissions(Permissions): + + "Permit saving of ACL-enabled comment pages." + + def __init__(self, user, pagename): + Permissions.__init__(self, user) + self.pagename = pagename + + def admin(self, pagename): + return pagename == self.pagename + + write = admin + def handle_presave(event): request = event.request _ = request.getText @@ -31,7 +45,7 @@ # Test the integrity of the page in order to prevent direct replacement # of the page. Reviewers can change the page as they please. - if is_reviewer(request) or is_queued_changes_user(request): + if is_reviewer(request) or isinstance(request.user.may, SpecialPermissions): return None else: return Abort(_("Queued changes may not be edited.")) @@ -44,7 +58,8 @@ # Save the page in the queue. - new_page = PageEditor(request, "%s/%s%s" % (pagename, user_specific_queue, queued_changes_page)) + queued_pagename = "%s/%s%s" % (pagename, user_specific_queue, queued_changes_page) + new_page = PageEditor(request, queued_pagename) # Add an ACL to prevent normal users from seeing the page anywhere. # Add a parent revision to the page. @@ -62,14 +77,20 @@ comment = (username or _("anonymous")) + " : " + _("Queued page edit") try: - # Switch user in order to save a page with an ACL. + # To add a page with an ACL, a special policy is required. - user = request.user - request.user = get_user_for_saving(request) + may = request.user.may + request.user.may = SpecialPermissions(request.user, queued_pagename) + + # Save the page with the ACL. + try: new_page.saveText(body, 0, comment=comment) + + # Restore the original policy. + finally: - request.user = user + request.user.may = may except PageEditor.Unchanged: pass