← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 18:42:36 2015
Reported on Fri Jul 31 18:48:15 2015

Filename/var/www/foswikidev/core/lib/Foswiki/Access/TopicACLAccess.pm
StatementsExecuted 3298 statements in 3.17ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1115.69ms5.97msFoswiki::Access::TopicACLAccess::::BEGIN@22Foswiki::Access::TopicACLAccess::BEGIN@22
252112.05ms2.63msFoswiki::Access::TopicACLAccess::::haveAccessFoswiki::Access::TopicACLAccess::haveAccess
11114µs40µsFoswiki::Access::TopicACLAccess::::BEGIN@19Foswiki::Access::TopicACLAccess::BEGIN@19
11113µs13µsFoswiki::Access::TopicACLAccess::::BEGIN@13Foswiki::Access::TopicACLAccess::BEGIN@13
11110µs10µsFoswiki::Access::TopicACLAccess::::newFoswiki::Access::TopicACLAccess::new
1119µs38µsFoswiki::Access::TopicACLAccess::::BEGIN@16Foswiki::Access::TopicACLAccess::BEGIN@16
1119µs20µsFoswiki::Access::TopicACLAccess::::BEGIN@18Foswiki::Access::TopicACLAccess::BEGIN@18
1115µs5µsFoswiki::Access::TopicACLAccess::::BEGIN@23Foswiki::Access::TopicACLAccess::BEGIN@23
1114µs4µsFoswiki::Access::TopicACLAccess::::BEGIN@21Foswiki::Access::TopicACLAccess::BEGIN@21
1114µs4µsFoswiki::Access::TopicACLAccess::::BEGIN@24Foswiki::Access::TopicACLAccess::BEGIN@24
1114µs4µsFoswiki::Access::TopicACLAccess::::BEGIN@26Foswiki::Access::TopicACLAccess::BEGIN@26
0000s0sFoswiki::Access::TopicACLAccess::::_getACLFoswiki::Access::TopicACLAccess::_getACL
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# See bottom of file for license and copyright information
2
3=pod
4
5---+ package Foswiki::Access::TopicACLAccess
6
7Implements the traditional, longstanding ACL in topic preference style.
8
9=cut
10
11package Foswiki::Access::TopicACLAccess;
12
13242µs113µs
# spent 13µs within Foswiki::Access::TopicACLAccess::BEGIN@13 which was called: # once (13µs+0s) by Foswiki::Access::new at line 13
use Foswiki::Access;
# spent 13µs making 1 call to Foswiki::Access::TopicACLAccess::BEGIN@13
1417µs@ISA = qw(Foswiki::Access);
15
16229µs268µs
# spent 38µs (9+29) within Foswiki::Access::TopicACLAccess::BEGIN@16 which was called: # once (9µs+29µs) by Foswiki::Access::new at line 16
use constant MONITOR => 0;
# spent 38µs making 1 call to Foswiki::Access::TopicACLAccess::BEGIN@16 # spent 29µs making 1 call to constant::import
17
18228µs231µs
# spent 20µs (9+11) within Foswiki::Access::TopicACLAccess::BEGIN@18 which was called: # once (9µs+11µs) by Foswiki::Access::new at line 18
use strict;
# spent 20µs making 1 call to Foswiki::Access::TopicACLAccess::BEGIN@18 # spent 11µs making 1 call to strict::import
19226µs265µs
# spent 40µs (14+25) within Foswiki::Access::TopicACLAccess::BEGIN@19 which was called: # once (14µs+25µs) by Foswiki::Access::new at line 19
use Assert;
# spent 40µs making 1 call to Foswiki::Access::TopicACLAccess::BEGIN@19 # spent 25µs making 1 call to Exporter::import
20
21218µs14µs
# spent 4µs within Foswiki::Access::TopicACLAccess::BEGIN@21 which was called: # once (4µs+0s) by Foswiki::Access::new at line 21
use Foswiki ();
# spent 4µs making 1 call to Foswiki::Access::TopicACLAccess::BEGIN@21
222120µs15.97ms
# spent 5.97ms (5.69+279µs) within Foswiki::Access::TopicACLAccess::BEGIN@22 which was called: # once (5.69ms+279µs) by Foswiki::Access::new at line 22
use Foswiki::Address ();
# spent 5.97ms making 1 call to Foswiki::Access::TopicACLAccess::BEGIN@22
23221µs15µs
# spent 5µs within Foswiki::Access::TopicACLAccess::BEGIN@23 which was called: # once (5µs+0s) by Foswiki::Access::new at line 23
use Foswiki::Meta ();
# spent 5µs making 1 call to Foswiki::Access::TopicACLAccess::BEGIN@23
24242µs14µs
# spent 4µs within Foswiki::Access::TopicACLAccess::BEGIN@24 which was called: # once (4µs+0s) by Foswiki::Access::new at line 24
use Foswiki::Users ();
# spent 4µs making 1 call to Foswiki::Access::TopicACLAccess::BEGIN@24
25
26
# spent 4µs within Foswiki::Access::TopicACLAccess::BEGIN@26 which was called: # once (4µs+0s) by Foswiki::Access::new at line 31
BEGIN {
2715µs if ( $Foswiki::cfg{UseLocale} ) {
28 require locale;
29 import locale();
30 }
311852µs14µs}
# spent 4µs making 1 call to Foswiki::Access::TopicACLAccess::BEGIN@26
32
33
# spent 10µs within Foswiki::Access::TopicACLAccess::new which was called: # once (10µs+0s) by Foswiki::Access::new at line 42 of /var/www/foswikidev/core/lib/Foswiki/Access.pm
sub new {
341900ns my ( $class, $session ) = @_;
35 ASSERT( $session->isa('Foswiki') ) if DEBUG;
3616µs my $this = bless( { session => $session }, $class );
37
3816µs return $this;
39}
40
41=begin TML
42
43---++ ObjectMethod haveAccess($mode, $User, $web, $topic, $attachment) -> $boolean
44---++ ObjectMethod haveAccess($mode, $User, $meta) -> $boolean
45---++ ObjectMethod haveAccess($mode, $User, $address) -> $boolean
46
47 * =$mode= - 'VIEW', 'CHANGE', 'CREATE', etc. (defaults to VIEW)
48 * =$cUID= - Canonical user id (defaults to current user)
49Check if the user has the given mode of access to the topic. This call
50may result in the topic being read.
51
52=cut
53
54
# spent 2.63ms (2.05+571µs) within Foswiki::Access::TopicACLAccess::haveAccess which was called 252 times, avg 10µs/call: # 252 times (2.05ms+571µs) by Foswiki::Meta::haveAccess at line 1925 of /var/www/foswikidev/core/lib/Foswiki/Meta.pm, avg 10µs/call
sub haveAccess {
55252190µs my ( $this, $mode, $cUID, $param1, $param2, $param3 ) = @_;
5625228µs $mode ||= 'VIEW';
5725225µs $cUID ||= $this->{session}->{user};
58
5925292µs my $session = $this->{session};
6025295µs undef $this->{failure};
61
62252168µs return 1
63 if ( defined $Foswiki::cfg{LoginManager}
64 && $Foswiki::cfg{LoginManager} eq 'none' );
65
6625227µs my $meta;
67
68252181µs if ( ref($param1) eq '' ) {
69
70 #scalar - treat as web, topic
71 $meta = Foswiki::Meta->load( $session, $param1, $param2 );
72 ASSERT( not defined($param3) )
73 if DEBUG
74 ; #attachment ACL not currently supported in traditional topic ACL
75 }
76 else {
77252105µs if ( ref($param1) eq 'Foswiki::Address' ) {
78 $meta =
79 Foswiki::Meta->load( $session, $param1->web(), $param1->topic() );
80 }
81 else {
8225281µs $meta = $param1;
83 }
84 }
85 ASSERT( $meta->isa('Foswiki::Meta') ) if DEBUG;
86
8725216µs print STDERR "Check $mode access $cUID to " . $meta->getPath() . "\n"
88 if MONITOR;
89
90 # super admin is always allowed
91252393µs252571µs if ( $session->{users}->isAdmin($cUID) ) {
# spent 571µs making 252 calls to Foswiki::Users::isAdmin, avg 2µs/call
92 print STDERR "$cUID - ADMIN\n" if MONITOR;
93252564µs return 1;
94 }
95
96 $mode = uc($mode);
97
98 my ( $allow, $deny );
99 if ( $meta->{_topic} ) {
100
101 $allow = $this->_getACL( $meta, 'ALLOWTOPIC' . $mode );
102 $deny = $this->_getACL( $meta, 'DENYTOPIC' . $mode );
103
104 # Check DENYTOPIC
105 if ( defined($deny) ) {
106 if ( scalar(@$deny) != 0 ) {
107 if ( $session->{users}->isInUserList( $cUID, $deny ) ) {
108 $this->{failure} =
109 $session->i18n->maketext('access denied on topic');
110 print STDERR 'a ' . $this->{failure}, "\n" if MONITOR;
111 return 0;
112 }
113 }
114 elsif ( $Foswiki::cfg{AccessControlACL}{EnableDeprecatedEmptyDeny} )
115 {
116
117 # If DENYTOPIC is empty, don't deny _anyone_
118 # DEPRECATED SYNTAX. Recommended replace with "ALLOWTOPIC=*"
119 print STDERR "Access allowed: deprecated DENYTOPIC is empty\n"
120 if MONITOR;
121 return 1;
122 }
123 }
124
125 # Check ALLOWTOPIC. If this is defined the user _must_ be in it
126 if ( defined($allow) && scalar(@$allow) != 0 ) {
127 if ( $session->{users}->isInUserList( $cUID, $allow ) ) {
128 print STDERR "in ALLOWTOPIC\n" if MONITOR;
129 return 1;
130 }
131 $this->{failure} =
132 $session->i18n->maketext('access not allowed on topic');
133 print STDERR 'b ' . $this->{failure}, "\n" if MONITOR;
134 return 0;
135 }
136 $meta = $meta->getContainer(); # Web
137 }
138
139 if ( $meta->{_web} ) {
140
141 $deny = $this->_getACL( $meta, 'DENYWEB' . $mode );
142 if ( defined($deny)
143 && $session->{users}->isInUserList( $cUID, $deny ) )
144 {
145 $this->{failure} = $session->i18n->maketext('access denied on web');
146 print STDERR 'c ' . $this->{failure}, "\n" if MONITOR;
147 return 0;
148 }
149
150 # Check ALLOWWEB. If this is defined and not overridden by
151 # ALLOWTOPIC, the user _must_ be in it.
152 $allow = $this->_getACL( $meta, 'ALLOWWEB' . $mode );
153
154 if ( defined($allow) && scalar(@$allow) != 0 ) {
155 unless ( $session->{users}->isInUserList( $cUID, $allow ) ) {
156 $this->{failure} =
157 $session->i18n->maketext('access not allowed on web');
158 print STDERR 'd ' . $this->{failure}, "\n" if MONITOR;
159 return 0;
160 }
161 }
162
163 }
164 else {
165
166 # No web, we are checking at the root. Check DENYROOT and ALLOWROOT.
167 $deny = $this->_getACL( $meta, 'DENYROOT' . $mode );
168
169 if ( defined($deny)
170 && $session->{users}->isInUserList( $cUID, $deny ) )
171 {
172 $this->{failure} =
173 $session->i18n->maketext('access denied on root');
174 print STDERR 'e ' . $this->{failure}, "\n" if MONITOR;
175 return 0;
176 }
177
178 $allow = $this->_getACL( $meta, 'ALLOWROOT' . $mode );
179
180 if ( defined($allow) && scalar(@$allow) != 0 ) {
181 unless ( $session->{users}->isInUserList( $cUID, $allow ) ) {
182 $this->{failure} =
183 $session->i18n->maketext('access not allowed on root');
184 print STDERR 'f ' . $this->{failure}, "\n" if MONITOR;
185 return 0;
186 }
187 }
188 }
189
190 if (MONITOR) {
191 print STDERR "OK, permitted\n";
192 print STDERR 'ALLOW: ' . join( ',', @$allow ) . "\n" if defined $allow;
193 print STDERR 'DENY: ' . join( ',', @$deny ) . "\n" if defined $deny;
194 }
195 return 1;
196}
197
198# Get an ACL preference. Returns a reference to a list of cUIDs, or undef.
199# If the preference is defined but is empty, then a reference to an
200# empty list is returned.
201# This function canonicalises the parsing of a users list. Is this the right
202# place for it?
203sub _getACL {
204 my ( $this, $meta, $mode ) = @_;
205
206 if ( defined $meta->topic && !defined $meta->getLoadedRev ) {
207
208 # Lazy load the latest version.
209 $meta->loadVersion();
210 }
211
212 my $text = $meta->getPreference($mode);
213 return undef unless defined $text;
214
215 # Remove HTML tags (compatibility, inherited from Users.pm
216 $text =~ s/(<[^>]*>)//g;
217
218 # Dump the users web specifier if userweb
219 my @list = grep { /\S/ } map {
220 s/^($Foswiki::cfg{UsersWebName}|%USERSWEB%|%MAINWEB%)\.//;
221 $_
222 } split( /[,\s]+/, $text );
223
224 #print STDERR "getACL($mode): ".join(', ', @list)."\n";
225
226 return \@list;
227}
228
22913µs1;
230__END__