/**
* Licensed to the Austrian Association for Software Tool Integration (AASTI)
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. The AASTI 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.openengsb.ui.common.usermanagement;
import java.beans.IntrospectionException;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.commons.lang.ObjectUtils;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.RequiredTextField;
import org.apache.wicket.markup.html.panel.EmptyPanel;
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.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.StringResourceModel;
import org.openengsb.core.api.security.model.Permission;
import org.openengsb.core.api.security.service.UserDataManager;
import org.openengsb.core.api.security.service.UserExistsException;
import org.openengsb.core.api.security.service.UserNotFoundException;
import org.openengsb.core.util.BeanUtilsExtended;
import org.openengsb.ui.common.usermanagement.PermissionInput.State;
import org.openengsb.ui.common.util.MethodUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
public abstract class UserEditPanel extends Panel {
private static final Logger LOGGER = LoggerFactory.getLogger(UserEditPanel.class);
private static final long serialVersionUID = 5587225457795713881L;
@Inject
@Named("userManager")
private UserDataManager userManager;
private boolean createMode = true;
private final UserInput input = new UserInput();
private WebMarkupContainer permissionListContainer;
private WebMarkupContainer createPermissionContainer;
private Panel permissionContentPanel;
private AjaxLink<Object> permissionCreateButton;
public UserEditPanel(String id) {
super(id);
initContent();
}
public UserEditPanel(String id, String username) throws UserNotFoundException {
super(id);
input.setUsername(username);
Collection<Permission> userPermissions = userManager.getPermissionsForUser(username);
Collection<PermissionInput> permissionInput =
Collections2.transform(userPermissions, new Function<Permission, PermissionInput>() {
@Override
public PermissionInput apply(Permission input) {
Map<String, String> values = BeanUtilsExtended.buildStringAttributeMap(input);
return new PermissionInput(input.getClass(), values);
}
});
input.setPermissions(Lists.newLinkedList(permissionInput));
createMode = false;
initContent();
}
private void initContent() {
final WebMarkupContainer container = new WebMarkupContainer("userEditorContainer");
add(container);
Form<UserInput> userForm = new Form<UserInput>("userForm") {
private static final long serialVersionUID = 6420993810725159979L;
@Override
protected void onSubmit() {
if (createUser()) {
afterSubmit();
}
}
};
container.add(userForm);
RequiredTextField<String> usernameField = new RequiredTextField<String>("username");
if (input.getUsername() != null) {
usernameField.setEnabled(false);
}
PasswordTextField passwordField = new PasswordTextField("password");
passwordField.setRequired(false);
PasswordTextField passwordVerficationField = new PasswordTextField("passwordVerification");
passwordVerficationField.setRequired(false);
usernameField.setOutputMarkupId(true);
passwordField.setOutputMarkupId(true);
passwordVerficationField.setOutputMarkupId(true);
userForm.add(usernameField);
userForm.add(passwordField);
userForm.add(passwordVerficationField);
userForm.setModel(new CompoundPropertyModel<UserInput>(input));
permissionListContainer = new WebMarkupContainer("permissionListContainer");
permissionListContainer.setOutputMarkupId(true);
userForm.add(permissionListContainer);
createPermissionContainer = new WebMarkupContainer("createPermissionContainer");
createPermissionContainer.setOutputMarkupId(true);
permissionListContainer.add(createPermissionContainer);
permissionContentPanel = new EmptyPanel("createPermissionContent");
createPermissionContainer.add(permissionContentPanel);
GenericListPanel<PermissionInput> permissionList = new GenericListPanel<PermissionInput>("permissionList") {
private static final long serialVersionUID = 8972059517453578207L;
@Override
protected IModel<List<PermissionInput>> getListModel() {
return new LoadableDetachableModel<List<PermissionInput>>() {
private static final long serialVersionUID = 5621251753383842382L;
@Override
protected List<PermissionInput> load() {
Collection<PermissionInput> filtered =
Collections2.filter(input.getPermissions(), new Predicate<PermissionInput>() {
@Override
public boolean apply(PermissionInput input) {
return input.getState() != State.DELETED;
}
});
return Lists.newArrayList(filtered);
}
};
}
@Override
protected void onDeleteClick(AjaxRequestTarget ajaxRequestTarget, Form<?> form, PermissionInput param) {
if (param.getState() == State.NEW) {
input.getPermissions().remove(param);
return;
}
param.setState(State.DELETED);
}
@Override
protected void onEditClick(AjaxRequestTarget target, PermissionInput param) {
LOGGER.info("would edit " + param);
showPermissionEditorPanel(target, "createPermissionContent", param);
}
@Override
protected boolean isDeleteLinkVisibleFor(PermissionInput permissionInput) {
return true;
}
@Override
protected boolean isEditLinkVisibleFor(PermissionInput permissionInput) {
try {
return !MethodUtil.getRelevantProperties(permissionInput.toPermission()).isEmpty();
} catch (IntrospectionException e) {
LOGGER.error("Could not introspect permission bean.", e);
return false;
}
}
};
permissionListContainer.add(permissionList);
permissionCreateButton = new AjaxLink<Object>("createPermission") {
private static final long serialVersionUID = 6887755633726845337L;
@Override
public void onClick(AjaxRequestTarget target) {
showPermissionEditorPanel(target, "createPermissionContent", input);
}
};
permissionListContainer.add(permissionCreateButton);
FeedbackPanel feedbackPanel = new FeedbackPanel("feedback");
feedbackPanel.setOutputMarkupId(true);
userForm.add(feedbackPanel);
}
private void showPermissionEditorPanel(AjaxRequestTarget target, String id, PermissionInput permissionInput) {
showPermissionEditorPanel(target, createPermissionEditorPanel(id, permissionInput));
}
private void showPermissionEditorPanel(AjaxRequestTarget target, String id, UserInput userInput) {
showPermissionEditorPanel(target, createPermissionEditorPanel(id, userInput));
}
private PermissionEditorPanel createPermissionEditorPanel(String id, UserInput userInput) {
return new PermissionEditorPanel(id, userInput) {
private static final long serialVersionUID = -7840663964887113677L;
@Override
protected void afterSubmit(AjaxRequestTarget target, Form<?> form) {
onAfterSubmitFromPermissionEditorPanel(target, form);
}
};
}
private PermissionEditorPanel createPermissionEditorPanel(String id, PermissionInput permissionInput) {
return new PermissionEditorPanel(id, permissionInput) {
private static final long serialVersionUID = -4712535765375580266L;
@Override
protected void afterSubmit(AjaxRequestTarget target, Form<?> form) {
onAfterSubmitFromPermissionEditorPanel(target, form);
}
};
}
private void onAfterSubmitFromPermissionEditorPanel(AjaxRequestTarget target, Form<?> form) {
LOGGER.info("replacing permission-panel with empty panel");
EmptyPanel emptyPanel = new EmptyPanel("createPermissionContent");
createPermissionContainer.addOrReplace(emptyPanel);
permissionContentPanel = emptyPanel;
target.add(createPermissionContainer);
permissionCreateButton.setEnabled(true);
target.add(permissionListContainer);
}
private void showPermissionEditorPanel(AjaxRequestTarget target, PermissionEditorPanel permissionEditorPanel) {
createPermissionContainer.addOrReplace(permissionEditorPanel);
permissionContentPanel = permissionEditorPanel;
target.add(createPermissionContainer);
permissionCreateButton.setEnabled(false);
target.add(permissionCreateButton);
}
private boolean createUser() {
String username = input.getUsername();
if (username == null) {
error(new StringResourceModel("usernameError", this, null).getString());
return false;
}
if (ObjectUtils.notEqual(input.getPassword(), input.getPasswordVerification())) {
error(new StringResourceModel("passwordError", this, null).getString());
return false;
}
if (createMode) {
if (input.getPassword() == null) {
error(new StringResourceModel("passwordError", this, null).getString());
return false;
}
try {
userManager.createUser(username);
} catch (UserExistsException e1) {
error(new StringResourceModel("userExistError", this, null).getString());
return false;
}
}
if (input.getPassword() != null) {
try {
userManager.setUserCredentials(username, "password", input.getPassword());
} catch (UserNotFoundException e) {
error(Throwables.getStackTraceAsString(e));
return false;
}
}
for (PermissionInput p : input.getPermissions()) {
if (p.getState() == State.UNMODIFIED) {
continue;
}
Permission perm = (Permission) BeanUtilsExtended.createBeanFromAttributeMap(p.getType(), p.getValues());
try {
if (p.getState() == State.NEW) {
userManager.addPermissionToUser(username, perm);
}
if (p.getState() == State.DELETED) {
userManager.removePermissionFromUser(username, perm);
}
} catch (UserNotFoundException e) {
error(Throwables.getStackTraceAsString(e));
return false;
}
}
return true;
}
protected abstract void afterSubmit();
class PermissionDesc implements Serializable {
private static final long serialVersionUID = -4440114734798836870L;
private String representation;
private String description;
public String getRepresentation() {
return representation;
}
public void setRepresentation(String representation) {
this.representation = representation;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
}