lib/TWiki/LoginManager/TemplateLogin.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) 2005-2006 TWiki Contributors.
colas@0
     4
# All Rights Reserved. TWiki Contributors
colas@0
     5
# are listed in the AUTHORS file in the root of this distribution.
colas@0
     6
# NOTE: Please extend that file, not this notice.
colas@0
     7
#
colas@0
     8
# Additional copyrights apply to some or all of the code in this
colas@0
     9
# file as follows:
colas@0
    10
# Copyright (C) 2005 Greg Abbas, twiki@abbas.org
colas@0
    11
#
colas@0
    12
# This program is free software; you can redistribute it and/or
colas@0
    13
# modify it under the terms of the GNU General Public License
colas@0
    14
# as published by the Free Software Foundation; either version 2
colas@0
    15
# of the License, or (at your option) any later version. For
colas@0
    16
# more details read LICENSE in the root of this distribution.
colas@0
    17
#
colas@0
    18
# This program is distributed in the hope that it will be useful,
colas@0
    19
# but WITHOUT ANY WARRANTY; without even the implied warranty of
colas@0
    20
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
colas@0
    21
#
colas@0
    22
# As per the GPL, removal of this notice is prohibited.
colas@0
    23
colas@0
    24
=pod
colas@0
    25
colas@0
    26
---+ package TWiki::LoginManager::TemplateLogin
colas@0
    27
colas@0
    28
This is a login manager that you can specify in the security setup section of
colas@0
    29
[[%SCRIPTURL{"configure"}%][configure]]. It provides users with a
colas@0
    30
template-based form to enter usernames and passwords, and works with the
colas@0
    31
PasswordManager that you specify to verify those passwords.
colas@0
    32
colas@0
    33
Subclass of TWiki::LoginManager; see that class for documentation of the
colas@0
    34
methods of this class.
colas@0
    35
colas@0
    36
=cut
colas@0
    37
colas@0
    38
package TWiki::LoginManager::TemplateLogin;
colas@0
    39
use base 'TWiki::LoginManager';
colas@0
    40
colas@0
    41
use strict;
colas@0
    42
use Assert;
colas@0
    43
colas@0
    44
colas@0
    45
=pod
colas@0
    46
colas@0
    47
---++ ClassMethod new ($session, $impl)
colas@0
    48
colas@0
    49
Construct the TemplateLogin object
colas@0
    50
colas@0
    51
=cut
colas@0
    52
colas@0
    53
sub new {
colas@0
    54
    my( $class, $session ) = @_;
colas@0
    55
    my $this = $class->SUPER::new($session);
colas@0
    56
    $session->enterContext( 'can_login' );
colas@0
    57
    if ($TWiki::cfg{Sessions}{ExpireCookiesAfter}) {
colas@0
    58
        $session->enterContext( 'can_remember_login' );
colas@0
    59
    }
colas@0
    60
    return $this;
colas@0
    61
}
colas@0
    62
colas@0
    63
=pod
colas@0
    64
colas@0
    65
---++ ObjectMethod forceAuthentication () -> boolean
colas@0
    66
colas@0
    67
method called when authentication is required - redirects to (...|view)auth
colas@0
    68
Triggered on auth fail
colas@0
    69
colas@0
    70
=cut
colas@0
    71
colas@0
    72
sub forceAuthentication {
colas@0
    73
    my $this = shift;
colas@0
    74
    my $twiki = $this->{twiki};
colas@0
    75
colas@0
    76
    unless( $twiki->inContext( 'authenticated' )) {
colas@0
    77
        my $query = $twiki->{cgiQuery};
colas@0
    78
        # Redirect with passthrough so we don't lose the original query params
colas@0
    79
        my $twiki = $this->{twiki};
colas@0
    80
        my $topic = $twiki->{topicName};
colas@0
    81
        my $web = $twiki->{webName};
colas@0
    82
        my $url = $twiki->getScriptUrl( 0, 'login', $web, $topic);
colas@0
    83
        $query->param( -name=>'origurl', -value=>$ENV{REQUEST_URI} );
colas@0
    84
        $twiki->redirect( $url, 1 );
colas@0
    85
        return 1;
colas@0
    86
    }
colas@0
    87
    return undef;
colas@0
    88
}
colas@0
    89
colas@0
    90
colas@0
    91
=pod
colas@0
    92
colas@0
    93
---++ ObjectMethod loginUrl () -> $loginUrl
colas@0
    94
colas@0
    95
TODO: why is this not used internally? When is it called, and why
colas@0
    96
Content of a login link
colas@0
    97
colas@0
    98
=cut
colas@0
    99
colas@0
   100
sub loginUrl {
colas@0
   101
    my $this = shift;
colas@0
   102
    my $twiki = $this->{twiki};
colas@0
   103
    my $topic = $twiki->{topicName};
colas@0
   104
    my $web = $twiki->{webName};
colas@0
   105
    return $twiki->getScriptUrl( 0, 'login', $web, $topic,
colas@0
   106
                                 origurl => $ENV{REQUEST_URI} );
colas@0
   107
}
colas@0
   108
colas@0
   109
=pod
colas@0
   110
colas@0
   111
---++ ObjectMethod login( $query, $twiki )
colas@0
   112
colas@0
   113
If a login name and password have been passed in the query, it
colas@0
   114
validates these and if authentic, redirects to the original
colas@0
   115
script. If there is no username in the query or the username/password is
colas@0
   116
invalid (validate returns non-zero) then it prompts again.
colas@0
   117
colas@0
   118
If a flag to remember the login has been passed in the query, then the
colas@0
   119
corresponding session variable will be set. This will result in the
colas@0
   120
login cookie being preserved across browser sessions.
colas@0
   121
colas@0
   122
The password handler is expected to return a perl true value if the password
colas@0
   123
is valid. This return value is stored in a session variable called
colas@0
   124
VALIDATION. This is so that password handlers can return extra information
colas@0
   125
about the user, such as a list of TWiki groups stored in a separate
colas@0
   126
database, that can then be displayed by referring to
colas@0
   127
%<nop>SESSION_VARIABLE{"VALIDATION"}%
colas@0
   128
colas@0
   129
=cut
colas@0
   130
colas@0
   131
sub login {
colas@0
   132
    my( $this, $query, $twikiSession ) = @_;
colas@0
   133
    my $twiki = $this->{twiki};
colas@0
   134
    my $users = $twiki->{users};
colas@0
   135
colas@0
   136
    my $origurl = $query->param( 'origurl' );
colas@0
   137
    my $loginName = $query->param( 'username' );
colas@0
   138
    my $loginPass = $query->param( 'password' );
colas@0
   139
    my $remember = $query->param( 'remember' );
colas@0
   140
colas@0
   141
    # Eat these so there's no risk of accidental passthrough
colas@0
   142
    $query->delete('origurl', 'username', 'password');
colas@0
   143
colas@0
   144
    # UserMappings can over-ride where the login template is defined
colas@0
   145
    my $loginTemplate = $users->loginTemplateName();        #defaults to login.tmpl
colas@0
   146
    my $tmpl = $twiki->templates->readTemplate(
colas@0
   147
        $loginTemplate, $twiki->getSkin() );
colas@0
   148
colas@0
   149
    my $banner = $twiki->templates->expandTemplate( 'LOG_IN_BANNER' );
colas@0
   150
    my $note = '';
colas@0
   151
    my $topic = $twiki->{topicName};
colas@0
   152
    my $web = $twiki->{webName};
colas@0
   153
colas@0
   154
    my $cgisession = $this->{_cgisession};
colas@0
   155
colas@0
   156
    $cgisession->param( 'REMEMBER', $remember ) if $cgisession;
colas@0
   157
    if( $cgisession && $cgisession->param( 'AUTHUSER' ) &&
colas@0
   158
        $loginName && $loginName ne $cgisession->param( 'AUTHUSER' )) {
colas@0
   159
        $banner = $twiki->templates->expandTemplate( 'LOGGED_IN_BANNER' );
colas@0
   160
        $note = $twiki->templates->expandTemplate( 'NEW_USER_NOTE' );
colas@0
   161
     }
colas@0
   162
colas@0
   163
    my $error = '';
colas@0
   164
colas@0
   165
    if( $loginName ) {
colas@0
   166
        my $validation = $users->checkPassword( $loginName, $loginPass );
colas@0
   167
        $error = $users->passwordError();
colas@0
   168
colas@0
   169
        if( $validation ) {
colas@0
   170
            $this->userLoggedIn( $loginName );
colas@0
   171
            $cgisession->param( 'VALIDATION', $validation ) if $cgisession;
colas@0
   172
            if( !$origurl || $origurl eq $query->url() ) {
colas@0
   173
                $origurl = $twiki->getScriptUrl( 0, 'view', $web, $topic );
colas@0
   174
            }
colas@0
   175
            #SUCCESS our user is authenticated..
colas@0
   176
            $query->delete('sudo'); #remove the sudo param - its only to tell TemplateLogin that we're using BaseMapper..
colas@0
   177
            # Redirect with passthrough
colas@0
   178
            $twikiSession->redirect($origurl, 1 );
colas@0
   179
            return;
colas@0
   180
        } else {
colas@0
   181
            $banner = $twiki->templates->expandTemplate('UNRECOGNISED_USER');
colas@0
   182
        }
colas@0
   183
    }
colas@0
   184
colas@0
   185
    # TODO: add JavaScript password encryption in the template
colas@0
   186
    # to use a template)
colas@0
   187
    $origurl ||= '';
colas@0
   188
    $twiki->{prefs}->pushPreferenceValues('SESSION', {ORIGURL=>$origurl, BANNER=>$banner, NOTE=>$note, ERROR=>$error});
colas@0
   189
colas@0
   190
    $tmpl = $twiki->handleCommonTags( $tmpl, $web, $topic );
colas@0
   191
    $tmpl = $twiki->renderer->getRenderedVersion( $tmpl, '' );
colas@0
   192
    $tmpl =~ s/<nop>//g;
colas@0
   193
    print $twiki->generateHTTPHeaders( $query );
colas@0
   194
    print $tmpl;
colas@0
   195
}
colas@0
   196
colas@0
   197
1;