lib/TWiki/UserMapping.pm
author Colas Nahaboo <colas@nahaboo.net>
Sat, 26 Jan 2008 15:50:53 +0100
changeset 0 414e01d06fd5
child 1 e2915a7cbdfa
permissions -rw-r--r--
RELEASE 4.2.0 freetown
colas@0
     1
# Module of TWiki Enterprise Collaboration Platform, http://TWiki.org/
colas@0
     2
#
colas@0
     3
# Copyright (C) 2007 TWiki Contributors. All Rights Reserved.
colas@0
     4
# TWiki Contributors are listed in the AUTHORS file in the root
colas@0
     5
# of this distribution.
colas@0
     6
# NOTE: Please extend that file, not this notice.
colas@0
     7
#
colas@0
     8
# This program is free software; you can redistribute it and/or
colas@0
     9
# modify it under the terms of the GNU General Public License
colas@0
    10
# as published by the Free Software Foundation; either version 2
colas@0
    11
# of the License, or (at your option) any later version. For
colas@0
    12
# more details read LICENSE in the root of this distribution.
colas@0
    13
#
colas@0
    14
# This program is distributed in the hope that it will be useful,
colas@0
    15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
colas@0
    16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
colas@0
    17
#
colas@0
    18
# As per the GPL, removal of this notice is prohibited.
colas@0
    19
colas@0
    20
=begin twiki
colas@0
    21
colas@0
    22
---+ package TWiki::UserMapping
colas@0
    23
colas@0
    24
This is a virtual base class (a.k.a an interface) for all user mappers. It is
colas@0
    25
*not* useable as a mapping in TWiki - use the BaseUserMapping for default
colas@0
    26
behaviour.
colas@0
    27
colas@0
    28
User mapping is the process by which TWiki maps from a username (a login name)
colas@0
    29
to a display name and back. It is also where groups are maintained.
colas@0
    30
colas@0
    31
See TWiki::Users::BaseUserMapping and TWiki::Users::TWikiUserMapping for
colas@0
    32
the default implementations of this interface.
colas@0
    33
colas@0
    34
If you want to write a user mapper, you will need to implement the methods
colas@0
    35
described in this class.
colas@0
    36
colas@0
    37
User mappings work by mapping both login names and display names to a
colas@0
    38
_canonical user id_. This user id is composed from a prefix that defines
colas@0
    39
the mapper in use (something like 'BaseUserMapping_' or 'LdapUserMapping_')
colas@0
    40
and a unique user id that the mapper uses to identify the user.
colas@0
    41
colas@0
    42
The null prefix is reserver for the TWikiUserMapping for compatibility
colas@0
    43
with old TWiki releases.
colas@0
    44
colas@0
    45
__Note:__ in all the following documentation, =$user= refers to a
colas@0
    46
*canonical user id*.
colas@0
    47
colas@0
    48
=cut
colas@0
    49
colas@0
    50
package TWiki::UserMapping;
colas@0
    51
colas@0
    52
use Assert;
colas@0
    53
use Error;
colas@0
    54
colas@0
    55
=pod
colas@0
    56
colas@0
    57
---++ PROTECTED ClassMethod new ($session, $mapping_id)
colas@0
    58
colas@0
    59
Construct a user mapping object, using the given mapping id.
colas@0
    60
colas@0
    61
=cut
colas@0
    62
colas@0
    63
sub new {
colas@0
    64
    my ($class, $session, $mid) = @_;
colas@0
    65
    my $this = bless( {
colas@0
    66
        mapping_id => $mid || '',
colas@0
    67
        session => $session,
colas@0
    68
    }, $class );
colas@0
    69
    return $this;
colas@0
    70
}
colas@0
    71
colas@0
    72
=begin twiki
colas@0
    73
colas@0
    74
---++ ObjectMethod finish()
colas@0
    75
Break circular references.
colas@0
    76
colas@0
    77
=cut
colas@0
    78
colas@0
    79
sub finish {
colas@0
    80
    my $this = shift;
colas@0
    81
    undef $this->{mapping_id};
colas@0
    82
    undef $this->{session};
colas@0
    83
}
colas@0
    84
colas@0
    85
=pod
colas@0
    86
colas@0
    87
---++ ObjectMethod loginTemplateName () -> $templateFile
colas@0
    88
colas@0
    89
Allows UserMappings to come with customised login screens - that should
colas@0
    90
preferably only over-ride the UI function
colas@0
    91
colas@0
    92
Default is "login"
colas@0
    93
colas@0
    94
=cut
colas@0
    95
colas@0
    96
sub loginTemplateName {
colas@0
    97
    return 'login';
colas@0
    98
}
colas@0
    99
colas@0
   100
=pod
colas@0
   101
colas@0
   102
---++ ObjectMethod supportsRegistration() -> $boolean
colas@0
   103
colas@0
   104
Return true if the UserMapper supports registration (ie can create new users)
colas@0
   105
colas@0
   106
Default is *false*
colas@0
   107
colas@0
   108
=cut
colas@0
   109
colas@0
   110
sub supportsRegistration {
colas@0
   111
    return 0; # NO, we don't
colas@0
   112
}
colas@0
   113
colas@0
   114
=pod
colas@0
   115
colas@0
   116
---++ ObjectMethod handlesUser ( $cUID, $login, $wikiname) -> $boolean
colas@0
   117
colas@0
   118
Called by the TWiki::Users object to determine which loaded mapping
colas@0
   119
to use for a given user (must be fast).
colas@0
   120
colas@0
   121
Default is *false*
colas@0
   122
colas@0
   123
=cut
colas@0
   124
colas@0
   125
sub handlesUser {
colas@0
   126
    return 0;
colas@0
   127
}
colas@0
   128
colas@0
   129
=begin twiki
colas@0
   130
colas@0
   131
---++ ObjectMethod getCanonicalUserID ($login, $dontcheck) -> cUID
colas@0
   132
colas@0
   133
Convert a login name to the corresponding canonical user name. The
colas@0
   134
canonical name can be any string of 7-bit alphanumeric and underscore
colas@0
   135
characters, and must correspond 1:1 to the login name.
colas@0
   136
(undef on failure)
colas@0
   137
colas@0
   138
(if dontcheck is true, return a cUID for a nonexistant user too - used for registration)
colas@0
   139
colas@0
   140
Subclasses *must* implement this method.
colas@0
   141
colas@0
   142
colas@0
   143
=cut
colas@0
   144
colas@0
   145
sub getCanonicalUserID {
colas@0
   146
    ASSERT(0);
colas@0
   147
}
colas@0
   148
colas@0
   149
=pod
colas@0
   150
colas@0
   151
---++ ObjectMethod getLoginName ($cUID) -> login
colas@0
   152
colas@0
   153
Converts an internal cUID to that user's login
colas@0
   154
(undef on failure)
colas@0
   155
colas@0
   156
Subclasses *must* implement this method.
colas@0
   157
colas@0
   158
=cut
colas@0
   159
colas@0
   160
sub getLoginName {
colas@0
   161
    ASSERT(0);
colas@0
   162
}
colas@0
   163
colas@0
   164
=pod
colas@0
   165
colas@0
   166
---++ ObjectMethod addUser ($login, $wikiname, $password, $emails) -> cUID
colas@0
   167
colas@0
   168
Add a user to the persistant mapping that maps from usernames to wikinames
colas@0
   169
and vice-versa, via a *canonical user id* (cUID).
colas@0
   170
colas@0
   171
$login and $wikiname must be acceptable to $TWiki::cfg{NameFilter}.
colas@0
   172
$login must *always* be specified. $wikiname may be undef, in which case
colas@0
   173
the user mapper should make one up.
colas@0
   174
colas@0
   175
This function must return a canonical user id that it uses to uniquely
colas@0
   176
identify the user. This can be the login name, or the wikiname if they
colas@0
   177
are all guaranteed unigue, or some other string consisting only of 7-bit
colas@0
   178
alphanumerics and underscores.
colas@0
   179
colas@0
   180
If you fail to create a new user (for eg your Mapper has read only access),
colas@0
   181
<pre>
colas@0
   182
    throw Error::Simple('Failed to add user: '.$error);
colas@0
   183
</pre>
colas@0
   184
where $error is a descriptive string.
colas@0
   185
colas@0
   186
Throws an Error::Simple if user adding is not supported (the default).
colas@0
   187
colas@0
   188
=cut
colas@0
   189
colas@0
   190
sub addUser {
colas@0
   191
    throw Error::Simple('Failed to add user: adding users is not supported');
colas@0
   192
}
colas@0
   193
colas@0
   194
=pod
colas@0
   195
colas@0
   196
---++ ObjectMethod removeUser( $user ) -> $boolean
colas@0
   197
colas@0
   198
Delete the users entry from this mapper. Throws an Error::Simple if
colas@0
   199
user removal is not supported (the default).
colas@0
   200
colas@0
   201
=cut
colas@0
   202
colas@0
   203
sub removeUser {
colas@0
   204
    throw Error::Simple(
colas@0
   205
        'Failed to remove user: user removal is not supported');
colas@0
   206
}
colas@0
   207
colas@0
   208
=pod
colas@0
   209
colas@0
   210
---++ ObjectMethod getWikiName ($cUID) -> wikiname
colas@0
   211
colas@0
   212
Map a canonical user name to a wikiname.
colas@0
   213
colas@0
   214
Returns the $cUID by default.
colas@0
   215
colas@0
   216
=cut
colas@0
   217
colas@0
   218
sub getWikiName {
colas@0
   219
    my ($this, $cUID) = @_;
colas@0
   220
    return $cUID;
colas@0
   221
}
colas@0
   222
colas@0
   223
=pod
colas@0
   224
colas@0
   225
---++ ObjectMethod userExists($cUID) -> $boolean
colas@0
   226
colas@0
   227
Determine if the user already exists or not. Whether a user exists
colas@0
   228
or not is determined by the password manager.
colas@0
   229
colas@0
   230
Subclasses *must* implement this method.
colas@0
   231
colas@0
   232
=cut
colas@0
   233
colas@0
   234
sub userExists {
colas@0
   235
    ASSERT(0);
colas@0
   236
}
colas@0
   237
colas@0
   238
=pod
colas@0
   239
colas@0
   240
---++ ObjectMethod eachUser () -> listIterator of cUIDs
colas@0
   241
colas@0
   242
Called from TWiki::Users. See the documentation of the corresponding
colas@0
   243
method in that module for details.
colas@0
   244
colas@0
   245
Subclasses *must* implement this method.
colas@0
   246
colas@0
   247
=cut
colas@0
   248
colas@0
   249
sub eachUser {
colas@0
   250
    ASSERT(0);
colas@0
   251
}
colas@0
   252
colas@0
   253
=pod
colas@0
   254
colas@0
   255
---++ ObjectMethod eachGroupMember ($group) ->  TWiki::ListIterator of cUIDs
colas@0
   256
colas@0
   257
Called from TWiki::Users. See the documentation of the corresponding
colas@0
   258
method in that module for details.
colas@0
   259
colas@0
   260
Subclasses *must* implement this method.
colas@0
   261
colas@0
   262
=cut
colas@0
   263
colas@0
   264
sub eachGroupMember {
colas@0
   265
    ASSERT(0);
colas@0
   266
}
colas@0
   267
colas@0
   268
=pod
colas@0
   269
colas@0
   270
---++ ObjectMethod isGroup ($user) -> boolean
colas@0
   271
colas@0
   272
Called from TWiki::Users. See the documentation of the corresponding
colas@0
   273
method in that module for details.
colas@0
   274
colas@0
   275
Subclasses *must* implement this method.
colas@0
   276
colas@0
   277
=cut
colas@0
   278
colas@0
   279
sub isGroup {
colas@0
   280
    ASSERT(0);
colas@0
   281
}
colas@0
   282
colas@0
   283
=pod
colas@0
   284
colas@0
   285
---++ ObjectMethod eachGroup () -> ListIterator of groupnames
colas@0
   286
colas@0
   287
Called from TWiki::Users. See the documentation of the corresponding
colas@0
   288
method in that module for details.
colas@0
   289
colas@0
   290
Subclasses *must* implement this method.
colas@0
   291
colas@0
   292
=cut
colas@0
   293
colas@0
   294
sub eachGroup {
colas@0
   295
    ASSERT(0);
colas@0
   296
}
colas@0
   297
colas@0
   298
=pod
colas@0
   299
colas@0
   300
---++ ObjectMethod eachMembership($cUID) -> ListIterator of groups this user is in
colas@0
   301
colas@0
   302
Called from TWiki::Users. See the documentation of the corresponding
colas@0
   303
method in that module for details.
colas@0
   304
colas@0
   305
Subclasses *must* implement this method.
colas@0
   306
colas@0
   307
=cut
colas@0
   308
colas@0
   309
sub eachMembership {
colas@0
   310
    ASSERT(0);
colas@0
   311
}
colas@0
   312
colas@0
   313
=pod
colas@0
   314
colas@0
   315
---++ ObjectMethod isAdmin( $user ) -> $boolean
colas@0
   316
colas@0
   317
True if the user is an administrator. Default is *false*
colas@0
   318
colas@0
   319
=cut
colas@0
   320
colas@0
   321
sub isAdmin {
colas@0
   322
    return 0;
colas@0
   323
}
colas@0
   324
colas@0
   325
=pod
colas@0
   326
colas@0
   327
---++ ObjectMethod isInGroup ($user, $group, $scanning) -> bool
colas@0
   328
colas@0
   329
Called from TWiki::Users. See the documentation of the corresponding
colas@0
   330
method in that module for details.
colas@0
   331
colas@0
   332
Default is *false*
colas@0
   333
colas@0
   334
=cut
colas@0
   335
colas@0
   336
sub isInGroup {
colas@0
   337
    return 0;
colas@0
   338
}
colas@0
   339
colas@0
   340
=pod
colas@0
   341
colas@0
   342
---++ ObjectMethod findUserByEmail( $email ) -> \@users
colas@0
   343
   * =$email= - email address to look up
colas@0
   344
Return a list of canonical user names for the users that have this email
colas@0
   345
registered with the password manager or the user mapping manager.
colas@0
   346
colas@0
   347
Returns an empty list by default.
colas@0
   348
colas@0
   349
=cut
colas@0
   350
colas@0
   351
sub findUserByEmail {
colas@0
   352
    return [];
colas@0
   353
}
colas@0
   354
colas@0
   355
=pod
colas@0
   356
colas@0
   357
---++ ObjectMethod getEmails($user) -> @emailAddress
colas@0
   358
colas@0
   359
If this is a user, return their email addresses. If it is a group,
colas@0
   360
return the addresses of everyone in the group.
colas@0
   361
colas@0
   362
Duplicates should be removed from the list.
colas@0
   363
colas@0
   364
By default, returns the empty list.
colas@0
   365
colas@0
   366
=cut
colas@0
   367
colas@0
   368
sub getEmails {
colas@0
   369
    return ();
colas@0
   370
}
colas@0
   371
colas@0
   372
=pod
colas@0
   373
colas@0
   374
---++ ObjectMethod setEmails($user, @emails)
colas@0
   375
colas@0
   376
Set the email address(es) for the given user. Does nothing by default.
colas@0
   377
colas@0
   378
=cut
colas@0
   379
colas@0
   380
sub setEmails {
colas@0
   381
}
colas@0
   382
colas@0
   383
=pod
colas@0
   384
colas@0
   385
---++ ObjectMethod findUserByWikiName ($wikiname) -> list of cUIDs associated with that wikiname
colas@0
   386
colas@0
   387
Called from TWiki::Users. See the documentation of the corresponding
colas@0
   388
method in that module for details.
colas@0
   389
colas@0
   390
Subclasses *must* implement this method.
colas@0
   391
colas@0
   392
=cut
colas@0
   393
colas@0
   394
sub findUserByWikiName {
colas@0
   395
    ASSERT(0);
colas@0
   396
}
colas@0
   397
colas@0
   398
=pod
colas@0
   399
colas@0
   400
---++ ObjectMethod checkPassword( $userName, $passwordU ) -> $boolean
colas@0
   401
colas@0
   402
Finds if the password is valid for the given user.
colas@0
   403
colas@0
   404
Returns 1 on success, undef on failure.
colas@0
   405
colas@0
   406
Default behaviour is to return 1.
colas@0
   407
colas@0
   408
=cut
colas@0
   409
colas@0
   410
sub checkPassword {
colas@0
   411
    return 1;
colas@0
   412
}
colas@0
   413
colas@0
   414
=pod
colas@0
   415
colas@0
   416
---++ ObjectMethod setPassword( $user, $newPassU, $oldPassU ) -> $boolean
colas@0
   417
colas@0
   418
If the $oldPassU matches matches the user's password, then it will
colas@0
   419
replace it with $newPassU.
colas@0
   420
colas@0
   421
If $oldPassU is not correct and not 1, will return 0.
colas@0
   422
colas@0
   423
If $oldPassU is 1, will force the change irrespective of
colas@0
   424
the existing password, adding the user if necessary.
colas@0
   425
colas@0
   426
Otherwise returns 1 on success, undef on failure.
colas@0
   427
colas@0
   428
Default behaviour is to fail.
colas@0
   429
colas@0
   430
=cut
colas@0
   431
colas@0
   432
sub setPassword {
colas@0
   433
    return undef;
colas@0
   434
}
colas@0
   435
colas@0
   436
=pod
colas@0
   437
colas@0
   438
---++ ObjectMethod passwordError( ) -> $string
colas@0
   439
colas@0
   440
Returns a string indicating the error that happened in the password handlers
colas@0
   441
TODO: these delayed errors should be replaced with Exceptions.
colas@0
   442
colas@0
   443
returns undef if no error 9the default)
colas@0
   444
colas@0
   445
=cut
colas@0
   446
colas@0
   447
sub passwordError {
colas@0
   448
    return undef;
colas@0
   449
}
colas@0
   450
colas@0
   451
=pod
colas@0
   452
colas@0
   453
---++ ObjectMethod ASSERT_IS_CANONICAL_USER_ID( $user_id ) -> $boolean
colas@0
   454
colas@0
   455
Used for debugging to ensure we are actually passing a canonical_id
colas@0
   456
colas@0
   457
=cut
colas@0
   458
colas@0
   459
sub ASSERT_IS_CANONICAL_USER_ID {
colas@0
   460
#    my( $this, $user_id ) = @_;
colas@0
   461
#    print STDERR "ASSERT_IS_CANONICAL_USER_ID($user_id)";
colas@0
   462
#    ASSERT( $user_id =~/^$this->{mapping_id}/e );
colas@0
   463
}
colas@0
   464
colas@0
   465
=pod
colas@0
   466
colas@0
   467
---++ ObjectMethod ASSERT_IS_USER_LOGIN_ID( $user_login ) -> $boolean
colas@0
   468
colas@0
   469
Used for debugging to ensure we are actually passing a user login
colas@0
   470
colas@0
   471
=cut
colas@0
   472
colas@0
   473
sub ASSERT_IS_USER_LOGIN_ID {
colas@0
   474
}
colas@0
   475
colas@0
   476
=pod
colas@0
   477
colas@0
   478
---++ ObjectMethod ASSERT_IS_USER_DISPLAY_NAME( $user_display ) -> $boolean
colas@0
   479
colas@0
   480
Used for debugging to ensure we are actually passing a user display_name
colas@0
   481
(commonly a WikiWord Name)
colas@0
   482
colas@0
   483
Returns true by default.
colas@0
   484
colas@0
   485
=cut
colas@0
   486
colas@0
   487
sub ASSERT_IS_USER_DISPLAY_NAME {
colas@0
   488
}
colas@0
   489
colas@0
   490
1;