← 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:10 2011

Filename/usr/local/src/github.com/foswiki/core/lib/Foswiki/UserMapping.pm
StatementsExecuted 167 statements in 2.28ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
222744µs83.9msFoswiki::UserMapping::::isInGroupFoswiki::UserMapping::isInGroup
22242µs42µsFoswiki::UserMapping::::newFoswiki::UserMapping::new
11126µs34µsFoswiki::UserMapping::::BEGIN@35Foswiki::UserMapping::BEGIN@35
22224µs24µsFoswiki::UserMapping::::finishFoswiki::UserMapping::finish
11116µs57µsFoswiki::UserMapping::::BEGIN@37Foswiki::UserMapping::BEGIN@37
11116µs34µsFoswiki::UserMapping::::BEGIN@36Foswiki::UserMapping::BEGIN@36
1119µs9µsFoswiki::UserMapping::::BEGIN@38Foswiki::UserMapping::BEGIN@38
0000s0sFoswiki::UserMapping::::addUserFoswiki::UserMapping::addUser
0000s0sFoswiki::UserMapping::::addUserToGroupFoswiki::UserMapping::addUserToGroup
0000s0sFoswiki::UserMapping::::checkPasswordFoswiki::UserMapping::checkPassword
0000s0sFoswiki::UserMapping::::eachGroupFoswiki::UserMapping::eachGroup
0000s0sFoswiki::UserMapping::::eachGroupMemberFoswiki::UserMapping::eachGroupMember
0000s0sFoswiki::UserMapping::::eachMembershipFoswiki::UserMapping::eachMembership
0000s0sFoswiki::UserMapping::::eachUserFoswiki::UserMapping::eachUser
0000s0sFoswiki::UserMapping::::findUserByEmailFoswiki::UserMapping::findUserByEmail
0000s0sFoswiki::UserMapping::::findUserByWikiNameFoswiki::UserMapping::findUserByWikiName
0000s0sFoswiki::UserMapping::::getEmailsFoswiki::UserMapping::getEmails
0000s0sFoswiki::UserMapping::::getLoginNameFoswiki::UserMapping::getLoginName
0000s0sFoswiki::UserMapping::::getWikiNameFoswiki::UserMapping::getWikiName
0000s0sFoswiki::UserMapping::::groupAllowsChangeFoswiki::UserMapping::groupAllowsChange
0000s0sFoswiki::UserMapping::::groupAllowsViewFoswiki::UserMapping::groupAllowsView
0000s0sFoswiki::UserMapping::::handlesUserFoswiki::UserMapping::handlesUser
0000s0sFoswiki::UserMapping::::isAdminFoswiki::UserMapping::isAdmin
0000s0sFoswiki::UserMapping::::isGroupFoswiki::UserMapping::isGroup
0000s0sFoswiki::UserMapping::::login2cUIDFoswiki::UserMapping::login2cUID
0000s0sFoswiki::UserMapping::::loginTemplateNameFoswiki::UserMapping::loginTemplateName
0000s0sFoswiki::UserMapping::::passwordErrorFoswiki::UserMapping::passwordError
0000s0sFoswiki::UserMapping::::removeUserFoswiki::UserMapping::removeUser
0000s0sFoswiki::UserMapping::::removeUserFromGroupFoswiki::UserMapping::removeUserFromGroup
0000s0sFoswiki::UserMapping::::setEmailsFoswiki::UserMapping::setEmails
0000s0sFoswiki::UserMapping::::setPasswordFoswiki::UserMapping::setPassword
0000s0sFoswiki::UserMapping::::supportsRegistrationFoswiki::UserMapping::supportsRegistration
0000s0sFoswiki::UserMapping::::userExistsFoswiki::UserMapping::userExists
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=begin TML
4
5---+ package Foswiki::UserMapping
6
7This is a virtual base class (a.k.a an interface) for all user mappers. It is
8*not* useable as a mapping in Foswiki - use the BaseUserMapping for default
9behaviour.
10
11User mapping is the process by which Foswiki maps from a username (a login name)
12to a display name and back. It is also where groups are maintained.
13
14See Foswiki::Users::BaseUserMapping and Foswiki::Users::TopicUserMapping for
15the default implementations of this interface.
16
17If you want to write a user mapper, you will need to implement the methods
18described in this class.
19
20User mappings work by mapping both login names and display names to a
21_canonical user id_. This user id is composed from a prefix that defines
22the mapper in use (something like 'BaseUserMapping_' or 'LdapUserMapping_')
23and a unique user id that the mapper uses to identify the user.
24
25The null prefix is reserver for the TopicUserMapping for compatibility
26with old Foswiki releases.
27
28__Note:__ in all the following documentation, =$cUID= refers to a
29*canonical user id*.
30
31=cut
32
33package Foswiki::UserMapping;
34
35249µs241µs
# spent 34µs (26+8) within Foswiki::UserMapping::BEGIN@35 which was called: # once (26µs+8µs) by Foswiki::Users::BaseUserMapping::BEGIN@33 at line 35
use strict;
# spent 34µs making 1 call to Foswiki::UserMapping::BEGIN@35 # spent 8µs making 1 call to strict::import
36242µs252µs
# spent 34µs (16+18) within Foswiki::UserMapping::BEGIN@36 which was called: # once (16µs+18µs) by Foswiki::Users::BaseUserMapping::BEGIN@33 at line 36
use warnings;
# spent 34µs making 1 call to Foswiki::UserMapping::BEGIN@36 # spent 18µs making 1 call to warnings::import
37242µs298µs
# spent 57µs (16+41) within Foswiki::UserMapping::BEGIN@37 which was called: # once (16µs+41µs) by Foswiki::Users::BaseUserMapping::BEGIN@33 at line 37
use Assert;
# spent 57µs making 1 call to Foswiki::UserMapping::BEGIN@37 # spent 41µs making 1 call to Assert::import
3821.40ms19µs
# spent 9µs within Foswiki::UserMapping::BEGIN@38 which was called: # once (9µs+0s) by Foswiki::Users::BaseUserMapping::BEGIN@33 at line 38
use Error ();
# spent 9µs making 1 call to Foswiki::UserMapping::BEGIN@38
39
40=begin TML
41
42---++ PROTECTED ClassMethod new ($session, $mapping_id)
43
44Construct a user mapping object, using the given mapping id.
45
46=cut
47
48
# spent 42µs within Foswiki::UserMapping::new which was called 2 times, avg 21µs/call: # once (23µs+0s) by Foswiki::Users::TopicUserMapping::new at line 59 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Users/TopicUserMapping.pm # once (19µs+0s) by Foswiki::Users::BaseUserMapping::new at line 109 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Users/BaseUserMapping.pm
sub new {
4926µs my ( $class, $session, $mid ) = @_;
50225µs my $this = bless(
51 {
52 mapping_id => $mid || '',
53 session => $session,
54 },
55 $class
56 );
57222µs return $this;
58}
59
60=begin TML
61
62---++ ObjectMethod finish()
63Break circular references.
64
65=cut
66
67
# spent 24µs within Foswiki::UserMapping::finish which was called 2 times, avg 12µs/call: # once (13µs+0s) by Foswiki::Users::BaseUserMapping::finish at line 156 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Users/BaseUserMapping.pm # once (11µs+0s) by Foswiki::Users::TopicUserMapping::finish at line 113 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Users/TopicUserMapping.pm
sub finish {
6824µs my $this = shift;
6928µs undef $this->{mapping_id};
70220µs undef $this->{session};
71}
72
73=begin TML
74
75---++ ObjectMethod loginTemplateName () -> $templateFile
76
77Allows UserMappings to come with customised login screens - that should
78preferably only over-ride the UI function
79
80Default is "login"
81
82=cut
83
84sub loginTemplateName {
85 return 'login';
86}
87
88=begin TML
89
90---++ ObjectMethod supportsRegistration() -> $boolean
91
92Return true if the UserMapper supports registration (ie can create new users)
93
94Default is *false*
95
96=cut
97
98sub supportsRegistration {
99 return 0; # NO, we don't
100}
101
102=begin TML
103
104---++ ObjectMethod handlesUser ( $cUID, $login, $wikiname) -> $boolean
105
106Called by the Foswiki::Users object to determine which loaded mapping
107to use for a given user (must be fast).
108
109The user can be identified by any of $cUID, $login or $wikiname. Any of
110these parameters may be undef, and they should be tested in order; cUID
111first, then login, then wikiname.
112
113=cut
114
115sub handlesUser {
116 return 0;
117}
118
119=begin TML
120
121---++ ObjectMethod login2cUID($login, $dontcheck) -> cUID
122
123Convert a login name to the corresponding canonical user name. The
124canonical name can be any string of 7-bit alphanumeric and underscore
125characters, and must map 1:1 to the login name.
126(undef on failure)
127
128(if $dontcheck is true, return a cUID for a nonexistant user too.
129This is used for registration)
130
131Subclasses *must* implement this method.
132
133Note: This method was previously (in TWiki 4.2.0) known as getCanonicalUserID.
134The name was changed to avoid confusion with Foswiki::Users::getCanonicalUserID,
135which has a more generic function. However to support older user mappers,
136getCanonicalUserID will still be called if login2cUID is not defined.
137
138=cut
139
140sub login2cUID {
141 ASSERT( 0, 'Must be implemented' );
142}
143
144=begin TML
145
146---++ ObjectMethod getLoginName ($cUID) -> login
147
148Converts an internal cUID to that user's login
149(undef on failure)
150
151Subclasses *must* implement this method.
152
153=cut
154
155sub getLoginName {
156 ASSERT(0);
157}
158
159=begin TML
160
161---++ ObjectMethod addUser ($login, $wikiname, $password, $emails) -> $cUID
162
163Add a user to the persistant mapping that maps from usernames to wikinames
164and vice-versa.
165
166$login and $wikiname must be acceptable to $Foswiki::cfg{NameFilter}.
167$login must *always* be specified. $wikiname may be undef, in which case
168the user mapper should make one up.
169
170This function must return a canonical user id that it uses to uniquely
171identify the user. This can be the login name, or the wikiname if they
172are all guaranteed unigue, or some other string consisting only of 7-bit
173alphanumerics and underscores.
174
175If you fail to create a new user (for eg your Mapper has read only access),
176<pre>
177 throw Error::Simple('Failed to add user: '.$error);
178</pre>
179where $error is a descriptive string.
180
181Throws an Error::Simple if user adding is not supported (the default).
182
183=cut
184
185sub addUser {
186 throw Error::Simple('Failed to add user: adding users is not supported');
187}
188
189=begin TML
190
191---++ ObjectMethod removeUser( $cUID ) -> $boolean
192
193Delete the users entry from this mapper. Throws an Error::Simple if
194user removal is not supported (the default).
195
196=cut
197
198sub removeUser {
199 throw Error::Simple('Failed to remove user: user removal is not supported');
200}
201
202=begin TML
203
204---++ ObjectMethod getWikiName ($cUID) -> $wikiname
205
206Map a canonical user name to a wikiname.
207
208Returns the $cUID by default.
209
210=cut
211
212sub getWikiName {
213 my ( $this, $cUID ) = @_;
214 return $cUID;
215}
216
217=begin TML
218
219---++ ObjectMethod userExists($cUID) -> $boolean
220
221Determine if the user already exists or not. Whether a user exists
222or not is determined by the password manager.
223
224Subclasses *must* implement this method.
225
226=cut
227
228sub userExists {
229 ASSERT(0);
230}
231
232=begin TML
233
234---++ ObjectMethod eachUser () -> $iterator
235
236Get an iterator over the list of all cUIDs of the registered
237users *not* including groups.
238
239Subclasses *must* implement this method.
240
241=cut
242
243sub eachUser {
244 ASSERT(0);
245}
246
247=begin TML
248
249---++ ObjectMethod eachGroupMember ($group, $expand) -> $iterator
250
251Return a iterator over the canonical user ids of users that are members
252of this group. Should only be called on groups.
253
254Note that groups may be defined recursively, so a group may contain other
255groups. Unless $expand is set to false, this method should *only* return
256users i.e. all contained groups should be fully expanded.
257
258Subclasses *must* implement this method.
259
260=cut
261
262sub eachGroupMember {
263 ASSERT(0);
264}
265
266=begin TML
267
268---++ ObjectMethod isGroup ($name) -> boolean
269
270Establish if a user refers to a group or not. If $name is not
271a group name it will probably be a canonical user id, though that
272should not be assumed.
273
274Subclasses *must* implement this method.
275
276=cut
277
278sub isGroup {
279 ASSERT(0);
280}
281
282=begin TML
283
284---++ ObjectMethod eachGroup () -> $iterator
285
286Get an iterator over the list of all the group names.
287
288Subclasses *must* implement this method.
289
290=cut
291
292sub eachGroup {
293 ASSERT(0);
294}
295
296=begin TML
297
298---++ ObjectMethod eachMembership($cUID) -> $iterator
299
300Return an iterator over the names of groups that $cUID is a member of.
301
302Subclasses *must* implement this method.
303
304=cut
305
306sub eachMembership {
307 ASSERT(0);
308}
309
310=begin TML
311
312---++ ObjectMethod groupAllowsView($group) -> boolean
313
314returns 1 if the group is able to be viewed by the current logged in user
315
316=cut
317
318sub groupAllowsView {
319 return 1;
320}
321
322=begin TML
323
324---++ ObjectMethod groupAllowsChange($group) -> boolean
325
326returns 1 if the group is able to be modified by the current logged in user
327
328=cut
329
330sub groupAllowsChange {
331 return 0;
332}
333
334=begin TML
335
336---++ ObjectMethod addToGroup( $cuid, $group, $create ) -> $boolean
337adds the user specified by the cuid to the group.
338If the group does not exist, it will return false and do nothing, unless the create flag is set.
339
340=cut
341
342sub addUserToGroup {
343 return 0;
344}
345
346=begin TML
347
348---++ ObjectMethod removeFromGroup( $cuid, $group ) -> $boolean
349
350=cut
351
352sub removeUserFromGroup {
353 return 0;
354}
355
356=begin TML
357
358---++ ObjectMethod isAdmin( $cUID ) -> $boolean
359
360True if the user is an administrator.
361
362=cut
363
364sub isAdmin {
365 return 0;
366}
367
368=begin TML
369
370---++ ObjectMethod isInGroup ($cUID, $group, $options ) -> $bool
371
372
373Test if the user identified by $cUID is in the given group. The default
374implementation iterates over all the members of $group, which is rather
375inefficient. $options is a hash array of options effecting the search.
376Available options are:
377
378 * =expand => 1= 0/1 - should nested groups be expanded when searching for the cUID? Default is 1 - expand nested groups
379
380=cut
381
38211µsmy %scanning;
383
384
# spent 83.9ms (744µs+83.2) within Foswiki::UserMapping::isInGroup which was called 2 times, avg 42.0ms/call: # once (649µs+83.0ms) by Foswiki::Users::TopicUserMapping::isAdmin at line 1135 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Users/TopicUserMapping.pm # once (94µs+113µs) by Foswiki::Users::BaseUserMapping::isAdmin at line 374 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Users/BaseUserMapping.pm
sub isInGroup {
38526µs my ( $this, $cUID, $group, $options ) = @_;
386210µs28µs ASSERT($cUID) if DEBUG;
# spent 8µs making 2 calls to Assert::ASSERTS_OFF, avg 4µs/call
387
38824µs my $expand = $options->{expand};
38923µs $expand = 1 unless ( defined $expand );
390
391 # If not recursively, clear the scanning hash
392228µs if ( ( caller(1) )[3] ne ( caller(0) )[3] ) {
39327µs %scanning = ();
394 }
395
396 #use Carp;
397 #Carp::cluck "Scanning for JoeUser\n" if $cUID eq 'JoeUser';
398 #die "Scanning for JoeUser\n" if $cUID eq 'JoeUser';
399
40025µs my @users;
401226µs281.7ms my $it = $this->eachGroupMember( $group, { expand => $expand } );
# spent 81.6ms making 1 call to Foswiki::Users::TopicUserMapping::eachGroupMember # spent 42µs making 1 call to Foswiki::Users::BaseUserMapping::eachGroupMember
402214µs251µs while ( $it->hasNext() ) {
# spent 51µs making 2 calls to Foswiki::ListIterator::hasNext, avg 25µs/call
40325132µs25553µs my $u = $it->next();
# spent 553µs making 25 calls to Foswiki::ListIterator::next, avg 22µs/call
4042537µs next if $scanning{$u};
4052545µs $scanning{$u} = 1;
406
4072535µs return 1 if $u eq $cUID;
40825276µs50893µs if ( $expand && $this->isGroup($u) ) {
# spent 564µs making 25 calls to Foswiki::ListIterator::hasNext, avg 23µs/call # spent 321µs making 24 calls to Foswiki::Users::TopicUserMapping::isGroup, avg 13µs/call # spent 8µs making 1 call to Foswiki::Users::BaseUserMapping::isGroup
409 return 1 if $this->isInGroup( $cUID, $u );
410 }
411 }
412228µs return 0;
413}
414
415=begin TML
416
417---++ ObjectMethod findUserByEmail( $email ) -> \@users
418 * =$email= - email address to look up
419Return a list of canonical user names for the users that have this email
420registered with the password manager or the user mapping manager.
421
422=cut
423
424sub findUserByEmail {
425 return [];
426}
427
428=begin TML
429
430---++ ObjectMethod getEmails($name) -> @emailAddress
431
432If $name is a cUID, return that user's email addresses. If it is a group,
433return the addresses of everyone in the group.
434
435Duplicates should be removed from the list.
436
437=cut
438
439sub getEmails {
440 return ();
441}
442
443=begin TML
444
445---++ ObjectMethod setEmails($cUID, @emails)
446
447Set the email address(es) for the given user.
448
449=cut
450
451sub setEmails {
452}
453
454=begin TML
455
456---++ ObjectMethod findUserByWikiName ($wikiname) -> list of cUIDs associated with that wikiname
457 * =$wikiname= - wikiname to look up
458Return a list of canonical user names for the users that have this wikiname.
459Since a single wikiname might be used by multiple login ids, we need a list.
460
461Note that if $wikiname is the name of a group, the group will *not* be
462expanded.
463
464Subclasses *must* implement this method.
465
466=cut
467
468sub findUserByWikiName {
469 ASSERT(0);
470}
471
472=begin TML
473
474---++ ObjectMethod checkPassword( $login, $passwordU ) -> $boolean
475
476Finds if the password is valid for the given login. This is called using
477a login name rather than a cUID because the user may not have been mapped
478at the time it is called.
479
480Returns 1 on success, undef on failure.
481
482Default behaviour is to return 1.
483
484=cut
485
486sub checkPassword {
487 return 1;
488}
489
490=begin TML
491
492---++ ObjectMethod setPassword( $cUID, $newPassU, $oldPassU ) -> $boolean
493
494If the $oldPassU matches matches the user's password, then it will
495replace it with $newPassU.
496
497If $oldPassU is not correct and not 1, will return 0.
498
499If $oldPassU is 1, will force the change irrespective of
500the existing password, adding the user if necessary.
501
502Otherwise returns 1 on success, undef on failure.
503
504Default behaviour is to fail.
505
506=cut
507
508sub setPassword {
509 return;
510}
511
512=begin TML
513
514---++ ObjectMethod passwordError( ) -> $string
515
516Returns a string indicating the error that happened in the password handlers
517TODO: these delayed errors should be replaced with Exceptions.
518
519returns undef if no error (the default)
520
521=cut
522
523sub passwordError {
524 return;
525}
526
52715µs1;
528__END__