/*
* This software and supporting documentation were developed by
*
* Siemens Corporate Technology
* Competence Center Knowledge Management and Business Transformation
* D-81730 Munich, Germany
*
* Authors (representing a really great team ;-) )
* Stefan B. Augustin, Thorbj�rn Hansen, Manfred Langen
*
* This software is Open Source under GNU General Public License (GPL).
* Read the text of this license in LICENSE.TXT
* or look at www.opensource.org/licenses/
*
* Once more we emphasize, that:
* THIS SOFTWARE IS MADE AVAILABLE, AS IS, WITHOUT ANY WARRANTY
* REGARDING THE SOFTWARE, ITS PERFORMANCE OR
* FITNESS FOR ANY PARTICULAR USE, FREEDOM FROM ANY COMPUTER DISEASES OR
* ITS CONFORMITY TO ANY SPECIFICATION. THE ENTIRE RISK AS TO QUALITY AND
* PERFORMANCE OF THE SOFTWARE IS WITH THE USER.
*
*/
// P_LoginPage
// ************ package ******************************************************
package appl.Portal.Personalize.GUI;
// ************ imports ******************************************************
// KFM packages
import KFM.Exceptions.*;
import KFM.GUI.*;
import KFM.GUI.beans.*;
import KFM.GUI.Templates.*;
import KFM.Servlet.*;
import KFM.*;
import KFM.log.*;
import KFM.DateTimeServices.*;
// servlet packages
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.*;
import mod.AccountDB.GUI.DBAuthorizedUserState2;
// Personalize packages
import appl.Portal.Personalize.DB.*;
import appl.Portal.Personalize.Utils.PersonalizeErrorCodes;
import appl.Portal.Personalize.GUI.P_Params;
/** Description: P_LoginPage.
*
* Note: Hacked to cooperate with `P_Servlet� (SIP's servlet `Personalize�).
*
* @version 0.1 (98 07 24)
*/
public class P_LoginPage extends LoginPage
{
// ************************************************************
// Variables
// ************************************************************
String templatePath;
// @@@ Hack! We need KFMIF2 for SieMarks.
// KfmTemplate templ;
PortalTemplate templ;
String registerUrl;
String adminEmail;
String mFooterTitle ="";
String mFooterUrl = "";
/** HACK: These three are changed when used by SIP's servlet `Personalize�. */
String mUSERNAME = SessionParam.USERNAME;
String mPASSWORD = SessionParam.PASSWORD;
String mTAN = SessionParam.TAN;
private ResourceBundle mBundle = null;
// ************************************************************
// Methods
// ************************************************************
/** DEPRECATED constructor.
*
*@param aLanguages Array of possible languages.
* In SIP, e.g. `{"de", "en"}�.
* In previous projects, e.g. `{"german", "english"}�
* @deprecated
*/
private P_LoginPage (
String bbasicURL, // KFM_Servlet2 has `myreq.getServletPath()� here.
String theTemplatePath,
String theTemplateName,
String theDefaultStylesheet,
String aRegisterUrl,
String aadminEmail,
String[] llanguage)
{
super(bbasicURL, "", llanguage);
templatePath = theTemplatePath;
registerUrl = aRegisterUrl;
adminEmail = aadminEmail;
templ = new /*KfmTemplate*/PortalTemplate(templatePath, theTemplateName, theDefaultStylesheet, /*""*/ this);
templ.setDebug(debug);
}
/** Default constructor.
*
*@param aLanguages Array of possible languages.
* In SIP, e.g. `{"de", "en"}�.
* In previous projects, e.g. `{"german", "english"}�
*/
public P_LoginPage (
String aBasicURL, // KFM_Servlet2 has `myreq.getServletPath()� here.
String aTemplateName,
KFM_Servlet2_Props aServletProps,
String[] aLanguages)
{
this(aBasicURL,
aServletProps.TemplateDir,
aTemplateName,
aServletProps.DefaultStylesheet,
aServletProps.RegisterUrl,
aServletProps.AdminEmail,
aLanguages);
mFooterTitle = aServletProps.FooterTitle;
mFooterUrl = aServletProps.FooterUrl;
}
/** HACK: Constructor for use by SIP's `Personalize� servlet.
*
*@param aLanguages Array of possible languages.
* In SIP, e.g. `{"de", "en"}�.
* In previous projects, e.g. `{"german", "english"}�
*@param aIsPersonalize Set to true if and only if called by SIP's `Personalize� servlet.
*/
public P_LoginPage (
String aBasicURL, // KFM_Servlet2 has `myreq.getServletPath()� here.
String aTemplateName,
KFM_Servlet2_Props aServletProps,
String[] aLanguages,
boolean aIsPersonalize)
{
this(aBasicURL, aTemplateName, aServletProps, aLanguages);
//HACK
if(aIsPersonalize) {
mUSERNAME = "members_nick";
mPASSWORD = "members_password";
mTAN = "sessionid";
} else {
// Use default values that were already set.
}
}
public void write (
UserState userState,
HttpServletRequest theReq,
PrintWriter aWriter)
throws java.io.IOException, KFMException
{
// do nothing
}
/** Method which will always be called to handle an http request.
*
* <P>Supported KFM labels:</P>
*
* <PRE>
* KFMIF NewLogin
* KFMIF WrongLogin
* KFMIF NewOrWrongLogin
* KFMIF SecurityCheck
* KFMIF ServerRestartedInsideFW
* KFMIF NotServerRestartedInsideFW
*
* KFM StartForm
* KFM AdminEmail -- Which might be the Admin or the Hotline.
* KFM RegisterUrl -- Goes to Subscribe's Person_New.
* KFM ActivateUrl -- Goes to Subscribe's UpdatePermission
* </PRE>
*/
public void write (
UserState userState,
HttpServletRequest aReq,
HttpServletResponse aRes)
throws java.io.IOException, KFMException
{
super.write(userState, aReq, aRes);
KFM_HttpServletRequest req = new KFM_HttpServletRequest(aReq);
String tLang = req.getParam(P_Params.LANGUAGE);
if (tLang == "")
tLang = "en"; //default
// * IN params
Language currentLanguage = new Language(tLang);
//Get the current resourcebundle for localized KFM Tag messages
//NIC: we have to get the bundle every time here, not only if it
//is null, because the user can change its language
mBundle = ResourceBundle.getBundle("KFM.Gui.TemplateLoginPage",
new Locale(currentLanguage.toString(),""));
String currentUser = req.getParam(mUSERNAME);
boolean tIsStandalone = ! (req.getParam(P_Params.STANDALONE).equals("no"));
String tAuthtype = req.getParam(P_Params.MEMBERS_AUTHTYPE);
// In case of plain login with sso set standalone to yes to
// pop up the login screen.
// Else you will get another profile as for the other authtypes because a new
// root category would be created (because plain login has no tcgid).
if (!tIsStandalone && tAuthtype.equals("plain"))
{
tIsStandalone = !tIsStandalone;
}
// The servlet has to relogin (because of Server restart), but we are not standalone:
// We want the template to be able to get the authentication data from the framework
boolean tIsRestartedInsideFW = ! tIsStandalone;
String tTcgid="";
// `login� means "first login attempt".
// `yes� means "this is not the first login attempt, user entered password wrong".
// All else mean "security check", e.g. unallowed multiple access or server restart.
String tTryLogin = req.getParam(SessionParam.TRYLOGIN);
// * Prepare the new request
req.removeParam(mUSERNAME);
req.removeParam(mPASSWORD);
req.removeParam(mTAN);
req.removeParam(P_Params.LANGUAGE);
// Here `yes� means "this is not the first login, user entered password wrong".
req.replaceParam(SessionParam.TRYLOGIN, "yes");
// 'new' means that parallel logins are allowed
req.replaceParam(SessionParam.UTASK, "new");
// req.removeParam(P_Params.EXECUTE);
// * Template stuff
templ.startWithLanguage(currentLanguage);
// When standalone="no", some behavior may be different
templ.replaceAllKfmIf("Standalone", tIsStandalone);
templ.replaceAllKfmIf("NotStandalone", ! tIsStandalone);
//
// ** Handle KFMIFs for new/wrong/security login
//
if (tTryLogin.equals("login") ||
(tTryLogin.equals("") && (currentUser.equals("")))) {
// `login� means "first login attempt".
// Special case: When currentUser is empty, we don't want the new login messages
boolean tSpecialCase = (tTryLogin.equals("") && (currentUser.equals("")));
templ.replaceAllKfmIf("NewLogin", ! tSpecialCase);
templ.replaceAllKfmIf("WrongLogin", false);
templ.replaceAllKfmIf("NewOrWrongLogin", ! tSpecialCase);
templ.replaceAllKfmIf("SecurityCheck", false);
templ.replaceAllKfmIf("NotSecurityCheck",true);
// Personalize (SCD)
deletePersonalizeESTags ();
templ.replaceAllKfmIf("BackButton", false);
} else if(tTryLogin.equals("yes")) {
// `yes� means "this is not the first login attempt, user entered password wrong".
// Personalize: SCD and PKI
if (userState instanceof P_DBAuthorizedUserState2){
P_DBAuthorizedUserState2 tUserState = (P_DBAuthorizedUserState2)userState;
tAuthtype = req.getParam(P_Params.MEMBERS_AUTHTYPE);
String tMultiple = req.getParam("multiple");
boolean tIsMultiple = tMultiple.equals("yes");
if (!tAuthtype.equals("plain")){
String tSubstatus = ((P_DBAuthorizedUserState2)userState).mSubstatus;
String tInfoUrl = ((P_DBAuthorizedUserState2)userState).mESInfoUrl;
templ.replaceAllKfmIf("WrongLogin", false);
setPersonalizeTags (tSubstatus, tInfoUrl, tIsMultiple);
} else {
templ.replaceAllKfmIf("WrongLogin", true);
deletePersonalizeESTags ();
}
} else {
templ.replaceAllKfmIf("WrongLogin", true);
deletePersonalizeESTags ();
}
templ.replaceAllKfmIf("NewLogin", false);
templ.replaceAllKfmIf("NewOrWrongLogin", true);
templ.replaceAllKfmIf("SecurityCheck", false);
templ.replaceAllKfmIf("NotSecurityCheck",true);
// Personalize: We have to distingish between first login (login via gadget) and
// login after session was expired (login via newLogin)
// in case of first login we do not want a back button, in case of newLogin we want a back
// button
if (req.getParam("firstLogin").equals("yes")){
templ.replaceAllKfmIf("BackButton", false);
} else {
templ.replaceAllKfmIf("BackButton", true);
}
} else {
// All else mean "security check", e.g. unallowed multiple access or server restart.
templ.replaceAllKfmIf("NewLogin", false);
templ.replaceAllKfmIf("WrongLogin", false);
templ.replaceAllKfmIf("NewOrWrongLogin", false);
templ.replaceAllKfmIf("SecurityCheck", true);
templ.replaceAllKfmIf("NotSecurityCheck",false);
// Personalize: SCD
deletePersonalizeESTags ();
templ.replaceAllKfmIf("BackButton", false);
// I wrote the following line to activate the whole application
// after a security check. But there was one fatal problem:
// if the user is a POST form before the check, he maybe
// has more than 1 kByte HTTP params. So, if we activate the
// complete application, the frameset will use the GET method
// and will loose some HTTP param content then.
//
// !!! Lession learnt: Don't reactivate the whole application!!!
//
// (Maybe later we will hold the state of the params in the
// userstate, but then other problems occur: What happens if
// the server crashes exactly at this time? The HTTP data would
// be lost!
//
// req.replaceParam(P_Params.ACTION, P_Params.V_CREATEAPPLICATION);
}
templ.replaceAllKfmIf("ServerRestartedInsideFW", tIsRestartedInsideFW);
if (userState instanceof DBAuthorizedUserState2)
{
DBAuthorizedUserState2 tUserState = (DBAuthorizedUserState2)userState;
templ.replaceAllKfm("SessionId", tUserState.mp_SessionId);
templ.replaceAllKfm("Utask", tUserState.mp_Utask);
templ.replaceAllKfm("Server", tUserState.mp_Server);
if (!tUserState.mIsAuthorized)
{
templ.replaceAllKfmIf("AuthenticationFailed", true);
templ.replaceAllKfmIf("HasNoPermission", false);
}
else if (!tUserState.mHasPermission)
{
templ.replaceAllKfmIf("AuthenticationFailed", false);
templ.replaceAllKfmIf("HasNoPermission", true);
}
}
else if (userState instanceof P_DBAuthorizedUserState2)
{
Hashtable[] tSCDEntries =((P_DBAuthorizedUserState2)userState).mSCDEntries;
replacePersonalizeTags((P_DBAuthorizedUserState2)userState, req, tSCDEntries);
}
templ.replaceAllKfmIf("NotServerRestartedInsideFW", ! tIsRestartedInsideFW);
// * KFMs
// KFM StartForm
templ.replaceAllKfm("StartForm",
newFormOpenTag("LoginForm") + req.toHiddenParams());
// KFM AdminEmail -- Which might be the Admin or the Hotline.
templ.replaceAllKfm("AdminEmail", adminEmail);
// KFM RegisterUrl -- Goes to Subscribe's Person_New.
templ.replaceAllKfm("RegisterUrl",
"<a href='" + registerUrl + "&language=" + currentLanguage.toString() + "'>");
// KFM ActivateUrl -- Goes to Subscribe's UpdatePermission
templ.replaceAllKfm("ActivateUrl",
"<a href='" + registerUrl + "&language=" + currentLanguage.toString()
+ "&execute=UpdatePermissions'>");
// KFM Username
templ.replaceAllKfm("Username", currentUser);
//
// * Insert text fields
//
templ.replaceAllKfmTextInputField("InputUsername", mUSERNAME, currentUser, "40", false);
templ.replaceAllKfmInputPassword("InputPassword", mPASSWORD, "", "20");
templ.replaceAllKfm("Nick", currentUser);
templ.replaceAllKfm("Authtype", req.getParam(P_Params.MEMBERS_AUTHTYPE));
//
// * Decide if more than one language is supported
//
if(null == mLanguages || 1 == mLanguages.length) {
templ.replaceAllKfmIf("MultiLanguage", false);
templ.replaceAllKfmIf("SingleLanguage", true);
if (1 == mLanguages.length) {
req.replaceParam(P_Params.LANGUAGE, mLanguages[0]);
} else {
req.removeParam(P_Params.LANGUAGE);
}
} else {
templ.replaceAllKfmIf("MultiLanguage", true);
templ.replaceAllKfmIf("SingleLanguage", false);
String langSelector = "\n<SELECT name=\"" + P_Params.LANGUAGE + "\">";
for(int xxx=0; xxx < mLanguages.length; xxx++) {
langSelector += "\n<OPTION value=\"" + mLanguages[xxx] + "\"";
if (currentLanguage.toString().equals(mLanguages[xxx])) {
langSelector += " selected";
}
langSelector += ">" + mLanguages[xxx] + "</OPTION>";
}
langSelector += "\n</SELECT>";
templ.replaceAllKfm("Language", langSelector);
}
templ.execute();
templ.write(aRes.getWriter());
}
/** Sets the required Personalize Tags in the login page.
*
*/
private void setPersonalizeTags (String aSubstatus, String aESInfoUrl, boolean aMultiple)
{
if ((aSubstatus.startsWith("CHANGEPW_0")) || (aSubstatus.startsWith("CHANGEPW_1")))
{
//the data security rules are violated
String tSubstatus = aSubstatus;
String tPrefix = "CHANGEPW_";
tSubstatus = tSubstatus.substring(tPrefix.length(), tSubstatus.length());
aSubstatus = "CHANGEPW_PASSWORD_NOT_CONSISTENT_WITH_IS_RULES_DETAILED";
String tStatsList = "";
for (int i = 0; i < 5; i ++)
{
tStatsList += "m_statList["+i+"]=" + (tSubstatus.charAt(i)==('1')? "true" : "false") + ";\n";
}
templ.replaceAllKfm("statList", tStatsList);
}
if (aMultiple && aSubstatus.equals("LOGIN_WRONG_PASSWORD"))
{
// set indication for the framework
aSubstatus = "LOGIN_MULTIPLE_WRONG_PASSWORD";
}
if (aSubstatus.endsWith("GET_NO_ANSWER_FROM_AUTHSERVLET_PROBLEM"))
{
String tErrorMsg = getLocalizedString(
mBundle,
"setPersonalizeTags.getNoAnswerFromAuthServlet",
"Connection to authentication service is too slow!");
templ.replaceAllKfm("ActionProcessingError", tErrorMsg);
}
else if (aSubstatus.endsWith("PERSONALIZE_ERROR_PROBLEM"))
{
String tErrorMsg = getLocalizedString(
mBundle,
"setPersonalizeTags.PersonalizeError",
"General Error in PersonalizeServlet!");
templ.replaceAllKfm("ActionProcessingError", tErrorMsg);
}
else if (aSubstatus.endsWith("ACTION_PROCESSING_PROBLEM"))
{
String tErrorMsg = getLocalizedString(
mBundle,
"setPersonalizeTags.ActionProcessing",
"General Error in Authentication Service!");
templ.replaceAllKfm("ActionProcessingError", tErrorMsg);
}
// set KFM tag belonging to the given substatus to true, other
// KFM tags to false
Enumeration tErrorCodes = PersonalizeErrorCodes.getErrorCodeList();
// set all KFM Tags to false
while (tErrorCodes.hasMoreElements())
{
String tErrorCode = (String) tErrorCodes.nextElement();
if (aSubstatus.equals(tErrorCode)){
templ.replaceAllKfmIf(tErrorCode, true);
} else {
templ.replaceAllKfmIf(tErrorCode, false);
}
}
// display help link if it is available
if ((aESInfoUrl != null) && !aESInfoUrl.equals("")){
templ.replaceAllKfmIf("Link", true);
templ.replaceAllKfm("HelpLink", aESInfoUrl);
} else {
templ.replaceAllKfmIf("Link", false);
}
}
/**
* Delete the Personalize ES KFM tags
*/
private void deletePersonalizeESTags ()
{
Enumeration tErrorCodes = PersonalizeErrorCodes.getErrorCodeList();
// set all KFM Tags to false
while (tErrorCodes.hasMoreElements())
{
String tErrorCode = (String) tErrorCodes.nextElement();
templ.replaceAllKfmIf(tErrorCode, false);
}
templ.replaceAllKfmIf("Link", false);
templ.replaceAllKfm("utask", "");
}
private void replacePersonalizeTags(
P_DBAuthorizedUserState2 aUserState,
KFM_HttpServletRequest aReq,
Hashtable[] aSCDEntries)
{
templ.replaceAllKfm("dn", aUserState.mDN);
templ.replaceAllKfm("tcgid", aUserState.mTcgid);
templ.replaceAllKfm("utask", aUserState.mUtask);
templ.replaceAllKfm("Server", aUserState.mServer);
String tDNList="";
String tTcgIDList="";
String [] tDNs = aUserState.mDNs;
String [] tGIDs = aUserState.mGIDs;
for(int i = 0; (tDNs != null && i < tDNs.length); i++) {
tDNList += "m_list["+i+"]=\"" + tDNs[i] + "\";\n";
tTcgIDList += "m_tcgIDlist["+i+"]=\""+tGIDs[i]+"\";\n";
}
templ.replaceAllKfm("dnList", tDNList);
templ.replaceAllKfm("tcgIDList", tTcgIDList);
}
/** Creates a default footer to the actual page.
*
* <P>It includes the Title as a link, a copyright and a timestamp.
* The result string will be returned.</P>
*
* @param language Either "german" or "english".
* @return Footer HTML string.
*
* Note: Snarfed from `Portal_ApplicationPage::createFooter�.
*/
public String createFooter (String language)
{
String tFooter = "<P>\n"
+ "<address><hr>\n"
+ "<table width='100%'><tr>\n"
+ "<td><h6>" + mFooterTitle + "</h6>"
+ "<td><h6>� Siemens AG, D-81730 M�nchen</h6></td>\n"
+ "<td align=right><h6>" + KFM_DateTimeService.createTimeStamp()
+ "</h6></td>\n"
+ "</tr></table>\n"
+ "</address>\n";
return tFooter;
}
/**
* Wraps mResourceBundle.getString(), except that when the named resource is not found,
* it returns the specific default instead of throwing an exception.
*
* @see David Flanagan, Java Examples In A Nutshell 2nd, Example 10-22
*/
private String getLocalizedString(ResourceBundle aBundle, String aKey, String aDefault)
{
try {
return aBundle.getString(aKey);
}
catch (MissingResourceException e) {
KFMSystem.log.error("Converter::getLocalizedString: resource file(s) " + aBundle.toString()
+ " has(have) no key '" + aKey + "', reverting to default");
return aDefault;
}
}
}