← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 19:05:14 2015
Reported on Fri Jul 31 19:08:09 2015

Filename/var/www/foswiki11/lib/Foswiki/Users.pm
StatementsExecuted 22724 statements in 37.4ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
9186120.1ms75.2msFoswiki::Users::::_getMappingFoswiki::Users::_getMapping
5332210.3ms33.8msFoswiki::Users::::findUserByWikiNameFoswiki::Users::findUserByWikiName
1067228.75ms9.38msFoswiki::Users::::mapLogin2cUIDFoswiki::Users::mapLogin2cUID
1117.07ms19.3msFoswiki::Users::::newFoswiki::Users::new
381656.94ms98.5msFoswiki::Users::::getCanonicalUserIDFoswiki::Users::getCanonicalUserID
1114.22ms4.42msFoswiki::Users::::BEGIN@64Foswiki::Users::BEGIN@64
325213.65ms310msFoswiki::Users::::isInUserListFoswiki::Users::isInUserList
374112.64ms226msFoswiki::Users::::isGroupFoswiki::Users::isGroup
585552.10ms4.58msFoswiki::Users::::isAdminFoswiki::Users::isAdmin
111414µs829µsFoswiki::Users::::BEGIN@63Foswiki::Users::BEGIN@63
4244175µs250µsFoswiki::Users::::getLoginNameFoswiki::Users::getLoginName
111152µs1.79msFoswiki::Users::::finishFoswiki::Users::finish
111112µs98.2msFoswiki::Users::::initialiseUserFoswiki::Users::initialiseUser
1444100µs136µsFoswiki::Users::::getWikiNameFoswiki::Users::getWikiName
31176µs20.5msFoswiki::Users::::isInGroupFoswiki::Users::isInGroup
52250µs151µsFoswiki::Users::::webDotWikiNameFoswiki::Users::webDotWikiName
101135µs35µsFoswiki::Users::::getLoginManagerFoswiki::Users::getLoginManager
11126µs30µsFoswiki::Users::::getCGISessionFoswiki::Users::getCGISession
11112µs25µsFoswiki::Users::::BEGIN@59Foswiki::Users::BEGIN@59
11112µs14µsFoswiki::Users::::BEGIN@408Foswiki::Users::BEGIN@408
11112µs31µsFoswiki::Users::::BEGIN@313Foswiki::Users::BEGIN@313
11112µs39.0msFoswiki::Users::::loadSessionFoswiki::Users::loadSession
11111µs13µsFoswiki::Users::::BEGIN@406Foswiki::Users::BEGIN@406
11110µs15µsFoswiki::Users::::BEGIN@60Foswiki::Users::BEGIN@60
1118µs20µsFoswiki::Users::::BEGIN@61Foswiki::Users::BEGIN@61
1116µs7µsFoswiki::Users::::supportsRegistrationFoswiki::Users::supportsRegistration
0000s0sFoswiki::Users::::addUserFoswiki::Users::addUser
0000s0sFoswiki::Users::::addUserToGroupFoswiki::Users::addUserToGroup
0000s0sFoswiki::Users::::checkPasswordFoswiki::Users::checkPassword
0000s0sFoswiki::Users::::eachGroupFoswiki::Users::eachGroup
0000s0sFoswiki::Users::::eachGroupMemberFoswiki::Users::eachGroupMember
0000s0sFoswiki::Users::::eachMembershipFoswiki::Users::eachMembership
0000s0sFoswiki::Users::::eachUserFoswiki::Users::eachUser
0000s0sFoswiki::Users::::findUserByEmailFoswiki::Users::findUserByEmail
0000s0sFoswiki::Users::::getEmailsFoswiki::Users::getEmails
0000s0sFoswiki::Users::::groupAllowsChangeFoswiki::Users::groupAllowsChange
0000s0sFoswiki::Users::::groupAllowsViewFoswiki::Users::groupAllowsView
0000s0sFoswiki::Users::::loginTemplateNameFoswiki::Users::loginTemplateName
0000s0sFoswiki::Users::::passwordErrorFoswiki::Users::passwordError
0000s0sFoswiki::Users::::randomPasswordFoswiki::Users::randomPassword
0000s0sFoswiki::Users::::removeUserFoswiki::Users::removeUser
0000s0sFoswiki::Users::::removeUserFromGroupFoswiki::Users::removeUserFromGroup
0000s0sFoswiki::Users::::setEmailsFoswiki::Users::setEmails
0000s0sFoswiki::Users::::setPasswordFoswiki::Users::setPassword
0000s0sFoswiki::Users::::userExistsFoswiki::Users::userExists
0000s0sFoswiki::Users::::validateRegistrationFieldFoswiki::Users::validateRegistrationField
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::Users
6This package provides services for the lookup and manipulation of login and
7wiki names of users, and their authentication.
8
9It is a Facade that presents a common interface to the User Mapping
10and Password modules. The rest of the core should *only* use the methods
11of this package, and should *never* call the mapping or password managers
12directly.
13
14Foswiki uses the concept of a _login name_ which is used to authenticate a
15user. A login name maps to a _wiki name_ that is used to identify the user
16for display. Each login name is unique to a single user, though several
17login names may map to the same wiki name.
18
19Using this module (and the associated plug-in user mapper) Foswiki supports
20the concept of _groups_. Groups are sets of login names that are treated
21equally for the purposes of access control. Group names do not have to be
22wiki names, though it is helpful for display if they are.
23
24Internally in the code Foswiki uses something referred to as a _canonical user
25id_ or just _user id_. The user id is also used externally to uniquely identify
26the user when (for example) recording topic histories. The user id is *usually*
27just the login name, but it doesn't need to be. It just has to be a unique
287-bit alphanumeric and underscore string that can be mapped to/from login
29and wiki names by the user mapper.
30
31The canonical user id should *never* be seen by a user. On the other hand,
32core code should never use anything *but* a canonical user id to refer
33to a user.
34
35*Terminology*
36 * A *login name* is the name used to log in to Foswiki. Each login name is
37 assumed to be unique to a human. The Password module is responsible for
38 authenticating and manipulating login names.
39 * A *canonical user id* is an internal Foswiki representation of a user. Each
40 canonical user id maps 1:1 to a login name.
41 * A *wikiname* is how a user is displayed. Many user ids may map to a
42 single wikiname. The user mapping module is responsible for mapping
43 the user id to a wikiname.
44 * A *group id* represents a group of users and other groups.
45 The user mapping module is responsible for mapping from a group id to
46 a list of canonical user ids for the users in that group.
47 * An *email* is an email address asscoiated with a *login name*. A single
48 login name may have many emails.
49
50*NOTE:*
51 * wherever the code references $cUID, its a canonical_id
52 * wherever the code references $group, its a group_name
53 * $name may be a group or a cUID
54
55=cut
56
57package Foswiki::Users;
58
59224µs238µs
# spent 25µs (12+13) within Foswiki::Users::BEGIN@59 which was called: # once (12µs+13µs) by Foswiki::BEGIN@636 at line 59
use strict;
# spent 25µs making 1 call to Foswiki::Users::BEGIN@59 # spent 13µs making 1 call to strict::import
60226µs220µs
# spent 15µs (10+5) within Foswiki::Users::BEGIN@60 which was called: # once (10µs+5µs) by Foswiki::BEGIN@636 at line 60
use warnings;
# spent 15µs making 1 call to Foswiki::Users::BEGIN@60 # spent 5µs making 1 call to warnings::import
61228µs232µs
# spent 20µs (8+12) within Foswiki::Users::BEGIN@61 which was called: # once (8µs+12µs) by Foswiki::BEGIN@636 at line 61
use Assert;
# spent 20µs making 1 call to Foswiki::Users::BEGIN@61 # spent 12µs making 1 call to Assert::import
62
63294µs1829µs
# spent 829µs (414+416) within Foswiki::Users::BEGIN@63 which was called: # once (414µs+416µs) by Foswiki::BEGIN@636 at line 63
use Foswiki::AggregateIterator ();
# spent 829µs making 1 call to Foswiki::Users::BEGIN@63
642771µs14.42ms
# spent 4.42ms (4.22+202µs) within Foswiki::Users::BEGIN@64 which was called: # once (4.22ms+202µs) by Foswiki::BEGIN@636 at line 64
use Foswiki::LoginManager ();
# spent 4.42ms making 1 call to Foswiki::Users::BEGIN@64
65
66#use Monitor;
67#Monitor::MonitorMethod('Foswiki::Users');
68
69=begin TML
70
71---++ ClassMethod new ($session)
72Construct the user management object that is the facade to the BaseUserMapping
73and the user mapping chosen in the configuration.
74
75=cut
76
77
# spent 19.3ms (7.07+12.3) within Foswiki::Users::new which was called: # once (7.07ms+12.3ms) by Foswiki::new at line 1762 of /var/www/foswiki11/lib/Foswiki.pm
sub new {
7811µs my ( $class, $session ) = @_;
7916µs my $this = bless( { session => $session }, $class );
80
81 # Do a dynamic 'use locale' for this module
8211µs if ( $Foswiki::cfg{UseLocale} ) {
831600ns require locale;
8413µs14µs import locale();
# spent 4µs making 1 call to locale::import
85 }
86
87 # making basemapping
8812µs my $implBaseUserMappingManager = $Foswiki::cfg{BaseUserMappingManager}
89 || 'Foswiki::Users::BaseUserMapping';
90120µs eval "require $implBaseUserMappingManager";
# spent 76µs executing statements in string eval
911400ns die $@ if $@;
9217µs174µs $this->{basemapping} = $implBaseUserMappingManager->new($session);
# spent 74µs making 1 call to Foswiki::Users::BaseUserMapping::new
93
9412µs my $implUserMappingManager = $Foswiki::cfg{UserMappingManager};
951500ns $implUserMappingManager = 'Foswiki::Users::TopicUserMapping'
96 if ( $implUserMappingManager eq 'none' );
97
9811µs if ( $implUserMappingManager eq 'Foswiki::Users::BaseUserMapping' ) {
99 $this->{mapping} = $this->{basemapping}; #TODO: probly make undef..
100 }
101 else {
102121µs eval "require $implUserMappingManager";
# spent 82µs executing statements in string eval
1031600ns die $@ if $@;
10417µs1651µs $this->{mapping} = $implUserMappingManager->new($session);
# spent 651µs making 1 call to Foswiki::Users::TopicUserMapping::new
105 }
106
10713µs1812µs $this->{loginManager} = Foswiki::LoginManager::makeLoginManager($session);
# spent 812µs making 1 call to Foswiki::LoginManager::makeLoginManager
108
109 # caches - not only used for speedup, but also for authenticated but
110 # unregistered users
111 # SMELL: this is basically a user object, something we had previously
112 # but dropped for efficiency reasons
1131700ns $this->{cUID2WikiName} = {};
1141900ns $this->{cUID2Login} = {};
1151700ns $this->{isAdmin} = {};
116
117 # the UI for rego supported/not is different from rego temporarily
118 # turned off
11913µs17µs if ( $this->supportsRegistration() ) {
# spent 7µs making 1 call to Foswiki::Users::supportsRegistration
12011µs13µs $session->enterContext('registration_supported');
# spent 3µs making 1 call to Foswiki::enterContext
12112µs12µs $session->enterContext('registration_enabled')
# spent 2µs making 1 call to Foswiki::enterContext
122 if $Foswiki::cfg{Register}{EnableNewUserRegistration};
123 }
124
12514µs return $this;
126}
127
128=begin TML
129
130---++ ObjectMethod loadSession()
131
132Setup the cgi session, from a cookie or the url. this may return
133the login, but even if it does, plugins will get the chance to
134override (in Foswiki.pm)
135
136=cut
137
138
# spent 39.0ms (12µs+39.0) within Foswiki::Users::loadSession which was called: # once (12µs+39.0ms) by Foswiki::new at line 1797 of /var/www/foswiki11/lib/Foswiki.pm
sub loadSession {
13911µs my ( $this, $defaultUser ) = @_;
140
141 # $this is passed in because it will be used to password check
142 # a command-line login. The {remoteUser} in the session will be
143 # whatever was passed in to the new Foswiki() call.
14417µs139.0ms my $remoteUser = $this->{loginManager}->loadSession( $defaultUser, $this );
# spent 39.0ms making 1 call to Foswiki::LoginManager::loadSession
145
14613µs return $remoteUser;
147}
148
149=begin TML
150
151---++ ObjectMethod finish()
152Break circular references.
153
154=cut
155
156# Note to developers; please undef *all* fields in the object explicitly,
157# whether they are references or not. That way this method is "golden
158# documentation" of the live fields in the object.
159
# spent 1.79ms (152µs+1.64) within Foswiki::Users::finish which was called: # once (152µs+1.64ms) by Foswiki::finish at line 2163 of /var/www/foswiki11/lib/Foswiki.pm
sub finish {
1601900ns my $this = shift;
161
162110µs134µs $this->{loginManager}->finish() if $this->{loginManager};
# spent 34µs making 1 call to Foswiki::LoginManager::finish
16316µs152µs $this->{basemapping}->finish() if $this->{basemapping};
# spent 52µs making 1 call to Foswiki::Users::BaseUserMapping::finish
164
16517µs11.56ms $this->{mapping}->finish()
# spent 1.56ms making 1 call to Foswiki::Users::TopicUserMapping::finish
166 if $this->{mapping}
167 && $this->{mapping} ne $this->{basemapping};
168
16916µs undef $this->{loginManager};
17018µs undef $this->{basemapping};
171193µs undef $this->{mapping};
1721700ns undef $this->{session};
17314µs undef $this->{cUID2WikiName};
17412µs undef $this->{cUID2Login};
17513µs undef $this->{wikiName2cUID};
17613µs undef $this->{login2cUID};
17717µs undef $this->{isAdmin};
178
179}
180
181=begin TML
182
183---++ ObjectMethod loginTemplateName () -> templateFile
184
185allows UserMappings to come with customised login screens - that should preffereably only over-ride the UI function
186
187=cut
188
189sub loginTemplateName {
190 my $this = shift;
191
192 #use login.sudo.tmpl for admin logins
193 return $this->{basemapping}->loginTemplateName()
194 if ( $this->{session}->inContext('sudo_login') );
195 return $this->{mapping}->loginTemplateName() || 'login';
196}
197
198# ($cUID, $login, $wikiname, $noFallBack) -> usermapping object
199
# spent 75.2ms (20.1+55.1) within Foswiki::Users::_getMapping which was called 918 times, avg 82µs/call: # 533 times (3.70ms+7.91ms) by Foswiki::Users::findUserByWikiName at line 532, avg 22µs/call # 378 times (16.3ms+47.1ms) by Foswiki::Users::getCanonicalUserID at line 478, avg 168µs/call # 3 times (35µs+23µs) by Foswiki::Users::isInGroup at line 861, avg 19µs/call # 2 times (46µs+37µs) by Foswiki::Users::isAdmin at line 617, avg 42µs/call # once (8µs+6µs) by Foswiki::Users::getWikiName at line 709 # once (8µs+5µs) by Foswiki::Users::getLoginName at line 677
sub _getMapping {
200918624µs my ( $this, $cUID, $login, $wikiname, $noFallBack ) = @_;
201
202918287µs $login = '' unless defined $login;
203918210µs $wikiname = '' unless defined $wikiname;
204
205918864µs $wikiname =~ s/^($Foswiki::cfg{UsersWebName}|%USERSWEB%|%MAINWEB%)\.//;
206
207 # The base user mapper users must always override those defined in
208 # custom mappings, even though that makes it impossible to maintain 100%
209 # compatibility with earlier releases (guest user edits will get saved as
210 # edits by $DEFAULT_USER_CUID).
2119182.09ms9182.80ms return $this->{basemapping}
# spent 2.80ms making 918 calls to Foswiki::Users::BaseUserMapping::handlesUser, avg 3µs/call
212 if ( $this->{basemapping}->handlesUser( $cUID, $login, $wikiname ) );
213
2145951.45ms59552.3ms return $this->{mapping}
# spent 52.3ms making 595 calls to Foswiki::Users::TopicUserMapping::handlesUser, avg 88µs/call
215 if ( $this->{mapping}->handlesUser( $cUID, $login, $wikiname ) );
216
217 # The base mapping and the selected mapping claim not to know about
218 # this user. Use the base mapping unless the caller has explicitly
219 # requested otherwise.
220432265µs return $this->{basemapping} unless ($noFallBack);
221
222377753µs return;
223}
224
225=begin TML
226
227---++ ObjectMethod supportsRegistration () -> boolean
228
229#return 1 if the main UserMapper supports registration (ie can create new users)
230
231=cut
232
233
# spent 7µs (6+900ns) within Foswiki::Users::supportsRegistration which was called: # once (6µs+900ns) by Foswiki::Users::new at line 119
sub supportsRegistration {
2341800ns my ($this) = @_;
23514µs1900ns return $this->{mapping}->supportsRegistration();
236}
237
238=begin TML
239
240---++ ObjectMethod validateRegistrationField ( $field, $value ) -> text
241
242Return the registration formfield sanitized by the mapper, or oops thrown to block the registration.
243
244=cut
245
246sub validateRegistrationField {
247 my ($this) = shift;
248 return $this->{mapping}->validateRegistrationField(@_);
249}
250
251=begin TML
252
253---++ ObjectMethod initialiseUser ($login) -> $cUID
254
255Given a login (which must have been authenticated) determine the cUID that
256corresponds to that user. This method is used from Foswiki.pm to map the
257$REMOTE_USER to a cUID.
258
259=cut
260
261
# spent 98.2ms (112µs+98.1) within Foswiki::Users::initialiseUser which was called: # once (112µs+98.1ms) by Foswiki::new at line 1939 of /var/www/foswiki11/lib/Foswiki.pm
sub initialiseUser {
26212µs my ( $this, $login ) = @_;
263
264 # For compatibility with older ways of building login managers,
265 # plugins can provide an alternate login name.
26618µs197.9ms my $plogin =
# spent 97.9ms making 1 call to Foswiki::Plugins::load
267 $this->{session}->{plugins}->load( $Foswiki::cfg{DisableAllPlugins} );
268
269 #Monitor::MARK("Plugins loaded");
270
27111µs $login = $plogin if $plogin;
272
2731300ns my $cUID;
27412µs if ( defined($login) && $login ne '' ) {
275
276 # In the case of a user mapper that accepts any identifier as
277 # a cUID,
27815µs1160µs $cUID = $this->getCanonicalUserID($login);
# spent 160µs making 1 call to Foswiki::Users::getCanonicalUserID
279
280 # see BugsItem4771 - it seems that authenticated, but unmapped
281 # users have rights too
28211µs if ( !defined($cUID) ) {
283
284 # There is no known canonical user ID for this login name.
285 # Generate a cUID for the login, and add it anyway. There is
286 # a risk that the generated cUID will overlap a cUID generated
287 # by a custom mapper, but since (1) the user has to be
288 # authenticated to get here and (2) the custom user mapper
289 # is specific to the login process used, that risk should be
290 # small (unless the author of the custom mapper screws up)
29114µs110µs $cUID = mapLogin2cUID($login);
# spent 10µs making 1 call to Foswiki::Users::mapLogin2cUID
292
29312µs $this->{cUID2Login}->{$cUID} = $login;
29411µs $this->{cUID2WikiName}->{$cUID} = $login;
295
296 # needs to be WikiName safe
297111µs $this->{cUID2WikiName}->{$cUID} =~ s/$Foswiki::cfg{NameFilter}//go;
29812µs $this->{cUID2WikiName}->{$cUID} =~ s/\.//go;
299
30011µs $this->{login2cUID}->{$login} = $cUID;
30112µs $this->{wikiName2cUID}->{ $this->{cUID2WikiName}->{$cUID} } = $cUID;
302 }
303 }
304
305 # if we get here without a login id, we are a guest. Get the guest
306 # cUID.
3071100ns $cUID ||= $this->getCanonicalUserID( $Foswiki::cfg{DefaultUserLogin} );
308
30914µs return $cUID;
310}
311
312# global used by test harness to give predictable results
3132241µs250µs
# spent 31µs (12+19) within Foswiki::Users::BEGIN@313 which was called: # once (12µs+19µs) by Foswiki::BEGIN@636 at line 313
use vars qw( $password );
# spent 31µs making 1 call to Foswiki::Users::BEGIN@313 # spent 19µs making 1 call to vars::import
314
315=begin TML
316
317---++ randomPassword()
318Static function that returns a random password. This function is not used
319in this module; it is provided as a service for other modules, such as
320custom mappers and registration modules.
321
322=cut
323
324sub randomPassword {
325
326 my $pwlen =
327 ( $Foswiki::cfg{MinPasswordLength} > 8 )
328 ? $Foswiki::cfg{MinPasswordLength}
329 : 8;
330 my @chars = ( 'a' .. 'z', 'A' .. 'Z', 0 .. 9, '_', '.', '/' );
331 my $newpw;
332
333 foreach ( 1 .. $pwlen ) {
334 $newpw .= $chars[ rand @chars ];
335 }
336 return $newpw;
337
338}
339
340=begin TML
341
342---++ ObjectMethod addUser($login, $wikiname, $password, $emails) -> $cUID
343
344 * =$login= - user login name. If =undef=, =$wikiname= will be used as
345 the login name.
346 * =$wikiname= - user wikiname. If =undef=, the user mapper will be asked
347 to provide it.
348 * =$password= - password. If undef, a password will be generated.
349
350Add a new Foswiki user identity, returning the canonical user id for the new
351user. Used ONLY for user registration.
352
353The user is added to the password system (if there is one, and if it accepts
354changes). If the user already exists in the password system, then the password
355is checked and an exception thrown if it doesn't match. If there is no
356existing user, and no password is given, a random password is generated.
357
358$login can be undef; $wikiname must always have a value.
359
360The return value is the canonical user id that is used
361by Foswiki to identify the user.
362
363=cut
364
365sub addUser {
366 my ( $this, $login, $wikiname, $password, $emails ) = @_;
367 my $removeOnFail = 0;
368
369 ASSERT( $login || $wikiname ) if DEBUG; # must have at least one
370
371 # create a new user and get the canonical user ID from the user mapping
372 # manager.
373 my $cUID =
374 $this->{mapping}->addUser( $login, $wikiname, $password, $emails );
375
376 # update the cached values
377 $this->{cUID2Login}->{$cUID} = $login;
378 $this->{cUID2WikiName}->{$cUID} = $wikiname;
379
380 $this->{login2cUID}->{$login} = $cUID;
381 $this->{wikiName2cUID}->{$wikiname} = $cUID;
382
383 return $cUID;
384}
385
386=begin TML
387
388---++ StaticMethod mapLogin2cUID( $login ) -> $cUID
389
390This function maps an arbitrary string into a valid cUID. The transformation
391is reversible, but the function is not idempotent (a cUID passed to this
392function will NOT be returned unchanged). The generated cUID will be unique
393for the given login name.
394
395This static function is designed to be called from custom user mappers that
396support 1:1 login-to-cUID mappings.
397
398=cut
399
400
# spent 9.38ms (8.75+635µs) within Foswiki::Users::mapLogin2cUID which was called 1067 times, avg 9µs/call: # 1066 times (8.74ms+634µs) by Foswiki::Users::TopicUserMapping::login2cUID at line 189 of /var/www/foswiki11/lib/Foswiki/Users/TopicUserMapping.pm, avg 9µs/call # once (9µs+700ns) by Foswiki::Users::initialiseUser at line 291
sub mapLogin2cUID {
4011067224µs my $cUID = shift;
402
4031067736µs1067635µs ASSERT( defined($cUID) ) if DEBUG;
# spent 635µs making 1067 calls to Assert::ASSERTS_OFF, avg 595ns/call
404
405 # use bytes to ignore character encoding
406252µs215µs
# spent 13µs (11+2) within Foswiki::Users::BEGIN@406 which was called: # once (11µs+2µs) by Foswiki::BEGIN@636 at line 406
use bytes;
# spent 13µs making 1 call to Foswiki::Users::BEGIN@406 # spent 2µs making 1 call to bytes::import
4071067574µs $cUID =~ s/([^a-zA-Z0-9])/'_'.sprintf('%02x', ord($1))/ge;
40821.56ms217µs
# spent 14µs (12+2) within Foswiki::Users::BEGIN@408 which was called: # once (12µs+2µs) by Foswiki::BEGIN@636 at line 408
no bytes;
# spent 14µs making 1 call to Foswiki::Users::BEGIN@408 # spent 2µs making 1 call to bytes::unimport
40910672.11ms return $cUID;
410}
411
412=begin TML
413
414---++ ObjectMethod getCGISession()
415Get the currect CGI session object
416
417=cut
418
419
# spent 30µs (26+4) within Foswiki::Users::getCGISession which was called: # once (26µs+4µs) by Foswiki::getCGISession at line 1276 of /var/www/foswiki11/lib/Foswiki.pm
sub getCGISession {
4201700ns my $this = shift;
421126µs14µs return $this->{loginManager}->getCGISession();
# spent 4µs making 1 call to Foswiki::LoginManager::getCGISession
422}
423
424=begin TML
425
426---++ ObjectMethod getLoginManager() -> $loginManager
427
428Get the Foswiki::LoginManager object associated with this session, if there is
429one. May return undef.
430
431=cut
432
433
# spent 35µs within Foswiki::Users::getLoginManager which was called 10 times, avg 4µs/call: # 10 times (35µs+0s) by Foswiki::getLoginManager at line 1289 of /var/www/foswiki11/lib/Foswiki.pm, avg 4µs/call
sub getLoginManager {
434105µs my $this = shift;
4351044µs return $this->{loginManager};
436}
437
438=begin TML
439
440---++ ObjectMethod getCanonicalUserID( $identifier ) -> $cUID
441
442Works out the Foswiki canonical user identifier for the user who either
443(1) logs in with the login name $identifier or (2) has the wikiname
444$identifier.
445
446The canonical user ID is an alphanumeric string that is unique
447to the login name, and can be mapped back to a login name and the
448corresponding wiki name using the methods of this class.
449
450Note that if the login name to wiki name mapping is not 1:1, this
451method will map a wikiname to one of the login names that corresponds
452to the wiki name, but there is no guarantee which one.
453
454Returns undef if the user does not exist.
455
456=cut
457
458# This function was previously known as forceCUID. It differs from that
459# implementation in that it does *not* accept a CUID as parameter, which
460# if why it has been renamed.
461
# spent 98.5ms (6.94+91.6) within Foswiki::Users::getCanonicalUserID which was called 381 times, avg 259µs/call: # 374 times (6.83ms+52.5ms) by Foswiki::Users::isInUserList at line 648, avg 159µs/call # 3 times (39µs+56µs) by Foswiki::Render::renderRevisionInfo at line 1758 of /var/www/foswiki11/lib/Foswiki/Render.pm, avg 32µs/call # once (26µs+38.8ms) by Foswiki::LoginManager::userLoggedIn at line 695 of /var/www/foswiki11/lib/Foswiki/LoginManager.pm # once (25µs+135µs) by Foswiki::Users::initialiseUser at line 278 # once (13µs+57µs) by Foswiki::Users::TopicUserMapping::_expandUserList at line 1754 of /var/www/foswiki11/lib/Foswiki/Users/TopicUserMapping.pm # once (10µs+800ns) by Foswiki::Func::getCanonicalUserID at line 902 of /var/www/foswiki11/lib/Foswiki/Func.pm
sub getCanonicalUserID {
462381217µs my ( $this, $identifier ) = @_;
46338157µs my $cUID;
464
465381444µs381422µs ASSERT( defined $identifier ) if DEBUG;
# spent 422µs making 381 calls to Assert::ASSERTS_OFF, avg 1µs/call
466
467 # Someone we already know?
468
469381497µs if ( defined( $this->{login2cUID}->{$identifier} ) ) {
470 $cUID = $this->{login2cUID}->{$identifier};
471 }
472 elsif ( defined( $this->{wikiName2cUID}->{$identifier} ) ) {
473 $cUID = $this->{wikiName2cUID}->{$identifier};
474 }
475 else {
476
477 # See if a mapping recognises the identifier as a login name
478378707µs37863.4ms my $mapping = $this->_getMapping( undef, $identifier, undef, 1 );
# spent 63.4ms making 378 calls to Foswiki::Users::_getMapping, avg 168µs/call
47937875µs if ($mapping) {
480119µs230µs if ( $mapping->can('login2cUID') ) {
# spent 28µs making 1 call to Foswiki::Users::TopicUserMapping::login2cUID # spent 2µs making 1 call to UNIVERSAL::can
481 $cUID = $mapping->login2cUID($identifier);
482 }
483 elsif ( $mapping->can('getCanonicalUserID') ) {
484
485 # Old name of login2cUID. Name changed to avoid confusion
486 # with Foswiki::Users::getCanonicalUserID. See
487 # Codev.UserMapperChangesBetween420And421 for more.
488 $cUID = $mapping->getCanonicalUserID($identifier);
489 }
490 else {
491 die(
492"Broken user mapping $mapping; does not implement login2cUID"
493 );
494 }
495 }
496
497378168µs unless ($cUID) {
498
499 # Finally see if it's a valid user wikiname
500
501 # Strip users web id (legacy, probably specific to
502 # TopicUserMappingContrib but may be used by other mappers
503 # that support user topics)
5043771.10ms3774.22ms my ( $dummy, $nid ) =
# spent 4.22ms making 377 calls to Foswiki::normalizeWebTopicName, avg 11µs/call
505 $this->{session}->normalizeWebTopicName( '', $identifier );
506377292µs $identifier = $nid if ( $dummy eq $Foswiki::cfg{UsersWebName} );
507
508377645µs37723.5ms my $found = $this->findUserByWikiName($identifier);
# spent 23.5ms making 377 calls to Foswiki::Users::findUserByWikiName, avg 62µs/call
509377573µs $cUID = $found->[0] if ( $found && scalar(@$found) );
510 }
511 }
5123811.04ms return $cUID;
513}
514
515=begin TML
516
517---++ ObjectMethod findUserByWikiName( $wn ) -> \@users
518 * =$wn= - wikiname to look up
519Return a list of canonical user names for the users that have this wikiname.
520Since a single wikiname might be used by multiple login ids, we need a list.
521
522If $wn is the name of a group, the group will *not* be expanded.
523
524=cut
525
526
# spent 33.8ms (10.3+23.5) within Foswiki::Users::findUserByWikiName which was called 533 times, avg 63µs/call: # 377 times (9.14ms+14.4ms) by Foswiki::Users::getCanonicalUserID at line 508, avg 62µs/call # 156 times (1.18ms+9.07ms) by Foswiki::Users::TopicUserMapping::_expandUserList at line 1747 of /var/www/foswiki11/lib/Foswiki/Users/TopicUserMapping.pm, avg 66µs/call
sub findUserByWikiName {
527533275µs my ( $this, $wn ) = @_;
528533450µs533394µs ASSERT($wn) if DEBUG;
# spent 394µs making 533 calls to Assert::ASSERTS_OFF, avg 740ns/call
529
530 # Trim the (pointless) userweb, if present
531533659µs $wn =~ s/^($Foswiki::cfg{UsersWebName}|%USERSWEB%|%MAINWEB%)\.//;
532533790µs53311.6ms my $mapping = $this->_getMapping( undef, undef, $wn );
# spent 11.6ms making 533 calls to Foswiki::Users::_getMapping, avg 22µs/call
533
534 #my $mapping = $this->_getMapping( $wn, $wn, $wn ); # why not?
5355331.78ms53311.4ms return $mapping->findUserByWikiName($wn);
# spent 9.79ms making 378 calls to Foswiki::Users::BaseUserMapping::findUserByWikiName, avg 26µs/call # spent 1.66ms making 155 calls to Foswiki::Users::TopicUserMapping::findUserByWikiName, avg 11µs/call
536}
537
538=begin TML
539
540---++ ObjectMethod findUserByEmail( $email ) -> \@users
541 * =$email= - email address to look up
542Return a list of canonical user names for the users that have this email
543registered with the user mapping managers.
544
545=cut
546
547sub findUserByEmail {
548 my ( $this, $email ) = @_;
549 ASSERT($email) if DEBUG;
550
551 my $users = $this->{mapping}->findUserByEmail($email);
552 push @{$users}, @{ $this->{basemapping}->findUserByEmail($email) };
553
554 return $users;
555}
556
557=begin TML
558
559---++ ObjectMethod getEmails($name) -> @emailAddress
560
561If $name is a cUID, return their email addresses. If it is a group,
562return the addresses of everyone in the group.
563
564The password manager and user mapping manager are both consulted for emails
565for each user (where they are actually found is implementation defined).
566
567Duplicates are removed from the list.
568
569=cut
570
571sub getEmails {
572 my ( $this, $name ) = @_;
573
574 return () unless ($name);
575 if ( $this->{mapping}->isGroup($name) ) {
576 return $this->{mapping}->getEmails($name);
577 }
578
579 return $this->_getMapping($name)->getEmails($name);
580}
581
582=begin TML
583
584---++ ObjectMethod setEmails($cUID, @emails)
585
586Set the email address(es) for the given user.
587The password manager is tried first, and if it doesn't want to know the
588user mapping manager is tried.
589
590=cut
591
592sub setEmails {
593 my $this = shift;
594 my $cUID = shift;
595 my @emails = @_;
596 return $this->_getMapping($cUID)->setEmails( $cUID, @emails );
597}
598
599=begin TML
600
601---++ ObjectMethod isAdmin( $cUID ) -> $boolean
602
603True if the user is an admin
604 * is $Foswiki::cfg{SuperAdminGroup}
605 * is a member of the $Foswiki::cfg{SuperAdminGroup}
606
607=cut
608
609
# spent 4.58ms (2.10+2.48) within Foswiki::Users::isAdmin which was called 585 times, avg 8µs/call: # 409 times (1.06ms+0s) by Foswiki::Meta::haveAccess at line 1747 of /var/www/foswiki11/lib/Foswiki/Meta.pm, avg 3µs/call # 94 times (520µs+0s) by Foswiki::WebFilter::ok at line 42 of /var/www/foswiki11/lib/Foswiki/WebFilter.pm, avg 6µs/call # 41 times (386µs+27µs) by Foswiki::Store::QueryAlgorithms::BruteForce::query at line 53 of /var/www/foswiki11/lib/Foswiki/Store/QueryAlgorithms/BruteForce.pm, avg 10µs/call # 40 times (94µs+0s) by Foswiki::Store::SearchAlgorithms::Forking::query at line 158 of /var/www/foswiki11/lib/Foswiki/Store/SearchAlgorithms/Forking.pm, avg 2µs/call # once (40µs+2.45ms) by Foswiki::new at line 1971 of /var/www/foswiki11/lib/Foswiki.pm
sub isAdmin {
610585407µs my ( $this, $cUID ) = @_;
611
612585127µs return 0 unless defined $cUID;
613
6145851.98ms return $this->{isAdmin}->{$cUID}
615 if ( defined( $this->{isAdmin}->{$cUID} ) );
616
617210µs283µs my $mapping = $this->_getMapping($cUID);
# spent 83µs making 2 calls to Foswiki::Users::_getMapping, avg 42µs/call
61826µs my $otherMapping =
619 ( $mapping eq $this->{basemapping} )
620 ? $this->{mapping}
621 : $this->{basemapping};
622
62322µs if ( $mapping eq $otherMapping ) {
624 return $mapping->isAdmin($cUID);
625 }
626220µs32.39ms $this->{isAdmin}->{$cUID} =
# spent 2.27ms making 2 calls to Foswiki::Users::TopicUserMapping::isAdmin, avg 1.14ms/call # spent 122µs making 1 call to Foswiki::Users::BaseUserMapping::isAdmin
627 ( $mapping->isAdmin($cUID) || $otherMapping->isAdmin($cUID) );
628212µs return $this->{isAdmin}->{$cUID};
629}
630
631=begin TML
632
633---++ ObjectMethod isInUserList( $cUID, \@list ) -> $boolean
634
635Return true if $cUID is in a list of user *wikinames*, *logins* and group ids.
636
637The list may contain the conventional web specifiers (which are ignored).
638
639=cut
640
641
# spent 310ms (3.65+306) within Foswiki::Users::isInUserList which was called 325 times, avg 953µs/call: # 322 times (3.61ms+63.5ms) by Foswiki::Meta::haveAccess at line 1797 of /var/www/foswiki11/lib/Foswiki/Meta.pm, avg 208µs/call # 3 times (44µs+243ms) by Foswiki::Meta::haveAccess at line 1811 of /var/www/foswiki11/lib/Foswiki/Meta.pm, avg 80.9ms/call
sub isInUserList {
642325206µs my ( $this, $cUID, $userlist ) = @_;
643
64432585µs return 0 unless defined $userlist && defined $cUID;
645
646325311µs foreach my $ident (@$userlist) {
647
648374644µs37459.3ms my $identCUID = $this->getCanonicalUserID($ident);
# spent 59.3ms making 374 calls to Foswiki::Users::getCanonicalUserID, avg 159µs/call
649
650374147µs if ( defined $identCUID ) {
651 return 1 if ( $identCUID eq $cUID );
652 }
6533741.08ms377247ms if ( $this->isGroup($ident) ) {
# spent 226ms making 374 calls to Foswiki::Users::isGroup, avg 605µs/call # spent 20.5ms making 3 calls to Foswiki::Users::isInGroup, avg 6.84ms/call
654 return 1 if ( $this->isInGroup( $cUID, $ident ) );
655 }
656 }
6573256.76ms return 0;
658}
659
660=begin TML
661
662---++ ObjectMethod getLoginName($cUID) -> $login
663
664Get the login name of a user. Returns undef if the user is not known.
665
666=cut
667
668
# spent 250µs (175+75) within Foswiki::Users::getLoginName which was called 42 times, avg 6µs/call: # 36 times (123µs+0s) by Foswiki::Plugin::__ANON__[/var/www/foswiki11/lib/Foswiki/Plugin.pm:241] at line 234 of /var/www/foswiki11/lib/Foswiki/Plugin.pm, avg 3µs/call # 3 times (29µs+75µs) by Foswiki::Render::renderRevisionInfo at line 1772 of /var/www/foswiki11/lib/Foswiki/Render.pm, avg 35µs/call # 2 times (13µs+0s) by Foswiki::__ANON__[/var/www/foswiki11/lib/Foswiki/Macros/USERINFO.pm:20] at line 16 of /var/www/foswiki11/lib/Foswiki/Macros/USERINFO.pm, avg 6µs/call # once (10µs+0s) by Foswiki::logEvent at line 2249 of /var/www/foswiki11/lib/Foswiki.pm
sub getLoginName {
6694228µs my ( $this, $cUID ) = @_;
670
6714212µs return unless defined($cUID);
672
67342190µs return $this->{cUID2Login}->{$cUID}
674 if ( defined( $this->{cUID2Login}->{$cUID} ) );
675
67612µs11µs ASSERT( $this->{basemapping} );
# spent 1µs making 1 call to Assert::dummyASSERT
67712µs113µs my $mapping = $this->_getMapping($cUID);
# spent 13µs making 1 call to Foswiki::Users::_getMapping
6781400ns my $login;
67913µs161µs if ( $cUID && $mapping ) {
# spent 61µs making 1 call to Foswiki::Users::TopicUserMapping::getLoginName
680 $login = $mapping->getLoginName($cUID);
681 }
682
68311µs if ( defined $login ) {
68412µs $this->{cUID2Login}->{$cUID} = $login;
68512µs $this->{login2cUID}->{$login} = $cUID;
686 }
687
68814µs return $login;
689}
690
691=begin TML
692
693---++ ObjectMethod getWikiName($cUID) -> $wikiName
694
695Get the wikiname to display for a canonical user identifier.
696
697Can return undef if the user is not in the mapping system
698(or the special case from initialiseUser)
699
700=cut
701
702
# spent 136µs (100+36) within Foswiki::Users::getWikiName which was called 14 times, avg 10µs/call: # 5 times (65µs+36µs) by Foswiki::Users::webDotWikiName at line 744, avg 20µs/call # 5 times (19µs+0s) by Foswiki::__ANON__[/var/www/foswiki11/lib/Foswiki/Macros/USERINFO.pm:36] at line 31 of /var/www/foswiki11/lib/Foswiki/Macros/USERINFO.pm, avg 4µs/call # 3 times (7µs+0s) by Foswiki::Render::renderRevisionInfo at line 1771 of /var/www/foswiki11/lib/Foswiki/Render.pm, avg 2µs/call # once (9µs+0s) by Foswiki::new at line 1962 of /var/www/foswiki11/lib/Foswiki.pm
sub getWikiName {
7031412µs my ( $this, $cUID ) = @_;
704144µs return 'UnknownUser' unless defined($cUID);
7051472µs return $this->{cUID2WikiName}->{$cUID}
706 if ( defined( $this->{cUID2WikiName}->{$cUID} ) );
707
7081300ns my $wikiname;
70911µs114µs my $mapping = $this->_getMapping($cUID);
# spent 14µs making 1 call to Foswiki::Users::_getMapping
71014µs122µs $wikiname = $mapping->getWikiName($cUID) if $mapping;
# spent 22µs making 1 call to Foswiki::Users::TopicUserMapping::getWikiName
711
712 #don't cache unknown users - it really makes a mess later.
71311µs if ( !defined($wikiname) ) {
714 if ( $Foswiki::cfg{RenderLoggedInButUnknownUsers} ) {
715 $wikiname = "UnknownUser (<nop>$cUID)";
716 }
717 else {
718 $wikiname = $cUID;
719 }
720 }
721 else {
722
723 # remove the web part
724 # SMELL: is this really needed?
725125µs $wikiname =~ s/^($Foswiki::cfg{UsersWebName}|%MAINWEB%|%USERSWEB%)\.//;
726
72713µs $this->{cUID2WikiName}->{$cUID} = $wikiname;
72812µs $this->{wikiName2cUID}->{$wikiname} = $cUID;
729 }
73015µs return $wikiname;
731}
732
733=begin TML
734
735---++ ObjectMethod webDotWikiName($cUID) -> $webDotWiki
736
737Return the fully qualified wikiname of the user
738
739=cut
740
741
# spent 151µs (50+101) within Foswiki::Users::webDotWikiName which was called 5 times, avg 30µs/call: # 3 times (23µs+90µs) by Foswiki::Render::renderRevisionInfo at line 1770 of /var/www/foswiki11/lib/Foswiki/Render.pm, avg 38µs/call # 2 times (27µs+11µs) by Foswiki::__ANON__[/var/www/foswiki11/lib/Foswiki/Macros/USERINFO.pm:45] at line 39 of /var/www/foswiki11/lib/Foswiki/Macros/USERINFO.pm, avg 19µs/call
sub webDotWikiName {
74256µs my ( $this, $cUID ) = @_;
743
744542µs5101µs return $Foswiki::cfg{UsersWebName} . '.' . $this->getWikiName($cUID);
# spent 101µs making 5 calls to Foswiki::Users::getWikiName, avg 20µs/call
745}
746
747=begin TML
748
749---++ ObjectMethod userExists($cUID) -> $boolean
750
751Determine if the user already exists or not. A user exists if they are
752known to to the user mapper.
753
754=cut
755
756sub userExists {
757 my ( $this, $cUID ) = @_;
758 return $this->_getMapping($cUID)->userExists($cUID);
759}
760
761=begin TML
762
763---++ ObjectMethod eachUser() -> Foswiki::Iterator of cUIDs
764
765Get an iterator over the list of all the registered users *not* including
766groups.
767
768list of canonical_ids ???
769
770Use it as follows:
771<verbatim>
772 my $iterator = $umm->eachUser();
773 while ($iterator->hasNext()) {
774 my $user = $iterator->next();
775 ...
776 }
777</verbatim>
778
779=cut
780
781sub eachUser {
782 my $this = shift;
783 my @list =
784 ( $this->{basemapping}->eachUser(@_), $this->{mapping}->eachUser(@_) );
785 return new Foswiki::AggregateIterator( \@list, 1 );
786
787 return shift->{mapping}->eachUser(@_);
788}
789
790=begin TML
791
792---++ ObjectMethod eachGroup() -> $iterator
793
794Get an iterator over the list of all the group names.
795
796=cut
797
798sub eachGroup {
799 my $this = shift;
800 my @list =
801 ( $this->{basemapping}->eachGroup(@_), $this->{mapping}->eachGroup(@_) );
802 return new Foswiki::AggregateIterator( \@list, 1 );
803}
804
805=begin TML
806
807---++ ObjectMethod eachGroupMember($group) -> $iterator
808
809Return a iterator of user ids that are members of this group.
810Should only be called on groups.
811
812Note that groups may be defined recursively, so a group may contain other
813groups. This method should *only* return users i.e. all contained groups
814should be fully expanded.
815
816=cut
817
818sub eachGroupMember {
819 my $this = shift;
820 my @list = (
821 $this->{basemapping}->eachGroupMember(@_),
822 $this->{mapping}->eachGroupMember(@_)
823 );
824 return new Foswiki::AggregateIterator( \@list, 1 );
825}
826
827=begin TML
828
829---++ ObjectMethod isGroup($name) -> boolean
830
831Establish if a $name refers to a group or not. If $name is not
832a group name it will probably be a canonical user id, though that
833should not be assumed.
834
835=cut
836
837
# spent 226ms (2.64+224) within Foswiki::Users::isGroup which was called 374 times, avg 605µs/call: # 374 times (2.64ms+224ms) by Foswiki::Users::isInUserList at line 653, avg 605µs/call
sub isGroup {
838374108µs my $this = shift;
8393741.86ms748224ms return ( $this->{basemapping}->isGroup(@_) )
# spent 223ms making 374 calls to Foswiki::Users::TopicUserMapping::isGroup, avg 596µs/call # spent 629µs making 374 calls to Foswiki::Users::BaseUserMapping::isGroup, avg 2µs/call
840 || ( $this->{mapping}->isGroup(@_) );
841}
842
843=begin TML
844
845---++ ObjectMethod isInGroup( $cUID, $group, $options) -> $boolean
846
847Test if the user identified by $cUID is in the given group. Options
848is a hash array of options effecting the search. Available options are:
849
850 * =expand => 1= 0/1 - should nested groups be expanded when searching for the user. Default is 1, to expand nested groups.
851
852=cut
853
854
# spent 20.5ms (76µs+20.4) within Foswiki::Users::isInGroup which was called 3 times, avg 6.84ms/call: # 3 times (76µs+20.4ms) by Foswiki::Users::isInUserList at line 653, avg 6.84ms/call
sub isInGroup {
85534µs my ( $this, $cUID, $group, $options ) = @_;
8563700ns return unless ( defined($cUID) );
857
85832µs my $expand = $options->{expand};
85931µs $expand = 1 unless ( defined $expand );
860
86135µs358µs my $mapping = $this->_getMapping($cUID);
# spent 58µs making 3 calls to Foswiki::Users::_getMapping, avg 19µs/call
86236µs my $otherMapping =
863 ( $mapping eq $this->{basemapping} )
864 ? $this->{mapping}
865 : $this->{basemapping};
866319µs320.2ms return 1 if $mapping->isInGroup( $cUID, $group, { expand => $expand } );
# spent 20.2ms making 3 calls to Foswiki::UserMapping::isInGroup, avg 6.74ms/call
867
868326µs3154µs return $otherMapping->isInGroup( $cUID, $group, { expand => $expand } )
# spent 154µs making 3 calls to Foswiki::UserMapping::isInGroup, avg 51µs/call
869 if ( $otherMapping ne $mapping );
870}
871
872=begin TML
873
874---++ ObjectMethod eachMembership($cUID) -> $iterator
875
876Return an iterator over the groups that $cUID
877is a member of.
878
879=cut
880
881sub eachMembership {
882 my ( $this, $cUID ) = @_;
883
884 my $mapping = $this->_getMapping($cUID);
885 my $wikiname = $mapping->getWikiName($cUID);
886
887 #stop if the user has no wikiname (generally means BugsItem4771)
888 unless ( defined($wikiname) ) {
889 require Foswiki::ListIterator;
890 return new Foswiki::ListIterator( \() );
891 }
892
893 my $otherMapping =
894 ( $mapping eq $this->{basemapping} )
895 ? $this->{mapping}
896 : $this->{basemapping};
897 if ( $mapping eq $otherMapping ) {
898
899 # only using BaseMapping.
900 return $mapping->eachMembership($cUID);
901 }
902
903 my @list =
904 ( $mapping->eachMembership($cUID), $otherMapping->eachMembership($cUID) );
905 return new Foswiki::AggregateIterator( \@list, 1 );
906}
907
908=begin TML
909
910---++ ObjectMethod groupAllowsView($group) -> boolean
911
912returns 1 if the group is able to be modified by the current logged in user
913
914=cut
915
916sub groupAllowsView {
917 my $this = shift;
918 my $group = shift;
919 my $mapping = $this->{mapping};
920 return $mapping->groupAllowsView($group);
921}
922
923=begin TML
924
925---++ ObjectMethod groupAllowsChange($group, $cuid) -> boolean
926
927returns 1 if the group is able to be modified by the current logged in user
928
929=cut
930
931sub groupAllowsChange {
932 my $this = shift;
933 my $group = shift;
934 my $cuid = shift || $this->{session}->{user};
935
936 return ( $this->{basemapping}->groupAllowsChange( $group, $cuid )
937 and $this->{mapping}->groupAllowsChange( $group, $cuid ) );
938}
939
940=begin TML
941
942---++ ObjectMethod addToGroup( $cuid, $group, $create ) -> $boolean
943adds the user specified by the cuid to the group.
944If the group does not exist, it will return false and do nothing, unless the create flag is set.
945
946=cut
947
948sub addUserToGroup {
949 my ( $this, $cuid, $group, $create ) = @_;
950 my $mapping = $this->{mapping};
951 return $mapping->addUserToGroup( $cuid, $group, $create );
952}
953
954=begin TML
955
956---++ ObjectMethod removeFromGroup( $cuid, $group ) -> $boolean
957
958=cut
959
960sub removeUserFromGroup {
961 my ( $this, $cuid, $group ) = @_;
962 my $mapping = $this->{mapping};
963 return $mapping->removeUserFromGroup( $cuid, $group );
964}
965
966=begin TML
967
968---++ ObjectMethod checkLogin( $login, $passwordU ) -> $boolean
969
970Finds if the password is valid for the given user. This method is
971called using the login name rather than the $cUID so that it can be called
972with a user who can be authenticated, but may not be mappable to a
973cUID (yet).
974
975Returns 1 on success, undef on failure.
976
977TODO: add special check for BaseMapping admin user's login, and if
978its there (and we're in sudo_context?) use that..
979
980=cut
981
982sub checkPassword {
983 my ( $this, $login, $pw ) = @_;
984 my $mapping = $this->_getMapping( undef, $login, undef, 0 );
985 return $mapping->checkPassword( $login, $pw );
986}
987
988=begin TML
989
990---++ ObjectMethod setPassword( $cUID, $newPassU, $oldPassU ) -> $boolean
991
992If the $oldPassU matches matches the user's password, then it will
993replace it with $newPassU.
994
995If $oldPassU is not correct and not 1, will return 0.
996
997If $oldPassU is 1, will force the change irrespective of
998the existing password, adding the user if necessary.
999
1000Otherwise returns 1 on success, undef on failure.
1001
1002=cut
1003
1004sub setPassword {
1005 my ( $this, $cUID, $newPassU, $oldPassU ) = @_;
1006 ASSERT($cUID) if DEBUG;
1007 return $this->_getMapping($cUID)
1008 ->setPassword( $this->getLoginName($cUID), $newPassU, $oldPassU );
1009}
1010
1011=begin TML
1012
1013---++ ObjectMethod passwordError($cUID) -> $string
1014
1015Returns a string indicating the error that happened in the password handler
1016The cUID is used to determine which mapper is handling the user. If called
1017without a cUID, then the Base mapping is used.
1018
1019TODO: these delayed error's should be replaced with Exceptions.
1020
1021returns undef if no error
1022
1023=cut
1024
1025sub passwordError {
1026 my ( $this, $cUID ) = @_;
1027 return $this->_getMapping($cUID)->passwordError();
1028}
1029
1030=begin TML
1031
1032---++ ObjectMethod removeUser( $cUID ) -> $boolean
1033
1034Delete the users entry. Removes the user from the password
1035manager and user mapping manager. Does *not* remove their personal
1036topics, which may still be linked.
1037
1038=cut
1039
1040sub removeUser {
1041 my ( $this, $cUID ) = @_;
1042 $this->_getMapping($cUID)->removeUser($cUID);
1043}
1044
104512µs1;
1046__END__