diff --git a/src/main/java/info/bukova/isspst/Constants.java b/src/main/java/info/bukova/isspst/Constants.java index 2d1b3923..26c5ca28 100644 --- a/src/main/java/info/bukova/isspst/Constants.java +++ b/src/main/java/info/bukova/isspst/Constants.java @@ -1,10 +1,29 @@ package info.bukova.isspst; +import info.bukova.isspst.data.Role; + public class Constants { public final static String DEF_ADMIN = "admin"; public final static String DEF_ADMIN_PASSWD = "admin"; public final static String ROLE_USER = "ROLE_USER"; public final static String ROLE_ADMIN = "ROLE_ADMIN"; - public final static String ROLES[] = {ROLE_USER, ROLE_ADMIN}; + public final static String ROLE_DIRECTOR = "ROLE_DIRECTOR"; + public final static String ROLE_MANAGER = "ROLE_MANAGER"; + public final static String ROLE_PRINCIPAL = "ROLE_PRINCIPAL"; + public final static String ROLE_ACCOUNTANT = "ROLE_ACCOUNTANT"; + public final static String ROLE_SUPPLIER = "ROLE_SUPPLIER"; + public final static String ROLE_TECHNICIAN = "ROLE_TECHNICIAN"; + public final static String ROLE_LEADER = "ROLE_LEADER"; + public final static Role ROLES[] = { + new Role(ROLE_ADMIN, "Administrátor"), + new Role(ROLE_DIRECTOR, "Ředitel"), + new Role(ROLE_MANAGER, "Správce"), + new Role(ROLE_PRINCIPAL, "Příkazce"), + new Role(ROLE_ACCOUNTANT, "Účetní"), + new Role(ROLE_SUPPLIER, "Zásobovač"), + new Role(ROLE_TECHNICIAN, "Technik"), + new Role(ROLE_LEADER, "Vedoucí"), + new Role(ROLE_USER, "Uživatel") + }; } diff --git a/src/main/java/info/bukova/isspst/DbInitListener.java b/src/main/java/info/bukova/isspst/DbInitListener.java index ada4fa8a..da5f8974 100644 --- a/src/main/java/info/bukova/isspst/DbInitListener.java +++ b/src/main/java/info/bukova/isspst/DbInitListener.java @@ -2,14 +2,15 @@ package info.bukova.isspst; import info.bukova.isspst.data.Role; import info.bukova.isspst.data.User; -import info.bukova.isspst.services.RoleService; -import info.bukova.isspst.services.UserService; +import info.bukova.isspst.services.users.RoleService; +import info.bukova.isspst.services.users.UserService; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; @@ -37,16 +38,10 @@ public class DbInitListener implements ServletContextListener { } private void checkRoles() { - Role r = null; - - for (String auth : Constants.ROLES) + for (Role role : Constants.ROLES) { - r = roleService.getRoleByAuthority(auth); - if (r == null) { - r = new Role(); - r.setAuthority(auth); - r.setDescription("---"); - roleService.add(r); + if (roleService.getRoleByAuthority(role.getAuthority()) == null) { + roleService.add(role); } } } @@ -62,12 +57,20 @@ public class DbInitListener implements ServletContextListener { } if (!adminExists) { - User u = new User(); - u.setUsername(Constants.DEF_ADMIN); - u.addAuthority(roleService.getRoleByAuthority(Constants.ROLE_ADMIN)); - u.setEnabled(true); - userService.setPassword(u, Constants.DEF_ADMIN_PASSWD); - userService.add(u); + User u = null; + try { + u = (User) userService.loadUserByUsername(Constants.DEF_ADMIN); + u.addAuthority(roleService.getRoleByAuthority(Constants.ROLE_ADMIN)); + u.setEnabled(true); + userService.update(u); + } catch(UsernameNotFoundException e) { + u = new User(); + u.setUsername(Constants.DEF_ADMIN); + userService.setPassword(u, Constants.DEF_ADMIN_PASSWD); + u.addAuthority(roleService.getRoleByAuthority(Constants.ROLE_ADMIN)); + u.setEnabled(true); + userService.add(u); + } } } diff --git a/src/main/java/info/bukova/isspst/HomeController.java b/src/main/java/info/bukova/isspst/HomeController.java index 0d5b9736..fb3ef412 100644 --- a/src/main/java/info/bukova/isspst/HomeController.java +++ b/src/main/java/info/bukova/isspst/HomeController.java @@ -1,7 +1,7 @@ package info.bukova.isspst; import info.bukova.isspst.data.User; -import info.bukova.isspst.services.UserService; +import info.bukova.isspst.services.users.UserService; import java.text.DateFormat; import java.util.Date; diff --git a/src/main/java/info/bukova/isspst/StringUtils.java b/src/main/java/info/bukova/isspst/StringUtils.java new file mode 100644 index 00000000..2720016f --- /dev/null +++ b/src/main/java/info/bukova/isspst/StringUtils.java @@ -0,0 +1,13 @@ +package info.bukova.isspst; + +public class StringUtils { + + public static String nullStr(String str) { + return str == null ? "" : str; + } + + public static String not0ToStr(long i) { + return i == 0 ? "" : String.valueOf(i); + } + +} diff --git a/src/main/java/info/bukova/isspst/data/Role.java b/src/main/java/info/bukova/isspst/data/Role.java index 6ecc2710..b957606f 100644 --- a/src/main/java/info/bukova/isspst/data/Role.java +++ b/src/main/java/info/bukova/isspst/data/Role.java @@ -34,6 +34,15 @@ public class Role implements GrantedAuthority, DataModel { private Date modified; @Transient private boolean valid; + + public Role(String authority, String description) { + this.authority = authority; + this.description = description; + } + + public Role() { + + } @Override public String getAuthority() { @@ -83,5 +92,14 @@ public class Role implements GrantedAuthority, DataModel { public void setValid(boolean valid) { this.valid = valid; } + + @Override + public boolean equals(Object o) { + if ((o instanceof Role) && ((Role)o).getId() == this.id) { + return true; + } else { + return false; + } + } } diff --git a/src/main/java/info/bukova/isspst/data/User.java b/src/main/java/info/bukova/isspst/data/User.java index 5091b7e9..fc3c20d7 100644 --- a/src/main/java/info/bukova/isspst/data/User.java +++ b/src/main/java/info/bukova/isspst/data/User.java @@ -9,9 +9,9 @@ import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; +import javax.persistence.JoinColumn; import javax.persistence.JoinTable; -import javax.persistence.MapKeyColumn; -import javax.persistence.OneToMany; +import javax.persistence.ManyToMany; import javax.persistence.Table; import javax.persistence.Transient; @@ -36,9 +36,18 @@ public class User implements UserDetails, DataModel { private String password; @Column(name="ENABLED") private boolean enabled; - private String fullName; - @OneToMany(fetch=FetchType.EAGER) @JoinTable(name="USER_ROLE") - @MapKeyColumn(name="ROLE_ID") + @Column(name="FIRST_NAME") + private String firstName; + @Column(name="LAST_NAME") + private String lastName; + @Column(name="PERSONAL_NUMBER") + private String personalNumber; + @Column(name="EMAIL") + private String email; + @Column(name="NOTIFY") + private boolean notify; + @ManyToMany(fetch=FetchType.EAGER) + @JoinTable(name="USER_ROLE", joinColumns={@JoinColumn(name="USER_ID")}, inverseJoinColumns={@JoinColumn(name="ROLE_ID")}) private List authorities; @Column(name="CREATED") private Date created; @@ -139,11 +148,51 @@ public class User implements UserDetails, DataModel { } public String getFullName() { - return fullName; + String ret = ""; + if (firstName != null && !firstName.isEmpty()) { + ret = firstName + " "; + } + return ret + lastName == null ? "" : lastName; } - public void setFullName(String fullName) { - this.fullName = fullName; + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getPersonalNumber() { + return personalNumber; + } + + public void setPersonalNumber(String personalNumber) { + this.personalNumber = personalNumber; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public boolean isNotify() { + return notify; + } + + public void setNotify(boolean notify) { + this.notify = notify; } } diff --git a/src/main/java/info/bukova/isspst/filters/UserFilter.java b/src/main/java/info/bukova/isspst/filters/UserFilter.java new file mode 100644 index 00000000..c613510c --- /dev/null +++ b/src/main/java/info/bukova/isspst/filters/UserFilter.java @@ -0,0 +1,57 @@ +package info.bukova.isspst.filters; + +import info.bukova.isspst.data.User; + +import org.hamcrest.Description; +import org.hamcrest.Factory; +import org.hamcrest.TypeSafeMatcher; + +import static info.bukova.isspst.StringUtils.nullStr; + +public class UserFilter implements Filter { + + private User condUser; + + public UserFilter(User condition) { + this.condUser = condition; + } + + private static class UserMatcher extends TypeSafeMatcher { + + private User condUser; + + public UserMatcher(User condition) { + this.condUser = condition; + } + + @Override + public void describeTo(Description description) { + description.appendText("user matcher"); + } + + @Override + public boolean matchesSafely(User item) { + return nullStr(item.getUsername()).toLowerCase().contains(nullStr(condUser.getUsername()).toLowerCase()) + && nullStr(item.getFirstName()).toLowerCase().contains(nullStr(condUser.getFirstName()).toLowerCase()) + && nullStr(item.getLastName()).toLowerCase().contains(nullStr(condUser.getLastName()).toLowerCase()) + && nullStr(item.getPersonalNumber()).toLowerCase().contains(nullStr(condUser.getPersonalNumber()).toLowerCase()); + } + + @Factory + public UserMatcher matchUser(User cond) { + return new UserMatcher(cond); + } + + } + + @Override + public TypeSafeMatcher matcher() { + return new UserMatcher(condUser); + } + + @Override + public String queryString() { + return null; + } + +} diff --git a/src/main/java/info/bukova/isspst/services/UserService.java b/src/main/java/info/bukova/isspst/services/UserService.java deleted file mode 100644 index de8af3b7..00000000 --- a/src/main/java/info/bukova/isspst/services/UserService.java +++ /dev/null @@ -1,11 +0,0 @@ -package info.bukova.isspst.services; - -import info.bukova.isspst.data.User; - -public interface UserService extends Service { - - public void setPassword(User user, String password); - public boolean hasRole(User user, String authority); - public void test(); - -} diff --git a/src/main/java/info/bukova/isspst/services/RoleService.java b/src/main/java/info/bukova/isspst/services/users/RoleService.java similarity index 62% rename from src/main/java/info/bukova/isspst/services/RoleService.java rename to src/main/java/info/bukova/isspst/services/users/RoleService.java index f85e27ca..e20ca4f2 100644 --- a/src/main/java/info/bukova/isspst/services/RoleService.java +++ b/src/main/java/info/bukova/isspst/services/users/RoleService.java @@ -1,6 +1,7 @@ -package info.bukova.isspst.services; +package info.bukova.isspst.services.users; import info.bukova.isspst.data.Role; +import info.bukova.isspst.services.Service; public interface RoleService extends Service { diff --git a/src/main/java/info/bukova/isspst/services/RoleServiceImpl.java b/src/main/java/info/bukova/isspst/services/users/RoleServiceImpl.java similarity index 78% rename from src/main/java/info/bukova/isspst/services/RoleServiceImpl.java rename to src/main/java/info/bukova/isspst/services/users/RoleServiceImpl.java index 0fd81feb..b538fe79 100644 --- a/src/main/java/info/bukova/isspst/services/RoleServiceImpl.java +++ b/src/main/java/info/bukova/isspst/services/users/RoleServiceImpl.java @@ -1,8 +1,9 @@ -package info.bukova.isspst.services; +package info.bukova.isspst.services.users; import org.springframework.transaction.annotation.Transactional; import info.bukova.isspst.data.Role; +import info.bukova.isspst.services.AbstractService; public class RoleServiceImpl extends AbstractService implements RoleService { diff --git a/src/main/java/info/bukova/isspst/services/users/UserService.java b/src/main/java/info/bukova/isspst/services/users/UserService.java new file mode 100644 index 00000000..466ea95e --- /dev/null +++ b/src/main/java/info/bukova/isspst/services/users/UserService.java @@ -0,0 +1,14 @@ +package info.bukova.isspst.services.users; + +import org.springframework.security.core.userdetails.UserDetailsService; + +import info.bukova.isspst.data.User; +import info.bukova.isspst.services.Service; + +public interface UserService extends UserDetailsService, Service { + + public void setPassword(User user, String password); + public boolean hasRole(User user, String authority); + public void saveWithPwd(User user, String password); + +} diff --git a/src/main/java/info/bukova/isspst/services/UserServiceImpl.java b/src/main/java/info/bukova/isspst/services/users/UserServiceImpl.java similarity index 79% rename from src/main/java/info/bukova/isspst/services/UserServiceImpl.java rename to src/main/java/info/bukova/isspst/services/users/UserServiceImpl.java index af5a3c75..f2f1531c 100644 --- a/src/main/java/info/bukova/isspst/services/UserServiceImpl.java +++ b/src/main/java/info/bukova/isspst/services/users/UserServiceImpl.java @@ -1,18 +1,16 @@ -package info.bukova.isspst.services; +package info.bukova.isspst.services.users; import org.hibernate.Query; -import org.springframework.security.access.annotation.Secured; import org.springframework.security.authentication.encoding.PasswordEncoder; import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.transaction.annotation.Transactional; -import info.bukova.isspst.Constants; import info.bukova.isspst.data.Role; import info.bukova.isspst.data.User; +import info.bukova.isspst.services.AbstractService; -public class UserServiceImpl extends AbstractService implements UserService, UserDetailsService { +public class UserServiceImpl extends AbstractService implements UserService { private PasswordEncoder encoder; @@ -51,9 +49,10 @@ public class UserServiceImpl extends AbstractService implements UserServic } @Override - @Secured(Constants.ROLE_ADMIN) - public void test() { - System.out.println("pokus secured"); + @Transactional + public void saveWithPwd(User user, String password) { + this.setPassword(user, password); + this.update(user); } diff --git a/src/main/java/info/bukova/isspst/ui/ListViewModel.java b/src/main/java/info/bukova/isspst/ui/ListViewModel.java index bdfbff3a..12e948d2 100644 --- a/src/main/java/info/bukova/isspst/ui/ListViewModel.java +++ b/src/main/java/info/bukova/isspst/ui/ListViewModel.java @@ -27,8 +27,7 @@ public class ListViewModel { private boolean filter = false; private Window editWin; private T dataBean; - //private T filterTemplate; - private Filter dataFilter; + private T filterTemplate; private T editBean; private List dataList; private List fullList; @@ -42,6 +41,7 @@ public class ListViewModel { protected Service service; protected Class dataClass; protected String formZul; + protected Filter dataFilter; public List getDataList() { if (dataList == null) { @@ -60,6 +60,20 @@ public class ListViewModel { this.dataFilter = dataFilter; } + public T getFilterTemplate() { + if (filterTemplate == null) { + try { + filterTemplate = dataClass.newInstance(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + return filterTemplate; + } + public T getDataBean() { return dataBean; } diff --git a/src/main/java/info/bukova/isspst/ui/UserForm.java b/src/main/java/info/bukova/isspst/ui/UserForm.java deleted file mode 100644 index 07116ed4..00000000 --- a/src/main/java/info/bukova/isspst/ui/UserForm.java +++ /dev/null @@ -1,14 +0,0 @@ -package info.bukova.isspst.ui; - -import org.zkoss.bind.annotation.Init; - -import info.bukova.isspst.data.User; - -public class UserForm extends FormViewModel { - - @Init(superclass = true) - public void init() { - - } - -} diff --git a/src/main/java/info/bukova/isspst/ui/users/RoleCheck.java b/src/main/java/info/bukova/isspst/ui/users/RoleCheck.java new file mode 100644 index 00000000..a564be95 --- /dev/null +++ b/src/main/java/info/bukova/isspst/ui/users/RoleCheck.java @@ -0,0 +1,43 @@ +package info.bukova.isspst.ui.users; + +import info.bukova.isspst.data.Role; +import info.bukova.isspst.data.User; + +public class RoleCheck { + + private Role role; + private User user; + private boolean checked; + + public RoleCheck(User user, Role role) { + this.user = user; + this.role = role; + if (user.getAuthorities().contains(role)) { + checked = true; + } else { + checked = false; + } + } + + public Role getRole() { + return role; + } + + public void setRole(Role role) { + this.role = role; + } + + public boolean isChecked() { + return checked; + } + + public void setChecked(boolean checked) { + this.checked = checked; + if (checked && !user.getAuthorities().contains(role)) { + user.addAuthority(role); + } else { + user.getAuthorities().remove(role); + } + } + +} diff --git a/src/main/java/info/bukova/isspst/ui/users/UserForm.java b/src/main/java/info/bukova/isspst/ui/users/UserForm.java new file mode 100644 index 00000000..2ebdb55c --- /dev/null +++ b/src/main/java/info/bukova/isspst/ui/users/UserForm.java @@ -0,0 +1,90 @@ +package info.bukova.isspst.ui.users; + +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.zkoss.bind.annotation.Command; +import org.zkoss.bind.annotation.Init; +import org.zkoss.bind.annotation.NotifyChange; +import org.zkoss.zk.ui.select.annotation.WireVariable; + +import info.bukova.isspst.data.User; +import info.bukova.isspst.services.users.RoleService; +import info.bukova.isspst.services.users.UserService; +import info.bukova.isspst.ui.FormViewModel; + +public class UserForm extends FormViewModel { + + @WireVariable + private RoleService roleService; + @WireVariable + private UserService userService; + private String retPasswd = ""; + private String password = ""; + private UserRoles userRoles; + private boolean loginFree; + + @Init(superclass = true) + public void init() { + userRoles = new UserRoles(getDataBean(), roleService.getAll()); + loginFree = true; + } + + public UserRoles getUserRoles() { + return userRoles; + } + + public String getRetPasswd() { + return retPasswd; + } + + @NotifyChange({"canSave", "pwMatches"}) + public void setRetPasswd(String retPasswd) { + this.retPasswd = retPasswd; + } + + public String getPassword() { + return password; + } + + @NotifyChange({"canSave", "pwMatches"}) + public void setPassword(String password) { + this.password = password; + } + + @Command + @NotifyChange({"loginFree", "canSave"}) + public void checkLogin() { + try { + userService.loadUserByUsername(getDataBean().getUsername()); + loginFree = false; + } catch(UsernameNotFoundException e) { + loginFree = true; + } + } + + public boolean isPwMatches() { + return password.equals(retPasswd); + } + + public boolean isLoginFree() { + return loginFree || isEdit(); + } + + public boolean isEdit() { + return getDataBean().getCreated() != null; + } + + @Override + protected void doSave() { + if (!password.isEmpty()) { + userService.saveWithPwd(getDataBean(), this.password); + } else { + super.doSave(); + } + } + + @Override + public boolean isCanSave() { + return password.equals(retPasswd) && isLoginFree() && getDataBean().getUsername() != null && !getDataBean().getUsername().isEmpty(); + } + +} diff --git a/src/main/java/info/bukova/isspst/ui/users/UserRoles.java b/src/main/java/info/bukova/isspst/ui/users/UserRoles.java new file mode 100644 index 00000000..7ff5fbe9 --- /dev/null +++ b/src/main/java/info/bukova/isspst/ui/users/UserRoles.java @@ -0,0 +1,24 @@ +package info.bukova.isspst.ui.users; + +import info.bukova.isspst.data.Role; +import info.bukova.isspst.data.User; + +import java.util.ArrayList; +import java.util.List; + +public class UserRoles { + + private List roleChecks; + + public UserRoles(User user, List roles) { + roleChecks = new ArrayList(); + for (Role r : roles) { + roleChecks.add(new RoleCheck(user, r)); + } + } + + public List getRoleChecks() { + return roleChecks; + } + +} diff --git a/src/main/java/info/bukova/isspst/ui/UsersList.java b/src/main/java/info/bukova/isspst/ui/users/UsersList.java similarity index 60% rename from src/main/java/info/bukova/isspst/ui/UsersList.java rename to src/main/java/info/bukova/isspst/ui/users/UsersList.java index c5ca0c0f..047f22ff 100644 --- a/src/main/java/info/bukova/isspst/ui/UsersList.java +++ b/src/main/java/info/bukova/isspst/ui/users/UsersList.java @@ -1,10 +1,12 @@ -package info.bukova.isspst.ui; +package info.bukova.isspst.ui.users; import org.zkoss.bind.annotation.Init; import org.zkoss.zk.ui.select.annotation.WireVariable; import info.bukova.isspst.data.User; -import info.bukova.isspst.services.UserService; +import info.bukova.isspst.filters.UserFilter; +import info.bukova.isspst.services.users.UserService; +import info.bukova.isspst.ui.ListViewModel; public class UsersList extends ListViewModel { @@ -16,6 +18,7 @@ public class UsersList extends ListViewModel { service = userService; dataClass = User.class; formZul = "userForm.zul"; + dataFilter = new UserFilter(getFilterTemplate()); } } diff --git a/src/main/webapp/WEB-INF/spring/root-context.xml b/src/main/webapp/WEB-INF/spring/root-context.xml index 39249fd2..2e95a6b7 100644 --- a/src/main/webapp/WEB-INF/spring/root-context.xml +++ b/src/main/webapp/WEB-INF/spring/root-context.xml @@ -89,12 +89,12 @@ - + - + diff --git a/src/main/webapp/admin/users/userForm.zul b/src/main/webapp/admin/users/userForm.zul index 635a212d..dd16454d 100644 --- a/src/main/webapp/admin/users/userForm.zul +++ b/src/main/webapp/admin/users/userForm.zul @@ -1,6 +1,34 @@ - - + +