diff --git a/src/main/java/info/bukova/isspst/Constants.java b/src/main/java/info/bukova/isspst/Constants.java index 26c5ca28..d07a84f0 100644 --- a/src/main/java/info/bukova/isspst/Constants.java +++ b/src/main/java/info/bukova/isspst/Constants.java @@ -1,6 +1,11 @@ package info.bukova.isspst; +import info.bukova.isspst.data.Permission; import info.bukova.isspst.data.Role; +import info.bukova.isspst.services.BuildingService; +import info.bukova.isspst.services.addressbook.AdbService; +import info.bukova.isspst.services.users.RoleService; +import info.bukova.isspst.services.users.UserService; public class Constants { @@ -25,5 +30,27 @@ public class Constants { new Role(ROLE_TECHNICIAN, "Technik"), new Role(ROLE_LEADER, "Vedoucí"), new Role(ROLE_USER, "Uživatel") - }; + }; + + public final static String PERM_READ = "PERM_READ"; + public final static String PERM_ADD = "PERM_ADD"; + public final static String PERM_EDIT = "PERM_EDIT"; + public final static String PERM_DELETE = "PERM_DELETE"; + public final static Permission DEF_PERMISSIONS[] = { + new Permission(PERM_READ, "Číst"), + new Permission(PERM_ADD, "Přidávat"), + new Permission(PERM_EDIT, "Upravit"), + new Permission(PERM_DELETE, "Mazat") + }; + + public final static String MOD_USERS = "USERS"; + public final static String MOD_PERMISSIONS = "PERMISSIONS"; + public final static String MOD_ADDRESSBOOK = "ADDRESSBOOK"; + public final static String MOD_BUILDINGS = "BUILDINGS"; + public final static Module MODULES[] = { + new Module(MOD_USERS, "Uživatelé", UserService.class), + new Module(MOD_PERMISSIONS, "Práva", RoleService.class), + new Module(MOD_ADDRESSBOOK, "Dodavatelé", AdbService.class), + new Module(MOD_BUILDINGS, "Budovy", BuildingService.class) + }; } diff --git a/src/main/java/info/bukova/isspst/DbInitListener.java b/src/main/java/info/bukova/isspst/DbInitListener.java index da5f8974..a72da4dd 100644 --- a/src/main/java/info/bukova/isspst/DbInitListener.java +++ b/src/main/java/info/bukova/isspst/DbInitListener.java @@ -1,7 +1,9 @@ package info.bukova.isspst; +import info.bukova.isspst.data.Permission; import info.bukova.isspst.data.Role; import info.bukova.isspst.data.User; +import info.bukova.isspst.services.users.PermissionService; import info.bukova.isspst.services.users.RoleService; import info.bukova.isspst.services.users.UserService; @@ -10,6 +12,8 @@ import javax.servlet.ServletContextListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; @@ -18,6 +22,7 @@ public class DbInitListener implements ServletContextListener { private RoleService roleService; private UserService userService; + private PermissionService permService; @Override public void contextDestroyed(ServletContextEvent arg0) { @@ -29,12 +34,23 @@ public class DbInitListener implements ServletContextListener { Logger logger = LoggerFactory.getLogger(DbInitListener.class); logger.info("Initializing database"); + User tmpAdmin = new User(); + Role tmpRole = new Role(); + tmpRole.setAuthority(Constants.ROLE_ADMIN); + tmpAdmin.setUsername(Constants.DEF_ADMIN); + tmpAdmin.addAuthority(tmpRole); + SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(tmpAdmin, null, tmpAdmin.getAuthorities())); + WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(evt.getServletContext()); roleService = ctx.getBean(RoleService.class); userService = ctx.getBean(UserService.class); + permService = ctx.getBean(PermissionService.class); checkRoles(); checkUsers(); + checkPermissions(); + + SecurityContextHolder.getContext().setAuthentication(null); } private void checkRoles() { @@ -73,5 +89,16 @@ public class DbInitListener implements ServletContextListener { } } } + + private void checkPermissions() { + for (Module m : Constants.MODULES) { + for (Permission p : Constants.DEF_PERMISSIONS) { + if (permService.getPermissionByModule(m.getId(), p.getAuthority()) == null) { + p.setModule(m.getId()); + permService.add(p); + } + } + } + } } diff --git a/src/main/java/info/bukova/isspst/IsspstPermissionEvaluator.java b/src/main/java/info/bukova/isspst/IsspstPermissionEvaluator.java new file mode 100644 index 00000000..5aed5aa6 --- /dev/null +++ b/src/main/java/info/bukova/isspst/IsspstPermissionEvaluator.java @@ -0,0 +1,55 @@ +package info.bukova.isspst; + +import info.bukova.isspst.data.Role; +import info.bukova.isspst.services.Service; + +import java.io.Serializable; +import java.util.List; + +import org.springframework.security.access.PermissionEvaluator; +import org.springframework.security.core.Authentication; + +public class IsspstPermissionEvaluator implements PermissionEvaluator { + + @SuppressWarnings("unchecked") + @Override + public boolean hasPermission(Authentication authentication, + Object targetDomainObject, Object permission) { + List perms = (List) authentication.getAuthorities(); + String moduleId = ""; + String perm = ""; + + if (permission instanceof String) { + perm = (String) permission; + } + + if (targetDomainObject instanceof Service) + { + for (Module m : Constants.MODULES) { + if (m.getServiceClass().isAssignableFrom(targetDomainObject.getClass())) { + moduleId = m.getId(); + } + } + + perm += "_" + moduleId; + + for (Role r : perms) { + if (r.getAuthority().equals(perm)) { + return true; + } + if (r.getAuthority().equals(Constants.ROLE_ADMIN)) { + return true; + } + } + } + + return false; + } + + @Override + public boolean hasPermission(Authentication authentication, + Serializable targetId, String targetType, Object permission) { + return false; + } + +} diff --git a/src/main/java/info/bukova/isspst/Module.java b/src/main/java/info/bukova/isspst/Module.java new file mode 100644 index 00000000..fd993384 --- /dev/null +++ b/src/main/java/info/bukova/isspst/Module.java @@ -0,0 +1,39 @@ +package info.bukova.isspst; + +public class Module { + + private String id; + private String name; + private Class serviceClass; + + public Class getServiceClass() { + return serviceClass; + } + + public void setServiceClass(Class serviceClass) { + this.serviceClass = serviceClass; + } + + public Module(String id, String name, Class serviceClass) { + this.id = id; + this.name = name; + this.serviceClass = serviceClass; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/src/main/java/info/bukova/isspst/dao/PermissionDao.java b/src/main/java/info/bukova/isspst/dao/PermissionDao.java new file mode 100644 index 00000000..306ef06c --- /dev/null +++ b/src/main/java/info/bukova/isspst/dao/PermissionDao.java @@ -0,0 +1,7 @@ +package info.bukova.isspst.dao; + +import info.bukova.isspst.data.Permission; + +public interface PermissionDao extends BaseDao { + +} diff --git a/src/main/java/info/bukova/isspst/dao/jpa/PermissionDaoJPA.java b/src/main/java/info/bukova/isspst/dao/jpa/PermissionDaoJPA.java new file mode 100644 index 00000000..a4f7d5ba --- /dev/null +++ b/src/main/java/info/bukova/isspst/dao/jpa/PermissionDaoJPA.java @@ -0,0 +1,13 @@ +package info.bukova.isspst.dao.jpa; + +import info.bukova.isspst.dao.PermissionDao; +import info.bukova.isspst.data.Permission; + +public class PermissionDaoJPA extends BaseDaoJPA implements PermissionDao { + + @Override + public String getEntityName() { + return Permission.class.getSimpleName(); + } + +} diff --git a/src/main/java/info/bukova/isspst/data/BaseSimpleData.java b/src/main/java/info/bukova/isspst/data/BaseSimpleData.java new file mode 100644 index 00000000..d25c9fce --- /dev/null +++ b/src/main/java/info/bukova/isspst/data/BaseSimpleData.java @@ -0,0 +1,65 @@ +package info.bukova.isspst.data; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; +import javax.persistence.Transient; + +@MappedSuperclass +public abstract class BaseSimpleData implements DataModel { + + @Id + @Column(name="ID") + @GeneratedValue + private int id; + @Column(name="CREATED") + private Date created; + @Column(name="MODIFIED") + private Date modified; + @Transient + private boolean valid; + + @Override + public int getId() { + return id; + } + + @Override + public void setId(int id) { + this.id = id; + } + + @Override + public Date getCreated() { + return created; + } + + @Override + public void setCreated(Date created) { + this.created = created; + } + + @Override + public Date getModified() { + return modified; + } + + @Override + public void setModified(Date modified) { + this.modified = modified; + } + + @Override + public boolean isValid() { + return valid; + } + + @Override + public void setValid(boolean valid) { + this.valid = valid; + } + +} diff --git a/src/main/java/info/bukova/isspst/data/Permission.java b/src/main/java/info/bukova/isspst/data/Permission.java new file mode 100644 index 00000000..64e510f8 --- /dev/null +++ b/src/main/java/info/bukova/isspst/data/Permission.java @@ -0,0 +1,69 @@ +package info.bukova.isspst.data; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; + +import org.springframework.security.core.GrantedAuthority; + +@Entity +@Table(name="PERMISSION") +public class Permission extends BaseSimpleData implements GrantedAuthority { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Column(name="AUTHORITY") + private String authority; + @Column(name="DESCRIPTION") + private String description; + @Column(name="MODULE") + private String module; + + public Permission(String authority, String description) { + this.authority = authority; + this.description = description; + this.module = ""; + } + + public Permission() { + + } + + @Override + public String getAuthority() { + return authority; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getModule() { + return module; + } + + public void setModule(String module) { + this.module = module; + } + + public void setAuthority(String authority) { + this.authority = authority; + } + + @Override + public boolean equals(Object o) { + if ((o instanceof Permission) && ((Permission)o).getId() == this.getId()) { + return true; + } else { + return false; + } + } + +} diff --git a/src/main/java/info/bukova/isspst/data/Role.java b/src/main/java/info/bukova/isspst/data/Role.java index b957606f..ead151fb 100644 --- a/src/main/java/info/bukova/isspst/data/Role.java +++ b/src/main/java/info/bukova/isspst/data/Role.java @@ -1,47 +1,45 @@ package info.bukova.isspst.data; -import java.util.Date; +import java.util.ArrayList; +import java.util.List; import javax.persistence.Column; import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; import javax.persistence.Table; -import javax.persistence.Transient; +import org.hibernate.annotations.LazyCollection; +import org.hibernate.annotations.LazyCollectionOption; import org.springframework.security.core.GrantedAuthority; @Entity @Table(name="ROLE") -public class Role implements GrantedAuthority, DataModel { +public class Role extends BaseSimpleData implements GrantedAuthority, DataModel { /** * */ private static final long serialVersionUID = 5677876140880991163L; - @Id - @Column(name="ID") - @GeneratedValue - private int id; @Column(name="AUTHORITY", unique=true) private String authority; @Column(name="DESCRIPTION") private String description; - @Column(name="CREATED") - private Date created; - @Column(name="MODIFIED") - private Date modified; - @Transient - private boolean valid; - + @ManyToMany + @LazyCollection(LazyCollectionOption.FALSE) + @JoinTable(name="ROLE_PERMISSION", joinColumns={@JoinColumn(name="ROLE_ID")}, inverseJoinColumns={@JoinColumn(name="PERMISSION_ID")}) + private List permissions; + public Role(String authority, String description) { this.authority = authority; this.description = description; + this.permissions = new ArrayList(); } public Role() { - + this.permissions = new ArrayList(); } @Override @@ -49,14 +47,6 @@ public class Role implements GrantedAuthority, DataModel { return authority; } - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - public String getDescription() { return description; } @@ -69,33 +59,21 @@ public class Role implements GrantedAuthority, DataModel { this.authority = authority; } - public Date getCreated() { - return created; + public List getPermissions() { + return permissions; } - public void setCreated(Date created) { - this.created = created; + public void setPermissions(List permissions) { + this.permissions = permissions; } - - public Date getModified() { - return modified; - } - - public void setModified(Date modified) { - this.modified = modified; - } - - public boolean isValid() { - return valid; + + public void addPermission(Permission permission) { + this.permissions.add(permission); } - public void setValid(boolean valid) { - this.valid = valid; - } - @Override public boolean equals(Object o) { - if ((o instanceof Role) && ((Role)o).getId() == this.id) { + if ((o instanceof Role) && ((Role)o).getId() == this.getId()) { 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 fc3c20d7..680c668f 100644 --- a/src/main/java/info/bukova/isspst/data/User.java +++ b/src/main/java/info/bukova/isspst/data/User.java @@ -1,35 +1,27 @@ package info.bukova.isspst.data; import java.util.ArrayList; -import java.util.Date; import java.util.List; import javax.persistence.Column; 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.ManyToMany; import javax.persistence.Table; -import javax.persistence.Transient; import org.springframework.security.core.userdetails.UserDetails; @Entity @Table(name="USER") -public class User implements UserDetails, DataModel { +public class User extends BaseSimpleData implements UserDetails, DataModel { /** * */ private static final long serialVersionUID = 5421234421833765433L; - @Id - @Column(name="ID") - @GeneratedValue - private int id; @Column(name="USERNAME", unique=true) private String username; @Column(name="PASSWORD") @@ -49,20 +41,33 @@ public class User implements UserDetails, DataModel { @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; - @Column(name="MODIFIED") - private Date modified; - @Transient - private boolean valid; - + public User() { authorities = new ArrayList(); } @Override public List getAuthorities() { - return authorities; + List roles = new ArrayList(); + for (Role r : authorities) { + roles.add(r); + for (Permission p : r.getPermissions()) { + Role role = new Role(); + boolean addRole = true; + role.setAuthority(p.getAuthority() + "_" + p.getModule()); + + for (Role chRole : roles) { + if (chRole.getAuthority().equals(role.getAuthority())) { + addRole = false; + } + } + + if (addRole) { + roles.add(role); + } + } + } + return roles; } @Override @@ -95,14 +100,6 @@ public class User implements UserDetails, DataModel { return enabled; } - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - public void setPassword(String password) { this.password = password; } @@ -122,29 +119,9 @@ public class User implements UserDetails, DataModel { public void addAuthority(Role role) { this.authorities.add(role); } - - public Date getCreated() { - return created; - } - - public void setCreated(Date created) { - this.created = created; - } - - public Date getModified() { - return modified; - } - - public void setModified(Date modified) { - this.modified = modified; - } - - public boolean isValid() { - return valid; - } - - public void setValid(boolean valid) { - this.valid = valid; + + public void removeAuthority(Role role) { + this.authorities.remove(role); } public String getFullName() { diff --git a/src/main/java/info/bukova/isspst/services/AbstractOwnedService.java b/src/main/java/info/bukova/isspst/services/AbstractOwnedService.java index 93e0a433..2236fc04 100644 --- a/src/main/java/info/bukova/isspst/services/AbstractOwnedService.java +++ b/src/main/java/info/bukova/isspst/services/AbstractOwnedService.java @@ -2,6 +2,9 @@ package info.bukova.isspst.services; import java.util.Date; +import org.hibernate.NonUniqueResultException; +import org.hibernate.Query; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.transaction.annotation.Transactional; @@ -12,6 +15,7 @@ public class AbstractOwnedService extends AbstractServ @Override @Transactional + @PreAuthorize("hasPermission(this, 'PERM_ADD')") public void add(T entity) { validate(entity); entity.setCreated(new Date()); @@ -21,19 +25,23 @@ public class AbstractOwnedService extends AbstractServ @Override @Transactional + @PreAuthorize("hasPermission(this, 'PERM_EDIT')") public void update(T entity) { - if (entity.getCreated() == null) { - add(entity); - } else { - validate(entity); - entity.setModifiedBy(getLoggedInUser()); - entity.setModified(new Date()); - dao.modify(entity); - } + validate(entity); + entity.setModifiedBy(getLoggedInUser()); + entity.setModified(new Date()); + dao.modify(entity); } + @Transactional protected User getLoggedInUser() { - return (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + try { + String query = "from User where ID = " + ((User)SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId(); + Query q = dao.getQuery(query); + return (User) q.uniqueResult(); + } catch (NonUniqueResultException e) { + return null; + } } } diff --git a/src/main/java/info/bukova/isspst/services/AbstractService.java b/src/main/java/info/bukova/isspst/services/AbstractService.java index 81b77371..73888a53 100644 --- a/src/main/java/info/bukova/isspst/services/AbstractService.java +++ b/src/main/java/info/bukova/isspst/services/AbstractService.java @@ -14,6 +14,7 @@ import javax.validation.Validator; import org.hibernate.NonUniqueResultException; import org.hibernate.Query; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Transactional; public abstract class AbstractService implements Service { @@ -25,8 +26,15 @@ public abstract class AbstractService implements Service this.dao = dao; } + @Override + @PreAuthorize("hasPermission(this, 'PERM_ADD')") + public final T create() { + return createEntity(); + } + @Override @Transactional + @PreAuthorize("hasPermission(this, 'PERM_ADD')") public void add(T entity) { validate(entity); entity.setCreated(new Date()); @@ -35,18 +43,16 @@ public abstract class AbstractService implements Service @Override @Transactional + @PreAuthorize("hasPermission(this, 'PERM_EDIT')") public void update(T entity) { - if (entity.getCreated() == null) { - add(entity); - } else { - validate(entity); - entity.setModified(new Date()); - dao.modify(entity); - } + validate(entity); + entity.setModified(new Date()); + dao.modify(entity); } @Override @Transactional + @PreAuthorize("hasPermission(this, 'PERM_DELETE')") public void delete(T entity) { dao.delete(entity); } @@ -80,6 +86,7 @@ public abstract class AbstractService implements Service @Override @Transactional + @PreAuthorize("hasPermission(this, 'PERM_READ')") public T getById(int id) { return dao.getById(id); @@ -87,12 +94,14 @@ public abstract class AbstractService implements Service @Override @Transactional + @PreAuthorize("hasPermission(this, 'PERM_READ')") public List getAll() { return dao.getAll(); } @Override @Transactional + @PreAuthorize("hasPermission(this, 'PERM_READ')") public List execQuery(String query) { return dao.execQuery(query); } @@ -100,6 +109,7 @@ public abstract class AbstractService implements Service @SuppressWarnings("unchecked") @Override @Transactional + @PreAuthorize("hasPermission(this, 'PERM_READ')") public T selectSingle(String query) { try { Query q = dao.getQuery(query); @@ -112,5 +122,9 @@ public abstract class AbstractService implements Service public void setValidator(Validator validator) { this.validator = validator; } + + protected T createEntity() { + return null; + } } diff --git a/src/main/java/info/bukova/isspst/services/Service.java b/src/main/java/info/bukova/isspst/services/Service.java index bf3ab850..4fe6149a 100644 --- a/src/main/java/info/bukova/isspst/services/Service.java +++ b/src/main/java/info/bukova/isspst/services/Service.java @@ -6,6 +6,7 @@ import java.util.List; public interface Service { + public T create(); public void add(T entity); public void update(T entity); public void delete(T entity); diff --git a/src/main/java/info/bukova/isspst/services/users/PermissionService.java b/src/main/java/info/bukova/isspst/services/users/PermissionService.java new file mode 100644 index 00000000..7ffc0d54 --- /dev/null +++ b/src/main/java/info/bukova/isspst/services/users/PermissionService.java @@ -0,0 +1,10 @@ +package info.bukova.isspst.services.users; + +import info.bukova.isspst.data.Permission; +import info.bukova.isspst.services.Service; + +public interface PermissionService extends Service { + + public Permission getPermissionByModule(String moduleId, String permission); + +} diff --git a/src/main/java/info/bukova/isspst/services/users/PermissionServiceImpl.java b/src/main/java/info/bukova/isspst/services/users/PermissionServiceImpl.java new file mode 100644 index 00000000..adde62b9 --- /dev/null +++ b/src/main/java/info/bukova/isspst/services/users/PermissionServiceImpl.java @@ -0,0 +1,17 @@ +package info.bukova.isspst.services.users; + +import org.springframework.transaction.annotation.Transactional; + +import info.bukova.isspst.data.Permission; +import info.bukova.isspst.services.AbstractService; + +public class PermissionServiceImpl extends AbstractService implements PermissionService { + + @Override + @Transactional + public Permission getPermissionByModule(String moduleId, String permission) { + return selectSingle("from Permission where MODULE = '" + moduleId + "' and AUTHORITY = '" + permission + "'"); + } + + +} diff --git a/src/main/java/info/bukova/isspst/services/users/UserService.java b/src/main/java/info/bukova/isspst/services/users/UserService.java index 466ea95e..429b472b 100644 --- a/src/main/java/info/bukova/isspst/services/users/UserService.java +++ b/src/main/java/info/bukova/isspst/services/users/UserService.java @@ -1,14 +1,16 @@ 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; +import org.springframework.security.core.userdetails.UserDetailsService; + 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); + public User getCurrent(); + public String encodePassword(User user, String plain); } diff --git a/src/main/java/info/bukova/isspst/services/users/UserServiceImpl.java b/src/main/java/info/bukova/isspst/services/users/UserServiceImpl.java index f2f1531c..ae4ee230 100644 --- a/src/main/java/info/bukova/isspst/services/users/UserServiceImpl.java +++ b/src/main/java/info/bukova/isspst/services/users/UserServiceImpl.java @@ -2,6 +2,8 @@ package info.bukova.isspst.services.users; import org.hibernate.Query; import org.springframework.security.authentication.encoding.PasswordEncoder; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.transaction.annotation.Transactional; @@ -35,7 +37,7 @@ public class UserServiceImpl extends AbstractService implements UserServic @Override public void setPassword(User user, String password) { - user.setPassword(encoder.encodePassword(password, user.getUsername())); + user.setPassword(encodePassword(user, password)); } @Override @@ -55,5 +57,21 @@ public class UserServiceImpl extends AbstractService implements UserServic this.update(user); } + @Override + public User getCurrent() { + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + + if (auth != null && auth.getPrincipal() != null) { + return (User)auth.getPrincipal(); + } + + return null; + } + + @Override + public String encodePassword(User user, String plain) { + return encoder.encodePassword(plain, user.getUsername()); + } + } diff --git a/src/main/java/info/bukova/isspst/ui/FormViewModel.java b/src/main/java/info/bukova/isspst/ui/FormViewModel.java index a3460c35..a5dab5a5 100644 --- a/src/main/java/info/bukova/isspst/ui/FormViewModel.java +++ b/src/main/java/info/bukova/isspst/ui/FormViewModel.java @@ -6,6 +6,7 @@ import info.bukova.isspst.services.ValidationException; import java.util.Map; +import org.springframework.security.access.AccessDeniedException; import org.zkoss.bind.annotation.BindingParam; import org.zkoss.bind.annotation.Command; import org.zkoss.bind.annotation.ExecutionArgParam; @@ -19,11 +20,17 @@ public class FormViewModel { private T dataBean; private Map errMessages; private Service service; + private boolean newRec; @Init public void init(@ExecutionArgParam("selected") T selected, @ExecutionArgParam("service") Service service) { this.dataBean = selected; this.service = service; + if (selected.getId() == 0 && selected.getCreated() == null) { + newRec = true; + } else { + newRec = false; + } } public T getDataBean() { @@ -34,7 +41,11 @@ public class FormViewModel { @NotifyChange("errMessages") public void save(@BindingParam("window") Window win) { try { - doSave(); + if (newRec) { + doAdd(); + } else { + doSave(); + } win.detach(); } catch (ValidationException e) { errMessages = e.getMessages(); @@ -45,8 +56,9 @@ public class FormViewModel { } Messagebox.show("Chyba validace", "Chyba", Messagebox.OK, Messagebox.ERROR); + } catch (AccessDeniedException e) { + Messagebox.show("K vykobání této operace nemáte dostatečná oprávnění", "Chyba", Messagebox.OK, Messagebox.ERROR); } catch (Exception e) { - dataBean.setCreated(null); e.printStackTrace(); Messagebox.show("Chyba při ukládání záznamu", "Chyba", Messagebox.OK, Messagebox.ERROR); } @@ -64,6 +76,10 @@ public class FormViewModel { service.update(dataBean); } + protected void doAdd() { + service.add(dataBean); + } + public boolean isCanSave() { return true; } diff --git a/src/main/java/info/bukova/isspst/ui/ListViewModel.java b/src/main/java/info/bukova/isspst/ui/ListViewModel.java index 1464678d..0537287a 100644 --- a/src/main/java/info/bukova/isspst/ui/ListViewModel.java +++ b/src/main/java/info/bukova/isspst/ui/ListViewModel.java @@ -10,6 +10,7 @@ import java.util.List; import java.util.Map; import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.security.access.AccessDeniedException; import org.zkoss.bind.BindUtils; import org.zkoss.bind.annotation.BindingParam; import org.zkoss.bind.annotation.Command; @@ -129,26 +130,31 @@ public class ListViewModel { public void addNew() { try { newRecMode(); - editBean = dataClass.newInstance(); + editBean = service.create(); + if (dataBean == null) { + editBean = dataClass.newInstance(); + } showForm(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); + } catch (AccessDeniedException e) { + Messagebox.show("K vykobání této operace nemáte dostatečná oprávnění", "Chyba", Messagebox.OK, Messagebox.ERROR); } } - + @Command public void edit() { int index = dataList.indexOf(dataBean); newRec = false; - if (index != -1) { + if (index != -1) { selIndex = index; } editBean = service.getById(dataBean.getId()); showForm(); } - + @Command @NotifyChange("confirmDelete") public void delObject() { @@ -174,9 +180,9 @@ public class ListViewModel { BindUtils.postNotifyChange(null, null, ListViewModel.this, "dataBean"); } catch (DataIntegrityViolationException e) { - Messagebox.show("Chyba při mazání záznamu", - "Chyba", Messagebox.OK, - Messagebox.ERROR); + Messagebox.show("Chyba při mazání záznamu", "Chyba", Messagebox.OK, Messagebox.ERROR); + } catch (AccessDeniedException e) { + Messagebox.show("K vykobání této operace nemáte dostatečná oprávnění", "Chyba", Messagebox.OK, Messagebox.ERROR); } } } diff --git a/src/main/java/info/bukova/isspst/ui/NavigationVM.java b/src/main/java/info/bukova/isspst/ui/NavigationVM.java index 3a4d927e..3c64dc6b 100644 --- a/src/main/java/info/bukova/isspst/ui/NavigationVM.java +++ b/src/main/java/info/bukova/isspst/ui/NavigationVM.java @@ -1,7 +1,9 @@ package info.bukova.isspst.ui; +import org.zkoss.bind.annotation.Command; import org.zkoss.bind.annotation.Init; import org.zkoss.zk.ui.Executions; +import org.zkoss.zul.Window; public class NavigationVM { @@ -14,6 +16,12 @@ public class NavigationVM { moduleUrl = Executions.getCurrent().getDesktop().getRequestPath(); } + @Command + public void passwd() { + Window window = (Window)Executions.createComponents("/app/passwd.zul", null, null); + window.doModal(); + } + public String getContextPath() { return contextPath; } diff --git a/src/main/java/info/bukova/isspst/ui/users/PasswdVM.java b/src/main/java/info/bukova/isspst/ui/users/PasswdVM.java new file mode 100644 index 00000000..47286063 --- /dev/null +++ b/src/main/java/info/bukova/isspst/ui/users/PasswdVM.java @@ -0,0 +1,83 @@ +package info.bukova.isspst.ui.users; + +import info.bukova.isspst.data.User; +import info.bukova.isspst.services.users.UserService; + +import org.zkoss.bind.annotation.BindingParam; +import org.zkoss.bind.annotation.Command; +import org.zkoss.bind.annotation.Init; +import org.zkoss.zk.ui.select.annotation.WireVariable; +import org.zkoss.zul.Messagebox; +import org.zkoss.zul.Window; + +public class PasswdVM { + + private String oldPw; + private String newPw; + private String retPw; + private User user; + @WireVariable + private UserService userService; + + @Init + public void init() { + user = userService.getCurrent(); + } + + @Command + public void save(@BindingParam("window") Window window) { + if (!canSave()) { + return; + } + + userService.saveWithPwd(user, newPw); + Messagebox.show("Heslo bylo změněno", "Změna hesla", Messagebox.OK, Messagebox.INFORMATION); + window.detach(); + } + + private boolean canSave() { + if (!user.getPassword().equals(userService.encodePassword(user, oldPw))) { + Messagebox.show("Špatné staré heslo", "Chyba", Messagebox.OK, Messagebox.ERROR); + return false; + } + + if (newPw == null || newPw.isEmpty()) { + Messagebox.show("Zadejte nové heslo", "Chyba", Messagebox.OK, Messagebox.ERROR); + return false; + } + + if (!newPw.equals(retPw)) { + Messagebox.show("Nasouhlasí nová hesla", "Chyba", Messagebox.OK, Messagebox.ERROR); + return false; + } + + return true; + } + + public String getOldPw() { + return oldPw; + } + + public void setOldPw(String oldPw) { + this.oldPw = oldPw; + } + + public String getNewPw() { + return newPw; + } + + public void setNewPw(String newPw) { + this.newPw = newPw; + } + + public String getRetPw() { + return retPw; + } + + public void setRetPw(String retPw) { + this.retPw = retPw; + } + + + +} diff --git a/src/main/java/info/bukova/isspst/ui/users/PermissionCheck.java b/src/main/java/info/bukova/isspst/ui/users/PermissionCheck.java new file mode 100644 index 00000000..75185ad4 --- /dev/null +++ b/src/main/java/info/bukova/isspst/ui/users/PermissionCheck.java @@ -0,0 +1,44 @@ +package info.bukova.isspst.ui.users; + +import info.bukova.isspst.data.Permission; +import info.bukova.isspst.data.Role; + +public class PermissionCheck { + + private Role role; + private Permission permission; + private boolean checked; + + public PermissionCheck(Role role, Permission permission) { + this.role = role; + this.permission = permission; + + if (role.getPermissions().contains(permission)) { + checked = true; + } else { + checked = false; + } + } + + public Permission getPermission() { + return permission; + } + + public void setPermission(Permission permission) { + this.permission = permission; + } + + public boolean isChecked() { + return checked; + } + + public void setChecked(boolean checked) { + this.checked = checked; + if (checked && !role.getPermissions().contains(permission)) { + role.addPermission(permission); + } else { + role.getPermissions().remove(permission); + } + } + +} diff --git a/src/main/java/info/bukova/isspst/ui/users/PermissionForm.java b/src/main/java/info/bukova/isspst/ui/users/PermissionForm.java new file mode 100644 index 00000000..ee5f4c0d --- /dev/null +++ b/src/main/java/info/bukova/isspst/ui/users/PermissionForm.java @@ -0,0 +1,34 @@ +package info.bukova.isspst.ui.users; + +import info.bukova.isspst.Constants; +import info.bukova.isspst.Module; +import info.bukova.isspst.data.Role; +import info.bukova.isspst.services.users.PermissionService; +import info.bukova.isspst.ui.FormViewModel; + +import java.util.Arrays; +import java.util.List; + +import org.zkoss.bind.annotation.Init; +import org.zkoss.zk.ui.select.annotation.WireVariable; + +public class PermissionForm extends FormViewModel { + + @WireVariable + private PermissionService permissionService; + private RolePermissions rolePerms; + + @Init(superclass = true) + public void init() { + rolePerms = new RolePermissions(getDataBean(), permissionService.getAll()); + } + + public List getModules() { + return Arrays.asList(Constants.MODULES); + } + + public RolePermissions getRolePerms() { + return rolePerms; + } + +} diff --git a/src/main/java/info/bukova/isspst/ui/users/PermissionsList.java b/src/main/java/info/bukova/isspst/ui/users/PermissionsList.java new file mode 100644 index 00000000..fe4a8509 --- /dev/null +++ b/src/main/java/info/bukova/isspst/ui/users/PermissionsList.java @@ -0,0 +1,31 @@ +package info.bukova.isspst.ui.users; + +import java.util.Arrays; +import java.util.List; + +import org.zkoss.bind.annotation.Init; +import org.zkoss.zk.ui.select.annotation.WireVariable; + +import info.bukova.isspst.Constants; +import info.bukova.isspst.Module; +import info.bukova.isspst.data.Role; +import info.bukova.isspst.services.users.RoleService; +import info.bukova.isspst.ui.ListViewModel; + +public class PermissionsList extends ListViewModel { + + @WireVariable + private RoleService roleService; + + @Init + public void init() { + service = roleService; + dataClass = Role.class; + formZul = "permForm.zul"; + } + + public List getModules() { + return Arrays.asList(Constants.MODULES); + } + +} diff --git a/src/main/java/info/bukova/isspst/ui/users/RoleCheck.java b/src/main/java/info/bukova/isspst/ui/users/RoleCheck.java index a564be95..66a4b76e 100644 --- a/src/main/java/info/bukova/isspst/ui/users/RoleCheck.java +++ b/src/main/java/info/bukova/isspst/ui/users/RoleCheck.java @@ -36,7 +36,7 @@ public class RoleCheck { if (checked && !user.getAuthorities().contains(role)) { user.addAuthority(role); } else { - user.getAuthorities().remove(role); + user.removeAuthority(role); } } diff --git a/src/main/java/info/bukova/isspst/ui/users/RolePermissions.java b/src/main/java/info/bukova/isspst/ui/users/RolePermissions.java new file mode 100644 index 00000000..bbe1e52f --- /dev/null +++ b/src/main/java/info/bukova/isspst/ui/users/RolePermissions.java @@ -0,0 +1,24 @@ +package info.bukova.isspst.ui.users; + +import info.bukova.isspst.data.Permission; +import info.bukova.isspst.data.Role; + +import java.util.ArrayList; +import java.util.List; + +public class RolePermissions { + + private List permissionChecks; + + public RolePermissions(Role role, List permissions) { + permissionChecks = new ArrayList(); + for (Permission p : permissions) { + permissionChecks.add(new PermissionCheck(role, p)); + } + } + + public List getPermissionChecks() { + return permissionChecks; + } + +} diff --git a/src/main/java/info/bukova/isspst/ui/users/UserForm.java b/src/main/java/info/bukova/isspst/ui/users/UserForm.java index 2ebdb55c..3d6d730c 100644 --- a/src/main/java/info/bukova/isspst/ui/users/UserForm.java +++ b/src/main/java/info/bukova/isspst/ui/users/UserForm.java @@ -82,6 +82,14 @@ public class UserForm extends FormViewModel { } } + @Override + protected void doAdd() { + if (!password.isEmpty()) { + userService.setPassword(getDataBean(), password); + userService.add(getDataBean()); + } + } + @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/UsersList.java b/src/main/java/info/bukova/isspst/ui/users/UsersList.java index 047f22ff..75e8175b 100644 --- a/src/main/java/info/bukova/isspst/ui/users/UsersList.java +++ b/src/main/java/info/bukova/isspst/ui/users/UsersList.java @@ -1,8 +1,18 @@ package info.bukova.isspst.ui.users; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.zkoss.bind.annotation.GlobalCommand; import org.zkoss.bind.annotation.Init; +import org.zkoss.bind.annotation.NotifyChange; import org.zkoss.zk.ui.select.annotation.WireVariable; +import info.bukova.isspst.Constants; +import info.bukova.isspst.Module; +import info.bukova.isspst.data.Permission; +import info.bukova.isspst.data.Role; import info.bukova.isspst.data.User; import info.bukova.isspst.filters.UserFilter; import info.bukova.isspst.services.users.UserService; @@ -20,5 +30,46 @@ public class UsersList extends ListViewModel { formZul = "userForm.zul"; dataFilter = new UserFilter(getFilterTemplate()); } + + public List getModules() { + return Arrays.asList(Constants.MODULES); + } + + @Override + @NotifyChange({"permissions", "dataBean"}) + public void setDataBean(User user) { + super.setDataBean(user); + } + + @Override + @GlobalCommand + @NotifyChange({"dataList", "dataBean", "permissions"}) + public void refresh() { + super.refresh(); + } + + public List getPermissions() { + if (getDataBean() == null) { + return null; + } + List ret = new ArrayList(); + + for (Role r : getDataBean().getAuthorities()) { + for (Permission p : r.getPermissions()) { + boolean addPerm = true; + for (Permission chPerm : ret) { + if (chPerm.getAuthority().equals(p.getAuthority()) + && chPerm.getModule().equals(p.getModule())) { + addPerm = false; + } + } + if (addPerm) { + ret.add(p); + } + } + } + + return ret; + } } diff --git a/src/main/resources/hibernate.cfg.xml b/src/main/resources/hibernate.cfg.xml index 5aeb6836..a50d30e6 100644 --- a/src/main/resources/hibernate.cfg.xml +++ b/src/main/resources/hibernate.cfg.xml @@ -7,6 +7,7 @@ + diff --git a/src/main/webapp/WEB-INF/jdbc.properties b/src/main/webapp/WEB-INF/jdbc.properties index 306c5336..658408f0 100644 --- a/src/main/webapp/WEB-INF/jdbc.properties +++ b/src/main/webapp/WEB-INF/jdbc.properties @@ -1,5 +1,5 @@ jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.dialect=org.hibernate.dialect.MySQLDialect -jdbc.databaseurl=jdbc:mysql://127.0.0.1:3306/isspst?characterEncoding=UTF-8 +jdbc.databaseurl=jdbc:mysql://127.0.0.1:3306/isspst?characterEncoding=utf8 jdbc.username=root jdbc.password=xsacfgd \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/spring/root-context.xml b/src/main/webapp/WEB-INF/spring/root-context.xml index 751fa526..13f46192 100644 --- a/src/main/webapp/WEB-INF/spring/root-context.xml +++ b/src/main/webapp/WEB-INF/spring/root-context.xml @@ -14,36 +14,55 @@ - - - - - - classpath:hibernate.cfg.xml - - - - ${jdbc.dialect} - true - update - - + + + + + + classpath:hibernate.cfg.xml + + + + ${jdbc.dialect} + true + update + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + @@ -59,31 +78,35 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -123,5 +146,9 @@ - + + + + + diff --git a/src/main/webapp/admin/permissions/index.zul b/src/main/webapp/admin/permissions/index.zul new file mode 100644 index 00000000..842069db --- /dev/null +++ b/src/main/webapp/admin/permissions/index.zul @@ -0,0 +1,10 @@ + + + + + String gridZul = "permissions.zul"; + + + + + \ No newline at end of file diff --git a/src/main/webapp/admin/permissions/permForm.zul b/src/main/webapp/admin/permissions/permForm.zul new file mode 100644 index 00000000..c416a563 --- /dev/null +++ b/src/main/webapp/admin/permissions/permForm.zul @@ -0,0 +1,24 @@ + + + +