Merge branch 'master' of git.sv.gnu.org:/srv/git/oddmuse

This commit is contained in:
Alex Schroeder
2012-11-20 15:38:51 +01:00
6 changed files with 224 additions and 6 deletions

View File

@@ -149,9 +149,6 @@ div.refer {
line-height: 13pt;
}
div.refer a:first-child:before { content: "" }
div.refer a:before { content: "• " }
div.message {
background-color:#fee;
color:#000;

View File

@@ -13,7 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/fix-encoding.pl">fix-encoding.pl</a></p>';
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/fix-encoding.pl">fix-encoding.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Fix_Encoding">Fix Encoding</a></p>';
$Action{'fix-encoding'} = \&FixEncoding;

View File

@@ -376,7 +376,7 @@ sub NewNamespaceBrowsePage {
#REDIRECT into different namespaces
my ($id, $raw, $comment, $status) = @_;
OpenPage($id);
my ($text, $revision) = GetTextRevision(GetParam('revision', ''));
my ($text, $revision) = GetTextRevision(GetParam('revision', ''), 1);
my $oldId = GetParam('oldid', '');
if (not $oldId and not $revision and (substr($text, 0, 10) eq '#REDIRECT ')
and (($WikiLinks and $text =~ /^\#REDIRECT\s+(($InterSitePattern:)?$InterLinkPattern)/)

128
modules/private-pages.pl Normal file
View File

@@ -0,0 +1,128 @@
# Copyright (C) 2012 Alex Schroeder <alex@gnu.org>
#
# 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/>.
=head1 Private Pages Extension
This module allows you to hide the content of particular pages in Oddmuse.
Unlike the I<Hidden Pages Extension>, this is not based on the user's role of
editor or administrator. Instead, every page can have a different password by
beginning it with #PASSWORD XYZZY where XYZZY is the password required to read
it. Multiple passwords can be supplied, separated by spaces.
Note that all the meta information of the private page remains public: The
I<name> of the page, the fact that is has been edited, the author, the
revision, the content of past revisions that have not been protected by a
password all remain visible to other users.
Notes:
=over
=item * This extension might not work in a mod_perl environment because it
sets C<$NewText> without ever resetting it.
=item * If you're protecting a comment page, people can still leave comments
-- they just can't read the resulting page.
=back
=cut
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/private-pages.pl">private-pages.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Private_Pages_Extension">Private Pages Extension</a></p>';
sub PrivatePageLocked {
my $text = shift;
my ($line) = split(/\n/, $text, 1);
my @token = split(/\s+/, $line);
my $lock = 0;
if (shift(@token) eq '#PASSWORD') {
my $pwd = GetParam('pwd', '');
$lock = 1;
foreach (@token) {
if ($pwd eq $_) {
$lock = 0;
break;
}
}
}
return $lock;
}
*OldPrivatePagesUserCanEdit = *UserCanEdit;
*UserCanEdit = *NewPrivatePagesUserCanEdit;
sub NewPrivatePagesUserCanEdit {
my ($id, $editing, @rest) = @_;
my $result = OldPrivatePagesUserCanEdit($id, $editing, @rest);
# bypass OpenPage and GetPageContent (these are redefined below)
if ($result > 0 and $editing and $IndexHash{$id}) {
my %data = ParseData(ReadFileOrDie(GetPageFile($id)));
if (PrivatePageLocked($data{text})) {
return 0;
}
}
return $result;
}
sub PrivatePageMessage {
return Ts('This page is password protected. If you know the password, you can %s. Once you have done that, return and reload this page.',
'[' . ScriptUrl('action=password') . ' '
. T('supply the password now') . ']');
}
*OldPrivatePagesOpenPage = *OpenPage;
*OpenPage = *NewPrivatePagesOpenPage;
sub NewPrivatePagesOpenPage {
OldPrivatePagesOpenPage(@_);
if (PrivatePageLocked($Page{text})) {
%Page = (); # reset everything
$NewText = PrivatePageMessage();
}
return $OpenPageName;
}
*OldPrivatePagesGetPageContent = *GetPageContent;
*GetPageContent = *NewPrivatePagesGetPageContent;
sub NewPrivatePagesGetPageContent {
my $text = OldPrivatePagesGetPageContent(@_);
if (PrivatePageLocked($text)) {
return PrivatePageMessage();
}
return $text;
}
push(@MyRules, \&PrivatePageRule);
sub PrivatePageRule {
if (pos == 0 && m/\G#PASSWORD.*\n/gc) {
return '';
}
return undef;
}
*OldPrivatePagesGetSummary = *GetSummary;
*GetSummary = *NewPrivatePagesGetSummary;
sub NewPrivatePagesGetSummary {
my $text = GetParam('text', '');
if ($text and $text =~ /^#PASSWORD\b/
# no text means aftertext is set (leaving a comment)
or $Page{text} =~ /^#PASSWORD\b/) {
# if no summary was set, set something in order to avoid the default
return '';
}
return OldPrivatePagesGetSummary();
}

93
t/private-pages.t Normal file
View File

@@ -0,0 +1,93 @@
# Copyright (C) 2012 Alex Schroeder <alex@gnu.org>
#
# 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/>.
require 't/test.pl';
package OddMuse;
use Test::More tests => 27;
clear_pages();
add_module('private-pages.pl');
# create password protected page: can't read it without password!
test_page(update_page('Privat', "#PASSWORD foo\nSo many secrets remain untold.\n"),
'This page is password protected');
# can't update password protected page
update_page('Privat', "#PASSWORD foo\nCats have secrets.\n");
test_page($redirect, 'Status: 403');
# use password foo to update protected page: can't read it without password!
test_page_negative(update_page('Privat', "#PASSWORD foo\nCats have secrets.\n", undef, undef, 1),
'Cats have secrets');
test_page($redirect, 'Status: 302');
# read it with password
my $page = get_page('action=browse id=Privat pwd=foo');
test_page_negative($page, 'This page is password protected');
test_page($page, 'Cats have secrets');
# a keep file was created as well
ok(-f GetKeepFile('Privat', 1), 'Keep file exists');
# can't read old revisions without a password
test_page_negative(get_page('action=browse id=Privat revision=1'),
'Cats have secrets');
# read old revisions with password
test_page(get_page('action=browse id=Privat revision=1 pwd=foo'),
'So many secrets remain untold');
# can't see secrets when printing raw pages
my $page = get_page('action=browse raw=1 id=Privat pwd=foo');
test_page_negative($page, 'This page is password protected');
test_page($page, 'Cats have secrets');
# can't see summaries with secrets
my $page = get_page('action=rc raw=1 all=1');
test_page($page, 'Privat');
test_page_negative($page, 'secret');
# can't search for secrets without a password
my $page = get_page('search=cats');
test_page($page, '0 pages found');
test_page_negative($page, "Privat");
# search finds secrets with password
my $page = get_page('search=cats pwd=foo');
test_page($page, '1 pages? found',
'Privat', '<strong>Cats</strong> have secrets');
# can't edit a private page without a password
my $page = get_page('action=edit id=Privat');
test_page($page, 'Editing not allowed');
test_page_negative($page, 'Cats have secrets');
# can edit a private page with a password
my $page = get_page('action=edit id=Privat pwd=foo');
test_page_negative($page, 'This page is password protected');
test_page($page, 'Cats have secrets');
# can't edit an old revision of a private page without a password
my $page = get_page('action=edit id=Privat revision=1');
test_page($page, 'Editing not allowed');
test_page_negative($page, 'secret');
# can't just post changes to a private page without a password
my $page = get_page('title=Privat text=YaddaYadda revision=1');
test_page($page, 'Editing not allowed');
test_page_negative($page, 'secret');
# can't include them
test_page_negative(update_page('Publik', '<include "Privat">'),
'Cats have secrets');

View File

@@ -2495,7 +2495,7 @@ sub PrintHtmlDiff {
if ($type == 1) {
$old = $Page{lastmajor} - 1;
($text, $new) = GetTextRevision($Page{lastmajor}, 1)
unless $new or $Page{lastmajor} == $Page{revision};
unless $new or $Page{lastmajor} == $Page{revision};
} elsif ($new) {
$old = $new - 1;
} else {