230 lines
7.0 KiB
Perl
230 lines
7.0 KiB
Perl
# Module of TWiki Enterprise Collaboration Platform, http://TWiki.org/
|
|
#
|
|
# Copyright (C) 1999-2007 Peter Thoeny, peter@thoeny.org
|
|
# and TWiki Contributors. All Rights Reserved. TWiki Contributors
|
|
# are listed in the AUTHORS file in the root of this distribution.
|
|
# NOTE: Please extend that file, not this notice.
|
|
#
|
|
# 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 2
|
|
# of the License, or (at your option) any later version. For
|
|
# more details read LICENSE in the root of this distribution.
|
|
#
|
|
# 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.
|
|
#
|
|
# As per the GPL, removal of this notice is prohibited.
|
|
|
|
=pod
|
|
|
|
---+ package TWiki::Access
|
|
|
|
A singleton object of this class manages the access control database.
|
|
|
|
=cut
|
|
|
|
package TWiki::Access;
|
|
|
|
use strict;
|
|
use Assert;
|
|
|
|
=pod
|
|
|
|
---++ ClassMethod new()
|
|
|
|
Construct a new singleton object to manage the permissions
|
|
database.
|
|
|
|
=cut
|
|
|
|
sub new {
|
|
my ( $class, $session ) = @_;
|
|
my $this = bless( {}, $class );
|
|
ASSERT($session->isa( 'TWiki')) if DEBUG;
|
|
$this->{session} = $session;
|
|
|
|
%{$this->{GROUPS}} = ();
|
|
|
|
return $this;
|
|
}
|
|
|
|
=pod
|
|
|
|
---++ ObjectMethod permissionsSet ( $web ) -> $boolean
|
|
|
|
Are there any security restrictions for this Web
|
|
(ignoring settings on individual pages).
|
|
|
|
=cut
|
|
|
|
sub permissionsSet {
|
|
my( $this, $web ) = @_;
|
|
ASSERT($this->isa( 'TWiki::Access')) if DEBUG;
|
|
|
|
my $permSet = 0;
|
|
|
|
my @types = qw/ALLOW DENY/;
|
|
my @actions = qw/CHANGE VIEW/;
|
|
my $prefs = $this->{session}->{prefs};
|
|
|
|
OUT: foreach my $type ( @types ) {
|
|
foreach my $action ( @actions ) {
|
|
my $pref = $type . 'WEB' . $action;
|
|
my $prefValue = $prefs->getWebPreferencesValue( $pref, $web ) || '';
|
|
if( $prefValue =~ /\S/ ) {
|
|
$permSet = 1;
|
|
last OUT;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $permSet;
|
|
}
|
|
|
|
=pod
|
|
|
|
---++ ObjectMethod getReason() -> $string
|
|
|
|
Return a string describing the reason why the last access control failure
|
|
occurred.
|
|
|
|
=cut
|
|
|
|
sub getReason {
|
|
my $this = shift;
|
|
|
|
return $this->{failure};
|
|
}
|
|
|
|
=pod
|
|
|
|
---++ ObjectMethod checkAccessPermission( $action, $user, $text, $meta, $topic, $web ) -> $boolean
|
|
|
|
Check if user is allowed to access topic
|
|
* =$action= - 'VIEW', 'CHANGE', 'CREATE', etc.
|
|
* =$user= - User object
|
|
* =$text= - If undef or '': Read '$theWebName.$theTopicName' to check permissions
|
|
* =$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.
|
|
* =$topic= - Topic name to check, e.g. 'SomeTopic' *undef to check web perms only)
|
|
* =$web= - Web, e.g. 'Know'
|
|
If the check fails, the reason can be recoveered using getReason.
|
|
|
|
=cut
|
|
|
|
sub checkAccessPermission {
|
|
my( $this, $mode, $user, $text, $meta, $topic, $web ) = @_;
|
|
ASSERT($this->isa( 'TWiki::Access')) if DEBUG;
|
|
ASSERT($user->isa( 'TWiki::User')) if DEBUG;
|
|
|
|
undef $this->{failure};
|
|
|
|
#print STDERR "Check $mode access ", $user->stringify()," to ", ($web||'undef'), '.', ($topic||'undef'),"\n";
|
|
|
|
# super admin is always allowed
|
|
if( $user->isAdmin() ) {
|
|
#print STDERR $user->stringify() . " - ADMIN\n";
|
|
return 1;
|
|
}
|
|
|
|
$mode = uc( $mode ); # upper case
|
|
|
|
my $prefs = $this->{session}->{prefs};
|
|
|
|
my $allowText;
|
|
my $denyText;
|
|
|
|
# extract the * Set (ALLOWTOPIC|DENYTOPIC)$mode
|
|
if( defined $text ) {
|
|
# override topic permissions.
|
|
$allowText = $prefs->getTextPreferencesValue(
|
|
'ALLOWTOPIC'.$mode, $text, $meta, $web, $topic );
|
|
$denyText = $prefs->getTextPreferencesValue(
|
|
'DENYTOPIC'.$mode, $text, $meta, $web, $topic );
|
|
} elsif( $topic ) {
|
|
$allowText = $prefs->getTopicPreferencesValue( 'ALLOWTOPIC'.$mode,
|
|
$web, $topic );
|
|
$denyText = $prefs->getTopicPreferencesValue( 'DENYTOPIC'.$mode,
|
|
$web, $topic );
|
|
}
|
|
|
|
# Check DENYTOPIC
|
|
if( defined( $denyText )) {
|
|
if( $denyText =~ /\S$/ ) {
|
|
if( $user->isInList( $denyText )) {
|
|
$this->{failure} = $this->{session}->{i18n}->maketext('access denied on topic');
|
|
#print STDERR $this->{failure},"\n";
|
|
return 0;
|
|
}
|
|
} else {
|
|
# If DENYTOPIC is empty, don't deny _anyone_
|
|
#print STDERR "DENYTOPIC is empty\n";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
# Check ALLOWTOPIC. If this is defined the user _must_ be in it
|
|
if( defined( $allowText ) && $allowText =~ /\S/ ) {
|
|
if( $user->isInList( $allowText )) {
|
|
#print STDERR "in ALLOWTOPIC\n";
|
|
return 1;
|
|
}
|
|
$this->{failure} = $this->{session}->{i18n}->maketext('access not allowed on topic');
|
|
#print STDERR $this->{failure},"\n";
|
|
return 0;
|
|
}
|
|
|
|
# Check DENYWEB, but only if DENYTOPIC is not set (even if it
|
|
# is empty - empty means "don't deny anybody")
|
|
unless( defined( $denyText )) {
|
|
$denyText =
|
|
$prefs->getWebPreferencesValue( 'DENYWEB'.$mode, $web );
|
|
if( defined( $denyText ) && $user->isInList( $denyText )) {
|
|
$this->{failure} = $this->{session}->{i18n}->maketext('access denied on web');
|
|
#print STDERR $this->{failure},"\n";
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
# Check ALLOWWEB. If this is defined and not overridden by
|
|
# ALLOWTOPIC, the user _must_ be in it.
|
|
$allowText = $prefs->getWebPreferencesValue( 'ALLOWWEB'.$mode, $web );
|
|
|
|
if( defined( $allowText ) && $allowText =~ /\S/ ) {
|
|
unless( $user->isInList( $allowText )) {
|
|
$this->{failure} = $this->{session}->{i18n}->maketext('access not allowed on web');
|
|
#print STDERR $this->{failure},"\n";
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
# Check DENYROOT and ALLOWROOT, but only if web is not defined
|
|
unless( $web ) {
|
|
$denyText =
|
|
$prefs->getPreferencesValue( 'DENYROOT'.$mode, $web );
|
|
if( defined( $denyText ) && $user->isInList( $denyText )) {
|
|
$this->{failure} = $this->{session}->{i18n}->maketext('access denied on root');
|
|
#print STDERR $this->{failure},"\n";
|
|
return 0;
|
|
}
|
|
|
|
$allowText = $prefs->getPreferencesValue( 'ALLOWROOT'.$mode, $web );
|
|
|
|
if( defined( $allowText ) && $allowText =~ /\S/ ) {
|
|
unless( $user->isInList( $allowText )) {
|
|
$this->{failure} = $this->{session}->{i18n}->maketext('access not allowed on root');
|
|
#print STDERR $this->{failure},"\n";
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
#print STDERR "OK, permitted\n";
|
|
#print STDERR "ALLOW: $allowText\n" if defined $allowText;
|
|
#print STDERR "DENY: $denyText\n" if defined $denyText;
|
|
return 1;
|
|
}
|
|
|
|
1;
|