← Index
NYTProf Performance Profile   « block view • line view • sub view »
For /usr/local/src/github.com/foswiki/core/bin/view
  Run on Sun Dec 4 17:17:59 2011
Reported on Sun Dec 4 17:27:15 2011

Filename/usr/local/src/github.com/foswiki/core/lib/Foswiki/Access/TopicACLAccess.pm
StatementsExecuted 1811 statements in 9.54ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1119.48ms9.96msFoswiki::Access::TopicACLAccess::::BEGIN@22Foswiki::Access::TopicACLAccess::BEGIN@22
56115.09ms60.9sFoswiki::Access::TopicACLAccess::::haveAccessFoswiki::Access::TopicACLAccess::haveAccess
132412.52ms60.8sFoswiki::Access::TopicACLAccess::::_getACLFoswiki::Access::TopicACLAccess::_getACL
401179µs79µsFoswiki::Access::TopicACLAccess::::CORE:substFoswiki::Access::TopicACLAccess::CORE:subst (opcode)
11129µs33µsFoswiki::Access::TopicACLAccess::::newFoswiki::Access::TopicACLAccess::new
11124µs78µsFoswiki::Access::TopicACLAccess::::BEGIN@19Foswiki::Access::TopicACLAccess::BEGIN@19
11121µs29µsFoswiki::Access::TopicACLAccess::::BEGIN@18Foswiki::Access::TopicACLAccess::BEGIN@18
11121µs21µsFoswiki::Access::TopicACLAccess::::BEGIN@13Foswiki::Access::TopicACLAccess::BEGIN@13
11120µs124µsFoswiki::Access::TopicACLAccess::::BEGIN@16Foswiki::Access::TopicACLAccess::BEGIN@16
11112µs12µsFoswiki::Access::TopicACLAccess::::BEGIN@23Foswiki::Access::TopicACLAccess::BEGIN@23
11110µs10µsFoswiki::Access::TopicACLAccess::::BEGIN@24Foswiki::Access::TopicACLAccess::BEGIN@24
11110µs10µsFoswiki::Access::TopicACLAccess::::BEGIN@21Foswiki::Access::TopicACLAccess::BEGIN@21
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
13268µs121µs
# spent 21µs within Foswiki::Access::TopicACLAccess::BEGIN@13 which was called: # once (21µs+0s) by Foswiki::Access::BEGIN@2 at line 13
use Foswiki::Access;
# spent 21µs making 1 call to Foswiki::Access::TopicACLAccess::BEGIN@13
14112µs@ISA = qw(Foswiki::Access);
15
16252µs2228µs
# spent 124µs (20+104) within Foswiki::Access::TopicACLAccess::BEGIN@16 which was called: # once (20µs+104µs) by Foswiki::Access::BEGIN@2 at line 16
use constant MONITOR => 0;
# spent 124µs making 1 call to Foswiki::Access::TopicACLAccess::BEGIN@16 # spent 104µs making 1 call to constant::import
17
18247µs237µs
# spent 29µs (21+8) within Foswiki::Access::TopicACLAccess::BEGIN@18 which was called: # once (21µs+8µs) by Foswiki::Access::BEGIN@2 at line 18
use strict;
# spent 29µs making 1 call to Foswiki::Access::TopicACLAccess::BEGIN@18 # spent 8µs making 1 call to strict::import
19250µs2133µs
# spent 78µs (24+55) within Foswiki::Access::TopicACLAccess::BEGIN@19 which was called: # once (24µs+55µs) by Foswiki::Access::BEGIN@2 at line 19
use Assert;
# spent 78µs making 1 call to Foswiki::Access::TopicACLAccess::BEGIN@19 # spent 55µs making 1 call to Assert::import
20
21240µs110µs
# spent 10µs within Foswiki::Access::TopicACLAccess::BEGIN@21 which was called: # once (10µs+0s) by Foswiki::Access::BEGIN@2 at line 21
use Foswiki ();
# spent 10µs making 1 call to Foswiki::Access::TopicACLAccess::BEGIN@21
222211µs19.96ms
# spent 9.96ms (9.48+478µs) within Foswiki::Access::TopicACLAccess::BEGIN@22 which was called: # once (9.48ms+478µs) by Foswiki::Access::BEGIN@2 at line 22
use Foswiki::Address ();
# spent 9.96ms making 1 call to Foswiki::Access::TopicACLAccess::BEGIN@22
23253µs112µs
# spent 12µs within Foswiki::Access::TopicACLAccess::BEGIN@23 which was called: # once (12µs+0s) by Foswiki::Access::BEGIN@2 at line 23
use Foswiki::Meta ();
# spent 12µs making 1 call to Foswiki::Access::TopicACLAccess::BEGIN@23
2421.63ms110µs
# spent 10µs within Foswiki::Access::TopicACLAccess::BEGIN@24 which was called: # once (10µs+0s) by Foswiki::Access::BEGIN@2 at line 24
use Foswiki::Users ();
# spent 10µs making 1 call to Foswiki::Access::TopicACLAccess::BEGIN@24
25
26
# spent 33µs (29+4) within Foswiki::Access::TopicACLAccess::new which was called: # once (29µs+4µs) by Foswiki::Access::new at line 34 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Access.pm
sub new {
2713µs my ( $class, $session ) = @_;
2815µs14µs ASSERT( $session->isa('Foswiki') ) if DEBUG;
# spent 4µs making 1 call to Assert::ASSERTS_OFF
29112µs my $this = bless( { session => $session }, $class );
30
3119µs return $this;
32}
33
34=begin TML
35
36---++ ObjectMethod haveAccess($mode, $User, $web, $topic, $attachment) -> $boolean
37---++ ObjectMethod haveAccess($mode, $User, $meta) -> $boolean
38---++ ObjectMethod haveAccess($mode, $User, $address) -> $boolean
39
40 * =$mode= - 'VIEW', 'CHANGE', 'CREATE', etc. (defaults to VIEW)
41 * =$cUID= - Canonical user id (defaults to current user)
42Check if the user has the given mode of access to the topic. This call
43may result in the topic being read.
44
45=cut
46
47
# spent 60.9s (5.09ms+60.9) within Foswiki::Access::TopicACLAccess::haveAccess which was called 56 times, avg 1.09s/call: # 56 times (5.09ms+60.9s) by Foswiki::Meta::haveAccess at line 1836 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Meta.pm, avg 1.09s/call
sub haveAccess {
4856183µs my ( $this, $mode, $cUID, $param1, $param2, $param3 ) = @_;
495680µs $mode ||= 'VIEW';
505674µs $cUID ||= $this->{session}->{user};
51
5256145µs my $session = $this->{session};
5356106µs undef $this->{failure};
54
555666µs my $meta;
56
5756244µs if ( ref($param1) eq '' ) {
58
59 #scalar - treat as web, topic
60 $meta = Foswiki::Meta->load( $session, $param1, $param2 );
61 ASSERT( not defined($param3) )
62 if DEBUG
63 ; #attachment ACL not currently supported in traditional topic ACL
64 }
65 else {
6656254µs if ( ref($param1) eq 'Foswiki::Address' ) {
67 $meta =
68 Foswiki::Meta->load( $session, $param1->web(), $param1->topic() );
69 }
70 else {
715686µs $meta = $param1;
72 }
73 }
7456264µs56192µs ASSERT( $meta->isa('Foswiki::Meta') ) if DEBUG;
# spent 192µs making 56 calls to Assert::ASSERTS_OFF, avg 3µs/call
75
76 print STDERR "Check $mode access $cUID to " . $meta->getPath() . "\n"
77 if MONITOR;
78
79 # super admin is always allowed
8056548µs5684.9ms if ( $session->{users}->isAdmin($cUID) ) {
# spent 84.9ms making 56 calls to Foswiki::Users::isAdmin, avg 1.52ms/call
81 print STDERR "$cUID - ADMIN\n" if MONITOR;
8223131µs return 1;
83 }
84
8533129µs $mode = uc($mode);
86
873357µs my ( $allow, $deny );
8833112µs if ( $meta->{_topic} ) {
89
9033311µs3372.5ms my $allow = $this->_getACL( $meta, 'ALLOWTOPIC' . $mode );
# spent 72.5ms making 33 calls to Foswiki::Access::TopicACLAccess::_getACL, avg 2.20ms/call
9133212µs331.07ms my $deny = $this->_getACL( $meta, 'DENYTOPIC' . $mode );
# spent 1.07ms making 33 calls to Foswiki::Access::TopicACLAccess::_getACL, avg 32µs/call
92
93 # Check DENYTOPIC
943356µs if ( defined($deny) ) {
95 if ( scalar(@$deny) != 0 ) {
96 if ( $session->{users}->isInUserList( $cUID, $deny ) ) {
97 $this->{failure} =
98 $session->i18n->maketext('access denied on topic');
99 print STDERR 'a ' . $this->{failure}, "\n" if MONITOR;
100 return 0;
101 }
102 }
103 else {
104
105 # If DENYTOPIC is empty, don't deny _anyone_
106 print STDERR "DENYTOPIC is empty\n" if MONITOR;
107 return 1;
108 }
109 }
110
111 # Check ALLOWTOPIC. If this is defined the user _must_ be in it
1123348µs if ( defined($allow) && scalar(@$allow) != 0 ) {
113 if ( $session->{users}->isInUserList( $cUID, $allow ) ) {
114 print STDERR "in ALLOWTOPIC\n" if MONITOR;
115 return 1;
116 }
117 $this->{failure} =
118 $session->i18n->maketext('access not allowed on topic');
119 print STDERR 'b ' . $this->{failure}, "\n" if MONITOR;
120 return 0;
121 }
12233222µs332.63ms $meta = $meta->getContainer(); # Web
# spent 2.63ms making 33 calls to Foswiki::Meta::getContainer, avg 80µs/call
123 }
124
12533101µs if ( $meta->{_web} ) {
126
127 # Check DENYWEB, but only if DENYTOPIC is not set (even if it
128 # is empty - empty means "don't deny anybody")
1293397µs unless ( defined($deny) ) {
13033306µs3360.7s $deny = $this->_getACL( $meta, 'DENYWEB' . $mode );
# spent 60.7s making 33 calls to Foswiki::Access::TopicACLAccess::_getACL, avg 1.84s/call
13133201µs20294µs if ( defined($deny)
# spent 294µs making 20 calls to Foswiki::Users::isInUserList, avg 15µs/call
132 && $session->{users}->isInUserList( $cUID, $deny ) )
133 {
134 $this->{failure} =
135 $session->i18n->maketext('access denied on web');
136 print STDERR 'c ' . $this->{failure}, "\n" if MONITOR;
137 return 0;
138 }
139 }
140
141 # Check ALLOWWEB. If this is defined and not overridden by
142 # ALLOWTOPIC, the user _must_ be in it.
14333268µs332.34ms $allow = $this->_getACL( $meta, 'ALLOWWEB' . $mode );
# spent 2.34ms making 33 calls to Foswiki::Access::TopicACLAccess::_getACL, avg 71µs/call
144
1453374µs if ( defined($allow) && scalar(@$allow) != 0 ) {
146 unless ( $session->{users}->isInUserList( $cUID, $allow ) ) {
147 $this->{failure} =
148 $session->i18n->maketext('access not allowed on web');
149 print STDERR 'd ' . $this->{failure}, "\n" if MONITOR;
150 return 0;
151 }
152 }
153
154 }
155 else {
156
157 # No web, we are checking at the root. Check DENYROOT and ALLOWROOT.
158 $deny = $this->_getACL( $meta, 'DENYROOT' . $mode );
159
160 if ( defined($deny)
161 && $session->{users}->isInUserList( $cUID, $deny ) )
162 {
163 $this->{failure} =
164 $session->i18n->maketext('access denied on root');
165 print STDERR 'e ' . $this->{failure}, "\n" if MONITOR;
166 return 0;
167 }
168
169 $allow = $this->_getACL( $meta, 'ALLOWROOT' . $mode );
170
171 if ( defined($allow) && scalar(@$allow) != 0 ) {
172 unless ( $session->{users}->isInUserList( $cUID, $allow ) ) {
173 $this->{failure} =
174 $session->i18n->maketext('access not allowed on root');
175 print STDERR 'f ' . $this->{failure}, "\n" if MONITOR;
176 return 0;
177 }
178 }
179 }
180
181 if (MONITOR) {
182 print STDERR "OK, permitted\n";
183 print STDERR 'ALLOW: ' . join( ',', @$allow ) . "\n" if defined $allow;
184 print STDERR 'DENY: ' . join( ',', @$deny ) . "\n" if defined $deny;
185 }
18633296µs return 1;
187}
188
189# Get an ACL preference. Returns a reference to a list of cUIDs, or undef.
190# If the preference is defined but is empty, then a reference to an
191# empty list is returned.
192# This function canonicalises the parsing of a users list. Is this the right
193# place for it?
194
# spent 60.8s (2.52ms+60.8) within Foswiki::Access::TopicACLAccess::_getACL which was called 132 times, avg 461ms/call: # 33 times (695µs+60.7s) by Foswiki::Access::TopicACLAccess::haveAccess at line 130, avg 1.84s/call # 33 times (734µs+71.8ms) by Foswiki::Access::TopicACLAccess::haveAccess at line 90, avg 2.20ms/call # 33 times (617µs+1.72ms) by Foswiki::Access::TopicACLAccess::haveAccess at line 143, avg 71µs/call # 33 times (476µs+593µs) by Foswiki::Access::TopicACLAccess::haveAccess at line 91, avg 32µs/call
sub _getACL {
195132335µs my ( $this, $meta, $mode ) = @_;
196
197132278µs if ( defined $meta->{_topic} && !defined $meta->{_loadedRev} ) {
198
199 # Lazy load the latest version.
200747µs734.7ms $meta->loadVersion();
# spent 34.7ms making 7 calls to Foswiki::Meta::loadVersion, avg 4.95ms/call
201 }
202
203132790µs13260.8s my $text = $meta->getPreference($mode);
# spent 60.8s making 132 calls to Foswiki::Meta::getPreference, avg 460ms/call
204132576µs return undef unless defined $text;
205
206 # Remove HTML tags (compatibility, inherited from Users.pm
20740274µs4079µs $text =~ s/(<[^>]*>)//g;
# spent 79µs making 40 calls to Foswiki::Access::TopicACLAccess::CORE:subst, avg 2µs/call
208
209 # Dump the users web specifier if userweb
210 my @list = grep { /\S/ } map {
21140104µs s/^($Foswiki::cfg{UsersWebName}|%USERSWEB%|%MAINWEB%)\.//;
212 $_
213 } split( /[,\s]+/, $text );
214
215 #print STDERR "getACL($mode): ".join(', ', @list)."\n";
216
21740272µs return \@list;
218}
219
22016µs1;
221__END__
 
# spent 79µs within Foswiki::Access::TopicACLAccess::CORE:subst which was called 40 times, avg 2µs/call: # 40 times (79µs+0s) by Foswiki::Access::TopicACLAccess::_getACL at line 207, avg 2µs/call
sub Foswiki::Access::TopicACLAccess::CORE:subst; # opcode