123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- #!/usr/bin/env perl
- use strict;
- use v5.10;
- # ====================[ autolock.pl ]====================
- =head1 NAME
- autolock - An Oddmuse module for locking pages via regular expression matching
- on page names.
- =head1 SYNOPSIS
- autolock automatically locks pages whose page name matches some regular
- expression from edits, creation, and deletion by non-privileged visitors (but
- not by password-verified editors or administrators).
- autolock thus "augments" the built-in, manual method for locking existing pages
- against page edits and page deletions, by providing an automated alternative;
- and provides a new method - which has no built-in, manual analogue - for locking
- against page creations.
- =head1 INSTALLATION
- autolock is easily installable: move this file into the B<wiki/modules/>
- directory of your Oddmuse Wiki.
- =cut
- AddModuleDescription('autolock.pl', 'Autolock Extension');
- our (@MyInitVariables, $CommentsPrefix, $EditAllowed, $NoEditFile, %LockOnCreation);
- # ....................{ CONFIGURATION }....................
- =head1 CONFIGURATION
- autolock is easily configurable: set these variables in the B<wiki/config.pl>
- file for your Oddmuse Wiki.
- =cut
- our ($AutoLockPagesMatching,
- $AutoLockCommentsPagesMatching,
- $AutoLockSeverity,
- $AutoLockUserCanEditEditorFix);
- =head2 $AutoLockPagesMatching
- A regular expression matching page names to be automatically locked against
- page edits, creations, and deletions; e.g., this regular expression prevents
- page edits, creations, and deletions for page names resembling
- "Red Apple Falls--1997-02-16":
- $AutoLockPagesMatching = '^Red_Apple_Falls--\d\d\d\d-\d\d-\d\d';
- This regular expression is left undefined, by default. (Thus, this module does
- nothing, by default.) When redefined, this regular expression:
- =over
- =item ...should not be a quoted regular expression (i.e., "qr/.../"); and
- =item ...should not be prefixed with the contents of the C<$CommentsPrefix>
- regular expression. (This module does that for you, as need be.)
- =back
- That aside, the limitless sky is yours.
- =cut
- $AutoLockPagesMatching = undef;
- =head2 $AutoLockSeverity
- A quadstate boolean specifying "how much" automatic locking to apply to pages
- whose names match the regular expression, above. This boolean, being
- "quadstate," may take any of four values, mirroring the C<$EditAllowed> site-
- wide setting as follows (where "visitors" are users who are neither password-
- verified administrators or password-verified editors):
- =over
- =item 0. B<Highest severity.> Do not allow visitors to edit, create, or delete any
- autolock-matched pages or page comments.
- =item 1. B<No severity.> Permissively allow visitors to edit, create, or delete any
- autolock-matched pages or page comments, so long as the C<UserCanEdit>
- function also allows that. (This disables autolock, effectively.)
- =item 2. B<Low severity.> Do not allow visitors to edit, create, or delete any
- autolock-matched pages but do allow visitors to edit, create, or delete
- autolock-matched page comments. (This is the default.)
- =item 3. B<Medium severity.> Do not allow visitors to edit, create, or delete any
- autolock-matched pages or edit or delete autolock-matched page comments,
- but do allow visitors to create new page comments.
- =back
- =cut
- $AutoLockSeverity = 2;
- =head2 $AutoLockUserCanEditEditorFix
- A boolean that, if true, prompts this module to overwrite the C<UserCanEdit>
- Oddmuse function with a "fix" to Oddmuse's page-locking logic. By default, the
- Oddmuse script (v1.865, as of this writing) allows administrators but not
- editors to edit locked pages; however, this contravenes explicit Oddmuse
- documentation to the contrary.
- "If you have the admin or the edit password, you may edit locked pages."
- http://www.oddmuse.org/cgi-bin/oddmuse/Page_Locking
- This minor "fix" amends that, by allowing both administrators and editors to
- edit locked pages.
- By default, this boolean is true; and therefore implements this fix.
- =cut
- $AutoLockUserCanEditEditorFix = 1;
- # ....................{ INITIALIZATION }....................
- push(@MyInitVariables, \&AutoLockInit);
- sub AutoLockInit {
- # Set "$AutoLockCommentsPagesMatching", if not already set (and relevant).
- if ( defined($AutoLockPagesMatching) &&
- !defined($AutoLockCommentsPagesMatching) && $CommentsPrefix) {
- if ($AutoLockPagesMatching =~ m/^\^/) {
- $AutoLockCommentsPagesMatching = $AutoLockPagesMatching;
- $AutoLockCommentsPagesMatching =~ s/^\^/^${CommentsPrefix}/;
- }
- else {
- $AutoLockCommentsPagesMatching =
- "^${CommentsPrefix}.*${AutoLockPagesMatching}";
- }
- }
- if ($AutoLockUserCanEditEditorFix) {
- *UserCanEditAutoLockOld = \&UserCanEditAutoLockFix;
- }
- }
- # ....................{ REDEFINITIONS }....................
- *UserCanEditAutoLockOld = \&UserCanEdit;
- *UserCanEdit = \&UserCanEditAutoLock;
- sub UserCanEditAutoLock {
- my ($page_name, $is_editing, $is_comment) = @_;
- my $user_can_edit = UserCanEditAutoLockOld(@_);
- if ($user_can_edit && $AutoLockSeverity != 1 && !(UserIsAdmin() || UserIsEditor())) {
- my $is_page_locked = defined($AutoLockPagesMatching) &&
- $page_name =~ m/$AutoLockPagesMatching/;
- my $is_comments_page_locked = defined($AutoLockCommentsPagesMatching) &&
- $page_name =~ m/$AutoLockCommentsPagesMatching/;
- if (
- ($AutoLockSeverity == 0 && ($is_page_locked || $is_comments_page_locked)) ||
- ($AutoLockSeverity == 2 && $is_page_locked && ! $is_comments_page_locked) ||
- ($AutoLockSeverity == 3 && $is_page_locked && !($is_comments_page_locked &&
- ($is_comment || (GetParam('aftertext', '') && !GetParam('text', '')))))) {
- return 0;
- }
- }
- return $user_can_edit;
- }
- sub UserCanEditAutoLockFix {
- my ($id, $editing, $comment) = @_;
- return 0 if $id eq 'SampleUndefinedPage' or $id eq T('SampleUndefinedPage')
- or $id eq 'Sample_Undefined_Page' or $id eq T('Sample_Undefined_Page');
- return 1 if UserIsAdmin() || UserIsEditor();
- return 0 if $id ne '' and IsFile(GetLockedPageFile($id));
- return 0 if $LockOnCreation{$id} and not IsFile(GetPageFile($id)); # new page
- return 0 if !$EditAllowed or IsFile($NoEditFile);
- return 0 if $editing and UserIsBanned(); # this call is more expensive
- return 0 if $EditAllowed >= 2 and (not $CommentsPrefix or $id !~ /^$CommentsPrefix/);
- return 1 if $EditAllowed >= 3 and ($comment or (GetParam('aftertext', '') and not GetParam('text', '')));
- return 0 if $EditAllowed >= 3;
- return 1;
- }
- =head1 MOTIVATION
- Oddmuse does provide a built-in, manual method for locking existing pages
- against page edits and page deletions: for each such page, manually browse to
- the "Administration" page and then "Lock ${PAGE_NAME}" page for that page. (This
- is, needless to say, a clumsy means of bulk-locking some series of similarly
- named pages.)
- Oddmuse does not, however, provide a built-in method for preventatively locking
- against page creations.
- Ergo, autolock.
- =head1 SEE ALSO
- Jorge Arroyo's B<lock-expression.pl> module, from which this module was
- (marginally) inspired and which this module (largely) replaces.
- =head1 COPYRIGHT AND LICENSE
- The information below applies to everything in this distribution,
- except where noted.
- Copyleft 2008 by B.w.Curry <http://www.raiazome.com>.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- =cut
|