Matrix Science header

login.pl

Logging in using the security module.

#!/usr/local/bin/perl
##############################################################################
# file: login.pl                                                             #
# 'msparser' toolkit                                                         #
# Mascot general purpose login script                                        #
##############################################################################
# COPYRIGHT NOTICE                                                           #
# Copyright 1998-2004 Matrix Science Limited  All Rights Reserved.           #
#                                                                            #
##############################################################################
#    $Archive:: /www/cgi/login.pl                                          $ #
#     $Author: villek@matrixscience.com $ #
#       $Date: 2018-07-30 16:23:53 +0100 $ #
#   $Revision: 1b450440f9c97e1e41d0fc6016a27d68951d4532 | MSPARSER_REL_2_8_1-0-gea32989045 $ #
# $NoKeywords::                                                            $ #
##############################################################################
use strict;
##############################################################################
#          
# When the script is run, the 'action' (if any) is performed, and then the
# display= is performed.
#
# If display=nothing, onerrdisplay=nothing and referer= is not defined, 
# then the output will be of the form:
#   error=[error number or 0 for ok]
#   errorstring=[error string or empty]
#   sessionID=[sessionID or empty]
#
# Postive error numbers are msparser error numbers
# Negative error numbers are login.pl error numbers:
# -1   An error in the parameters
# -2   User is not authorised to perform requested task
# -3   Security is enabled - returned from issecuritydisabled
# -4   If action=webauthentication and webauthentication is not enabled
# -5   If action=guestlogin and the guest account is not enabled
#
# Parameter     Default       Allowed_values     Description
# ------------------------------------------------------------------------------
# action=                     login              Requires username and password
#                                                If sectask is specified and the
#                                                user is not permitted an error
#                                                of -2 will be set and sessionID
#                                                will be empty
#                             logout             Uses sessionID or cookie
#                             newpassword        Requires username, newpw1
#                                                newpw2 and password
#                             issecuritydisabled Used to determine if
#                                                Mascot security is disabled.
#                                                If it is disabled, it returns 
#                                                error=0 and sessionID will be 
#                                                a 'disabled' sessionID that 
#                                                can be used.blank. If security 
#                                                is enabled, then error=-3
#                                                and sessionID is blank.
#                             webauthentication  If web server authentication is
#                                                enabled for the user who is
#                                                submitting this request, then
#                                                then this will return error=0
#                                                and sessionID will be the 
#                                                session to use. If it is not 
#                                                enabled then error=-4
#                             guestlogin         If the guest account is enabled
#                                                then this will return error=0
#                                                and sessionID will be the 
#                                                session to use. If it is not 
#                                                enabled then error=-5
#                             ispermitted        Pass sessionID and sectask
#                                                if it fails, the sessionID
#                                                output will be empty. The 
#                                                error= output is undefined.
#                             isfastapermitted   Use to determine if the user
#                                                has access to the fasta file
#                                                specified with fasta=
#                                                Also pass sessionID. If it 
#                                                fails, the sessionID output 
#                                                will be empty. The
#                                                error= output is undefined.
#                             integralogin       Requires username, 
#                                                connectionID and integradb.
#                                                Returns a sessionID if it 
#                                                succeeds.
# display=      login_prompt  nothing            No display - just text output
#                             login_prompt       Displays prompt for login
#                             newpw_prompt       Displays request for a new 
#                                                password.
#                             logout_prompt      Not particularly useful except 
#                                                for testing
#
# onerrdisplay= login_prompt  as display=        If there is an error in the 
#                                                action (e.g. invalid password)
#                                                then display this form.
#
# username=                   any username       Performs the actual login. 
#
# password=                   valid password     
# 
# newpw1=                                        For action=newpassword. User 
# newpw2=                                        enters password twice to check
#
# sessionID=                  valid sessionID    Used for logout action, or 
#                                                used to logout before logging
#                                                in with action=login
#
# savecookie=   0 or 1           0 or 1          Default is 1 for action=login
# clearcookie=  0 or 1           0 or 1          Default is 1 for action=logout
# 
#
# referer=                    any URL            After performing the action go
#                                                to this URL. display= should 
#                                                not be set when using this
#
# sectask=                    any valid integer  For login and ispermitted
#
# fasta=                      name of fasta      For example, MSDB. Use with 
#                                                action=isfastapermitted
#
# connectionID=               integra connection Used with action=integralogin.
#                                                The connection string is the
#                                                integra equivalent of the
#                                                Mascot sessionID
# integradb=                  integra database   Used with action=integralogin.
#
# error=                      error number       For action=nothing or when no
# errorstring=                error string       action verb supplied. The error
#                                                string will be displayed on the
#                                                login form
#
################################################################################

use lib "../bin";
use CGI;
use msparser 2.000_054;

my ($session, 
    $thisScript, 
    $cookie1, 
    $cookie2, 
    $sec,
    $opts,
    $sessionID,
    $error,
    $errorstring,
    $action,
    $display,
    $onerrdisplay,
    $savecookie,
    $clearcookie,
    $shipper,
    );

$thisScript = new CGI;

# pull in common subroutines
require "./common_subs.pl";

$error = 0 unless ($error = $thisScript->param('error'));
$errorstring = "" unless ($errorstring = $thisScript->param('errorstring'));

if (defined($thisScript->param('sessionID'))) {
    # sessionID supplied as argument takes priority
    # empty string may be useful when debugging 
    $sessionID = $thisScript->param('sessionID');
} else {
    # try to get from cookie
    $sessionID = $thisScript->cookie('MASCOT_SESSION');
}

# Set variables according to defaults
if (defined($thisScript->param('action'))) {
    $action = $thisScript->param('action');
} else {
    $action = 'nothing';
}

# If display is not defined then assume login_prompt
if (defined($thisScript->param('display'))) {
    $display = $thisScript->param('display');
} else {
    $display = 'login_prompt';
}

if (defined($thisScript->param('savecookie'))) {
    $savecookie = $thisScript->param('savecookie');
} else {
    if ($action eq 'login' && $display ne 'nothing') {
        $savecookie = 1;
    } else {
        $savecookie = 0;
    }
}

if (defined($thisScript->param('clearcookie'))) {
    $clearcookie = $thisScript->param('clearcookie');
} else {
    if ($action eq 'logout' && $display ne 'nothing') {
        $clearcookie = 1;
    } else {
        $clearcookie = 0;
    }
}

if (defined($thisScript->param('onerrdisplay'))) {
    $onerrdisplay = $thisScript->param('onerrdisplay');
} else {
    $onerrdisplay = 'login_prompt';
}

# Check required parameters
if (($action ne 'nothing')
&&  ($action ne 'login')
&&  ($action ne 'logout')
&&  ($action ne 'newpassword')
&&  ($action ne 'issecuritydisabled')
&&  ($action ne 'webauthentication')
&&  ($action ne 'guestlogin')
&&  ($action ne 'ispermitted')
&&  ($action ne 'isfastapermitted')
&&  ($action ne 'integralogin')) {
    $error = -1;
    $errorstring = $action . " is not a valid value for the action parameter";
    $sessionID="";
}

if (($display ne 'nothing')
&&  ($display ne 'login_prompt')
&&  ($display ne 'newpw_prompt')
&&  ($display ne 'logout_prompt')) {
    $error = -1;
    $errorstring = $display . " is not a valid value for the display parameter";
    $sessionID="";
}

if (($onerrdisplay ne 'nothing')
&&  ($onerrdisplay ne 'login_prompt')
&&  ($onerrdisplay ne 'newpw_prompt')
&&  ($onerrdisplay ne 'logout_prompt')) {
    $error = -1;
    $errorstring = $onerrdisplay . " is not a valid value for the onerrdisplay parameter";
    $sessionID="";
}

if (($action eq 'login')
&&  (!defined($thisScript->param('username')) || !defined($thisScript->param('password')))) {
    $error = -1;
    $errorstring = "action parameter is login, but username and password have not been defined";
    $sessionID="";
}

if (($action eq 'integralogin')
&&  (!defined($thisScript->param('username')) || !defined($thisScript->param('connectionID')) || !defined($thisScript->param('integradb')))) {
    $error = -1;
    $errorstring = "action parameter is integralogin, but username, connectionID and integradb have not been defined";
    $sessionID="";
}

if ($action eq 'newpassword') {
    if (defined($thisScript->param('username'))
    &&  defined($thisScript->param('newpw1'))
    &&  defined($thisScript->param('newpw2'))
    &&  defined($thisScript->param('password'))) {
        if ($thisScript->param('newpw1') ne $thisScript->param('newpw2')) {
            $error = -1;
            $errorstring = "Confirmation password does not match. Please try again.";
            $sessionID="";
        }
    } else {
        $error = -1;
        $errorstring = "Require username, newpw1, newpw2 and password parameters to change password";
        $sessionID="";
    }
}

if ($action eq 'ispermitted') {
    if (!$sessionID || !$thisScript->param('sectask')) {
        $error = -1;
        $errorstring = "The ispermitted action requires both sessionID and task identifier";
        $sessionID="";
    }
}

if ($action eq 'isfastapermitted') {
    if (!$sessionID || !$thisScript->param('fasta')) {
        $error = -1;
        $errorstring = "The isfastapermitted action requires sessionID and fasta file";
        $sessionID="";
    }
}

# Do any action now. Must not print errors or anything at this stage because
# headers have not been printed.
if (!$error) {
    if ($action eq 'login') {
        $session = new msparser::ms_session($thisScript->param('username'),
                                            $thisScript->param('password'));
        if ($session->isValid) {
            $sessionID = $session->getID;
            if (defined($thisScript->param('sectask'))) {
              unless ($session->isPermitted($thisScript->param('sectask'))) {
                $session->destroy;
                undef $session;
                $error = -2;
                $errorstring = 'User is not authorised to perform requested task';
                $sessionID="";
              }
            }
        } else {
            $error = $session->getLastError;
            $errorstring = $session->getLastErrorString;
            $sessionID="";
            
            # Special case - if the error is 'new password required' and
            # the onerrdisplay is set, need to reset onerrdisplay to 
            # show the update password form
            if (($error == $msparser::ms_errs::ERR_MSP_SECURITY_PASSWORDEXPIRED) 
            &&  ($onerrdisplay ne 'nothing')) {
                $onerrdisplay = 'newpw_prompt';
            }
        }
    }
    if ($action eq 'logout') {
        if ($sessionID) {
            $session = new msparser::ms_session($sessionID);
        } else {
            $session = new msparser::ms_session;
        }
        if ($session->isValid) {
            $session->destroy;
    #    } else {
    #        $error = $session->getLastError;
    #        $errorstring = $session->getLastErrorString;
        }
        undef $session;
        $sessionID="";
    }
    if ($action eq 'integralogin') {
        $session = new msparser::ms_session($thisScript->param('username'),
                                            $thisScript->param('connectionID'),
                                            $thisScript->param('integradb'));
        if ($session->isValid) {
            $sessionID = $session->getID;
            if (defined($thisScript->param('sectask'))) {
              unless ($session->isPermitted($thisScript->param('sectask'))) {
                $session->destroy;
                undef $session;
                $error = -2;
                $errorstring = 'User is not authorised to perform requested task';
                $sessionID="";
              }
            }
        } else {
            $error = $session->getLastError;
            $errorstring = $session->getLastErrorString;
            $sessionID="";
        }
    }
    if ($action eq 'newpassword') {
        $sec = new msparser::ms_security;
        if (!$sec->updatePassword("", # $session->getID, 
                                  $thisScript->param('username'),
                                  $thisScript->param('password'),
                                  $thisScript->param('newpw1'))) {
            $error = $sec->getLastError;
            $errorstring = $sec->getLastErrorString;
        }
    }
    if ($action eq 'issecuritydisabled') {
        $session = new msparser::ms_session;
        if ($session->isValid && $session->getUserType == $msparser::ms_user::USER_SECURITY_DISABLED ) {
            $sessionID = $session->getID;
            $error = 0;
            $errorstring = "";
        } else {
            $error = -3;
            $errorstring = "Mascot security is enabled";
            $sessionID="";
        }
    }
    
    if ($action eq 'webauthentication') {
        if (defined($ENV{'REMOTE_USER'})) {
            my ($sess_name) = $ENV{'REMOTE_USER'} . "_webserverauth";
            $session = new msparser::ms_session($sess_name);
            if ($session->isValid && $session->getUserType == $msparser::ms_user::USER_WEBAUTH ) {
                $sessionID = $session->getID;
            } else {
                $error = -4;
                $errorstring = $ENV{'REMOTE_USER'} . " is not set up to use web server authentication in Mascot";
                $sessionID="";
            }
        } else {
            $error = -4;
            $errorstring = "Web authentication is not enabled on your web server";
            $sessionID="";
        }
    }

    if ($action eq 'guestlogin') {
        $session = new msparser::ms_session('guest_guestsession');
        if ($session->isValid && $session->getUserID == $msparser::ms_user::USERID_GUEST) {
            $sessionID = $session->getID;
        } else {
            $error = -5;
            $errorstring = "Mascot guest account is disabled";
            $sessionID="";
        }
    }

    if ($action eq 'ispermitted') {
        $session = new msparser::ms_session($sessionID);
        if ($session->isValid) {
            unless ($session->isPermitted($thisScript->param('sectask'))) {
                $sessionID="";
                undef $session;
            }
        } else {
            $error = $session->getLastError;
            $errorstring = $session->getLastErrorString;
            $sessionID = "";
        }
    }

    if ($action eq 'isfastapermitted') {
        $session = new msparser::ms_session($sessionID);
        if ($session->isValid) {
            unless ($session->isFastaPermitted($thisScript->param('fasta'))) {
                $sessionID="";
                undef $session;
            }
        } else {
            $error = $session->getLastError;
            $errorstring = $session->getLastErrorString;
            $sessionID = "";
        }
    }
}

# If from the login or logout button, set/clear cookie.
# Has to be done before outputting any other html, so store up errors.
if ($savecookie && !$error) {
    $opts = new msparser::ms_security_options;
    if ($opts->getUseSessionCookies) {
        $cookie1 = $thisScript->cookie (
                    -name    => 'MASCOT_SESSION',
                    -value   => $session->getID,
                    -path    => '/'); # no expiry
        $cookie2 = $thisScript->cookie (
                    -name    => 'MASCOT_USERNAME',
                    -value   => $session->getUserName,
                    -path    => '/'); # no expiry
    } else {
        $cookie1 = $thisScript->cookie (
                    -name    => 'MASCOT_SESSION',
                    -value   => $session->getID,
                    -path    => '/',
                    -expires => '+3M'); # 3 months in the future
        $cookie2 = $thisScript->cookie (
                    -name    => 'MASCOT_USERNAME',
                    -value   => $session->getUserName,
                    -path    => '/',
                    -expires => '+3M'); # 3 months in the future
    }
    # The expires in the next line is for the page, not the cookie
    print $thisScript->header(-cookie => [$cookie1,$cookie2], -expires=>'-1d');
} elsif ($clearcookie) {
    $cookie1 = $thisScript->cookie (
                -name    => 'MASCOT_SESSION',
                -value   => '',
                -path    => '/',
                -expires => '-1d'); # -1d means delete cookie
    $cookie2 = $thisScript->cookie (
                -name    => 'MASCOT_USERNAME',
                -value   => '',
                -path    => '/',
                -expires => '-1d'); # -1d means delete cookie
    # The expires in the next line is for the page, not the cookie
    print $thisScript->header(-cookie => [$cookie1,$cookie2], -expires=>'-1d');        
} else {
    print $thisScript->header(-expires=>'-1d');
}

# Now the display
# Print html 'header' if doing a display
if ((!$error && $display ne 'nothing')
||  ($error && defined($onerrdisplay) && $onerrdisplay ne 'nothing')) {
    &printHeader1("Matrix Science - Mascot Login");
    &printHeader2("", "Mascot Login", 0);
    print "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0>\n";
    print "<TR><TD COLSPAN=2>\n";
    print "<H1>Mascot Login</H1>\n";

    if (defined($onerrdisplay) && $error) {
        print "<B><FONT COLOR=#FF0000>Error: " . $errorstring . "</FONT></B><p>\n";
        if ($onerrdisplay eq 'login_prompt' ) {
            &displayLoginForm;
        } elsif ($onerrdisplay eq 'newpw_prompt' ) {
            &displayNewPasswordForm;
        } elsif ($onerrdisplay eq 'logout_prompt') {
            &displayLogoutForm;
        } else {
            print "Error with onerrdisplay parameter<br>\n";
        }
    } else {
        if ($display eq 'login_prompt') {
            &displayLoginForm;
        } elsif ($display eq 'newpw_prompt') {
            &displayNewPasswordForm;
        } elsif ($display eq 'logout_prompt') {
            &displayLogoutForm;
        } else {
            print "Error with display parameter<br>\n";
        }
    }
    
  print "</TD></TR>\n";
  print "</TABLE>\n";
  &printFooter();
  print "</BODY>\n";
  print "</HTML>\n";

} elsif (defined($thisScript->param('referer'))) {
    &displayReferer();
} else {
    # text output
    print "error=" . $error . "\n";
    print "errorstring=" . $errorstring . "\n";
    print "sessionID=" . $sessionID . "\n";
}


sub displayLoginForm {
    print "<form ID=\"mascot_login\" NAME=\"mascot_login\" action=\"" . $thisScript->url(-relative=>1) . "\" ENCTYPE=\"multipart/form-data\" METHOD=\"POST\">\n";
    print "<table align=\"center\" border=\"0\" cellspacing=\"0\" cellpadding=\"3\">\n";
    print "<tr><td>Username:</td><td>\n";
    print "<input type=\"text\" ID=\"username\" name=\"username\" value=\"" 
      . $thisScript->cookie('MASCOT_USERNAME') 
      . "\" maxlength=\"40\">\n";
    print "</td></tr>\n";
    print "<tr><td>Password:</td><td>\n";
    print "<input type=\"password\" name=\"password\" maxlength=\"50\">\n";
    print "</td></tr>\n";
    print "<tr><td colspan=\"2\" align=\"right\">\n";
    print "<input type=\"submit\" name=\"submit\" value=\"Login\">\n";
    print "</td></tr>\n";
    print "<tr><td colspan=\"2\" align=\"right\">&nbsp;</td></tr>\n";
    print "<tr><td>&nbsp;</td><td><A HREF=\"./edit_profile.pl\">Edit profile</A></td></tr>\n";
    print "</table>\n";
    if (defined($thisScript->param('referer'))) {
        print "<input type=\"hidden\" name=\"referer\" value=\"" . $thisScript->param('referer') . "\">\n";
        print "<input type=\"hidden\" name=\"display\" value=\"nothing\">\n";
    } else {
        print "<input type=\"hidden\" name=\"display\" value=\"logout_prompt\">\n";
    }
    print "<input type=\"hidden\" name=\"savecookie\" value=\"1\">\n";
    print "<input type=\"hidden\" name=\"action\" value=\"login\">\n";

    print "<input type=\"hidden\" name=\"onerrdisplay\" value=\"login_prompt\">\n";
    print "</form>\n";
    print "<script type=\"text/javascript\"><!--\n";
    if ($thisScript->cookie('MASCOT_USERNAME')) {
      print "document.mascot_login.password.focus();\n";
    } else {
      print "document.mascot_login.username.focus();\n";
    }
    print "//--></script>\n";
}

sub displayLogoutForm {
    print "<form action=\"" . $thisScript->url(-relative=>1) . "\" ENCTYPE=\"multipart/form-data\" METHOD=\"POST\">\n";
    if ($sessionID) {
        print "<input type=\"hidden\" name=\"sessionID\" value=\"" . $sessionID . "\">\n";
    }
    print "<input type=\"hidden\" name=\"action\" value=\"logout\">\n";
    print "<input type=\"hidden\" name=\"display\" value=\"login_prompt\">\n";
    print "Logged in as " . $session->getUserName . "&nbsp;";
    print "<input type=\"submit\" name=\"logout\" value=\"Logout\">\n";
    print "</form>\n";
}

sub displayNewPasswordForm {
    print "<form ID=\"mascot_newpw\" NAME=\"mascot_newpw\" action=\"" . $thisScript->url(-relative=>1) . "\" ENCTYPE=\"multipart/form-data\" METHOD=\"POST\">\n";
    print "<table align=\"center\" border=\"0\" cellspacing=\"0\" cellpadding=\"3\">\n";
    print "<tr><td>Old password:</td><td>\n";
    print "<input type=\"password\" id=\"password\" name=\"password\" maxlength=\"40\">\n";
    print "</td></tr>\n";
    print "<tr><td>New password:</td><td>\n";
    print "<input type=\"password\" name=\"newpw1\" maxlength=\"50\">\n";
    print "</td></tr>\n";
    print "<tr><td>Confirm new password:</td><td>\n";
    print "<input type=\"password\" name=\"newpw2\" maxlength=\"50\">\n";
    print "</td></tr>\n";
    print "<tr><td colspan=\"2\" align=\"right\">\n";
    print "<input type=\"hidden\" name=\"action\" value=\"newpassword\">\n";
    print "<input type=\"submit\" name=\"submit\" value=\"Change password\">\n";
    print "</td></tr>\n";
    print "</table>\n";
    if (defined($thisScript->param('referer'))) {
        print "<input type=\"hidden\" name=\"referer\" value=\"" . $thisScript->param('referer') . "\">\n";
    } else {
        print "<input type=\"hidden\" name=\"display\" value=\"login_prompt\">\n";
    }
    print "<input type=\"hidden\" name=\"onerrdisplay\" value=\"newpw_prompt\">\n";
    print "<input type=\"hidden\" name=\"username\"  value=\"" . $thisScript->param('username') . "\">\n";
    print "</form>\n";

    print "<script type=\"text/javascript\"><!--\n";
    print "document.mascot_login.username.focus();\n";
    print "//--></script>\n";
}


# Cannot just use the cgi redirect function:
# - The redirect() function redirects the browser to a different URL. 
# - If you use redirection like this, you should not print out a header as well.
# Which would also mean that you cannot set cookies. So, do it the hard way.
sub displayReferer() {
    print "<html>\n";
    print "<head>\n";
    print "<title>Login</title>\n";
    print "</head>\n";
    print "<body>\n";
    print "Logged in successfuly - please wait<br>\n";
    print "<SCRIPT LANGUAGE=\"JavaScript\">\n";
    print "<!-- Begin hiding Javascript from old browsers.\n";
    print "if(window.navigator.userAgent.indexOf(\"MSIE\") != -1){\n";
    print "  window.location.replace(\"" . $thisScript->param('referer') . "\");\n";
    print "} else if (window.location.replace == null){\n";
    print "  window.location.assign(\"" . $thisScript->param('referer') . "\");\n";
    print "} else {\n";
    print "  window.location.replace(\"" . $thisScript->param('referer') . "\");\n";
    print "}\n";
    print "\n";
    print "\n";
    print "// End hiding Javascript from old browsers. -->\n";
    print "</SCRIPT>\n";
    print "<NOSCRIPT>\n";
    print "<A HREF=\"" . $thisScript->param('referer') . "\">Click here to if you are not redirected automatically</A>",
    print "</NOSCRIPT>\n";
    print "</body>\n";
    print "</html>\n";
}

Copyright © 2022 Matrix Science Ltd.  All Rights Reserved. Generated on Thu Mar 31 2022 01:12:29