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