package org.atricore.idbus.capabilities.sso.ui.page.selfsvcs.registration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.*;
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.model.LoadableDetachableModel;
import org.apache.wicket.model.PropertyModel;
import org.atricore.idbus.capabilities.sso.ui.internal.BaseWebApplication;
import org.atricore.idbus.capabilities.sso.ui.internal.SSOIdPApplication;
import org.atricore.idbus.capabilities.sso.ui.page.selfsvcs.PasswordUtil;
import org.atricore.idbus.capabilities.sso.ui.page.selfsvcs.profile.ProfilePage;
import org.atricore.idbus.kernel.main.provisioning.domain.SecurityQuestion;
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.IllegalCredentialException;
import org.atricore.idbus.kernel.main.provisioning.exception.IllegalPasswordException;
import org.atricore.idbus.kernel.main.provisioning.exception.ProvisioningException;
import org.atricore.idbus.kernel.main.provisioning.exception.TransactionExpiredExcxeption;
import org.atricore.idbus.kernel.main.provisioning.spi.ProvisioningTarget;
import org.atricore.idbus.kernel.main.provisioning.spi.request.AddUserRequest;
import org.atricore.idbus.kernel.main.provisioning.spi.request.ConfirmAddUserRequest;
import org.atricore.idbus.kernel.main.provisioning.spi.request.FindUserByUsernameRequest;
import org.atricore.idbus.kernel.main.provisioning.spi.request.ListSecurityQuestionsRequest;
import org.atricore.idbus.kernel.main.provisioning.spi.response.AddUserResponse;
import org.atricore.idbus.kernel.main.provisioning.spi.response.FindUserByUsernameResponse;
import org.atricore.idbus.kernel.main.provisioning.spi.response.ListSecurityQuestionsResponse;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
*
*/
public class RegistrationPanel extends Panel {
private static final Log logger = LogFactory.getLog(RegistrationPanel.class);
private Form form;
private User newUser;
private String transactionId;
private RegistrationModel registration;
private List <SecurityQuestion> secQuestions = new ArrayList<SecurityQuestion>();
private String hashAlgorithm = "MD5";
private String hashEncoding = "HEX";
public RegistrationPanel(String id, String transactionId, String hashAlgorithm, String hashEncoding) {
this(id, transactionId);
this.hashAlgorithm = hashAlgorithm;
this.hashEncoding = hashEncoding;
}
public RegistrationPanel(String id, String transactionId) {
super(id);
registration = new RegistrationModel();
SSOIdPApplication app = (SSOIdPApplication) getApplication();
try {
ListSecurityQuestionsResponse resp = app.getProvisioningTarget().listSecurityQuestions(new ListSecurityQuestionsRequest());
Collections.addAll(secQuestions, resp.getSecurityQuestions());
} catch (ProvisioningException e) {
logger.error(e.getMessage(), e);
}
this.transactionId = transactionId;
form = new Form<RegistrationModel>("registerForm", new CompoundPropertyModel<RegistrationModel>(registration));
// Password fields
final PasswordTextField password = new PasswordTextField("password");
form.add(password);
final PasswordTextField newPassword = new PasswordTextField("newPassword");
form.add(newPassword);
final PasswordTextField retypedPassword = new PasswordTextField("retypedPassword");
form.add(retypedPassword);
// Sec. Question 1
DropDownChoice<SecurityQuestion> secQuestion1 =
new DropDownChoice<SecurityQuestion>("secQuestion1",
new PropertyModel<SecurityQuestion>(registration, "secQuestion1"),
new LoadableDetachableModel<List<SecurityQuestion>>() {
@Override
protected List<SecurityQuestion> load() {
return secQuestions;
}
},
new IChoiceRenderer<SecurityQuestion>() {
public Object getDisplayValue(SecurityQuestion securityQuestion) {
return securityQuestion.getMessageKey() != null ?
getString(securityQuestion.getMessageKey(), null, securityQuestion.getDefaultMessage()) :
securityQuestion.getDefaultMessage();
}
public String getIdValue(SecurityQuestion securityQuestion, int i) {
return secQuestions.get(i).getId() + "";
}
}
);
form.add(secQuestion1);
final CheckBox useCustomSecQuestion1 = new CheckBox("useCustomSecQuestion1");
form.add(useCustomSecQuestion1);
final TextField<String> customSecQuestion1 = new TextField<String>("customSecQuestion1");
form.add(customSecQuestion1);
final TextField<String> secAnswer1 = new TextField<String>("secAnswer1");
form.add(secAnswer1);
// Sec. Question 2
DropDownChoice<SecurityQuestion> secQuestion2 =
new DropDownChoice<SecurityQuestion>("secQuestion2",
new PropertyModel<SecurityQuestion>(registration, "secQuestion2"),
new LoadableDetachableModel<List<SecurityQuestion>>() {
@Override
protected List<SecurityQuestion> load() {
return secQuestions;
}
},
new IChoiceRenderer<SecurityQuestion>() {
public Object getDisplayValue(SecurityQuestion securityQuestion) {
return securityQuestion.getMessageKey() != null ?
getString(securityQuestion.getMessageKey(), null, securityQuestion.getDefaultMessage()) :
securityQuestion.getDefaultMessage();
}
public String getIdValue(SecurityQuestion securityQuestion, int i) {
return secQuestions.get(i).getId() + "";
}
}
);
form.add(secQuestion2);
final CheckBox useCustomSecQuestion2 = new CheckBox("useCustomSecQuestion2");
form.add(useCustomSecQuestion2);
final TextField<String> customSecQuestion2 = new TextField<String>("customSecQuestion2");
form.add(customSecQuestion2);
final TextField<String> secAnswer2 = new TextField<String>("secAnswer2");
form.add(secAnswer2);
// Sec. Question 3
DropDownChoice<SecurityQuestion> secQuestion3 =
new DropDownChoice<SecurityQuestion>("secQuestion3",
new PropertyModel<SecurityQuestion>(registration, "secQuestion3"),
new LoadableDetachableModel<List<SecurityQuestion>>() {
@Override
protected List<SecurityQuestion> load() {
return secQuestions;
}
},
new IChoiceRenderer<SecurityQuestion>() {
public Object getDisplayValue(SecurityQuestion securityQuestion) {
return securityQuestion.getMessageKey() != null ?
getString(securityQuestion.getMessageKey(), null, securityQuestion.getDefaultMessage()) :
securityQuestion.getDefaultMessage();
}
public String getIdValue(SecurityQuestion securityQuestion, int i) {
return secQuestions.get(i).getId() + "";
}
}
);
form.add(secQuestion3);
final CheckBox useCustomSecQuestion3 = new CheckBox("useCustomSecQuestion3");
form.add(useCustomSecQuestion3);
final TextField<String> customSecQuestion3 = new TextField<String>("customSecQuestion3");
form.add(customSecQuestion3);
final TextField<String> secAnswer3 = new TextField<String>("secAnswer3");
form.add(secAnswer3);
/*
// Sec. Question 4
DropDownChoice<SecurityQuestion> secQuestion4 =
new DropDownChoice<SecurityQuestion>("secQuestion4",
new PropertyModel<SecurityQuestion>(registration, "secQuestion4"),
new LoadableDetachableModel<List<SecurityQuestion>>() {
@Override
protected List<SecurityQuestion> load() {
return secQuestions;
}
},
new IChoiceRenderer<SecurityQuestion>() {
public Object getDisplayValue(SecurityQuestion securityQuestion) {
return securityQuestion.getMessageKey() != null ?
getString(securityQuestion.getMessageKey(), null, securityQuestion.getDefaultMessage()) :
securityQuestion.getDefaultMessage();
}
public String getIdValue(SecurityQuestion securityQuestion, int i) {
return secQuestions.get(i).getId() + "";
}
}
);
form.add(secQuestion4);
final CheckBox useCustomSecQuestion4 = new CheckBox("useCustomSecQuestion4");
form.add(useCustomSecQuestion4);
final TextField<String> customSecQuestion4 = new TextField<String>("customSecQuestion4");
form.add(customSecQuestion4);
final TextField<String> secAnswer4 = new TextField<String>("secAnswer4");
form.add(secAnswer4);
// Sec. Question 5
DropDownChoice<SecurityQuestion> secQuestion5 =
new DropDownChoice<SecurityQuestion>("secQuestion5",
new PropertyModel<SecurityQuestion>(registration, "secQuestion5"),
new LoadableDetachableModel<List<SecurityQuestion>>() {
@Override
protected List<SecurityQuestion> load() {
return secQuestions;
}
},
new IChoiceRenderer<SecurityQuestion>() {
public Object getDisplayValue(SecurityQuestion securityQuestion) {
return securityQuestion.getMessageKey() != null ?
getString(securityQuestion.getMessageKey(), null, securityQuestion.getDefaultMessage()) :
securityQuestion.getDefaultMessage();
}
public String getIdValue(SecurityQuestion securityQuestion, int i) {
return secQuestions.get(i).getId() + "";
}
}
);
form.add(secQuestion5);
final CheckBox useCustomSecQuestion5 = new CheckBox("useCustomSecQuestion5");
form.add(useCustomSecQuestion5);
final TextField<String> customSecQuestion5 = new TextField<String>("customSecQuestion5");
form.add(customSecQuestion5);
final TextField<String> secAnswer5 = new TextField<String>("secAnswer5");
form.add(secAnswer5);
*/
// Submit
final SubmitLink submit = new SubmitLink("doRegister") {
@Override
public void onSubmit() {
try {
register();
onRegisterSucceeded();
} catch (TransactionExpiredExcxeption e) {
onRegisterExpired();
} catch (IllegalPasswordException e) {
onIllegalPassword();
} catch (IllegalCredentialException e) {
onIllegalSecurityQuestion();
} catch (Exception e) {
logger.error("Fatal error during registration : " + e.getMessage(), e);
onRegisterFailed(e);
}
}
};
form.add(submit);
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);
}
@Override
protected void onInitialize() {
super.onInitialize();
// Look for transaction ID
SSOIdPApplication app = (SSOIdPApplication) getApplication();
ProvisioningTarget pt = app.getProvisioningTarget();
if (!pt.isTransactionValid(transactionId))
onRegisterExpired();
}
private RegistrationModel getRegisterModel() {
return (RegistrationModel) form.getDefaultModelObject();
}
protected void onRegisterSucceeded() {
// Go to profile
form.setResponsePage(((BaseWebApplication)getApplication()).resolvePage("SS/PROFILE"));
}
protected void onRegisterFailed(Exception e) {
if (e != null ) {
if (e instanceof RegistrationException) {
RegistrationException re = (RegistrationException) e;
String messageKey = re.getMessageKey();
// Show app. error page
error(getLocalizer().getString(messageKey, this, "Operation failed"));
} else {
// Show app. error page
error(getLocalizer().getString("app.error", this, "Operation failed"));
}
} else {
error(getLocalizer().getString("app.error", this, "Operation failed"));
}
}
protected void onRegisterExpired() {
// Show app. error page
error(getLocalizer().getString("error.registration.expired", this, "Operation failed"));
}
protected void onIllegalPassword() {
// Show app. error page
error(getLocalizer().getString("error.password.illegal", this, "Operation failed"));
}
protected void onIllegalSecurityQuestion() {
error(getLocalizer().getString("error.securityQuestion.illegal", this, "Operation failed"));
}
protected void register() throws ProvisioningException, RegistrationException {
SSOIdPApplication app = (SSOIdPApplication) getApplication();
ProvisioningTarget pt = app.getProvisioningTarget();
if (!pt.isTransactionValid(transactionId)) {
throw new TransactionExpiredExcxeption(transactionId);
}
AddUserRequest addUserRequest = (AddUserRequest) pt.lookupTransactionRequest(transactionId);
FindUserByUsernameResponse fu = pt.findUserByUsername(new FindUserByUsernameRequest(addUserRequest.getUserName()));
User tmpUser = fu.getUser();
if (!registration.getNewPassword().equals(registration.getRetypedPassword()))
throw new RegistrationException("error.password.doNotMatch", "Invalid temporary password");
/** TODO : Verify temporary password
String hash = PasswordUtil.createPasswordHash(registration.getPassword(), getHashAlgorithm(), getHashEncoding(), getDigest());
if (!hash.equals(tmpUser.getUserPassword())) {
throw new RegistrationException("error.tmpPassword.invalid", "Invalid temporary password");
} **/
RegistrationModel registration = getRegisterModel();
UserSecurityQuestion[] secQuestions = null;
// Q1
UserSecurityQuestion q1 = new UserSecurityQuestion();
q1.setAnswer(registration.getSecAnswer1());
if (registration.isUseCustomSecQuestion1())
q1.setCustomMessage((registration.getCustomSecQuestion1()));
else
q1.setQuestion(registration.getSecQuestion1());
// Q2
UserSecurityQuestion q2 = new UserSecurityQuestion();
q2.setAnswer(registration.getSecAnswer2());
if (registration.isUseCustomSecQuestion2())
q2.setCustomMessage((registration.getCustomSecQuestion2()));
else
q2.setQuestion(registration.getSecQuestion2());
// Q3
UserSecurityQuestion q3 = new UserSecurityQuestion();
q3.setAnswer(registration.getSecAnswer3());
if (registration.isUseCustomSecQuestion3())
q3.setCustomMessage((registration.getCustomSecQuestion3()));
else
q3.setQuestion(registration.getSecQuestion3());
/*
// Q4
UserSecurityQuestion q4 = new UserSecurityQuestion();
q4.setAnswer(registration.getSecAnswer4());
if (registration.isUseCustomSecQuestion4())
q4.setCustomMessage((registration.getCustomSecQuestion4()));
else
q4.setQuestion(registration.getSecQuestion4());
// Q5
UserSecurityQuestion q5 = new UserSecurityQuestion();
q5.setAnswer(registration.getSecAnswer5());
if (registration.isUseCustomSecQuestion5())
q5.setCustomMessage((registration.getCustomSecQuestion5()));
else
q5.setQuestion(registration.getSecQuestion5());
*/
ConfirmAddUserRequest req = new ConfirmAddUserRequest ();
req.setUserPassword(registration.getNewPassword());
//req.setSecurityQuestions(new UserSecurityQuestion[] {q1, q2, q3, q4, q5});
req.setSecurityQuestions(new UserSecurityQuestion[] {q1, q2, q3});
req.setTransactionId(transactionId);
AddUserResponse resp = pt.confirmAddUser(req);
}
public String getHashEncoding() {
return hashEncoding;
}
public void setHashEncoding(String hashEncoding) {
this.hashEncoding = hashEncoding;
}
public String getHashAlgorithm() {
return hashAlgorithm;
}
public void setHashAlgorithm(String hashAlgorithm) {
this.hashAlgorithm = hashAlgorithm;
}
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;
}
protected SecurityQuestion lookupQuestion(String id) {
for (SecurityQuestion sq : this.secQuestions) {
if (sq.getId().equals(id))
return sq;
}
return null;
}
}