/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.isis.viewer.wicket.ui.pages.accmngt.register;
import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.authroles.authentication.AuthenticatedWebSession;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.RequiredTextField;
import org.apache.wicket.markup.html.form.StatelessForm;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.form.validation.EqualPasswordInputValidator;
import org.apache.wicket.markup.html.form.validation.IFormValidator;
import org.apache.wicket.markup.html.panel.GenericPanel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import org.apache.isis.applib.services.userreg.UserDetails;
import org.apache.isis.applib.services.userreg.UserRegistrationService;
import org.apache.isis.core.runtime.system.context.IsisContext;
import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
import org.apache.isis.core.runtime.system.transaction.TransactionalClosure;
import org.apache.isis.viewer.wicket.ui.components.widgets.bootstrap.FormGroup;
import org.apache.isis.viewer.wicket.ui.pages.accmngt.AccountConfirmationMap;
import org.apache.isis.viewer.wicket.ui.pages.accmngt.UsernameAvailableValidator;
/**
* A panel with a form for self-registration of a user
*/
public abstract class RegisterPanel extends GenericPanel<UserDetails> {
protected static final String ID_REGISTER_FORM = "registerForm";
private static final String ID_USERNAME = "username";
private static final String ID_USERNAME_FORM_GROUP = "usernameFormGroup";
private static final String ID_PASSWORD = "password";
private static final String ID_PASSWORD_FORM_GROUP = "passwordFormGroup";
private static final String ID_CONFIRM_PASSWORD = "confirmPassword";
private static final String ID_CONFIRM_PASSWORD_FORM_GROUP = "confirmPasswordFormGroup";
private static final String ID_EMAIL = "email";
private final UserDetails userDetails;
private final String uuid;
public RegisterPanel(final String id, final UserDetails userDetails, final String uuid) {
super(id);
this.userDetails = userDetails;
this.uuid = uuid;
}
@Override
protected void onInitialize() {
super.onInitialize();
RegisterForm registerForm = new RegisterForm(ID_REGISTER_FORM, uuid, userDetails);
add(registerForm);
Component username = newUsernameField();
MarkupContainer password = newPasswordField();
MarkupContainer confirmPassword = newConfirmPasswordField();
registerForm.add(newEqualPasswordInputValidator(password, confirmPassword));
TextField<String> emailField = newEmailField(userDetails);
registerForm.add(username, password, confirmPassword, emailField);
registerForm.add(newExtraFieldsContainer("extraFieldsContainer"));
}
protected abstract MarkupContainer newExtraFieldsContainer(String id);
private IFormValidator newEqualPasswordInputValidator(MarkupContainer password, MarkupContainer confirmPassword) {
FormComponent passwordField = (FormComponent) password.get(ID_PASSWORD);
FormComponent confirmPasswordField = (FormComponent) confirmPassword.get(ID_CONFIRM_PASSWORD);
return new EqualPasswordInputValidator(passwordField, confirmPasswordField);
}
/**
* Register user form.
*/
private class RegisterForm extends StatelessForm<UserDetails>
{
private static final long serialVersionUID = 1L;
private final String uuid;
/**
* Constructor.
*
* @param id
* id of the form component
* @param userDetails
*/
public RegisterForm(final String id, final String uuid, UserDetails userDetails)
{
super(id, new CompoundPropertyModel<>(userDetails));
this.uuid = uuid;
String email = getEmail();
userDetails.setEmailAddress(email);
}
@Override
public final void onSubmit()
{
final UserDetails userDetails = getModelObject();
getIsisSessionFactory().doInSession(new Runnable() {
@Override
public void run() {
final UserRegistrationService userRegistrationService = getIsisSessionFactory()
.getServicesInjector().lookupService(UserRegistrationService.class);
getIsisSessionFactory().getCurrentSession().getPersistenceSession().getTransactionManager()
.executeWithinTransaction(new TransactionalClosure() {
@Override
public void execute() {
userRegistrationService.registerUser(userDetails);
removeAccountConfirmation();
}
});
}
});
signIn(userDetails.getUsername(), userDetails.getPassword());
setResponsePage(getApplication().getHomePage());
}
private boolean signIn(String username, String password)
{
return AuthenticatedWebSession.get().signIn(username, password);
}
private String getEmail() {
AccountConfirmationMap accountConfirmationMap = getApplication().getMetaData(AccountConfirmationMap.KEY);
return accountConfirmationMap.get(uuid);
}
private void removeAccountConfirmation() {
AccountConfirmationMap accountConfirmationMap = getApplication().getMetaData(AccountConfirmationMap.KEY);
accountConfirmationMap.remove(uuid);
}
}
protected TextField<String> newEmailField(final UserDetails userDetails) {
// use readonly-ish model to prevent changing the email with manual form submits
TextField<String> emailField = new TextField<>(ID_EMAIL, new Model<String>() {
@Override
public String getObject() {
return userDetails.getEmailAddress();
}
});
return emailField;
}
protected MarkupContainer newConfirmPasswordField() {
PasswordTextField confirmPassword = new PasswordTextField(ID_CONFIRM_PASSWORD);
confirmPassword.setLabel(new ResourceModel("confirmPasswordLabel"));
FormGroup confirmPasswordFormGroup = new FormGroup(ID_CONFIRM_PASSWORD_FORM_GROUP, confirmPassword);
confirmPasswordFormGroup.add(confirmPassword);
return confirmPasswordFormGroup;
}
protected MarkupContainer newPasswordField() {
PasswordTextField password = new PasswordTextField(ID_PASSWORD);
password.setLabel(new ResourceModel("passwordLabel"));
FormGroup passwordFormGroup = new FormGroup(ID_PASSWORD_FORM_GROUP, password);
passwordFormGroup.add(password);
return passwordFormGroup;
}
protected MarkupContainer newUsernameField() {
RequiredTextField<String> username = new RequiredTextField<>(ID_USERNAME);
username.add(UsernameAvailableValidator.INSTANCE);
FormGroup usernameFormGroup = new FormGroup(ID_USERNAME_FORM_GROUP, username);
usernameFormGroup.add(username);
return usernameFormGroup;
}
IsisSessionFactory getIsisSessionFactory() {
return IsisContext.getSessionFactory();
}
}