// The contents of this file are subject to the Mozilla Public License Version 1.1
// (the "License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
// 
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
// WARRANTY OF ANY KIND, either express or implied. See the License for the specific
// language governing rights and limitations under the License.
// 
// The Original Code is the Venice Web Communities System.
// 
// The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
// for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
// Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
// 
// Contributor(s): 

importPackage(Packages.org.sourceid.sso.xml);
importClass(Packages.com.silverwrist.dynamo.Namespaces);
importClass(Packages.com.silverwrist.dynamo.UserInfoNamespace);
importPackage(Packages.com.silverwrist.dynamo.iface);
importPackage(Packages.com.silverwrist.dynamo.mail);
importPackage(Packages.com.silverwrist.dynamo.util);
importClass(Packages.com.silverwrist.venice.VeniceNamespaces);
importPackage(Packages.com.silverwrist.venice.content);
importPackage(Packages.com.silverwrist.venice.frame);
importPackage(Packages.com.silverwrist.venice.session);

req = bsf.lookupBean("request");           // get request
rhelp = bsf.lookupBean("request_help");    // get request helper
target = rhelp.getParameterString("tgt");  // get the target for this operation
if (target==null)
  target = "top.js.vs";
vlib.setOnError(req,target);

session = rhelp.getSession();              // get the session
user = vlib.getUser(session);
if (!(user.isAnonymous()))  // user already logged in, just bounce back to where we came from
  dynamo.scriptReturn(new Redirect("SERVLET",target));

// Load the login dialog.
loader = cast.queryDialogLoader(req);
dlg = loader.loadDialogResource("login.dlg.xml");

if (rhelp.isVerb("GET"))
{ // just display the dialog and return
  dlg.setValue("tgt",target);
  vlib.setLocation(req,target);

  // Get an error message that was left here by the SSO process, if any.
  msg = null;
  try
  { // get the message
    msg = session.getObject("venice-sso:","failure.message") + "";
    session.removeObject("venice-sso:","failure.message");

  } // end try
  catch (e)
  { // ObjectNotFoundException, presumably
    msg = null;

  } // end catch

  if (msg!=null)
    dlg.setErrorMessage(msg);

  // Get the ProviderDirectory and the list of configured identity providers.
  pdir = sourceid.getProviderDirectory(req);
  idp_list = pdir.getIDPList();

  // Create the return value.
  rc = new VelocityView(vlib.dialogFrameTitle(dlg),"sourceid/login_dialog.vm");
  rc.setParameter("loginDialog",dlg);
  rc.setParameter("idpList",idp_list);
  rc.setParameter("target",target);
  dynamo.scriptReturn(rc);
  
} // end if

// everything that follows is for a POST operation
op = dlg.getClickedButton(req) + "";
if (op=="cancel")  // user cancelled login - bounce back to the target
  dynamo.scriptReturn(new Redirect("SERVLET",target));
  
dlg.load(req);  // load dialog contents
if (op=="reminder")
{ // generate a password reminder
  errmsg = null;
  user = vlib.lookupUser(req,dlg.getValue("user"));
  if (user!=null)
  { // user found...
    if (user.isAnonymous()) // can't do this for the Anonymous_Honyak account
      errmsg = "This account cannot be explicitly logged into.  Please try again.";
    else
    { // get the user's password reminder
      reminder_msg = PropertyUtils.getPropertyNoErr(user,VeniceNamespaces.USER_SETTINGS_NAMESPACE,
                                                    "password.reminder");
      if (reminder_msg==null)
        reminder_msg = "";

      // generate and set authentication for the password recovery system
      auth = vlib.randomRecoveryAuth() + "." + dynamo.currentTimeMillis();
      user.setAuthenticationData(user,VeniceNamespaces.SESSION_CONTROL_NAMESPACE,"password.recovery","",auth);

      // create and send the reminder E-mail message
      mailprov = cast.queryMailMessageProvider(req);
      msg = mailprov.createSystemMessage(req);
      msg.addRecipient(MailMessage.RECIP_TO,user.getEMailAddress());
      globals = vcast.getGlobalPropertiesStore(req);
      msg.setSubject(globals.getObject(VeniceNamespaces.MAIL_MESSAGES_NAMESPACE,
                                       "reminder.message.title").toString());
      blocks = vcast.getGlobalBlocksStore(req);
      msg.setText(blocks.getObject(VeniceNamespaces.MAIL_MESSAGES_NAMESPACE,"reminder.message").toString());
      msg.setVariable("username",user.getName());
      msg.setVariable("reminder",reminder_msg);
      msg.setVariable("uid",cast.toIntegerObject(user.getUID()));
      msg.setVariable("auth",auth);
      msg.send();

      // set the error message and prepare the dialog for reset
      errmsg = "Password reminder has been sent to the E-mail address for user '" + user.getName() + "'.";
      dlg.setValue("pass",null);

    } // end else

  } // end if
  else // user not found - bounce back with an error message
    errmsg = "The user account you have specified does not exist.  Please try again.";

  if (errmsg!=null)
  { // set the error message and bounce back the dialog
    dlg.setErrorMessage(errmsg);
    dlg.setValue("user",null);
    dlg.setValue("pass",null);
    vlib.setLocation(req,target);
    dynamo.scriptOutput(new FrameDialog(dlg));

  } // end if
  else   // this ain't right
    dynamo.scriptOutput(new ErrorBox("Internal Error","Unknown outcome from password reminder",
                                     "SERVLET",target));

} // end if
else if (op=="login")
{ // attempt to log the user in!
  errmsg = null;
  new_user = vlib.lookupUser(req,dlg.getValue("user"));
  if (new_user!=null)
  { // the user is present - we can do this
    if (new_user.isAnonymous())
    { // can't log in as Anonymous_Honyak, foo!
      errmsg = "This account cannot be explicitly logged into.  Please try again.";
      audit.write(req,new_user,VeniceNamespaces.USER_EVENT_NAMESPACE,"login.fail","Anonymous user");
      dlg.setValue("user",null);
      dlg.setValue("pass",null);

    } // end if
    else if (new_user.isLocked())
    { // account locked out - sorry!
      errmsg = "This account has been locked out.  Please contact the system administrator for assistance.";
      audit.write(req,new_user,VeniceNamespaces.USER_EVENT_NAMESPACE,"login.fail","Locked Account");
      dlg.setValue("pass",null);

    } // end else if
    else
    { // OK, we can try to authenticate with this account!
      if (new_user.authenticate(UserInfoNamespace.NAMESPACE,UserInfoNamespace.AUTH_DEFAULT,"",
                                dlg.getValue("pass")))
      { // authenticated OK - set user into session
        logger.debug("User \"" + new_user.getName() + "\" logged in successfully");
        session.setObject(SessionInfoParams.NAMESPACE,SessionInfoParams.ATTR_USER,new_user);
        audit.write(req,new_user,VeniceNamespaces.USER_EVENT_NAMESPACE,"login.ok");
        new_user.setLastAccessDate(new_user,new java.util.Date());

        // Now set up this user's default objects.
        dynamo.exec("/util/setup_user.js");

        if (cast.toBoolean(dlg.getValue("saveme")))
        { // user wants a cookie - generate one
          source = vlib.randomString(32);
          auth = vlib.randomString(32);
          try
          { // set the user authentication data
            new_user.setAuthenticationData(new_user,VeniceNamespaces.SESSION_CONTROL_NAMESPACE,"cookie",
                                           source,auth);

            // save the persistent cookie value
            cval = "VQAT2:" + new_user.getUID() + ":" + source + ":" + auth;
            cctrl = cast.queryCookieControl(req);
            cctrl.putPersistentCookie(venice_session.loginCookieName,cval,venice_session.loginCookieAge);

            // set the cookie authentication source so we can delete the auth info later at logout
            session.setObject(SessionInfoParams.NAMESPACE,SessionInfoParams.ATTR_COOKIE_AUTH_SOURCE,source);

          } // end try
          catch (e)
          { // ignore exception here
            logger.warn("cookie setup process threw exception",e);

          } // end catch

        } // end if

        // Has the user verified their E-mail address yet?  If not, bounce them there.
	if (PropertyUtils.hasProperty(new_user,VeniceNamespaces.USER_SETTINGS_NAMESPACE,"confirmation.number"))
          dynamo.scriptReturn(new Redirect("SERVLET","verify_email.js.vs?tgt="
                                                     + stringutils.encodeURL(target)));
        else
          dynamo.scriptReturn(new Redirect("SERVLET",target));

      } // end if
      else
      { // the password is wrong - please try again
        errmsg = "The password specified for this user account is incorrect.  Please try again.";
        audit.write(req,new_user,VeniceNamespaces.USER_EVENT_NAMESPACE,"login.fail","Bad password");
        dlg.setValue("pass",null);

      } // end else

    } // end else

  } // end if
  else
  { // user not found - bounce back with an error message
    errmsg = "The user account you have specified does not exist.  Please try again.";
    audit.write(req,null,VeniceNamespaces.USER_EVENT_NAMESPACE,"login.fail","Bad username",
                dlg.getValue("user"));
    dlg.setValue("user",null);
    dlg.setValue("pass",null);

  } // end else

  if (errmsg!=null)
  { // set the error message and bounce back the dialog
    dlg.setErrorMessage(errmsg);
    vlib.setLocation(req,target);
    dynamo.scriptOutput(new FrameDialog(dlg));

  } // end if
  else
    dynamo.scriptOutput(new ErrorBox("Internal Error","Unknown outcome from login","SERVLET",target));

} // end else if
else
{ // unknown command button pressed!
  logger.error("no known button click on POST to login.js");
  dynamo.scriptOutput(new ErrorBox("Internal Error","Unknown command button pressed","SERVLET",target));

} // end else
