~kosova/+junk/tuxfamily-twiki

« back to all changes in this revision

Viewing changes to foswiki/lib/Foswiki/LoginManager/TemplateLogin.pm

  • Committer: James Michael DuPont
  • Date: 2009-07-18 19:58:49 UTC
  • Revision ID: jamesmikedupont@gmail.com-20090718195849-vgbmaht2ys791uo2
added foswiki

Show diffs side-by-side

added added

removed removed

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