~kosova/+junk/tuxfamily-twiki

« back to all changes in this revision

Viewing changes to foswiki/lib/Foswiki/Access.pm

  • Committer: James Michael DuPont
  • Date: 2009-07-18 19:58:49 UTC
  • Revision ID: jamesmikedupont@gmail.com-20090718195849-vgbmaht2ys791uo2
added foswiki

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Module of Foswiki - The Free and Open Source Wiki, http://foswiki.org/
 
2
#
 
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.
 
6
#
 
7
# Additional copyrights apply to some or all of the code in this
 
8
# file as follows:
 
9
#
 
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.
 
13
#
 
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.
 
19
#
 
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.
 
23
#
 
24
# As per the GPL, removal of this notice is prohibited.
 
25
 
 
26
=begin TML
 
27
 
 
28
---+ package Foswiki::Access
 
29
 
 
30
A singleton object of this class manages the access control database.
 
31
 
 
32
=cut
 
33
 
 
34
package Foswiki::Access;
 
35
 
 
36
use strict;
 
37
use Assert;
 
38
 
 
39
# Enable this for debug. Done as a sub to allow perl to optimise it out.
 
40
sub MONITOR { 0 }
 
41
 
 
42
=begin TML
 
43
 
 
44
---++ ClassMethod new($session)
 
45
 
 
46
Constructor.
 
47
 
 
48
=cut
 
49
 
 
50
sub new {
 
51
    my ( $class, $session ) = @_;
 
52
    my $this = bless( { session => $session }, $class );
 
53
 
 
54
    return $this;
 
55
}
 
56
 
 
57
=begin TML
 
58
 
 
59
---++ ObjectMethod finish()
 
60
Break circular references.
 
61
 
 
62
=cut
 
63
 
 
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.
 
67
sub finish {
 
68
    my $this = shift;
 
69
    undef $this->{failure};
 
70
    undef $this->{session};
 
71
}
 
72
 
 
73
=begin TML
 
74
 
 
75
---++ ObjectMethod getReason() -> $string
 
76
 
 
77
Return a string describing the reason why the last access control failure
 
78
occurred.
 
79
 
 
80
=cut
 
81
 
 
82
sub getReason {
 
83
    my $this = shift;
 
84
 
 
85
    return $this->{failure};
 
86
}
 
87
 
 
88
=begin TML
 
89
 
 
90
---++ ObjectMethod checkAccessPermission( $action, $user, $text, $meta, $topic, $web ) -> $boolean
 
91
 
 
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.
 
100
 
 
101
=cut
 
102
 
 
103
sub checkAccessPermission {
 
104
    my ( $this, $mode, $user, $text, $meta, $topic, $web ) = @_;
 
105
 
 
106
    undef $this->{failure};
 
107
 
 
108
    print STDERR "Check $mode access $user to "
 
109
      . ( $web   || 'undef' ) . '.'
 
110
      . ( $topic || 'undef' ) . "\n"
 
111
      if MONITOR;
 
112
 
 
113
    # super admin is always allowed
 
114
    if ( $this->{session}->{users}->isAdmin($user) ) {
 
115
        print STDERR "$user - ADMIN\n" if MONITOR;
 
116
        return 1;
 
117
    }
 
118
 
 
119
    $mode = uc($mode);    # upper case
 
120
 
 
121
    my $prefs = $this->{session}->{prefs};
 
122
 
 
123
    my $allowText;
 
124
    my $denyText;
 
125
 
 
126
    # extract the * Set (ALLOWTOPIC|DENYTOPIC)$mode
 
127
    if ( defined $text ) {
 
128
 
 
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 );
 
134
    }
 
135
    elsif ($topic) {
 
136
        $allowText =
 
137
          $prefs->getTopicPreferencesValue( 'ALLOWTOPIC' . $mode, $web,
 
138
            $topic );
 
139
        $denyText =
 
140
          $prefs->getTopicPreferencesValue( 'DENYTOPIC' . $mode, $web, $topic );
 
141
    }
 
142
 
 
143
    # Check DENYTOPIC
 
144
    if ( defined($denyText) ) {
 
145
        if ( $denyText =~ /\S$/ ) {
 
146
            if ( $this->{session}->{users}->isInList( $user, $denyText ) ) {
 
147
                $this->{failure} =
 
148
                  $this->{session}->i18n->maketext('access denied on topic');
 
149
                print STDERR $this->{failure} . " ($denyText)\n" if MONITOR;
 
150
                return 0;
 
151
            }
 
152
        }
 
153
        else {
 
154
 
 
155
            # If DENYTOPIC is empty, don't deny _anyone_
 
156
            print STDERR "DENYTOPIC is empty\n" if MONITOR;
 
157
            return 1;
 
158
        }
 
159
    }
 
160
 
 
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;
 
165
            return 1;
 
166
        }
 
167
        $this->{failure} =
 
168
          $this->{session}->i18n->maketext('access not allowed on topic');
 
169
        print STDERR $this->{failure} . " ($allowText)\n" if MONITOR;
 
170
        return 0;
 
171
    }
 
172
 
 
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 ) )
 
179
        {
 
180
            $this->{failure} =
 
181
              $this->{session}->i18n->maketext('access denied on web');
 
182
            print STDERR $this->{failure} . "\n" if MONITOR;
 
183
            return 0;
 
184
        }
 
185
    }
 
186
 
 
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 );
 
190
 
 
191
    if ( defined($allowText) && $allowText =~ /\S/ ) {
 
192
        unless ( $this->{session}->{users}->isInList( $user, $allowText ) ) {
 
193
            $this->{failure} =
 
194
              $this->{session}->i18n->maketext('access not allowed on web');
 
195
            print STDERR $this->{failure} . "\n" if MONITOR;
 
196
            return 0;
 
197
        }
 
198
    }
 
199
 
 
200
    # Check DENYROOT and ALLOWROOT, but only if web is not defined
 
201
    unless ($web) {
 
202
        $denyText = $prefs->getPreferencesValue( 'DENYROOT' . $mode, $web );
 
203
        if ( defined($denyText)
 
204
            && $this->{session}->{users}->isInList( $user, $denyText ) )
 
205
        {
 
206
            $this->{failure} =
 
207
              $this->{session}->i18n->maketext('access denied on root');
 
208
            print STDERR $this->{failure} . "\n" if MONITOR;
 
209
            return 0;
 
210
        }
 
211
 
 
212
        $allowText = $prefs->getPreferencesValue( 'ALLOWROOT' . $mode, $web );
 
213
 
 
214
        if ( defined($allowText) && $allowText =~ /\S/ ) {
 
215
            unless ( $this->{session}->{users}->isInList( $user, $allowText ) )
 
216
            {
 
217
                $this->{failure} =
 
218
                  $this->{session}
 
219
                  ->i18n->maketext('access not allowed on root');
 
220
                print STDERR $this->{failure} . "\n" if MONITOR;
 
221
                return 0;
 
222
            }
 
223
        }
 
224
    }
 
225
 
 
226
    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;
 
230
    }
 
231
    return 1;
 
232
}
 
233
 
 
234
1;