Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Item14342: Implement Additive ALLOWTOPIC ACLs
  • Loading branch information
gac410 committed Mar 14, 2017
1 parent 91ce45d commit a4402d4
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 4 deletions.
92 changes: 92 additions & 0 deletions UnitTestContrib/test/unit/AccessControlTests.pm
Expand Up @@ -68,6 +68,13 @@ THIS
return;
}

sub loadExtraConfig {
my $this = shift;
$this->SUPER::loadExtraConfig();

$Foswiki::cfg{AccessControlACL}{EnableAdditiveRules} = 1;
}

sub DENIED {
my ( $this, $mode, $user, $web, $topic ) = @_;
$web ||= $this->{test_web};
Expand Down Expand Up @@ -594,6 +601,91 @@ THIS
return;
}

# Ensure additive topic ACL overrides web allow
sub test_allow_web_additive_topic {
my $this = shift;
my ($topicObject) =
Foswiki::Func::readTopic( $this->{test_web},
$Foswiki::cfg{WebPrefsTopicName} );
$topicObject->text(
<<'THIS'
If ALLOWWEB is set to a list of wikinames
* people in the list will be PERMITTED
* everyone else will be DENIED
* Set ALLOWWEBVIEW = MrGreen
THIS
);
$topicObject->save();
$topicObject->finish();

# renew Foswiki, so WebPreferences gets re-read
$this->createNewFoswikiSession();

($topicObject) =
Foswiki::Func::readTopic( $this->{test_web}, $this->{test_topic} );
$topicObject->text(
<<'THIS'
If ALLOWTOPIC is set
1. people in the list are PERMITTED
2. everyone else is DENIED
* Set ALLOWTOPICVIEW = +MrWhite, %USERSWEB%.MrBlue
THIS
);
$topicObject->save();
$topicObject->finish();

$this->DENIED( "VIEW", $MrOrange );
$this->PERMITTED( "VIEW", $MrWhite );
$this->PERMITTED( "VIEW", $MrGreen );
$this->DENIED( "VIEW", $MrYellow );
$this->PERMITTED( "view", $MrBlue );

return;
}

# Ensure additive topic ACL overrides web deny & allow
sub test_deny_web_additive_topic {
my $this = shift;
my ($topicObject) =
Foswiki::Func::readTopic( $this->{test_web},
$Foswiki::cfg{WebPrefsTopicName} );
$topicObject->text(
<<'THIS'
If ALLOWWEB is set to a list of wikinames
* people in the list will be PERMITTED
* everyone else will be DENIED
* Set DENYWEBVIEW = MrGreen
* Set ALLOWWEBVIEW = MrOrange
THIS
);
$topicObject->save();
$topicObject->finish();

# renew Foswiki, so WebPreferences gets re-read
$this->createNewFoswikiSession();

($topicObject) =
Foswiki::Func::readTopic( $this->{test_web}, $this->{test_topic} );
$topicObject->text(
<<'THIS'
If ALLOWTOPIC is set
1. people in the list are PERMITTED
2. everyone else is DENIED
* Set ALLOWTOPICVIEW = +MrWhite, %USERSWEB%.MrGreen
THIS
);
$topicObject->save();
$topicObject->finish();

$this->PERMITTED( "VIEW", $MrOrange );
$this->PERMITTED( "VIEW", $MrWhite );
$this->PERMITTED( "VIEW", $MrGreen );
$this->DENIED( "VIEW", $MrYellow );
$this->DENIED( "view", $MrBlue );

return;
}

# Test that Web.UserName is equivalent to UserName in ACLs
sub test_webDotUserName {
my $this = shift;
Expand Down
21 changes: 20 additions & 1 deletion core/data/System/AccessControl.txt
@@ -1,4 +1,4 @@
%META:TOPICINFO{author="ProjectContributor" date="1489206078" format="1.1" version="1"}%
%META:TOPICINFO{author="ProjectContributor" date="1489521912" format="1.1" version="1"}%
%META:TOPICPARENT{name="UserDocumentationCategory"}%
%STARTINCLUDE%
---+ Access Control
Expand Down Expand Up @@ -213,6 +213,25 @@ For example if you want completely open access to a topic __for logged in users_

See "How Foswiki evaluates ALLOW/DENY settings" below for more on how ALLOW and DENY interacts.

---++++ Additive ALLOWTOPIC rules

An optional EXPERT level configuration parameter is avalable to enable Additive ALLOWTOPIC ACLs. As described above, ALLOWTOPIC* rules will
override the corresponding ALLOWWEB* settings. If {AccessControlACL}{EnableAdditiveRules} is enabled, then ALLOWTOPIC settings can be defined
as additive by beginning the setting with the plus symbol (+).

%IF{"{AccessControlACL}{EnableAdditiveRules}" then=""
else="<div class='foswikiHelp'>Additive Access Control Rules are *not* enabled on this system.</div>"
}%

* #Set ALLOWWEBVIEW = !SomeUser
* #Set ALLOWTOPICVIEW = + !AnotherUser !AThirdUser

With the setting enabled, the TOPIC level settings _add_ to the Web level settings resulting in the equivalent:
* #Set ALLOWTOPICVIEW = !SomeUser !AnotherUser !AThirdUser

Note that Additive ACLS only apply to ALLOWTOPIC* settings.


---+++ Controlling access to attachments

Attachments are referred to directly, and are not normally indirected via Foswiki scripts. This means that the above instructions for access control will _not_ apply to attachments. It is possible that someone may inadvertently publicise a URL that they expected to be access-controlled.
Expand Down
4 changes: 2 additions & 2 deletions core/data/TestCases/WebStatistics.txt
@@ -1,12 +1,12 @@
%META:TOPICINFO{author="ProjectContributor" date="1229198928" format="1.1" version="1"}%
%META:TOPICINFO{author="ProjectContributor" comment="" date="1489521912" format="1.1" version="1"}%
%META:TOPICPARENT{name="WebHome"}%
---++ Statistics for <nop>%WEB% Web

| *Month:* | *Topic <br /> views:* | *Topic <br /> saves:* | *File <br /> uploads:* | *Most popular <br /> topic views:* | *Top contributors for <br /> topic save and uploads:* |
| <!--statDate--> | <!--statViews--> | <!--statSaves--> | <!--statUploads--> | <!--statTopViews--> | <!--statTopContributors--> |
| Mar 2017 | 24 | 0 | 0 | &nbsp;&nbsp;1 [[TestCaseAutoRegionTags]]<br />&nbsp;&nbsp;1 [[TestCaseAutoTOC]]<br />&nbsp;&nbsp;1 [[TestCaseAutoIncludes]]<br />&nbsp;&nbsp;1 [[TestCaseAutoCategoryTable1]]<br />&nbsp;&nbsp;1 [[TestCaseAutoTableInclude]]<br />&nbsp;&nbsp;1 [[TestCaseAutoInOutPre]]<br />&nbsp;&nbsp;1 [[TestCaseAutoInterwikiPlugin]]<br />&nbsp;&nbsp;1 [[TestCaseAutoIncludeAttachment]]<br />&nbsp;&nbsp;1 [[TestCaseAutoUnexpandedTagsInSearchResults]]<br />&nbsp;&nbsp;1 [[TestCaseAutoSearch]]<br />&nbsp;&nbsp;1 [[TestCaseAutoSearchOrder]] | |

*Notes:*
* Do not edit this topic, it is updated automatically. (You can also [[%SCRIPTURL{"statistics"}%/%WEB%][force]] an update)
* [[%SYSTEMWEB%.SiteTools#WebStatistics_site_statistics][SiteTools]] tells you how to enable the automatic updates of the statistics.
* Suggestion: You could archive this topic once a year and delete the previous year's statistics from the table.

11 changes: 11 additions & 0 deletions core/lib/Foswiki.spec
Expand Up @@ -576,6 +576,16 @@ $Foswiki::cfg{TopicUserMapping}{ForceManageEmails} = $FALSE;
# for access permission, then it will not get blocked by these controls.
$Foswiki::cfg{AccessControl} = 'Foswiki::Access::TopicACLAccess';

# **BOOLEAN LABEL="Enable Additive Topic ACLs" EXPERT **
# Optionally support Addititive Topic ACLs. Normally ACLs specified at the
# Topic level override Web level access control. If this feature is enabled,
# the "+" plus sign can be used at the Topic level to add to the Web ACLs.
#
# If the Web ACL specifies _"ALLOWTOPICVIEW = JoeUser"_, then a Topic ACL of
# _"ALLOWTOPICVIEW = + FredUser"_ will allow both JoeUser and FredUser
# to view the topic.
$Foswiki::cfg{AccessControlACL}{EnableAdditiveRules} = $FALSE;

# **BOOLEAN LABEL="Enable Deprecated Empty Deny" EXPERT **
# Optionally restore the deprecated empty =DENY= ACL behavior.
# If this setting is enabled, the "Empty" =DENY= ACL is interpreted as
Expand Down Expand Up @@ -887,6 +897,7 @@ $Foswiki::cfg{Register}{EmailFilter} = '';
# items are quite innocent, it's better to be a bit paranoid.
$Foswiki::cfg{AccessibleCFG} = [
'{AccessControlACL}{EnableDeprecatedEmptyDeny}',
'{AccessControlACL}{EnableAdditiveRules}',
'{AccessibleCFG}',
'{AdminUserLogin}',
'{AdminUserWikiName}',
Expand Down
15 changes: 14 additions & 1 deletion core/lib/Foswiki/Access/TopicACLAccess.pm
Expand Up @@ -57,6 +57,7 @@ sub haveAccess {
my $session = $this->{session};
undef $this->{failure};

# If site doesn't permit login authentication, everything is allowed.
return 1
if ( defined $Foswiki::cfg{LoginManager}
&& $Foswiki::cfg{LoginManager} eq 'none' );
Expand Down Expand Up @@ -204,6 +205,18 @@ sub _getACL {
my $text = $meta->getPreference($mode);
return undef unless defined $text;

if ( $Foswiki::cfg{AccessControlACL}{EnableAdditiveRules}
&& substr( $text, 0, 1 ) eq '+' )
{
$text = substr $text, 1;
print STDERR "Additive enabled, checking WEB level\n" if MONITOR;

if ( $mode =~ m/^ALLOWTOPIC(.*)/ ) {
my $tmptext = $meta->getContainer()->getPreference("ALLOWWEB$1");
$text .= ", " . $tmptext if $tmptext;
}
}

# Remove HTML tags (compatibility, inherited from Users.pm
$text =~ s/(<[^>]*>)//g;

Expand All @@ -213,7 +226,7 @@ sub _getACL {
$_
} split( /[,\s]+/, $text );

#print STDERR "getACL($mode): ".join(', ', @list)."\n";
#print STDERR "getACL($mode): ".join(', ', @list)."\n" if MONITOR;

return \@list;
}
Expand Down

0 comments on commit a4402d4

Please sign in to comment.