Filename | /var/www/foswiki11/lib/Foswiki/UserMapping.pm |
Statements | Executed 1605 statements in 3.14ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 7.53ms | 7.72ms | BEGIN@39 | Foswiki::UserMapping::
8 | 4 | 3 | 3.14ms | 22.7ms | isInGroup | Foswiki::UserMapping::
2 | 2 | 2 | 17µs | 17µs | new | Foswiki::UserMapping::
1 | 1 | 1 | 16µs | 28µs | BEGIN@35 | Foswiki::UserMapping::
2 | 2 | 2 | 9µs | 9µs | finish | Foswiki::UserMapping::
1 | 1 | 1 | 8µs | 14µs | BEGIN@36 | Foswiki::UserMapping::
1 | 1 | 1 | 8µs | 21µs | BEGIN@37 | Foswiki::UserMapping::
1 | 1 | 1 | 4µs | 4µs | BEGIN@38 | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | addUser | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | addUserToGroup | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | checkPassword | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | eachGroup | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | eachGroupMember | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | eachMembership | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | eachUser | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | findUserByEmail | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | findUserByWikiName | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | getEmails | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | getLoginName | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | getWikiName | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | groupAllowsChange | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | groupAllowsView | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | handlesUser | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | isAdmin | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | isGroup | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | login2cUID | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | loginTemplateName | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | passwordError | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | removeUser | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | removeUserFromGroup | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | setEmails | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | setPassword | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | supportsRegistration | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | userExists | Foswiki::UserMapping::
0 | 0 | 0 | 0s | 0s | validateRegistrationField | Foswiki::UserMapping::
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 | |||||
7 | This 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 | ||||
9 | behaviour. | ||||
10 | |||||
11 | User mapping is the process by which Foswiki maps from a username (a login name) | ||||
12 | to a display name and back. It is also where groups are maintained. | ||||
13 | |||||
14 | See Foswiki::Users::BaseUserMapping and Foswiki::Users::TopicUserMapping for | ||||
15 | the default implementations of this interface. | ||||
16 | |||||
17 | If you want to write a user mapper, you will need to implement the methods | ||||
18 | described in this class. | ||||
19 | |||||
20 | User 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 | ||||
22 | the mapper in use (something like 'BaseUserMapping_' or 'LdapUserMapping_') | ||||
23 | and a unique user id that the mapper uses to identify the user. | ||||
24 | |||||
25 | The null prefix is reserver for the TopicUserMapping for compatibility | ||||
26 | with old Foswiki releases. | ||||
27 | |||||
28 | __Note:__ in all the following documentation, =$cUID= refers to a | ||||
29 | *canonical user id*. | ||||
30 | |||||
31 | =cut | ||||
32 | |||||
33 | package Foswiki::UserMapping; | ||||
34 | |||||
35 | 2 | 26µs | 2 | 40µs | # spent 28µs (16+12) within Foswiki::UserMapping::BEGIN@35 which was called:
# once (16µs+12µs) by Foswiki::Users::BaseUserMapping::BEGIN@33 at line 35 # spent 28µs making 1 call to Foswiki::UserMapping::BEGIN@35
# spent 12µs making 1 call to strict::import |
36 | 2 | 26µs | 2 | 19µs | # spent 14µs (8+5) within Foswiki::UserMapping::BEGIN@36 which was called:
# once (8µs+5µs) by Foswiki::Users::BaseUserMapping::BEGIN@33 at line 36 # spent 14µs making 1 call to Foswiki::UserMapping::BEGIN@36
# spent 5µs making 1 call to warnings::import |
37 | 2 | 25µs | 2 | 34µs | # spent 21µs (8+13) within Foswiki::UserMapping::BEGIN@37 which was called:
# once (8µs+13µs) by Foswiki::Users::BaseUserMapping::BEGIN@33 at line 37 # spent 21µs making 1 call to Foswiki::UserMapping::BEGIN@37
# spent 13µs making 1 call to Assert::import |
38 | 2 | 24µs | 1 | 4µs | # spent 4µs within Foswiki::UserMapping::BEGIN@38 which was called:
# once (4µs+0s) by Foswiki::Users::BaseUserMapping::BEGIN@33 at line 38 # spent 4µs making 1 call to Foswiki::UserMapping::BEGIN@38 |
39 | 2 | 1.01ms | 1 | 7.72ms | # spent 7.72ms (7.53+190µs) within Foswiki::UserMapping::BEGIN@39 which was called:
# once (7.53ms+190µs) by Foswiki::Users::BaseUserMapping::BEGIN@33 at line 39 # spent 7.72ms making 1 call to Foswiki::UserMapping::BEGIN@39 |
40 | |||||
41 | =begin TML | ||||
42 | |||||
43 | ---++ PROTECTED ClassMethod new ($session, $mapping_id) | ||||
44 | |||||
45 | Construct a user mapping object, using the given mapping id. | ||||
46 | |||||
47 | =cut | ||||
48 | |||||
49 | # spent 17µs within Foswiki::UserMapping::new which was called 2 times, avg 9µs/call:
# once (9µs+0s) by Foswiki::Users::BaseUserMapping::new at line 111 of /var/www/foswiki11/lib/Foswiki/Users/BaseUserMapping.pm
# once (8µs+0s) by Foswiki::Users::TopicUserMapping::new at line 59 of /var/www/foswiki11/lib/Foswiki/Users/TopicUserMapping.pm | ||||
50 | 2 | 2µs | my ( $class, $session, $mid ) = @_; | ||
51 | 2 | 12µs | my $this = bless( | ||
52 | { | ||||
53 | mapping_id => $mid || '', | ||||
54 | session => $session, | ||||
55 | }, | ||||
56 | $class | ||||
57 | ); | ||||
58 | 2 | 12µs | return $this; | ||
59 | } | ||||
60 | |||||
61 | =begin TML | ||||
62 | |||||
63 | ---++ ObjectMethod finish() | ||||
64 | Break circular references. | ||||
65 | |||||
66 | =cut | ||||
67 | |||||
68 | # spent 9µs within Foswiki::UserMapping::finish which was called 2 times, avg 4µs/call:
# once (5µs+0s) by Foswiki::Users::BaseUserMapping::finish at line 158 of /var/www/foswiki11/lib/Foswiki/Users/BaseUserMapping.pm
# once (4µs+0s) by Foswiki::Users::TopicUserMapping::finish at line 113 of /var/www/foswiki11/lib/Foswiki/Users/TopicUserMapping.pm | ||||
69 | 2 | 2µs | my $this = shift; | ||
70 | 2 | 2µs | undef $this->{mapping_id}; | ||
71 | 2 | 12µs | undef $this->{session}; | ||
72 | } | ||||
73 | |||||
74 | =begin TML | ||||
75 | |||||
76 | ---++ ObjectMethod loginTemplateName () -> $templateFile | ||||
77 | |||||
78 | Allows UserMappings to come with customised login screens - that should | ||||
79 | preferably only over-ride the UI function | ||||
80 | |||||
81 | Default is "login" | ||||
82 | |||||
83 | =cut | ||||
84 | |||||
85 | sub loginTemplateName { | ||||
86 | return 'login'; | ||||
87 | } | ||||
88 | |||||
89 | =begin TML | ||||
90 | |||||
91 | ---++ ObjectMethod supportsRegistration() -> $boolean | ||||
92 | |||||
93 | Return true if the UserMapper supports registration (ie can create new users) | ||||
94 | |||||
95 | Default is *false* | ||||
96 | |||||
97 | =cut | ||||
98 | |||||
99 | sub supportsRegistration { | ||||
100 | return 0; # NO, we don't | ||||
101 | } | ||||
102 | |||||
103 | =begin TML | ||||
104 | |||||
105 | ---++ ObjectMethod handlesUser ( $cUID, $login, $wikiname) -> $boolean | ||||
106 | |||||
107 | Called by the Foswiki::Users object to determine which loaded mapping | ||||
108 | to use for a given user (must be fast). | ||||
109 | |||||
110 | The user can be identified by any of $cUID, $login or $wikiname. Any of | ||||
111 | these parameters may be undef, and they should be tested in order; cUID | ||||
112 | first, then login, then wikiname. | ||||
113 | |||||
114 | =cut | ||||
115 | |||||
116 | sub handlesUser { | ||||
117 | return 0; | ||||
118 | } | ||||
119 | |||||
120 | =begin TML | ||||
121 | |||||
122 | ---++ ObjectMethod login2cUID($login, $dontcheck) -> cUID | ||||
123 | |||||
124 | Convert a login name to the corresponding canonical user name. The | ||||
125 | canonical name can be any string of 7-bit alphanumeric and underscore | ||||
126 | characters, and must map 1:1 to the login name. | ||||
127 | (undef on failure) | ||||
128 | |||||
129 | (if $dontcheck is true, return a cUID for a nonexistant user too. | ||||
130 | This is used for registration) | ||||
131 | |||||
132 | Subclasses *must* implement this method. | ||||
133 | |||||
134 | Note: This method was previously (in TWiki 4.2.0) known as getCanonicalUserID. | ||||
135 | The name was changed to avoid confusion with Foswiki::Users::getCanonicalUserID, | ||||
136 | which has a more generic function. However to support older user mappers, | ||||
137 | getCanonicalUserID will still be called if login2cUID is not defined. | ||||
138 | |||||
139 | =cut | ||||
140 | |||||
141 | sub login2cUID { | ||||
142 | ASSERT( 0, 'Must be implemented' ); | ||||
143 | } | ||||
144 | |||||
145 | =begin TML | ||||
146 | |||||
147 | ---++ ObjectMethod getLoginName ($cUID) -> login | ||||
148 | |||||
149 | Converts an internal cUID to that user's login | ||||
150 | (undef on failure) | ||||
151 | |||||
152 | Subclasses *must* implement this method. | ||||
153 | |||||
154 | =cut | ||||
155 | |||||
156 | sub getLoginName { | ||||
157 | ASSERT(0); | ||||
158 | } | ||||
159 | |||||
160 | =begin TML | ||||
161 | |||||
162 | ---++ ObjectMethod addUser ($login, $wikiname, $password, $emails) -> $cUID | ||||
163 | |||||
164 | Add a user to the persistant mapping that maps from usernames to wikinames | ||||
165 | and vice-versa. | ||||
166 | |||||
167 | $login and $wikiname must be acceptable to $Foswiki::cfg{NameFilter}. | ||||
168 | $login must *always* be specified. $wikiname may be undef, in which case | ||||
169 | the user mapper should make one up. | ||||
170 | |||||
171 | This function must return a canonical user id that it uses to uniquely | ||||
172 | identify the user. This can be the login name, or the wikiname if they | ||||
173 | are all guaranteed unigue, or some other string consisting only of 7-bit | ||||
174 | alphanumerics and underscores. | ||||
175 | |||||
176 | If you fail to create a new user (for eg your Mapper has read only access), | ||||
177 | <pre> | ||||
178 | throw Error::Simple('Failed to add user: '.$error); | ||||
179 | </pre> | ||||
180 | where $error is a descriptive string. | ||||
181 | |||||
182 | Throws an Error::Simple if user adding is not supported (the default). | ||||
183 | |||||
184 | =cut | ||||
185 | |||||
186 | sub addUser { | ||||
187 | throw Error::Simple('Failed to add user: adding users is not supported'); | ||||
188 | } | ||||
189 | |||||
190 | =begin TML | ||||
191 | |||||
192 | ---++ ObjectMethod removeUser( $cUID ) -> $boolean | ||||
193 | |||||
194 | Delete the users entry from this mapper. Throws an Error::Simple if | ||||
195 | user removal is not supported (the default). | ||||
196 | |||||
197 | =cut | ||||
198 | |||||
199 | sub removeUser { | ||||
200 | throw Error::Simple('Failed to remove user: user removal is not supported'); | ||||
201 | } | ||||
202 | |||||
203 | =begin TML | ||||
204 | |||||
205 | ---++ ObjectMethod getWikiName ($cUID) -> $wikiname | ||||
206 | |||||
207 | Map a canonical user name to a wikiname. | ||||
208 | |||||
209 | Returns the $cUID by default. | ||||
210 | |||||
211 | =cut | ||||
212 | |||||
213 | sub getWikiName { | ||||
214 | my ( $this, $cUID ) = @_; | ||||
215 | return $cUID; | ||||
216 | } | ||||
217 | |||||
218 | =begin TML | ||||
219 | |||||
220 | ---++ ObjectMethod userExists($cUID) -> $boolean | ||||
221 | |||||
222 | Determine if the user already exists or not. Whether a user exists | ||||
223 | or not is determined by the password manager. | ||||
224 | |||||
225 | Subclasses *must* implement this method. | ||||
226 | |||||
227 | =cut | ||||
228 | |||||
229 | sub userExists { | ||||
230 | ASSERT(0); | ||||
231 | } | ||||
232 | |||||
233 | =begin TML | ||||
234 | |||||
235 | ---++ ObjectMethod eachUser () -> $iterator | ||||
236 | |||||
237 | Get an iterator over the list of all cUIDs of the registered | ||||
238 | users *not* including groups. | ||||
239 | |||||
240 | Subclasses *must* implement this method. | ||||
241 | |||||
242 | =cut | ||||
243 | |||||
244 | sub eachUser { | ||||
245 | ASSERT(0); | ||||
246 | } | ||||
247 | |||||
248 | =begin TML | ||||
249 | |||||
250 | ---++ ObjectMethod eachGroupMember ($group, $expand) -> $iterator | ||||
251 | |||||
252 | Return a iterator over the canonical user ids of users that are members | ||||
253 | of this group. Should only be called on groups. | ||||
254 | |||||
255 | Note that groups may be defined recursively, so a group may contain other | ||||
256 | groups. Unless $expand is set to false, this method should *only* return | ||||
257 | users i.e. all contained groups should be fully expanded. | ||||
258 | |||||
259 | Subclasses *must* implement this method. | ||||
260 | |||||
261 | =cut | ||||
262 | |||||
263 | sub eachGroupMember { | ||||
264 | ASSERT(0); | ||||
265 | } | ||||
266 | |||||
267 | =begin TML | ||||
268 | |||||
269 | ---++ ObjectMethod isGroup ($name) -> boolean | ||||
270 | |||||
271 | Establish if a user refers to a group or not. If $name is not | ||||
272 | a group name it will probably be a canonical user id, though that | ||||
273 | should not be assumed. | ||||
274 | |||||
275 | Subclasses *must* implement this method. | ||||
276 | |||||
277 | =cut | ||||
278 | |||||
279 | sub isGroup { | ||||
280 | ASSERT(0); | ||||
281 | } | ||||
282 | |||||
283 | =begin TML | ||||
284 | |||||
285 | ---++ ObjectMethod eachGroup () -> $iterator | ||||
286 | |||||
287 | Get an iterator over the list of all the group names. | ||||
288 | |||||
289 | Subclasses *must* implement this method. | ||||
290 | |||||
291 | =cut | ||||
292 | |||||
293 | sub eachGroup { | ||||
294 | ASSERT(0); | ||||
295 | } | ||||
296 | |||||
297 | =begin TML | ||||
298 | |||||
299 | ---++ ObjectMethod eachMembership($cUID) -> $iterator | ||||
300 | |||||
301 | Return an iterator over the names of groups that $cUID is a member of. | ||||
302 | |||||
303 | Subclasses *must* implement this method. | ||||
304 | |||||
305 | =cut | ||||
306 | |||||
307 | sub eachMembership { | ||||
308 | ASSERT(0); | ||||
309 | } | ||||
310 | |||||
311 | =begin TML | ||||
312 | |||||
313 | ---++ ObjectMethod groupAllowsView($group) -> boolean | ||||
314 | |||||
315 | returns 1 if the group is able to be viewed by the current logged in user | ||||
316 | |||||
317 | =cut | ||||
318 | |||||
319 | sub groupAllowsView { | ||||
320 | return 1; | ||||
321 | } | ||||
322 | |||||
323 | =begin TML | ||||
324 | |||||
325 | ---++ ObjectMethod groupAllowsChange($group) -> boolean | ||||
326 | |||||
327 | returns 1 if the group is able to be modified by the current logged in user | ||||
328 | |||||
329 | =cut | ||||
330 | |||||
331 | sub groupAllowsChange { | ||||
332 | return 0; | ||||
333 | } | ||||
334 | |||||
335 | =begin TML | ||||
336 | |||||
337 | ---++ ObjectMethod addToGroup( $cuid, $group, $create ) -> $boolean | ||||
338 | adds the user specified by the cuid to the group. | ||||
339 | |||||
340 | Mapper should throws Error::Simple if errors are encountered. For example, | ||||
341 | if the group does not exist, and the create flag is not supplied: | ||||
342 | <pre> | ||||
343 | throw Error::Simple( $this->{session} | ||||
344 | ->i18n->maketext('Group does not exist and create not permitted') | ||||
345 | ) unless ($create); | ||||
346 | </pre> | ||||
347 | |||||
348 | =cut | ||||
349 | |||||
350 | sub addUserToGroup { | ||||
351 | return 0; | ||||
352 | } | ||||
353 | |||||
354 | =begin TML | ||||
355 | |||||
356 | ---++ ObjectMethod removeFromGroup( $cuid, $group ) -> $boolean | ||||
357 | |||||
358 | Mapper should throws Error::Simple if errors are encountered. For example, | ||||
359 | if the user does not exist in the group: | ||||
360 | <pre> | ||||
361 | throw Error::Simple( | ||||
362 | $this->{session}->i18n->maketext( | ||||
363 | 'User [_1] not in group, cannot be removed', $cuid | ||||
364 | ) | ||||
365 | ); | ||||
366 | </pre> | ||||
367 | |||||
368 | =cut | ||||
369 | |||||
370 | sub removeUserFromGroup { | ||||
371 | return 0; | ||||
372 | } | ||||
373 | |||||
374 | =begin TML | ||||
375 | |||||
376 | ---++ ObjectMethod isAdmin( $cUID ) -> $boolean | ||||
377 | |||||
378 | True if the user is an administrator. | ||||
379 | |||||
380 | =cut | ||||
381 | |||||
382 | sub isAdmin { | ||||
383 | return 0; | ||||
384 | } | ||||
385 | |||||
386 | =begin TML | ||||
387 | |||||
388 | ---++ ObjectMethod isInGroup ($cUID, $group, $options ) -> $bool | ||||
389 | |||||
390 | |||||
391 | Test if the user identified by $cUID is in the given group. The default | ||||
392 | implementation iterates over all the members of $group, which is rather | ||||
393 | inefficient. $options is a hash array of options effecting the search. | ||||
394 | Available options are: | ||||
395 | |||||
396 | * =expand => 1= 0/1 - should nested groups be expanded when searching for the cUID? Default is 1 - expand nested groups | ||||
397 | |||||
398 | =cut | ||||
399 | |||||
400 | 1 | 200ns | my %scanning; | ||
401 | |||||
402 | # spent 22.7ms (3.14+19.6) within Foswiki::UserMapping::isInGroup which was called 8 times, avg 2.84ms/call:
# 3 times (2.87ms+17.4ms) by Foswiki::Users::isInGroup at line 866 of /var/www/foswiki11/lib/Foswiki/Users.pm, avg 6.74ms/call
# 3 times (86µs+68µs) by Foswiki::Users::isInGroup at line 868 of /var/www/foswiki11/lib/Foswiki/Users.pm, avg 51µs/call
# once (128µs+2.11ms) by Foswiki::Users::TopicUserMapping::isAdmin at line 1215 of /var/www/foswiki11/lib/Foswiki/Users/TopicUserMapping.pm
# once (53µs+54µs) by Foswiki::Users::BaseUserMapping::isAdmin at line 376 of /var/www/foswiki11/lib/Foswiki/Users/BaseUserMapping.pm | ||||
403 | 8 | 16µs | my ( $this, $cUID, $group, $options ) = @_; | ||
404 | 8 | 11µs | 8 | 11µs | ASSERT($cUID) if DEBUG; # spent 11µs making 8 calls to Assert::ASSERTS_OFF, avg 1µs/call |
405 | |||||
406 | 8 | 6µs | my $expand = $options->{expand}; | ||
407 | 8 | 3µs | $expand = 1 unless ( defined $expand ); | ||
408 | |||||
409 | # If not recursively, clear the scanning hash | ||||
410 | 8 | 143µs | if ( ( caller(1) )[3] ne ( caller(0) )[3] ) { | ||
411 | %scanning = (); | ||||
412 | } | ||||
413 | |||||
414 | #use Carp; | ||||
415 | #Carp::cluck "Scanning for JoeUser\n" if $cUID eq 'JoeUser'; | ||||
416 | #die "Scanning for JoeUser\n" if $cUID eq 'JoeUser'; | ||||
417 | |||||
418 | 8 | 2µs | my @users; | ||
419 | 8 | 46µs | 8 | 15.7ms | my $it = $this->eachGroupMember( $group, { expand => $expand } ); # spent 15.6ms making 4 calls to Foswiki::Users::TopicUserMapping::eachGroupMember, avg 3.90ms/call
# spent 82µs making 4 calls to Foswiki::Users::BaseUserMapping::eachGroupMember, avg 21µs/call |
420 | 8 | 24µs | 10 | 55µs | while ( $it->hasNext() ) { # spent 55µs making 10 calls to Foswiki::ListIterator::hasNext, avg 6µs/call |
421 | 303 | 435µs | 303 | 1.87ms | my $u = $it->next(); # spent 1.87ms making 303 calls to Foswiki::ListIterator::next, avg 6µs/call |
422 | 303 | 97µs | next if $scanning{$u}; | ||
423 | 301 | 221µs | $scanning{$u} = 1; | ||
424 | |||||
425 | 301 | 56µs | return 1 if $u eq $cUID; | ||
426 | 301 | 878µs | 602 | 1.96ms | if ( $expand && $this->isGroup($u) ) { # spent 1.26ms making 301 calls to Foswiki::ListIterator::hasNext, avg 4µs/call
# spent 689µs making 300 calls to Foswiki::Users::TopicUserMapping::isGroup, avg 2µs/call
# spent 7µs making 1 call to Foswiki::Users::BaseUserMapping::isGroup |
427 | return 1 if $this->isInGroup( $cUID, $u ); | ||||
428 | } | ||||
429 | } | ||||
430 | 8 | 47µs | return 0; | ||
431 | } | ||||
432 | |||||
433 | =begin TML | ||||
434 | |||||
435 | ---++ ObjectMethod findUserByEmail( $email ) -> \@users | ||||
436 | * =$email= - email address to look up | ||||
437 | Return a list of canonical user names for the users that have this email | ||||
438 | registered with the password manager or the user mapping manager. | ||||
439 | |||||
440 | =cut | ||||
441 | |||||
442 | sub findUserByEmail { | ||||
443 | return []; | ||||
444 | } | ||||
445 | |||||
446 | =begin TML | ||||
447 | |||||
448 | ---++ ObjectMethod getEmails($name) -> @emailAddress | ||||
449 | |||||
450 | If $name is a cUID, return that user's email addresses. If it is a group, | ||||
451 | return the addresses of everyone in the group. | ||||
452 | |||||
453 | Duplicates should be removed from the list. | ||||
454 | |||||
455 | =cut | ||||
456 | |||||
457 | sub getEmails { | ||||
458 | return (); | ||||
459 | } | ||||
460 | |||||
461 | =begin TML | ||||
462 | |||||
463 | ---++ ObjectMethod setEmails($cUID, @emails) | ||||
464 | |||||
465 | Set the email address(es) for the given user. | ||||
466 | |||||
467 | =cut | ||||
468 | |||||
469 | sub setEmails { | ||||
470 | } | ||||
471 | |||||
472 | =begin TML | ||||
473 | |||||
474 | ---++ ObjectMethod findUserByWikiName ($wikiname) -> list of cUIDs associated with that wikiname | ||||
475 | * =$wikiname= - wikiname to look up | ||||
476 | Return a list of canonical user names for the users that have this wikiname. | ||||
477 | Since a single wikiname might be used by multiple login ids, we need a list. | ||||
478 | |||||
479 | Note that if $wikiname is the name of a group, the group will *not* be | ||||
480 | expanded. | ||||
481 | |||||
482 | Subclasses *must* implement this method. | ||||
483 | |||||
484 | =cut | ||||
485 | |||||
486 | sub findUserByWikiName { | ||||
487 | ASSERT(0); | ||||
488 | } | ||||
489 | |||||
490 | =begin TML | ||||
491 | |||||
492 | ---++ ObjectMethod checkPassword( $login, $passwordU ) -> $boolean | ||||
493 | |||||
494 | Finds if the password is valid for the given login. This is called using | ||||
495 | a login name rather than a cUID because the user may not have been mapped | ||||
496 | at the time it is called. | ||||
497 | |||||
498 | Returns 1 on success, undef on failure. | ||||
499 | |||||
500 | Default behaviour is to return 1. | ||||
501 | |||||
502 | =cut | ||||
503 | |||||
504 | sub checkPassword { | ||||
505 | return 1; | ||||
506 | } | ||||
507 | |||||
508 | =begin TML | ||||
509 | |||||
510 | ---++ ObjectMethod setPassword( $cUID, $newPassU, $oldPassU ) -> $boolean | ||||
511 | |||||
512 | If the $oldPassU matches matches the user's password, then it will | ||||
513 | replace it with $newPassU. | ||||
514 | |||||
515 | If $oldPassU is not correct and not 1, will return 0. | ||||
516 | |||||
517 | If $oldPassU is 1, will force the change irrespective of | ||||
518 | the existing password, adding the user if necessary. | ||||
519 | |||||
520 | Otherwise returns 1 on success, undef on failure. | ||||
521 | |||||
522 | Default behaviour is to fail. | ||||
523 | |||||
524 | =cut | ||||
525 | |||||
526 | sub setPassword { | ||||
527 | return; | ||||
528 | } | ||||
529 | |||||
530 | =begin TML | ||||
531 | |||||
532 | ---++ ObjectMethod passwordError( ) -> $string | ||||
533 | |||||
534 | Returns a string indicating the error that happened in the password handlers | ||||
535 | TODO: these delayed errors should be replaced with Exceptions. | ||||
536 | |||||
537 | returns undef if no error (the default) | ||||
538 | |||||
539 | =cut | ||||
540 | |||||
541 | sub passwordError { | ||||
542 | return; | ||||
543 | } | ||||
544 | |||||
545 | =begin TML | ||||
546 | |||||
547 | ---++ ObjectMethod validateRegistrationField($field, $value ) -> $string | ||||
548 | |||||
549 | Returns a string containing the sanitized registration field, or can throw an oops | ||||
550 | if the field contains illegal data to block the registration. | ||||
551 | |||||
552 | returns the string unchanged if no issue found. | ||||
553 | |||||
554 | =cut | ||||
555 | |||||
556 | sub validateRegistrationField { | ||||
557 | |||||
558 | #my ($this, $field, $value) = @_; | ||||
559 | |||||
560 | # Filter username per the login validation rules. | ||||
561 | # Note: loginname excluded as it's validated directly in the mapper | ||||
562 | |||||
563 | return $_[2] if ( lc( $_[1] ) eq 'loginname' ); | ||||
564 | |||||
565 | if ( ( lc( $_[1] ) eq 'username' ) | ||||
566 | && length( $_[2] ) | ||||
567 | && !( $_[2] =~ m/$Foswiki::cfg{LoginNameFilterIn}/ ) ) | ||||
568 | { | ||||
569 | throw Error::Simple("Invalid $_[1]"); | ||||
570 | } | ||||
571 | |||||
572 | # Don't check contents of password - it's never displayed. | ||||
573 | return $_[2] if ( lc( $_[1] ) eq 'password' || lc( $_[1] ) eq 'confirm' ); | ||||
574 | |||||
575 | unless ( $_[1] =~ m/^(?:firstname|lastname|email|wikiname|name|)$/i ) { | ||||
576 | |||||
577 | # SMELL This would be better but for now I can't make it work. | ||||
578 | # Undefined subroutine &Foswiki::Macros::ENCODE called | ||||
579 | # | ||||
580 | #require Foswiki::Macros::ENCODE; | ||||
581 | #my $session = $Foswiki::Plugins::SESSION; | ||||
582 | #my $value = Foswiki::Macros::ENCODE->ENCODE( $session, { type => 'safe', _DEFAULT => $_[2] } ); | ||||
583 | #print STDERR "Encoding $_[1] as $value\n"; | ||||
584 | |||||
585 | # This is the "safe" encode in ENCODE.pm | ||||
586 | $_[2] =~ s/([<>%'"])/'&#'.ord($1).';'/ge; | ||||
587 | } | ||||
588 | |||||
589 | # Don't allow html markup in any other fields. | ||||
590 | # This should never hit if the encoding works correctly. | ||||
591 | throw Error::Simple("Invalid $_[1]") if ( $_[2] =~ m/[<>]+/ ); | ||||
592 | |||||
593 | return $_[2]; | ||||
594 | } | ||||
595 | |||||
596 | 1 | 3µs | 1; | ||
597 | __END__ |