diff --git a/libreplan-business/src/main/java/org/libreplan/business/resources/entities/Worker.java b/libreplan-business/src/main/java/org/libreplan/business/resources/entities/Worker.java index ede056bc9..9f5ea2286 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/resources/entities/Worker.java +++ b/libreplan-business/src/main/java/org/libreplan/business/resources/entities/Worker.java @@ -25,6 +25,7 @@ package org.libreplan.business.resources.entities; import org.apache.commons.lang.StringUtils; import org.hibernate.validator.AssertTrue; import org.hibernate.validator.NotEmpty; +import org.hibernate.validator.Valid; import org.libreplan.business.common.Registry; import org.libreplan.business.common.exceptions.InstanceNotFoundException; import org.libreplan.business.users.daos.IUserDAO; @@ -207,6 +208,7 @@ public class Worker extends Resource { return firstName + " " + surname; } + @Valid public User getUser() { return user; } @@ -255,4 +257,11 @@ public class Worker extends Resource { return true; } + public void updateUserData() { + if (user != null) { + user.setFirstName(firstName); + user.setLastName(surname); + } + } + } diff --git a/libreplan-business/src/main/java/org/libreplan/business/users/entities/User.java b/libreplan-business/src/main/java/org/libreplan/business/users/entities/User.java index d8eca3f72..d9f2e5f17 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/users/entities/User.java +++ b/libreplan-business/src/main/java/org/libreplan/business/users/entities/User.java @@ -89,6 +89,12 @@ public class User extends BaseEntity implements IHumanIdentifiable{ this.roles = roles; } + private User(String loginName, String password, String email) { + this.loginName = loginName; + this.password = password; + this.email = email; + } + public static User create(String loginName, String password, Set roles) { @@ -100,6 +106,10 @@ public class User extends BaseEntity implements IHumanIdentifiable{ return create(new User()); } + public static User create(String loginName, String password, String email) { + return create(new User(loginName, password, email)); + } + @NotEmpty(message = "login name not specified") public String getLoginName() { return loginName; diff --git a/libreplan-business/src/test/java/org/libreplan/business/test/resources/daos/ResourceDAOTest.java b/libreplan-business/src/test/java/org/libreplan/business/test/resources/daos/ResourceDAOTest.java index 35ad7b0fe..e61e29e27 100644 --- a/libreplan-business/src/test/java/org/libreplan/business/test/resources/daos/ResourceDAOTest.java +++ b/libreplan-business/src/test/java/org/libreplan/business/test/resources/daos/ResourceDAOTest.java @@ -246,7 +246,7 @@ public class ResourceDAOTest { @Override public User execute() { User user = User.create("login" + UUID.randomUUID(), - "password", null); + "password", ""); userDAO.save(user); user.dontPoseAsTransientObjectAnymore(); return user; diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/resources/worker/WorkerCRUDController.java b/libreplan-webapp/src/main/java/org/libreplan/web/resources/worker/WorkerCRUDController.java index 8462f3aeb..59a0ec3a2 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/resources/worker/WorkerCRUDController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/resources/worker/WorkerCRUDController.java @@ -54,6 +54,8 @@ import org.libreplan.web.common.entrypoints.EntryPointsHandler; import org.libreplan.web.common.entrypoints.IURLHandlerRegistry; import org.libreplan.web.costcategories.ResourcesCostCategoryAssignmentController; import org.libreplan.web.resources.search.ResourcePredicate; +import org.libreplan.web.users.services.IDBPasswordEncoderService; +import org.springframework.beans.factory.annotation.Autowired; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.WrongValueException; import org.zkoss.zk.ui.event.CheckEvent; @@ -74,12 +76,15 @@ import org.zkoss.zul.Listcell; import org.zkoss.zul.Listitem; import org.zkoss.zul.ListitemRenderer; import org.zkoss.zul.Messagebox; +import org.zkoss.zul.Radio; import org.zkoss.zul.Row; import org.zkoss.zul.RowRenderer; import org.zkoss.zul.SimpleListModel; import org.zkoss.zul.Tab; import org.zkoss.zul.Textbox; import org.zkoss.zul.api.Caption; +import org.zkoss.zul.api.Groupbox; +import org.zkoss.zul.api.Radiogroup; import org.zkoss.zul.api.Window; /** @@ -92,6 +97,9 @@ import org.zkoss.zul.api.Window; public class WorkerCRUDController extends GenericForwardComposer implements IWorkerCRUDControllerEntryPoints { + @Autowired + private IDBPasswordEncoderService dbPasswordEncoderService; + private Window listWindow; private Window editWindow; @@ -146,6 +154,33 @@ public class WorkerCRUDController extends GenericForwardComposer implements private CRUDControllerState state = CRUDControllerState.LIST; + private Groupbox userBindingGroupbox; + + private Radiogroup userBindingRadiogroup; + + private Listbox userListbox; + + private Textbox loginNameTextbox; + + private Textbox emailTextbox; + + private Textbox passwordTextbox; + + private Textbox passwordConfirmationTextbox; + + private enum UserBindingOption { + NOT_BOUND(_("Not bound")), + EXISTING_USER(_("Existing user")), + CREATE_NEW_USER(_("Create new user")); + + private String label; + + private UserBindingOption(String label) { + this.label = label; + } + + }; + public WorkerCRUDController() { } @@ -204,6 +239,8 @@ public class WorkerCRUDController extends GenericForwardComposer implements public boolean save() { validateConstraints(); + setUserBindingInfo(); + // Validate 'Cost category assignment' tab is correct if (resourcesCostCategoryAssignmentController != null) { if (!resourcesCostCategoryAssignmentController.validate()) { @@ -232,6 +269,58 @@ public class WorkerCRUDController extends GenericForwardComposer implements return false; } + private void setUserBindingInfo() { + int option = userBindingRadiogroup.getSelectedIndex(); + + if (UserBindingOption.NOT_BOUND.ordinal() == option) { + getWorker().setUser(null); + } + + if (UserBindingOption.EXISTING_USER.ordinal() == option) { + if (getWorker().getUser() == null) { + throw new WrongValueException(userListbox, + _("please select a user to bound")); + } + getWorker().updateUserData(); + } + + if (UserBindingOption.CREATE_NEW_USER.ordinal() == option) { + getWorker().setUser(createNewUserForBinding()); + } + } + + private User createNewUserForBinding() { + String loginName = loginNameTextbox.getValue(); + if (StringUtils.isBlank(loginName)) { + throw new WrongValueException(loginNameTextbox, + _("cannot be null or empty")); + } + + String password = passwordTextbox.getValue(); + if (StringUtils.isBlank(loginName)) { + throw new WrongValueException(passwordTextbox, + _("cannot be null or empty")); + } + + String passwordConfirmation = passwordConfirmationTextbox.getValue(); + if (!password.equals(passwordConfirmation)) { + throw new WrongValueException(passwordConfirmationTextbox, + _("passwords do not match")); + } + + String encodedPassword = dbPasswordEncoderService.encodePassword( + password, loginName); + + User newUser = User.create(loginName, encodedPassword, + emailTextbox.getValue()); + + Worker worker = getWorker(); + newUser.setFirstName(worker.getFirstName()); + newUser.setLastName(worker.getSurname()); + + return newUser; + } + private void validateConstraints() { Tab selectedTab = personalDataTab; try { @@ -285,9 +374,29 @@ public class WorkerCRUDController extends GenericForwardComposer implements editCalendar(); } editAsignedCriterions(); + updateUserBindingComponents(); showEditWindow(_("Edit Worker: {0}", worker.getHumanId())); } + private void updateUserBindingComponents() { + User user = getBoundUser(); + if (user == null) { + userBindingRadiogroup.setSelectedIndex(UserBindingOption.NOT_BOUND + .ordinal()); + } else { + userBindingRadiogroup + .setSelectedIndex(UserBindingOption.EXISTING_USER.ordinal()); + } + + // Reste new user fields + loginNameTextbox.setValue(""); + emailTextbox.setValue(""); + passwordTextbox.setValue(""); + passwordConfirmationTextbox.setValue(""); + + Util.reloadBindings(userBindingGroupbox); + } + public void goToEditVirtualWorkerForm(Worker worker) { state = CRUDControllerState.EDIT; workerModel.prepareEditFor(worker); @@ -316,6 +425,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements createAsignedCriterions(); resourcesCostCategoryAssignmentController.setResource(workerModel .getWorker()); + updateUserBindingComponents(); showEditWindow(_("Create Worker")); resourceCalendarModel.cancel(); } @@ -348,6 +458,29 @@ public class WorkerCRUDController extends GenericForwardComposer implements initFilterComponent(); setupFilterLimitingResourceListbox(); initializeTabs(); + initUserBindingComponents(); + } + + private void initUserBindingComponents() { + userBindingGroupbox = (Groupbox) editWindow + .getFellowIfAny("userBindingGroupbox"); + userBindingRadiogroup = (Radiogroup) editWindow + .getFellowIfAny("userBindingRadiogroup"); + initUserBindingOptions(); + userListbox = (Listbox) editWindow.getFellowIfAny("userListbox"); + loginNameTextbox = (Textbox) editWindow.getFellowIfAny("loginName"); + passwordTextbox = (Textbox) editWindow.getFellowIfAny("password"); + passwordConfirmationTextbox = (Textbox) editWindow + .getFellowIfAny("passwordConfirmation"); + emailTextbox = (Textbox) editWindow.getFellowIfAny("email"); + } + + private void initUserBindingOptions() { + UserBindingOption[] values = UserBindingOption.values(); + for (UserBindingOption option : values) { + Radio radio = new Radio(option.label); + userBindingRadiogroup.appendChild(radio); + } } private void initializeTabs() { @@ -782,6 +915,10 @@ public class WorkerCRUDController extends GenericForwardComposer implements Worker worker = getWorker(); if (worker != null) { worker.setResourceType(LimitingResourceEnum.toResourceType(option)); + if (worker.isLimitingResource()) { + worker.setUser(null); + } + Util.reloadBindings(userBindingGroupbox); } } @@ -910,6 +1047,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements public void setBoundUser(User user) { workerModel.setBoundUser(user); + updateUserBindingComponents(); } public ListitemRenderer getUsersRenderer() { @@ -925,4 +1063,50 @@ public class WorkerCRUDController extends GenericForwardComposer implements }; } + public boolean isUserSelected() { + if (userListbox.getSelectedItem() == null + || userListbox.getSelectedItem().getValue() == null) { + return false; + } + return true; + } + + public String getLoginName() { + User user = getBoundUser(); + if (user != null) { + return user.getLoginName(); + } + return ""; + } + + public String getEmail() { + User user = getBoundUser(); + if (user != null) { + return user.getEmail(); + } + return ""; + } + + public boolean isExistingUser() { + int option = userBindingRadiogroup.getSelectedIndex(); + return UserBindingOption.EXISTING_USER.ordinal() == option; + } + + public boolean isCreateNewUser() { + int option = userBindingRadiogroup.getSelectedIndex(); + return UserBindingOption.CREATE_NEW_USER.ordinal() == option; + } + + public void updateUserBindingView() { + Util.reloadBindings(userBindingGroupbox); + } + + public boolean isNotLimitingOrVirtualResource() { + Worker worker = getWorker(); + if (worker != null) { + return !(worker.isLimitingResource() || worker.isVirtual()); + } + return false; + } + } diff --git a/libreplan-webapp/src/main/webapp/resources/worker/_edition.zul b/libreplan-webapp/src/main/webapp/resources/worker/_edition.zul index 4d0874868..363ad1b1b 100644 --- a/libreplan-webapp/src/main/webapp/resources/worker/_edition.zul +++ b/libreplan-webapp/src/main/webapp/resources/worker/_edition.zul @@ -95,23 +95,71 @@ - + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +