diff --git a/pom.xml b/pom.xml
index e5e408c5..04fe105a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -70,6 +70,21 @@
spring-security-config
${org.springframework-version}
+
+ org.springframework.security
+ spring-security-ldap
+ ${org.springframework-version}
+
+
+
+
+ org.slf4j
+ slf4j-log4j12
+ 1.5.6
+ jar
+ compile
+
+
log4j
log4j
@@ -204,6 +226,12 @@
org.zkoss.zk
zul
${zk.version}
+
+
+ org.slf4j
+ slf4j-jdk14
+
+
org.zkoss.zk
diff --git a/src/main/java/info/bukova/isspst/DbInitListener.java b/src/main/java/info/bukova/isspst/DbInitListener.java
index a72da4dd..75f6fd23 100644
--- a/src/main/java/info/bukova/isspst/DbInitListener.java
+++ b/src/main/java/info/bukova/isspst/DbInitListener.java
@@ -12,8 +12,6 @@ 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;
@@ -34,23 +32,16 @@ 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);
+ userService.grantAdmin();
checkRoles();
checkUsers();
checkPermissions();
-
- SecurityContextHolder.getContext().setAuthentication(null);
+ userService.removeAccess();
}
private void checkRoles() {
diff --git a/src/main/java/info/bukova/isspst/data/User.java b/src/main/java/info/bukova/isspst/data/User.java
index 680c668f..51adb0c0 100644
--- a/src/main/java/info/bukova/isspst/data/User.java
+++ b/src/main/java/info/bukova/isspst/data/User.java
@@ -49,12 +49,15 @@ public class User extends BaseSimpleData implements UserDetails, DataModel {
@Override
public List getAuthorities() {
List roles = new ArrayList();
+ int i = 10000000;
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());
+ role.setId(i);
+ ++i;
for (Role chRole : roles) {
if (chRole.getAuthority().equals(role.getAuthority())) {
diff --git a/src/main/java/info/bukova/isspst/security/AuthPopulator.java b/src/main/java/info/bukova/isspst/security/AuthPopulator.java
new file mode 100644
index 00000000..5701a609
--- /dev/null
+++ b/src/main/java/info/bukova/isspst/security/AuthPopulator.java
@@ -0,0 +1,76 @@
+package info.bukova.isspst.security;
+
+import info.bukova.isspst.Constants;
+import info.bukova.isspst.data.Role;
+import info.bukova.isspst.data.User;
+import info.bukova.isspst.services.users.RoleService;
+import info.bukova.isspst.services.users.UserService;
+
+import java.util.Collection;
+
+import javax.naming.NamingException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.ldap.core.DirContextOperations;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator;
+
+public class AuthPopulator implements LdapAuthoritiesPopulator {
+
+ private UserService userService;
+ private RoleService roleService;
+
+ public AuthPopulator(UserService userService, RoleService roleService) {
+ this.userService = userService;
+ this.roleService = roleService;
+ }
+
+ @Override
+ public Collection extends GrantedAuthority> getGrantedAuthorities(
+ DirContextOperations userData, String login) {
+
+ User user = null;
+ try {
+ user = (User) userService.loadUserByUsername(login);
+ } catch (UsernameNotFoundException e) {
+ Logger logger = LoggerFactory.getLogger(AuthPopulator.class);
+ logger.info("Importing user from LDAP");
+
+ user = new User();
+ user.setUsername(login);
+ Role role = roleService.getRoleByAuthority(Constants.ROLE_USER);
+ user.addAuthority(role);
+
+ if (userData.attributeExists("givenName")) {
+ try {
+ user.setFirstName(userData.getAttributes().get("givenName").get().toString());
+ } catch (NamingException e1) {
+ logger.info("LDAP object has no 'givenName' attribute");
+ }
+ }
+ if (userData.attributeExists("sn")) {
+ try {
+ user.setLastName(userData.getAttributes().get("sn").get().toString());
+ } catch (NamingException e1) {
+ logger.info("LDAP object has no 'sn' attribute");
+ }
+ }
+ if (userData.attributeExists("mail")) {
+ try {
+ user.setEmail(userData.getAttributes().get("mail").get().toString());
+ } catch (NamingException e1) {
+ logger.info("LDAP object has no 'mail' attribute");
+ }
+ }
+
+ userService.grantAdmin();
+ userService.add(user);
+ userService.removeAccess();
+ }
+
+ return user != null ? user.getAuthorities() : null;
+ }
+
+}
diff --git a/src/main/java/info/bukova/isspst/IsspstPermissionEvaluator.java b/src/main/java/info/bukova/isspst/security/IsspstPermissionEvaluator.java
similarity index 92%
rename from src/main/java/info/bukova/isspst/IsspstPermissionEvaluator.java
rename to src/main/java/info/bukova/isspst/security/IsspstPermissionEvaluator.java
index 5aed5aa6..574e30c1 100644
--- a/src/main/java/info/bukova/isspst/IsspstPermissionEvaluator.java
+++ b/src/main/java/info/bukova/isspst/security/IsspstPermissionEvaluator.java
@@ -1,5 +1,7 @@
-package info.bukova.isspst;
+package info.bukova.isspst.security;
+import info.bukova.isspst.Constants;
+import info.bukova.isspst.Module;
import info.bukova.isspst.data.Role;
import info.bukova.isspst.services.Service;
diff --git a/src/main/java/info/bukova/isspst/LoginFailHandler.java b/src/main/java/info/bukova/isspst/security/LoginFailHandler.java
similarity index 95%
rename from src/main/java/info/bukova/isspst/LoginFailHandler.java
rename to src/main/java/info/bukova/isspst/security/LoginFailHandler.java
index 8d2bb71e..10e2313d 100644
--- a/src/main/java/info/bukova/isspst/LoginFailHandler.java
+++ b/src/main/java/info/bukova/isspst/security/LoginFailHandler.java
@@ -1,4 +1,4 @@
-package info.bukova.isspst;
+package info.bukova.isspst.security;
import java.io.IOException;
diff --git a/src/main/java/info/bukova/isspst/services/AbstractOwnedService.java b/src/main/java/info/bukova/isspst/services/AbstractOwnedService.java
index 2236fc04..af1051d0 100644
--- a/src/main/java/info/bukova/isspst/services/AbstractOwnedService.java
+++ b/src/main/java/info/bukova/isspst/services/AbstractOwnedService.java
@@ -6,6 +6,7 @@ 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.security.core.userdetails.UserDetails;
import org.springframework.transaction.annotation.Transactional;
import info.bukova.isspst.data.OwnedDataModel;
@@ -36,7 +37,7 @@ public class AbstractOwnedService extends AbstractServ
@Transactional
protected User getLoggedInUser() {
try {
- String query = "from User where ID = " + ((User)SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId();
+ String query = "from User where USERNAME = '" + ((UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername() + "'";
Query q = dao.getQuery(query);
return (User) q.uniqueResult();
} catch (NonUniqueResultException e) {
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 429b472b..d97e3620 100644
--- a/src/main/java/info/bukova/isspst/services/users/UserService.java
+++ b/src/main/java/info/bukova/isspst/services/users/UserService.java
@@ -12,5 +12,7 @@ public interface UserService extends UserDetailsService, Service {
public void saveWithPwd(User user, String password);
public User getCurrent();
public String encodePassword(User user, String plain);
+ public void grantAdmin();
+ public void removeAccess();
}
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 ae4ee230..ae3f5683 100644
--- a/src/main/java/info/bukova/isspst/services/users/UserServiceImpl.java
+++ b/src/main/java/info/bukova/isspst/services/users/UserServiceImpl.java
@@ -1,6 +1,7 @@
package info.bukova.isspst.services.users;
import org.hibernate.Query;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
@@ -8,6 +9,7 @@ import org.springframework.security.core.userdetails.UserDetails;
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;
@@ -58,11 +60,16 @@ public class UserServiceImpl extends AbstractService implements UserServic
}
@Override
+ @Transactional
public User getCurrent() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.getPrincipal() != null) {
- return (User)auth.getPrincipal();
+ try {
+ return (User)loadUserByUsername(((UserDetails)auth.getPrincipal()).getUsername());
+ } catch(UsernameNotFoundException e) {
+ return null;
+ }
}
return null;
@@ -73,5 +80,20 @@ public class UserServiceImpl extends AbstractService implements UserServic
return encoder.encodePassword(plain, user.getUsername());
}
+ @Override
+ public void grantAdmin() {
+ 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()));
+ }
+
+ @Override
+ public void removeAccess() {
+ SecurityContextHolder.getContext().setAuthentication(null);
+ }
+
}
diff --git a/src/main/java/info/bukova/isspst/ui/FormViewModel.java b/src/main/java/info/bukova/isspst/ui/FormViewModel.java
index a5dab5a5..f0dc3b4e 100644
--- a/src/main/java/info/bukova/isspst/ui/FormViewModel.java
+++ b/src/main/java/info/bukova/isspst/ui/FormViewModel.java
@@ -21,11 +21,15 @@ public class FormViewModel {
private Map errMessages;
private Service service;
private boolean newRec;
+ private ServiceConstraint constraint;
@Init
public void init(@ExecutionArgParam("selected") T selected, @ExecutionArgParam("service") Service service) {
this.dataBean = selected;
this.service = service;
+ constraint = new ServiceConstraint();
+ constraint.setDataBean(selected);
+ constraint.setService(service);
if (selected.getId() == 0 && selected.getCreated() == null) {
newRec = true;
} else {
@@ -33,6 +37,10 @@ public class FormViewModel {
}
}
+ public ServiceConstraint getConstriant() {
+ return constraint;
+ }
+
public T getDataBean() {
return dataBean;
}
diff --git a/src/main/java/info/bukova/isspst/ui/ListViewModel.java b/src/main/java/info/bukova/isspst/ui/ListViewModel.java
index 0537287a..ca42ea03 100644
--- a/src/main/java/info/bukova/isspst/ui/ListViewModel.java
+++ b/src/main/java/info/bukova/isspst/ui/ListViewModel.java
@@ -131,7 +131,7 @@ public class ListViewModel {
try {
newRecMode();
editBean = service.create();
- if (dataBean == null) {
+ if (editBean == null) {
editBean = dataClass.newInstance();
}
showForm();
diff --git a/src/main/java/info/bukova/isspst/ui/ServiceConstraint.java b/src/main/java/info/bukova/isspst/ui/ServiceConstraint.java
new file mode 100644
index 00000000..dd0e4283
--- /dev/null
+++ b/src/main/java/info/bukova/isspst/ui/ServiceConstraint.java
@@ -0,0 +1,54 @@
+package info.bukova.isspst.ui;
+
+import info.bukova.isspst.data.DataModel;
+import info.bukova.isspst.services.Service;
+import info.bukova.isspst.services.ValidationException;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Map;
+
+import org.apache.commons.beanutils.BeanUtils;
+import org.zkoss.zk.ui.Component;
+import org.zkoss.zk.ui.WrongValueException;
+import org.zkoss.zul.Constraint;
+
+public class ServiceConstraint implements Constraint {
+
+ private Service service;
+ private T dataBean;
+
+ @Override
+ public void validate(Component component, Object value)
+ throws WrongValueException {
+
+ String id = component.getId();
+ if (id == null || id.isEmpty()) {
+ return;
+ }
+
+ try {
+ BeanUtils.setProperty(dataBean, id, value);
+ service.validate(dataBean);
+ } catch (ValidationException e) {
+ Map errMessages = e.getMessages();
+
+ if (errMessages != null && errMessages.get(id) != null && !errMessages.get(id).isEmpty()) {
+ WrongValueException ex = new WrongValueException(component, errMessages.get(id));
+ throw ex;
+ }
+ } catch (IllegalAccessException e) {
+
+ } catch (InvocationTargetException e) {
+
+ }
+ }
+
+ public void setService(Service service) {
+ this.service = service;
+ }
+
+ public void setDataBean(T dataBean) {
+ this.dataBean = dataBean;
+ }
+
+}
diff --git a/src/main/resources/users.ldif b/src/main/resources/users.ldif
new file mode 100644
index 00000000..e6bc13b2
--- /dev/null
+++ b/src/main/resources/users.ldif
@@ -0,0 +1,71 @@
+dn: ou=groups,dc=bukova,dc=info
+objectclass: top
+objectclass: organizationalUnit
+ou: groups
+
+dn: ou=people,dc=bukova,dc=info
+objectclass: top
+objectclass: organizationalUnit
+ou: people
+
+dn: uid=kadel,ou=people,dc=bukova,dc=info
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+cn: Kadel Pohlavnik
+sn: Pohlavnik
+givenName: Kadel
+uid: kadel
+userPassword: pokus
+
+dn: uid=admin,ou=people,dc=bukova,dc=info
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+cn: Administrator
+sn: admin
+uid: admin
+userPassword: xsacfgd
+
+dn: uid=dianne,ou=people,dc=bukova,dc=info
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+cn: Dianne Emu
+sn: Emu
+uid: dianne
+userPassword: emu
+
+dn: uid=scott,ou=people,dc=bukova,dc=info
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+cn: Scott
+sn: Wombat
+uid: scott
+userPassword: wombat
+
+dn: cn=user,ou=groups,dc=bukova,dc=info
+objectclass: top
+objectclass: groupOfNames
+cn: user
+member: uid=rod,ou=people,dc=bukova,dc=info
+member: uid=dianne,ou=people,dc=bukova,dc=info
+member: uid=scott,ou=people,dc=bukova,dc=info
+
+dn: cn=teller,ou=groups,dc=bukova,dc=info
+objectclass: top
+objectclass: groupOfNames
+cn: teller
+member: uid=rod,ou=people,dc=bukova,dc=info
+member: dianne=rod,ou=people,dc=bukova,dc=info
+
+dn: cn=supervisor,ou=groups,dc=bukova,dc=info
+objectclass: top
+objectclass: groupOfNames
+cn: supervisor
+member: uid=rod,ou=people,dc=bukova,dc=info
diff --git a/src/main/webapp/WEB-INF/ldap.properties b/src/main/webapp/WEB-INF/ldap.properties
new file mode 100644
index 00000000..4060b43d
--- /dev/null
+++ b/src/main/webapp/WEB-INF/ldap.properties
@@ -0,0 +1,2 @@
+ldap.server=ldap://localhost:3089
+ldap.userDNPattern=uid=\{0\},OU=people,DC=bukova,DC=info
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/spring/database-auth.xml b/src/main/webapp/WEB-INF/spring/database-auth.xml
new file mode 100644
index 00000000..275a3c1d
--- /dev/null
+++ b/src/main/webapp/WEB-INF/spring/database-auth.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/webapp/WEB-INF/spring/ldap-auth.xml b/src/main/webapp/WEB-INF/spring/ldap-auth.xml
new file mode 100644
index 00000000..5670d09f
--- /dev/null
+++ b/src/main/webapp/WEB-INF/spring/ldap-auth.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${ldap.userDNPattern}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/webapp/WEB-INF/spring/root-context.xml b/src/main/webapp/WEB-INF/spring/root-context.xml
index 13f46192..fe183541 100644
--- a/src/main/webapp/WEB-INF/spring/root-context.xml
+++ b/src/main/webapp/WEB-INF/spring/root-context.xml
@@ -11,7 +11,14 @@
-
+
+
+
+ /WEB-INF/jdbc.properties
+ /WEB-INF/ldap.properties
+
+
+
-
+
@@ -65,13 +72,8 @@
-
-
-
-
-
-
-
+
+
@@ -81,7 +83,7 @@
-
+
diff --git a/src/main/webapp/admin/addressbook/address.zul b/src/main/webapp/admin/addressbook/address.zul
index 2d54e43c..9fe94a87 100644
--- a/src/main/webapp/admin/addressbook/address.zul
+++ b/src/main/webapp/admin/addressbook/address.zul
@@ -12,12 +12,10 @@
-
-
-
+
@@ -33,14 +31,13 @@
-
+
-
+
-
-
+
@@ -49,12 +46,10 @@
-
-
+
-
-
+
diff --git a/src/main/webapp/app/passwd.zul b/src/main/webapp/app/passwd.zul
index fbed95d7..d79f4b0a 100644
--- a/src/main/webapp/app/passwd.zul
+++ b/src/main/webapp/app/passwd.zul
@@ -2,9 +2,10 @@
-
+
diff --git a/src/main/webapp/buildings/buildingForm.zul b/src/main/webapp/buildings/buildingForm.zul
index 6360ca1d..4d96b660 100644
--- a/src/main/webapp/buildings/buildingForm.zul
+++ b/src/main/webapp/buildings/buildingForm.zul
@@ -8,16 +8,12 @@
-
${labels.BuildingsFormCode} : |
-
- |
-
-
+
|
diff --git a/src/main/webapp/img/passwd.png b/src/main/webapp/img/passwd.png
new file mode 100644
index 00000000..f9ca66aa
Binary files /dev/null and b/src/main/webapp/img/passwd.png differ