package org.atricore.idbus.capabilities.sso.ui.page.selfsvcs.pwdreset;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.wicket.RestartResponseAtInterceptPageException;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.StatelessForm;
import org.apache.wicket.markup.html.form.SubmitLink;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.atricore.idbus.capabilities.sso.ui.internal.BaseWebApplication;
import org.atricore.idbus.capabilities.sso.ui.internal.SSOWebSession;
import org.atricore.idbus.capabilities.sso.ui.page.selfsvcs.PasswordUtil;
import org.atricore.idbus.kernel.main.authn.util.CipherUtil;
import org.atricore.idbus.kernel.main.provisioning.domain.User;
import org.atricore.idbus.kernel.main.provisioning.domain.UserSecurityQuestion;
import org.atricore.idbus.kernel.main.provisioning.exception.ProvisioningException;
import org.atricore.idbus.kernel.main.util.UUIDGenerator;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* @author: sgonzalez@atriocore.com
* @date: 4/16/13
*/
public class VerifyPwdResetPanel extends Panel {
private static final Log logger = LogFactory.getLog(ReqPwdResetPanel.class);
private static final UUIDGenerator uuidGenerator = new UUIDGenerator();
private static final int SEC_QUESTIONS_PER_USER = 3;
private Form form;
private SubmitLink submit;
private User user;
private UserSecurityQuestion[] questions;
private String hashAlgorithm = "MD5";
private String hashEncoding = "HEX";
private VerifyPwdResetModel model;
public VerifyPwdResetPanel(String id, User user, String hashAlgorithm, String hashEncoding) {
this(id, user);
this.hashAlgorithm = hashAlgorithm;
this.hashEncoding = hashEncoding;
}
public VerifyPwdResetPanel(String id, User user) {
super(id);
this.user = user;
Random rg = new Random();
model = new VerifyPwdResetModel();
// Get three security questions to recover the password:
Map<Integer, UserSecurityQuestion> q = new HashMap<Integer, UserSecurityQuestion>();
for (int i = 0 ; i < 3 ; i ++) {
q.put(i, user.getSecurityQuestions()[i]);
}
SSOWebSession session = (SSOWebSession) getSession();
if (session.getSecurityQuestions() == null) {
questions = new UserSecurityQuestion[q.values().size()];
int idx = 0;
for (UserSecurityQuestion sq : q.values()) {
questions[idx] = sq;
idx ++;
}
session.setSecurityQuestions(questions);
} else {
questions = session.getSecurityQuestions();
}
form = new StatelessForm<VerifyPwdResetModel>("verifyPwdResetForm", new CompoundPropertyModel<VerifyPwdResetModel>(model));
submit = new SubmitLink("doVerifyPwdReset") {
@Override
public void onSubmit() {
try {
if (!verifyPwdReset()) {
onVerifyPwdResetFailed();
return;
}
} catch (Exception e) {
logger.error("Fatal error during password reset request : " + e.getMessage(), e);
onVerifyPwdResetError();
return;
}
onVerifyPwdResetSucceeded();
}
};
form.add(submit);
// Q1
UserSecurityQuestion q1 = questions[0];
String q1Text = getQuestionText(q1);
final Label q1Label = new Label("question1", q1Text);
form.add(q1Label);
final TextField<String> answer1 = new TextField<String>("answer1");
form.add(answer1);
// Q2
UserSecurityQuestion q2 = questions[1];
String q2Text = getQuestionText(q2);
final Label q2Label = new Label("question2", q2Text);
form.add(q2Label);
final TextField<String> answer2 = new TextField<String>("answer2");
form.add(answer2);
// Q3
UserSecurityQuestion q3 = questions[2];
String q3Text = getQuestionText(q3);
final Label q3Label = new Label("question3", q3Text);
form.add(q3Label);
final TextField<String> answer3 = new TextField<String>("answer3");
form.add(answer3);
add(form);
// Create feedback panel and add it to page
final WebMarkupContainer feedbackBox = new WebMarkupContainer("feedbackBox");
add(feedbackBox);
final FeedbackPanel feedback = new FeedbackPanel("feedback");
feedback.setOutputMarkupId(true);
feedbackBox.add(feedback);
}
protected boolean verifyPwdReset() throws Exception {
// Verify each question
String a1 = model.getAnswer1();
if (!a1.equals(questions[0].getAnswer())) {
return false;
}
String a2 = model.getAnswer2();
if (!a2.equals(questions[1].getAnswer())) {
return false;
}
String a3 = model.getAnswer3();
if (!a3.equals(questions[2].getAnswer())) {
return false;
}
return true;
}
protected void onVerifyPwdResetSucceeded() {
PageParameters params = new PageParameters();
params.add("username", user.getUserName());
throw new RestartResponseAtInterceptPageException(((BaseWebApplication)getApplication()).resolvePage("SS/PWDRESET"), params);
}
protected void onVerifyPwdResetError() {
submit.setEnabled(false);
error(getLocalizer().getString("app.error", this, "Operation failed"));
}
protected void onVerifyPwdResetFailed() {
SSOWebSession session = (SSOWebSession) getSession();
session.setSecurityQuestions(null);
error(getLocalizer().getString("verification.error", this, "Operation failed"));
}
protected String getQuestionText(UserSecurityQuestion q) {
if (q.getCustomMessage() != null)
return q.getCustomMessage();
return getLocalizer().getString(q.getQuestion().getMessageKey(), this, q.getQuestion().getDefaultMessage());
}
protected MessageDigest getDigest() throws ProvisioningException {
MessageDigest digest = null;
if (hashAlgorithm != null) {
try {
digest = MessageDigest.getInstance(hashAlgorithm);
logger.debug("Using hash algorithm/encoding : " + hashAlgorithm + "/" + hashEncoding);
} catch (NoSuchAlgorithmException e) {
logger.error("Algorithm not supported : " + hashAlgorithm, e);
throw new ProvisioningException(e.getMessage(), e);
}
}
return digest;
}
public String getHashAlgorithm() {
return hashAlgorithm;
}
public String getHashEncoding() {
return hashEncoding;
}
}