1
# Module of Foswiki - The Free and Open Source Wiki, http://foswiki.org/
3
# Copyright (C) 2008-2009 Foswiki Contributors. Foswiki Contributors
4
# are listed in the AUTHORS file in the root of this distribution.
5
# NOTE: Please extend that file, not this notice.
7
# Additional copyrights apply to some or all of the code in this
10
# Copyright (C) 1999-2007 Peter Thoeny, peter@thoeny.org
11
# and TWiki Contributors. All Rights Reserved. TWiki Contributors
12
# are listed in the AUTHORS file in the root of this distribution.
14
# This program is free software; you can redistribute it and/or
15
# modify it under the terms of the GNU General Public License
16
# as published by the Free Software Foundation; either version 2
17
# of the License, or (at your option) any later version. For
18
# more details read LICENSE in the root of this distribution.
20
# This program is distributed in the hope that it will be useful,
21
# but WITHOUT ANY WARRANTY; without even the implied warranty of
22
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
24
# As per the GPL, removal of this notice is prohibited.
28
---+ package Foswiki::Access
30
A singleton object of this class manages the access control database.
34
package Foswiki::Access;
39
# Enable this for debug. Done as a sub to allow perl to optimise it out.
44
---++ ClassMethod new($session)
51
my ( $class, $session ) = @_;
52
my $this = bless( { session => $session }, $class );
59
---++ ObjectMethod finish()
60
Break circular references.
64
# Note to developers; please undef *all* fields in the object explicitly,
65
# whether they are references or not. That way this method is "golden
66
# documentation" of the live fields in the object.
69
undef $this->{failure};
70
undef $this->{session};
75
---++ ObjectMethod getReason() -> $string
77
Return a string describing the reason why the last access control failure
85
return $this->{failure};
90
---++ ObjectMethod checkAccessPermission( $action, $user, $text, $meta, $topic, $web ) -> $boolean
92
Check if user is allowed to access topic
93
* =$action= - 'VIEW', 'CHANGE', 'CREATE', etc.
94
* =$user= - User id (*not* wikiname)
95
* =$text= - If undef or '': Read '$theWebName.$theTopicName' to check permissions
96
* =$meta= - If undef, but =$text= is defined, then metadata will be parsed from =$text=. If defined, then metadata embedded in =$text= will be ignored. Always ignored if =$text= is undefined. Settings in =$meta= override * Set settings in plain text.
97
* =$topic= - Topic name to check, e.g. 'SomeTopic' *undef to check web perms only)
98
* =$web= - Web, e.g. 'Know'
99
If the check fails, the reason can be recoveered using getReason.
103
sub checkAccessPermission {
104
my ( $this, $mode, $user, $text, $meta, $topic, $web ) = @_;
106
undef $this->{failure};
108
print STDERR "Check $mode access $user to "
109
. ( $web || 'undef' ) . '.'
110
. ( $topic || 'undef' ) . "\n"
113
# super admin is always allowed
114
if ( $this->{session}->{users}->isAdmin($user) ) {
115
print STDERR "$user - ADMIN\n" if MONITOR;
119
$mode = uc($mode); # upper case
121
my $prefs = $this->{session}->{prefs};
126
# extract the * Set (ALLOWTOPIC|DENYTOPIC)$mode
127
if ( defined $text ) {
129
# override topic permissions.
130
$allowText = $prefs->getTextPreferencesValue( 'ALLOWTOPIC' . $mode,
131
$text, $meta, $web, $topic );
132
$denyText = $prefs->getTextPreferencesValue( 'DENYTOPIC' . $mode,
133
$text, $meta, $web, $topic );
137
$prefs->getTopicPreferencesValue( 'ALLOWTOPIC' . $mode, $web,
140
$prefs->getTopicPreferencesValue( 'DENYTOPIC' . $mode, $web, $topic );
144
if ( defined($denyText) ) {
145
if ( $denyText =~ /\S$/ ) {
146
if ( $this->{session}->{users}->isInList( $user, $denyText ) ) {
148
$this->{session}->i18n->maketext('access denied on topic');
149
print STDERR $this->{failure} . " ($denyText)\n" if MONITOR;
155
# If DENYTOPIC is empty, don't deny _anyone_
156
print STDERR "DENYTOPIC is empty\n" if MONITOR;
161
# Check ALLOWTOPIC. If this is defined the user _must_ be in it
162
if ( defined($allowText) && $allowText =~ /\S/ ) {
163
if ( $this->{session}->{users}->isInList( $user, $allowText ) ) {
164
print STDERR "in ALLOWTOPIC\n" if MONITOR;
168
$this->{session}->i18n->maketext('access not allowed on topic');
169
print STDERR $this->{failure} . " ($allowText)\n" if MONITOR;
173
# Check DENYWEB, but only if DENYTOPIC is not set (even if it
174
# is empty - empty means "don't deny anybody")
175
unless ( defined($denyText) ) {
176
$denyText = $prefs->getWebPreferencesValue( 'DENYWEB' . $mode, $web );
177
if ( defined($denyText)
178
&& $this->{session}->{users}->isInList( $user, $denyText ) )
181
$this->{session}->i18n->maketext('access denied on web');
182
print STDERR $this->{failure} . "\n" if MONITOR;
187
# Check ALLOWWEB. If this is defined and not overridden by
188
# ALLOWTOPIC, the user _must_ be in it.
189
$allowText = $prefs->getWebPreferencesValue( 'ALLOWWEB' . $mode, $web );
191
if ( defined($allowText) && $allowText =~ /\S/ ) {
192
unless ( $this->{session}->{users}->isInList( $user, $allowText ) ) {
194
$this->{session}->i18n->maketext('access not allowed on web');
195
print STDERR $this->{failure} . "\n" if MONITOR;
200
# Check DENYROOT and ALLOWROOT, but only if web is not defined
202
$denyText = $prefs->getPreferencesValue( 'DENYROOT' . $mode, $web );
203
if ( defined($denyText)
204
&& $this->{session}->{users}->isInList( $user, $denyText ) )
207
$this->{session}->i18n->maketext('access denied on root');
208
print STDERR $this->{failure} . "\n" if MONITOR;
212
$allowText = $prefs->getPreferencesValue( 'ALLOWROOT' . $mode, $web );
214
if ( defined($allowText) && $allowText =~ /\S/ ) {
215
unless ( $this->{session}->{users}->isInList( $user, $allowText ) )
219
->i18n->maketext('access not allowed on root');
220
print STDERR $this->{failure} . "\n" if MONITOR;
227
print STDERR "OK, permitted\n";
228
print STDERR "ALLOW: $allowText\n" if defined $allowText;
229
print STDERR "DENY: $denyText\n" if defined $denyText;