Plenty of bugs fixed
authorelgekko <vasary@elgekko.net>
Sun, 2 Jul 2023 23:14:01 +0000 (01:14 +0200)
committerelgekko <vasary@elgekko.net>
Sun, 2 Jul 2023 23:14:01 +0000 (01:14 +0200)
45 files changed:
KB.md
lis-app/pom.xml
lis-app/src/main/resources/application.yaml
lis-app/src/test/java/hu/user/lis/AssociatesDataModelIT.java [new file with mode: 0644]
lis-app/src/test/java/hu/user/lis/RepositoryIT.java [moved from lis-app/src/test/java/hu/user/lis/ITRepository.java with 98% similarity]
lis-db/migrations/scripts/003_add_remotely_authenticated_to_associate.sql [new file with mode: 0644]
lis-db/pom.xml
lis-db/src/main/java/hu/user/lis/db/Associate.java
lis-db/src/main/java/hu/user/lis/db/repository/AssociateRepository.java
lis-db/src/main/java/hu/user/lis/db/repository/AssociateRepositorySearchImpl.java
lis-db/src/main/java/hu/user/lis/db/repository/PartnerRepositorySearchImpl.java
lis-db/src/main/java/hu/user/lis/db/repository/ProjectAssociateRepository.java
lis-db/src/main/java/hu/user/lis/db/repository/ProjectRepositorySearch.java
lis-db/src/main/java/hu/user/lis/db/repository/ProjectRepositorySearchImpl.java
lis-db/src/main/java/hu/user/lis/db/repository/ServiceRecordRepositorySearchImpl.java
lis-services/pom.xml
lis-ui/pom.xml
lis-ui/src/main/java/hu/user/lis/ui/auth/CurrentProfile.java [new file with mode: 0644]
lis-ui/src/main/java/hu/user/lis/ui/auth/Guard.java [new file with mode: 0644]
lis-ui/src/main/java/hu/user/lis/ui/auth/LdapUserDetailsContextMapper.java [new file with mode: 0644]
lis-ui/src/main/java/hu/user/lis/ui/auth/LocalAuthProvider.java [new file with mode: 0644]
lis-ui/src/main/java/hu/user/lis/ui/config/WebSecurityConfig.java
lis-ui/src/main/java/hu/user/lis/ui/data/AssociateSelectorDataModel.java
lis-ui/src/main/java/hu/user/lis/ui/data/AssociatesDataModel.java
lis-ui/src/main/java/hu/user/lis/ui/data/CachedDataModel.java
lis-ui/src/main/java/hu/user/lis/ui/data/PartnerSelectorDataModel.java
lis-ui/src/main/java/hu/user/lis/ui/data/PartnersDataModel.java
lis-ui/src/main/java/hu/user/lis/ui/data/ProjectAssociatesDataModel.java
lis-ui/src/main/java/hu/user/lis/ui/data/ProjectSelectorDataModel.java
lis-ui/src/main/java/hu/user/lis/ui/data/ProjectStatusDataModel.java
lis-ui/src/main/java/hu/user/lis/ui/data/ProjectsDataModel.java
lis-ui/src/main/java/hu/user/lis/ui/data/ServiceRecordsDataModel.java
lis-ui/src/main/java/hu/user/lis/ui/data/SuppliersDataModel.java
lis-ui/src/main/java/hu/user/lis/ui/data/SuppliersSimpleDataModel.java
lis-ui/src/main/java/hu/user/lis/ui/editor/AssociateEditorModel.java
lis-ui/src/main/java/hu/user/lis/ui/view/IndexViewModel.java
lis-ui/src/main/java/hu/user/lis/ui/view/PartnersViewModel.java
lis-ui/src/main/java/hu/user/lis/ui/view/ProjectsViewModel.java
lis-ui/src/main/java/hu/user/lis/ui/view/ServiceRecordsViewModel.java
lis-ui/src/main/java/hu/user/lis/ui/view/SettingsViewModel.java
lis-ui/src/main/resources/metainfo/zk/zk.xml
lis-ui/src/main/resources/web/associate-editor.zul
lis-ui/src/main/resources/web/index.zul
lis-ui/src/main/resources/web/login.zul
lis-ui/src/main/resources/web/settings.zul

diff --git a/KB.md b/KB.md
index 7668341ce3d8976ab16783edc4a5cb0142ecbaa2..4aa1b8fdadd866a48ff3742dc5f4d64d0e780b7c 100644 (file)
--- a/KB.md
+++ b/KB.md
@@ -58,6 +58,8 @@ https://www.zkoss.org/documentation#References
 https://www.zkoss.org/wiki/ZK_Spring_Essentials/Working_with_ZK_Spring/Working_with_ZK_Spring_Security/Secure_a_ZK_Application_with_Spring_Security
 https://www.zkoss.org/wiki/ZK_Spring_Essentials/Working_with_ZK_Spring/Working_with_ZK_Spring_Security/Add_Security_in_the_View_Layer
 (To enable remove @SpringBootApplication with exludes and @ComponentScan)
+https://www.baeldung.com/get-user-in-spring-security
+https://www.baeldung.com/spring-security-authentication-provider
 
 ##### ZK Style
 
index 7935481df6433d0fec236558a219d5cd0dee3387..e64e7d23ac9663280d9c0b77c18e1bb2dbf30cad 100644 (file)
@@ -2,9 +2,8 @@
 <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
-    <groupId>hu.user</groupId>
     <artifactId>lis-app</artifactId>
-    <version>0.1.1-SNAPSHOT</version>
+    <version>0.1.2-SNAPSHOT</version>
     <parent>
         <groupId>hu.user</groupId>
         <artifactId>lis</artifactId>
index 4f0ccb0a007ea11e976197a4ad9b6431da402e7f..3f2d8e42464d0269190e5976d4bfb41242a1769a 100644 (file)
@@ -9,7 +9,7 @@ spring:
   jpa:
     hibernate:
       use-new-id-generator-mappings: false
-    show-sql: false
+    show-sql: true
     properties:
       hibernate:
         format_sql: true
@@ -24,7 +24,8 @@ spring:
 logging:
   level:
     org.hibernate.engine.jdbc.spi.SqlExceptionHelper: ERROR
-    org.springframework.security.web: DEBUG
+    org.springframework.security: DEBUG
+    org.springframework.security.web: INFO
 #  pattern:
 #    console: "%d %-5level %logger : %msg%n"
 #    file: "%d %-5level [%thread] %logger : %msg%n"
\ No newline at end of file
diff --git a/lis-app/src/test/java/hu/user/lis/AssociatesDataModelIT.java b/lis-app/src/test/java/hu/user/lis/AssociatesDataModelIT.java
new file mode 100644 (file)
index 0000000..7617378
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) $today.year-$today.month-24.
+ * By elGekko
+ */
+
+package hu.user.lis;
+
+import hu.user.lis.ui.data.AssociatesDataModel;
+import lombok.extern.log4j.Log4j2;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.test.context.junit4.SpringRunner;
+
+
+@Log4j2
+@RunWith(SpringRunner.class)
+@ComponentScan("hu.user.lis")
+@SpringBootTest
+//@TestPropertySource("classpath:application.yaml")
+//@AutoConfigureMockMvc
+public class AssociatesDataModelIT {
+    @Autowired
+    private AssociatesDataModel associatesDataModel;
+
+    @Test
+    public void testRepositoryCapabilities() {
+        associatesDataModel.search("lé");
+        log.info("Found {} items", associatesDataModel.getResultSetCount());
+        associatesDataModel.getResultSet(0, 10, null)
+                .forEach(c -> log.info("{}", c.getName()));
+    }
+
+}
similarity index 98%
rename from lis-app/src/test/java/hu/user/lis/ITRepository.java
rename to lis-app/src/test/java/hu/user/lis/RepositoryIT.java
index b45fb5b41415dda58e70250111a6a16edd4147b9..af2701c65842cf272de1e9834c888be87439b714 100644 (file)
@@ -24,7 +24,7 @@ import java.util.List;
 @SpringBootTest
 //@TestPropertySource("classpath:application.yaml")
 //@AutoConfigureMockMvc
-public class ITRepository {
+public class RepositoryIT {
     @Autowired
     private ServiceRecordRepository serviceRecordRepository;
 
diff --git a/lis-db/migrations/scripts/003_add_remotely_authenticated_to_associate.sql b/lis-db/migrations/scripts/003_add_remotely_authenticated_to_associate.sql
new file mode 100644 (file)
index 0000000..bd50d37
--- /dev/null
@@ -0,0 +1,12 @@
+-- // add_remotely_authenticated_to_associate
+-- Migration SQL that makes the change goes here.
+
+ALTER TABLE associate
+    ADD COLUMN remotely_authenticated SMALLINT NOT NULL DEFAULT 0;
+
+-- //@UNDO
+-- SQL to undo the change goes here.
+
+ALTER TABLE associate
+    DROP COLUMN remotely_authenticated;
+
index 24a52daa74f084f5ba667654154868f1861f33c0..15486c6302ce7ef87842983a52128b76600f8578 100644 (file)
@@ -4,7 +4,6 @@
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
         xmlns="http://maven.apache.org/POM/4.0.0">
     <modelVersion>4.0.0</modelVersion>
-    <groupId>hu.user</groupId>
     <artifactId>lis-db</artifactId>
     <parent>
         <groupId>hu.user</groupId>
index d2cbcc6f0d6984ba29bd7011ea950d4034156af1..6561526b14bc8ee3a30849db64bdb17aec4dfdee 100644 (file)
@@ -22,4 +22,5 @@ public class Associate {
     String password;
     double monthlyCost;
     boolean active;
+    boolean remotelyAuthenticated;
 }
index 380e10b9dadfdadf0da32f17930f61303c5c925f..5716df0a1e479ba55469ba1d3a9f4cf538e12213 100644 (file)
@@ -4,5 +4,7 @@ import hu.user.lis.db.Associate;
 import org.springframework.data.jpa.repository.JpaRepository;
 
 public interface AssociateRepository extends JpaRepository<Associate, Long>, AssociateRepositorySearch {
+    Associate findByLoginAndPassword(String login, String password);
 
+    Associate findByLogin(String login);
 }
index 783055bfc918e0fcda843ce7b88e8d16ad37865c..1cafe7550f4e6935f1d3d8cac38e75db05d765d8 100644 (file)
@@ -34,26 +34,14 @@ public class AssociateRepositorySearchImpl implements AssociateRepositorySearch
         return predicates.toArray(new Predicate[]{});
     }
 
-//    Predicate[] getPredicates(CriteriaBuilder cb, Root<Associate> root, String partialName, boolean filterShowActive) {
-//        List<Predicate> predicates = new ArrayList<>();
-//        if (StringUtils.isNotBlank(partialName)) {
-//            predicates.add(cb.like(root.get("name"), "%" + partialName + "%"));
-//        }
-//        if (filterShowActive) {
-//            predicates.add(cb.isTrue(root.get("active")));
-//        } else {
-//            predicates.add(cb.isFalse(root.get("active")));
-//        }
-//        return predicates.toArray(new Predicate[]{});
-//    }
-
     @Override
     public List<Associate> search(String partialName, boolean filterShowActive, boolean filterShowInActive, Pageable pageable) {
         CriteriaBuilder cb = entityManager.getCriteriaBuilder();
         CriteriaQuery<Associate> cq = cb.createQuery(Associate.class);
         Root<Associate> root = cq.from(Associate.class);
-        TypedQuery<Associate> query = entityManager.createQuery(cq);
+
         cq.where(getPredicates(cb, root, partialName, filterShowActive, filterShowInActive));
+        TypedQuery<Associate> query = entityManager.createQuery(cq);
         query.setMaxResults(pageable.getPageSize());
         query.setFirstResult(pageable.getPageSize() * pageable.getPageNumber());
         return query.getResultList();
@@ -64,30 +52,10 @@ public class AssociateRepositorySearchImpl implements AssociateRepositorySearch
         CriteriaBuilder cb = entityManager.getCriteriaBuilder();
         CriteriaQuery<Long> cq = cb.createQuery(Long.class);
         Root<Associate> root = cq.from(Associate.class);
+
         cq.select(cb.count(root));
         cq.where(getPredicates(cb, root, partialName, filterShowActive, filterShowInActive));
         return entityManager.createQuery(cq).getSingleResult();
     }
 
-//    @Override
-//    public List<Associate> search(String partialName, boolean filterShowActive, Pageable pageable) {
-//        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
-//        CriteriaQuery<Associate> cq = cb.createQuery(Associate.class);
-//        Root<Associate> root = cq.from(Associate.class);
-//        TypedQuery<Associate> query = entityManager.createQuery(cq);
-//        cq.where(getPredicates(cb, root, partialName, filterShowActive));
-//        query.setMaxResults(pageable.getPageSize());
-//        query.setFirstResult(pageable.getPageSize() * pageable.getPageNumber());
-//        return query.getResultList();
-//    }
-//
-//    @Override
-//    public long count(String partialName, boolean filterShowActive) {
-//        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
-//        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
-//        Root<Associate> root = cq.from(Associate.class);
-//        cq.select(cb.count(root));
-//        cq.where(getPredicates(cb, root, partialName, filterShowActive));
-//        return entityManager.createQuery(cq).getSingleResult();
-//    }
 }
index adf75db720d77748557941b22369c5c93098a271..7266539a3c878582ad4764e9ee14c07e2c31e842 100644 (file)
@@ -63,6 +63,7 @@ public class PartnerRepositorySearchImpl implements PartnerRepositorySearch {
         CriteriaBuilder cb = entityManager.getCriteriaBuilder();
         CriteriaQuery<Partner> cq = cb.createQuery(Partner.class);
         Root<Partner> root = cq.from(Partner.class);
+
         cq.where(getPredicates(cb, root, partialName, partialVatNr, partialAddress, filterShowActive, filterShowInActive));
         TypedQuery<Partner> query = entityManager.createQuery(cq);
         query.setMaxResults(pageable.getPageSize());
@@ -75,6 +76,7 @@ public class PartnerRepositorySearchImpl implements PartnerRepositorySearch {
         CriteriaBuilder cb = entityManager.getCriteriaBuilder();
         CriteriaQuery<Long> cq = cb.createQuery(Long.class);
         Root<Partner> root = cq.from(Partner.class);
+
         cq.select(cb.count(root));
         cq.where(getPredicates(cb, root, partialName, partialVatNr, partialAddress, filterShowActive, filterShowInActive));
         return entityManager.createQuery(cq).getSingleResult();
index ad74956605b8ebe05f685183dc3c1db50d158d10..721c76c9303278c7477f782c9cf2689554ae5556 100644 (file)
@@ -1,7 +1,13 @@
 package hu.user.lis.db.repository;
 
 import hu.user.lis.db.ProjectAssociate;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaRepository;
 
 public interface ProjectAssociateRepository extends JpaRepository<ProjectAssociate, Long> {
+    Page<ProjectAssociate> findAllByProjectId(Long projectId, Pageable pageable);
+
+    Long countByProjectId(Long projectId);
+
 }
index c6c5420aae265c1618952f1bab4df6954a6a0b5b..b39dfe213c1546a5c72271327be90b15299011e9 100644 (file)
@@ -6,8 +6,8 @@ import org.springframework.data.domain.Pageable;
 import java.util.List;
 
 public interface ProjectRepositorySearch {
-    List<Project> search(String partialName, boolean filterShowActive, boolean filterShowInActive, Pageable pageable);
+    List<Project> search(String partialSearch, boolean filterShowActive, boolean filterShowInActive, Pageable pageable);
 
-    long count(String partialName, boolean filterShowActive, boolean filterShowInActive);
+    long count(String partialSearch, boolean filterShowActive, boolean filterShowInActive);
 
 }
index 3cf53115efa77880f7e3471ca27dd610fd6e0f9c..6d7a4efb8b11befd2ad9749a9a5c69c542af1520 100644 (file)
@@ -20,13 +20,13 @@ public class ProjectRepositorySearchImpl implements ProjectRepositorySearch {
     @PersistenceContext
     EntityManager entityManager;
 
-    Predicate[] getPredicates(CriteriaBuilder cb, Root<Project> root, String partialName, boolean filterShowActive, boolean filterShowInActive) {
+    Predicate[] getPredicates(CriteriaBuilder cb, Root<Project> root, String partialSearch, boolean filterShowActive, boolean filterShowInActive) {
         List<Predicate> predicates = new ArrayList<>();
-        if (StringUtils.isNotBlank(partialName)) {
+        if (StringUtils.isNotBlank(partialSearch)) {
             List<Predicate> orPredicates = new ArrayList<>();
-            orPredicates.add(cb.like(cb.lower(root.get("name")), "%" + partialName.toLowerCase() + "%"));
-            orPredicates.add(cb.like(cb.lower(root.get("humanId")), "%" + partialName.toLowerCase() + "%"));
-            orPredicates.add(cb.like(cb.lower(root.join("partner").get("name")), "%" + partialName.toLowerCase() + "%"));
+            orPredicates.add(cb.like(cb.lower(root.get("name")), "%" + partialSearch.toLowerCase() + "%"));
+            orPredicates.add(cb.like(cb.lower(root.get("humanId")), "%" + partialSearch.toLowerCase() + "%"));
+            orPredicates.add(cb.like(cb.lower(root.join("partner").get("name")), "%" + partialSearch.toLowerCase() + "%"));
             predicates.add(cb.or(orPredicates.toArray(new Predicate[]{})));
         }
 
@@ -40,24 +40,26 @@ public class ProjectRepositorySearchImpl implements ProjectRepositorySearch {
     }
 
     @Override
-    public List<Project> search(String partialName, boolean filterShowActive, boolean filterShowInActive, Pageable pageable) {
+    public List<Project> search(String partialSearch, boolean filterShowActive, boolean filterShowInActive, Pageable pageable) {
         CriteriaBuilder cb = entityManager.getCriteriaBuilder();
         CriteriaQuery<Project> cq = cb.createQuery(Project.class);
         Root<Project> root = cq.from(Project.class);
+
+        cq.where(getPredicates(cb, root, partialSearch, filterShowActive, filterShowInActive));
         TypedQuery<Project> query = entityManager.createQuery(cq);
-        cq.where(getPredicates(cb, root, partialName, filterShowActive, filterShowInActive));
         query.setMaxResults(pageable.getPageSize());
         query.setFirstResult(pageable.getPageSize() * pageable.getPageNumber());
         return query.getResultList();
     }
 
     @Override
-    public long count(String partialName, boolean filterShowActive, boolean filterShowInActive) {
+    public long count(String partialSearch, boolean filterShowActive, boolean filterShowInActive) {
         CriteriaBuilder cb = entityManager.getCriteriaBuilder();
         CriteriaQuery<Long> cq = cb.createQuery(Long.class);
         Root<Project> root = cq.from(Project.class);
+
         cq.select(cb.count(root));
-        cq.where(getPredicates(cb, root, partialName, filterShowActive, filterShowInActive));
+        cq.where(getPredicates(cb, root, partialSearch, filterShowActive, filterShowInActive));
         return entityManager.createQuery(cq).getSingleResult();
     }
 }
index 4b5f7a05e50440bfd3d85708f1232aaed57a566a..8d89ebe9ddd2f52ef4130ae723105f16c0481ea9 100644 (file)
@@ -34,6 +34,7 @@ public class ServiceRecordRepositorySearchImpl implements ServiceRecordRepositor
         CriteriaBuilder cb = entityManager.getCriteriaBuilder();
         CriteriaQuery<ServiceRecord> cq = cb.createQuery(ServiceRecord.class);
         Root<ServiceRecord> root = cq.from(ServiceRecord.class);
+
         cq.where(getPredicates(cb, root, filterProjectId, filterAssociateId));
         TypedQuery<ServiceRecord> query = entityManager.createQuery(cq);
         query.setMaxResults(pageable.getPageSize());
@@ -46,6 +47,7 @@ public class ServiceRecordRepositorySearchImpl implements ServiceRecordRepositor
         CriteriaBuilder cb = entityManager.getCriteriaBuilder();
         CriteriaQuery<Long> cq = cb.createQuery(Long.class);
         Root<ServiceRecord> root = cq.from(ServiceRecord.class);
+
         cq.select(cb.count(root));
         cq.where(getPredicates(cb, root, filterProjectId, filterAssociateId));
         return entityManager.createQuery(cq).getSingleResult();
index a22a4f60f562eb6363641920a2a3100190013e9c..d7a39580f65ae2efb6a80018a23e4838d0e013f1 100644 (file)
@@ -2,7 +2,6 @@
 <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
-    <groupId>hu.user</groupId>
     <artifactId>lis-services</artifactId>
     <parent>
         <groupId>hu.user</groupId>
index 3d2a7e16b40860a5a5cf532afda7b5b83d919743..91ebb287a22efbfe16aa6338ec3b37579ba00dc5 100644 (file)
@@ -3,7 +3,6 @@
          xmlns="http://maven.apache.org/POM/4.0.0"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
-    <groupId>hu.user</groupId>
     <artifactId>lis-ui</artifactId>
     <parent>
         <groupId>hu.user</groupId>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-security</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-ldap</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.ldap</groupId>
+            <artifactId>spring-ldap-core</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.javassist</groupId>
             <artifactId>javassist</artifactId>
diff --git a/lis-ui/src/main/java/hu/user/lis/ui/auth/CurrentProfile.java b/lis-ui/src/main/java/hu/user/lis/ui/auth/CurrentProfile.java
new file mode 100644 (file)
index 0000000..a8700fe
--- /dev/null
@@ -0,0 +1,16 @@
+package hu.user.lis.ui.auth;
+
+import hu.user.lis.db.Associate;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.stereotype.Service;
+
+@Service
+@Getter
+@Setter
+public class CurrentProfile {
+
+    private Associate associate;
+
+    
+}
diff --git a/lis-ui/src/main/java/hu/user/lis/ui/auth/Guard.java b/lis-ui/src/main/java/hu/user/lis/ui/auth/Guard.java
new file mode 100644 (file)
index 0000000..4dbac67
--- /dev/null
@@ -0,0 +1,25 @@
+package hu.user.lis.ui.auth;
+
+import lombok.extern.log4j.Log4j2;
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.zkoss.zk.ui.Executions;
+import org.zkoss.zk.ui.Page;
+import org.zkoss.zk.ui.util.Initiator;
+
+import java.util.Map;
+
+@Log4j2
+public class Guard implements Initiator {
+    @Override
+    public void doInit(Page page, Map<String, Object> args) throws Exception {
+        //HttpServletRequest request = (HttpServletRequest) Executions.getCurrent().getNativeRequest();
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+
+        if (authentication == null || authentication instanceof AnonymousAuthenticationToken) {
+            Executions.sendRedirect("/login");
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/lis-ui/src/main/java/hu/user/lis/ui/auth/LdapUserDetailsContextMapper.java b/lis-ui/src/main/java/hu/user/lis/ui/auth/LdapUserDetailsContextMapper.java
new file mode 100644 (file)
index 0000000..2cb9dfe
--- /dev/null
@@ -0,0 +1,54 @@
+package hu.user.lis.ui.auth;
+
+import hu.user.lis.db.Associate;
+import hu.user.lis.db.repository.AssociateRepository;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.ldap.core.DirContextOperations;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.ldap.userdetails.LdapUserDetailsImpl;
+import org.springframework.security.ldap.userdetails.LdapUserDetailsMapper;
+import org.springframework.security.ldap.userdetails.UserDetailsContextMapper;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.Objects;
+
+@Service
+@Log4j2
+public class LdapUserDetailsContextMapper extends LdapUserDetailsMapper implements UserDetailsContextMapper {
+    @Autowired
+    AssociateRepository associateRepository;
+
+    @Autowired
+    CurrentProfile currentProfile;
+
+    @Override
+    public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
+        LdapUserDetailsImpl ldapUserDetailsImpl = (LdapUserDetailsImpl) super.mapUserFromContext(ctx, username, authorities);
+//        String dn = ldapDetails.getDn();
+//        int beginIndex = dn.indexOf("cn=") + 3;
+//        int endIndex = dn.indexOf(",");
+//        String username = dn.substring(beginIndex, endIndex);
+//        myUserDetails.setAccountNonExpired(ldapUserDetailsImpl.isAccountNonExpired());
+//        myUserDetails.setAccountNonLocked(ldapUserDetailsImpl.isAccountNonLocked());
+//        myUserDetails.setCredentialsNonExpired(ldapUserDetailsImpl.isCredentialsNonExpired());
+//        myUserDetails.setEnabled(ldapUserDetailsImpl.isEnabled());
+//        myUserDetails.setAuthorities(ldapUserDetailsImpl.getAuthorities());
+//        myUserDetails.setUsername();
+        Associate associate = associateRepository.findByLogin(ldapUserDetailsImpl.getUsername());
+        if (Objects.isNull(associate)) {
+            associate = Associate.builder()
+                    .login(ldapUserDetailsImpl.getUsername())
+                    .name(ctx.getObjectAttribute("displayname").toString())
+                    .active(true)
+                    .remotelyAuthenticated(true)
+                    .build();
+//            ctx.getObjectAttribute("mail")
+            associateRepository.save(associate);
+        }
+        currentProfile.setAssociate(associate);
+        return ldapUserDetailsImpl;
+    }
+}
\ No newline at end of file
diff --git a/lis-ui/src/main/java/hu/user/lis/ui/auth/LocalAuthProvider.java b/lis-ui/src/main/java/hu/user/lis/ui/auth/LocalAuthProvider.java
new file mode 100644 (file)
index 0000000..7aa5944
--- /dev/null
@@ -0,0 +1,48 @@
+package hu.user.lis.ui.auth;
+
+import hu.user.lis.db.Associate;
+import hu.user.lis.db.repository.AssociateRepository;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.stereotype.Component;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+@Component
+public class LocalAuthProvider implements AuthenticationProvider {
+    @Autowired
+    AssociateRepository associateRepository;
+
+    @Autowired
+    CurrentProfile currentProfile;
+
+    @Override
+    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
+        UsernamePasswordAuthenticationToken result;
+        String name = authentication.getName();
+        String password = authentication.getCredentials().toString();
+
+        Associate associate = null;
+        if (StringUtils.isNotBlank(password)) {
+            associate = associateRepository.findByLoginAndPassword(name, password);
+        }
+        if (Objects.nonNull(associate)) {
+            result = new UsernamePasswordAuthenticationToken(name, password, Arrays.asList());
+            currentProfile.setAssociate(associate);
+        } else {
+            throw new BadCredentialsException("Local authentication failed!");
+        }
+        return result;
+    }
+
+    @Override
+    public boolean supports(Class<?> authentication) {
+        return authentication.equals(UsernamePasswordAuthenticationToken.class);
+    }
+}
index 0dc146fca8d8692a119c5834079bf1c1d8457f07..bde12a7df1a64e0421a3b5c7b90897ef0892e8a0 100644 (file)
@@ -1,29 +1,32 @@
 package hu.user.lis.ui.config;
 
-import org.springframework.context.annotation.Bean;
+import hu.user.lis.ui.auth.LdapUserDetailsContextMapper;
+import hu.user.lis.ui.auth.LocalAuthProvider;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.http.HttpMethod;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.core.userdetails.User;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.provisioning.InMemoryUserDetailsManager;
 
 import static hu.user.lis.ui.view.IndexViewModel.NAVIGATION;
 
-/**
- * This is an example of minimal configuration for ZK + Spring Security, we open as less access as possible to run a ZK-based application.
- * Please understand the configuration and modify it upon your requirement.
- */
 @Configuration
 @EnableWebSecurity
 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
     public static final String ZUL_FILES = "/zkau/web/**/*.zul";
+
     public static final String[] ZK_RESOURCES = {"/zkau/web/**/js/**", "/zkau/web/**/zul/css/**", "/zkau/web/**/img/**"};
+
     // allow desktop cleanup after logout or when reloading login page
     public static final String REMOVE_DESKTOP_REGEX = "/zkau\\?dtid=.*&cmd_0=rmDesktop&.*";
+    @Autowired
+    LocalAuthProvider localAuthProvider;
+
+    @Autowired
+    LdapUserDetailsContextMapper ldapUserDetailsContextMapper;
 
     @Override
     protected void configure(HttpSecurity http) throws Exception {
@@ -35,7 +38,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
                 .regexMatchers(HttpMethod.GET, REMOVE_DESKTOP_REGEX).permitAll() // allow desktop cleanup
                 .requestMatchers(req -> "rmDesktop".equals(req.getParameter("cmd_0"))).permitAll() // allow desktop cleanup from ZATS
                 .mvcMatchers("/", "/login", "/logout").permitAll()
-                .mvcMatchers(navigation).hasRole("USER")
+                //mvcMatchers(navigation).hasRole("USER")
                 .anyRequest().authenticated()
                 .and()
                 .formLogin()
@@ -44,16 +47,20 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
                 .logout().logoutUrl("/logout").logoutSuccessUrl("/");
     }
 
-    @Bean
-    @Override
-    public UserDetailsService userDetailsService() {
-        UserDetails user =
-                User.withDefaultPasswordEncoder()
-                        .username("user")
-                        .password("password")
-                        .roles("USER")
-                        .build();
-
-        return new InMemoryUserDetailsManager(user);
+    @Autowired
+    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+        auth.ldapAuthentication()
+                .userDnPatterns("uid={0},ou=people")
+                .groupSearchBase("ou=groups")
+                .userDetailsContextMapper(ldapUserDetailsContextMapper)
+                .contextSource()
+//                .url("ldap://fds.in.useribm.hu:389/dc=user,dc=hu")
+                .url("ldaps://fds.useribm.hu:636/dc=user,dc=hu")
+//                .and()
+//                .passwordCompare()
+//                  .passwordEncoder(new BCryptPasswordEncoder())
+//                .passwordAttribute("userPassword")
+        ;
+        auth.authenticationProvider(localAuthProvider);
     }
 }
\ No newline at end of file
index 46ae165dc51025398d0708a8980f3f58b99e9e2f..608c43497f3aae3ee607c3689d2d6d7ee78b8f93 100644 (file)
@@ -23,15 +23,10 @@ public class AssociateSelectorDataModel extends CachedSpringDataModel<Associate>
     private String partialName;
 
     @Override
-    protected List<Associate> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+    public List<Associate> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
         Pageable pageable = createPageable(0, SEARCH_LIMIT, null);
         List<Associate> result = StringUtils.isBlank(partialName) ? associateRepository.findAll(pageable).toList() :
                 associateRepository.search(partialName, true, false, pageable);
-
-        log.info("Associate filter: {}", partialName);
-        result.forEach(a -> {
-            log.info("Associate: {}", a.getName());
-        });
         return result;
     }
 
@@ -40,8 +35,6 @@ public class AssociateSelectorDataModel extends CachedSpringDataModel<Associate>
         int result = StringUtils.isBlank(partialName) ?
                 (int) associateRepository.count() :
                 (int) associateRepository.count(partialName, true, false);
-        log.info("Associate filter: {}", partialName);
-        log.info("Associate count: {}", result);
         return result > SEARCH_LIMIT ? SEARCH_LIMIT : result;
     }
 
index aecb9c88cc8983cb69cd8814b903d889cf02d399..11c283da7600a264399a5089486f2f45493851e3 100644 (file)
@@ -27,7 +27,7 @@ public class AssociatesDataModel extends CachedSpringDataModel<Associate> {
     private boolean filterShowActive;
 
     @Override
-    protected List<Associate> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+    public List<Associate> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
         Pageable pageable = createPageable(page, pageSize, sortComparator);
         List<Associate> result = listAll ? associateRepository.findAll(pageable).toList() :
                 associateRepository.search(partialName, filterShowActive, filterShowInActive, pageable);
index 198aaf41850ba88ccf602d6144c806d4e11dd78f..2704ac1b59ec45bfb87b3a5e49cb0a00f020acab 100644 (file)
@@ -36,8 +36,12 @@ public abstract class CachedDataModel<T> extends ListModelList<T> {
         this.cacheEnd = 0;
 
         clearCache();
-        fireEvent(ListDataEvent.STRUCTURE_CHANGED, -1, -1);
-        BindUtils.postNotifyChange(null, null, this, "*");
+        try {
+            fireEvent(ListDataEvent.STRUCTURE_CHANGED, -1, -1);
+            BindUtils.postNotifyChange(null, null, this, "*");
+        } catch (Exception e) {
+            log.warn(e.getMessage());
+        }
     }
 
     public void clearCache() {
@@ -166,7 +170,7 @@ public abstract class CachedDataModel<T> extends ListModelList<T> {
         }
     }
 
-    abstract protected List<T> getResultSet(int page, int pageSize, FieldComparator sortComparator);
+    abstract public List<T> getResultSet(int page, int pageSize, FieldComparator sortComparator);
 
     abstract public int getResultSetCount();
 
index 4542b193282be33d03d7441079882c22e9a20570..689b750dcbeb40b401c15a8797ece9347aa4d152 100644 (file)
@@ -1,63 +1,49 @@
 package hu.user.lis.ui.data;
 
 import hu.user.lis.db.Partner;
-import hu.user.lis.services.data.PartnerService;
+import hu.user.lis.db.repository.PartnerRepository;
 import lombok.extern.log4j.Log4j2;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.config.ConfigurableBeanFactory;
 import org.springframework.context.annotation.Scope;
+import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Component;
-import org.zkoss.bind.BindUtils;
 import org.zkoss.zul.FieldComparator;
 
-import java.util.Comparator;
 import java.util.List;
-import java.util.stream.Collectors;
 
 @Component
 @Log4j2
 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
-public class PartnerSelectorDataModel extends CachedDataModel<Partner> {
+public class PartnerSelectorDataModel extends CachedSpringDataModel<Partner> {
     static private final int SEARCH_LIMIT = 10;
+
     @Autowired
-    PartnerService partnerService;
-    private String partialName;
+    PartnerRepository partnerRepository;
 
-    private boolean filter(Partner partner) {
-        if (StringUtils.isBlank(partialName)) {
-            return true;
-        } else {
-            if (partner.getName().toLowerCase().startsWith(partialName.toLowerCase())) {
-                return true;
-            }
-        }
-        return false;
-    }
+    private String partialName;
 
     @Override
-    protected List<Partner> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
-        List<Partner> result = partnerService.getAll().stream()
-                .sorted(Comparator.comparing(Partner::getName))
-                .filter(s -> filter(s))
-                .limit(SEARCH_LIMIT)
-                .collect(Collectors.toList());
+    public List<Partner> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+        Pageable pageable = createPageable(page, pageSize, sortComparator);
+        List<Partner> result = StringUtils.isBlank(partialName) ? partnerRepository.findAll() :
+                partnerRepository.search(partialName, partialName, partialName, true, false, pageable);
         return result;
     }
 
+
     @Override
     public int getResultSetCount() {
-        int result = (int) partnerService.getAll().stream()
-                .filter(s -> filter(s))
-                .limit(SEARCH_LIMIT)
-                .count();
-        return result;
+        int result = StringUtils.isBlank(partialName) ?
+                (int) partnerRepository.count() :
+                (int) partnerRepository.count(partialName, partialName, partialName, true, false);
+        return result > SEARCH_LIMIT ? SEARCH_LIMIT : result;
     }
 
     public void search(String partialName) {
         log.info("Searching partner using filter {}", partialName);
         this.partialName = partialName;
         super.reset();
-        BindUtils.postNotifyChange(null, null, this, "*");
     }
 }
index a76defeceadb84422912431eb490e5823088815f..23b3e2ca385097e81781be79a445f18fa90ddc15 100644 (file)
@@ -19,18 +19,25 @@ import java.util.List;
 public class PartnersDataModel extends CachedSpringDataModel<Partner> {
     @Autowired
     PartnerRepository partnerRepository;
+
     @Autowired
     PartnerService partnerService;
+
     private String partialName;
+
     private String partialAddress;
+
     private String partialVatNr;
+
     private boolean listAll;
+
     private boolean filterShowInActive;
+
     private boolean filterShowActive;
 
 
     @Override
-    protected List<Partner> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+    public List<Partner> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
         Pageable pageable = createPageable(page, pageSize, sortComparator);
         List<Partner> result = listAll ? partnerRepository.findAll() :
                 partnerRepository.search(partialName, partialVatNr, partialAddress, filterShowActive, filterShowInActive, pageable);
index b52a6a6b2f9f71abf7ce6d1708e33cdad05325e0..b9498e7a39de5ecd27794925e029f7126e4419da 100644 (file)
@@ -1,73 +1,49 @@
 package hu.user.lis.ui.data;
 
 import hu.user.lis.db.ProjectAssociate;
+import hu.user.lis.db.repository.ProjectAssociateRepository;
 import hu.user.lis.services.data.ProjectAssociateService;
-import lombok.Getter;
 import lombok.extern.log4j.Log4j2;
-import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.config.ConfigurableBeanFactory;
 import org.springframework.context.annotation.Scope;
+import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Component;
-import org.zkoss.bind.BindUtils;
 import org.zkoss.zul.FieldComparator;
 
 import java.util.List;
-import java.util.stream.Collectors;
 
 @Component
 @Log4j2
 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
-public class ProjectAssociatesDataModel extends CachedDataModel<ProjectAssociate> {
-    @Getter
+public class ProjectAssociatesDataModel extends CachedSpringDataModel<ProjectAssociate> {
+
+    @Autowired
+    ProjectAssociateRepository projectAssociateRepository;
+
     @Autowired
     ProjectAssociateService projectAssociateService;
-    private String projectId;
 
+    private Long projectId;
 
-    private boolean canExecuteSearch() {
-        boolean result = StringUtils.isNotBlank(projectId);
-        log.info("Can execute search: {}", result);
-        return result;
-    }
-
-    private boolean filter(ProjectAssociate projectAssociate) {
-        boolean result = true;
-        if (StringUtils.isNotBlank(projectId)) {
-            if (!projectAssociate.getProject().getId().equals(projectId)) {
-                result = false;
-            }
-        }
-        return result;
-    }
 
     @Override
-    protected List<ProjectAssociate> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
-        List<ProjectAssociate> result = null;
-        if (canExecuteSearch()) {
-            result = projectAssociateService.getAll().stream()
-                    .filter(s -> filter(s))
-                    .collect(Collectors.toList());
-        }
+    public List<ProjectAssociate> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+        Pageable pageable = createPageable(page, pageSize, sortComparator);
+        List<ProjectAssociate> result = projectAssociateRepository.findAllByProjectId(projectId, pageable).getContent();
         return result;
     }
 
     @Override
     public int getResultSetCount() {
-        int result = 0;
-        if (canExecuteSearch()) {
-            result = (int) projectAssociateService.getAll().stream()
-                    .filter(s -> filter(s))
-                    .count();
-        }
-        return result;
+        long result = projectAssociateRepository.countByProjectId(projectId);
+        return (int) result;
     }
 
-    public void search(String projectId) {
-        log.info("Searching project associate using filters: projectId LIKE {}", projectId);
+    public void search(Long projectId) {
+        log.info("Searching project associate using filter: projectId LIKE {}", projectId);
         this.projectId = projectId;
         super.reset();
-        BindUtils.postNotifyChange(null, null, this, "*");
     }
 
 }
index 1da8ceccf7248efc55c9764d17637afa235b0917..058b7141ebab1b35586313273f62c03a8dbad5ef 100644 (file)
@@ -23,7 +23,7 @@ public class ProjectSelectorDataModel extends CachedSpringDataModel<Project> {
     private String partialSearch;
 
     @Override
-    protected List<Project> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+    public List<Project> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
         Pageable pageable = createPageable(0, SEARCH_LIMIT, null);
         List<Project> result = StringUtils.isBlank(partialSearch) ? projectRepository.findAll(pageable).toList() :
                 projectRepository.search(partialSearch, true, false, pageable);
index fba594ff51541c8176592f777cd86e12cef74ab1..f1ce273d7ea19a08ba7b96776c38ab2ba9ccabd5 100644 (file)
@@ -24,7 +24,7 @@ public class ProjectStatusDataModel extends CachedSpringDataModel<ProjectStatus>
     private boolean activeOnly;
 
     @Override
-    protected List<ProjectStatus> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+    public List<ProjectStatus> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
         List<ProjectStatus> result;
         if (activeOnly) {
             result = projectStatusRepository.findByActiveIsTrue(Sort.by(Sort.Direction.ASC, "order"));
@@ -51,10 +51,12 @@ public class ProjectStatusDataModel extends CachedSpringDataModel<ProjectStatus>
     }
 
     public void moveUp(ProjectStatus entity) {
-        projectStatusService.getAll().stream().anyMatch(s -> {
+        projectStatusRepository.findAll(Sort.by(Sort.Direction.ASC, "order")).stream().anyMatch(s -> {
             if (s.getOrder() == entity.getOrder() + 1) {
                 s.setOrder(s.getOrder() - 1);
+                projectStatusRepository.save(s);
                 entity.setOrder(entity.getOrder() + 1);
+                projectStatusRepository.save(entity);
                 return true;
             }
             return false;
@@ -62,10 +64,12 @@ public class ProjectStatusDataModel extends CachedSpringDataModel<ProjectStatus>
     }
 
     public void moveDown(ProjectStatus entity) {
-        projectStatusService.getAll().stream().anyMatch(s -> {
+        projectStatusRepository.findAll(Sort.by(Sort.Direction.ASC, "order")).stream().anyMatch(s -> {
             if (s.getOrder() == entity.getOrder() - 1) {
                 s.setOrder(s.getOrder() + 1);
+                projectStatusRepository.save(s);
                 entity.setOrder(entity.getOrder() - 1);
+                projectStatusRepository.save(entity);
                 return true;
             }
             return false;
@@ -78,4 +82,8 @@ public class ProjectStatusDataModel extends CachedSpringDataModel<ProjectStatus>
         entity.setOrder((int) currentCount + 1);
         projectStatusRepository.save(entity);
     }
+
+    public void save(ProjectStatus entity) {
+        projectStatusRepository.save(entity);
+    }
 }
index f16eb13dee40971f920deccc484833a4b2de68d6..8f6a15bedf4ab2b7106d3145cac91d500679d3a1 100644 (file)
@@ -1,98 +1,56 @@
 package hu.user.lis.ui.data;
 
 import hu.user.lis.db.Project;
+import hu.user.lis.db.repository.ProjectRepository;
 import hu.user.lis.services.data.ProjectService;
-import lombok.Getter;
 import lombok.extern.log4j.Log4j2;
-import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.config.ConfigurableBeanFactory;
 import org.springframework.context.annotation.Scope;
+import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Component;
-import org.zkoss.bind.BindUtils;
 import org.zkoss.zul.FieldComparator;
 
-import java.util.Comparator;
 import java.util.List;
-import java.util.stream.Collectors;
 
 @Component
 @Log4j2
 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
-public class ProjectsDataModel extends CachedDataModel<Project> {
-    @Getter
+public class ProjectsDataModel extends CachedSpringDataModel<Project> {
+    @Autowired
+    ProjectRepository projectRepository;
+
     @Autowired
     ProjectService projectService;
+
     private String partialName;
-    private String partialHumanId;
-    private boolean listAll;
-    private boolean filterShowInActive;
-    private boolean filterShowActive;
 
+    private boolean listAll;
 
-    private boolean canExecuteSearch() {
-        boolean result = listAll || filterShowActive || filterShowInActive ||
-                StringUtils.isNotBlank(partialName) ||
-                StringUtils.isNotBlank(partialHumanId);
-        log.info("Can execute search: {}", result);
-        return result;
-    }
+    private boolean filterShowInActive;
 
-    private boolean filter(Project entity) {
-        if (listAll) {
-            return true;
-        }
-        boolean result = true;
-        if (StringUtils.isNotBlank(partialName)) {
-            if (!entity.getName().toLowerCase().startsWith(partialName.toLowerCase())) {
-                result = false;
-            }
-        }
-        if (StringUtils.isNotBlank(partialHumanId)) {
-            if (!entity.getHumanId().toLowerCase().startsWith(partialHumanId.toLowerCase())) {
-                result = false;
-            }
-        }
-        if (!filterShowActive && entity.isActive()) {
-            result = false;
-        }
-        if (!filterShowInActive && !entity.isActive()) {
-            result = false;
-        }
-        return result;
-    }
+    private boolean filterShowActive;
 
     @Override
-    protected List<Project> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
-        List<Project> result = null;
-        if (canExecuteSearch()) {
-            result = projectService.getAll().stream()
-                    .filter(s -> filter(s))
-                    .sorted(Comparator.comparing(Project::getName, String.CASE_INSENSITIVE_ORDER))
-                    .collect(Collectors.toList());
-        }
+    public List<Project> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+        Pageable pageable = createPageable(page, pageSize, sortComparator);
+        List<Project> result = listAll ? projectRepository.findAll() :
+                projectRepository.search(partialName, filterShowActive, filterShowInActive, pageable);
         return result;
     }
 
     @Override
     public int getResultSetCount() {
-        int result = 0;
-        if (canExecuteSearch()) {
-            result = (int) projectService.getAll().stream()
-                    .filter(s -> filter(s))
-                    .count();
-        }
-        return result;
+        long result = listAll ? projectRepository.count() :
+                projectRepository.count(partialName, filterShowActive, filterShowInActive);
+        return (int) result;
     }
 
-    public void search(String partialName, String partialHumanId) {
-        log.info("Searching partner using filters: name LIKE {}, VAT human ID LIKE {}",
-                partialName, partialHumanId);
+    public void search(String partialName) {
+        log.info("Searching partner using filters: name LIKE {}");
         listAll = false;
         this.partialName = partialName;
-        this.partialHumanId = partialHumanId;
         super.reset();
-        BindUtils.postNotifyChange(null, null, this, "*");
     }
 
 
@@ -103,13 +61,27 @@ public class ProjectsDataModel extends CachedDataModel<Project> {
         this.filterShowInActive = filterShowInActive;
         listAll = false;
         super.reset();
-        BindUtils.postNotifyChange(null, null, this, "*");
     }
 
     public void listAll() {
         log.info("List all projects");
         listAll = true;
         super.reset();
-        BindUtils.postNotifyChange(null, null, this, "*");
+    }
+
+    public Project createNew() {
+        return projectService.createNew();
+    }
+
+    public void addNew(Project entity) {
+        projectRepository.save(entity);
+    }
+
+    public Project copy(Project selectedEntity) {
+        return projectService.copy(selectedEntity);
+    }
+
+    public Project save(Project selectedEntity) {
+        return projectRepository.save(selectedEntity);
     }
 }
index 39e80a936221713672e91cf1a0bb5d425618d70b..62e8f863de73a541a12e01e031148b17d91b00c6 100644 (file)
@@ -40,7 +40,7 @@ public class ServiceRecordsDataModel extends CachedSpringDataModel<ServiceRecord
     }
 
     @Override
-    protected List<ServiceRecord> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+    public List<ServiceRecord> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
         Pageable pageable = createPageable(page, pageSize, sortComparator);
         List<ServiceRecord> result = listAll ? serviceRecordRepository.findAll(pageable).toList() :
                 serviceRecordRepository.search(filterProjectId, filterAssociateId, pageable);
index cd3f7eedf0f8058dc2ae8661cedf41f8d62a44ea..79c767221b3435dd3fdf64ecd5526d11e5cefc6a 100644 (file)
@@ -51,7 +51,7 @@ public class SuppliersDataModel extends CachedDataModel<Supplier> {
     }
 
     @Override
-    protected List<Supplier> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+    public List<Supplier> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
         List<Supplier> result = null;
         if (canExecuteSearch()) {
             result = supplierService.getAll().stream()
index 7b9b897bebebefb20b19bc8a5b188dd06a73ff73..5e6d6b9c4648b97f08df34b06157aa72648c4903 100644 (file)
@@ -36,7 +36,7 @@ public class SuppliersSimpleDataModel extends CachedDataModel<Supplier> {
     }
 
     @Override
-    protected List<Supplier> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+    public List<Supplier> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
         List<Supplier> result = supplierService.getAll().stream()
                 .sorted(Comparator.comparing(Supplier::getName))
                 .filter(s -> filter(s))
index 67f9417d89696129854ea38016710cca64d06d66..fd29d54aeca0f54923cc00fb28c70fe9c4343c02 100644 (file)
@@ -66,7 +66,7 @@ public class AssociateEditorModel extends AbstractValidator {
             }
             if (StringUtils.isBlank(newData.getName()) ||
                     StringUtils.isBlank(newData.getLogin()) ||
-                    StringUtils.isBlank(newData.getPassword()) ||
+                    (!newData.isRemotelyAuthenticated() && StringUtils.isBlank(newData.getPassword())) ||
                     newData.getMonthlyCost() < 1
             ) {
                 log.info("Document is not valid");
index f00bcad5d0a5fc2f255f5662ab1c971be3f63ec6..108075912afb271fec2d0b3e7fd7b9fccc79fc3e 100644 (file)
@@ -2,6 +2,7 @@ package hu.user.lis.ui.view;
 
 import com.google.common.collect.ImmutableMap;
 import hu.user.lis.ui.Constants;
+import hu.user.lis.ui.auth.CurrentProfile;
 import hu.user.lis.ui.event.EventBus;
 import hu.user.lis.ui.session.SessionSettings;
 import lombok.Getter;
@@ -48,7 +49,12 @@ public class IndexViewModel implements EventListener {
     SessionSettings sessionSettings;
     @WireVariable
     EventBus eventBus;
+
+    @WireVariable
+    CurrentProfile currentProfile;
+
     String searchPhrase;
+
     String page;
 
     @Init
@@ -60,6 +66,9 @@ public class IndexViewModel implements EventListener {
         //project editor
         route(path);
 
+//        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+//        if (authentication != null && !(authentication instanceof AnonymousAuthenticationToken)) {
+//        }
         log.info("Init {}", path);
     }
 
index b81f636d5ed922013f1f8f2e5c11682cd8712b4b..cff9f541f4c3a8ca6903b7ddaf508861eef4aa0a 100644 (file)
@@ -41,7 +41,7 @@ public class PartnersViewModel extends AsyncBaseModel {
     @Init
     public void init() {
         setFilterShowActive(true);
-        Clients.evalJavaScript("pushNav('/')");
+        Clients.evalJavaScript("pushNav('/partners')");
         log.info("Initialized");
     }
 
@@ -84,7 +84,7 @@ public class PartnersViewModel extends AsyncBaseModel {
         editorWindow.addEventListener("onClose", e -> {
             if (e.getData() != null) {
                 log.info("Partner popup result {}", e.getData());
-                partnersDataModel.add(newEntity);
+                partnersDataModel.addNew(newEntity);
                 partnersDataModel.clearSelection();
                 refresh();
                 partnersDataModel.addToSelection(newEntity);
index 97eff6070fbf0ee6dcb8a128741c2df066800b1a..2459dd60fd41c76b16e20f8aad0f00cdc7b6760d 100644 (file)
@@ -77,7 +77,7 @@ public class ProjectsViewModel extends AsyncBaseModel implements EventListener {
 
     @Command
     public void onAdd() {
-        Project newEntity = projectsDataModel.getProjectService().createNew();
+        Project newEntity = projectsDataModel.createNew();
 //        eventBus.showProjectEditor(ImmutableMap.of("formDocument", newEntity));
         eventBus.showProjectEditor(null);
     }
@@ -137,9 +137,9 @@ public class ProjectsViewModel extends AsyncBaseModel implements EventListener {
             Project formDocument = args.get("formDocument");
             if (args.containsKey("origDocument")) {
                 Project origDocument = args.get("origDocument");
-                projectsDataModel.getProjectService().replace(origDocument, formDocument);
+                projectsDataModel.save(formDocument);
             } else {
-                projectsDataModel.getProjectService().add(formDocument);
+                projectsDataModel.addNew(formDocument);
             }
             refresh();
             projectsDataModel.addToSelection(formDocument);
index f77889c76fdbc599fc5cd8359ab4df363b4ac8db..0b7e9273b7ece8308feb781748157a8bb7a558da 100644 (file)
@@ -119,7 +119,7 @@ public class ServiceRecordsViewModel implements EventListener {
         editorWindow.addEventListener("onClose", e -> {
             if (e.getData() != null) {
                 log.info("Partner popup result {}", e.getData());
-                serviceRecordsDataModel.add(newEntity);
+                serviceRecordsDataModel.addNew(newEntity);
                 serviceRecordsDataModel.clearSelection();
                 refresh();
                 serviceRecordsDataModel.addToSelection(newEntity);
index f29e80f3398ec33c22634dd03ba762e7f0671226..4bba82db24ecf36e4b8b9218841c03701103bb89 100644 (file)
@@ -1,12 +1,13 @@
 package hu.user.lis.ui.view;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
 import hu.user.lis.db.ProjectStatus;
 import hu.user.lis.ui.data.ProjectStatusDataModel;
 import lombok.Getter;
-import lombok.Setter;
 import lombok.extern.log4j.Log4j2;
+import org.zkoss.bind.BindContext;
 import org.zkoss.bind.annotation.Command;
+import org.zkoss.bind.annotation.ContextParam;
+import org.zkoss.bind.annotation.ContextType;
 import org.zkoss.bind.annotation.Init;
 import org.zkoss.zk.ui.select.annotation.VariableResolver;
 import org.zkoss.zk.ui.select.annotation.WireVariable;
@@ -20,7 +21,6 @@ public class SettingsViewModel extends AsyncBaseModel {
     @Getter
     ProjectStatusDataModel projectStatusDataModel;
     @Getter
-    @Setter
     private ProjectStatus selectedProjectStatus;
 
     @Init
@@ -54,10 +54,20 @@ public class SettingsViewModel extends AsyncBaseModel {
     }
 
     @Command
-    public void onAppend() throws JsonProcessingException {
+    public void onAppend() {
         projectStatusDataModel.append();
         projectStatusDataModel.listAll();
     }
 
+    @Command
+    public void onActiveChecked(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) {
+//        CheckEvent evt = (CheckEvent) ctx.getTriggerEvent();
+//        ProjectStatus entity = (ProjectStatus) evt.getData();
+//        projectStatusDataModel.save(entity);
+    }
 
+    public void setSelectedProjectStatus(ProjectStatus selectedProjectStatus) {
+        log.info("Sekected {}", selectedProjectStatus.getName());
+        this.selectedProjectStatus = selectedProjectStatus;
+    }
 }
index 632cf9540ce12691e28fcf80044d74d670e81839..861c2fa8eba31e5400327817d4ccf3f296567e56 100644 (file)
@@ -5,6 +5,10 @@
         <session-timeout>300</session-timeout>
         <timeout-uri>/timeout</timeout-uri>
     </session-config>
+    <!--    <error-page>-->
+    <!--        <exception-type>java.lang.Throwable</exception-type>-->
+    <!--        <location>/timeout</location>-->
+    <!--    </error-page>-->
     <!--    <system-config>-->
     <!--        <ui-factory-class>org.zkoss.zk.ui.http.SerializableUiFactory</ui-factory-class>-->
     <!--        <max-upload-size>10240</max-upload-size>-->
index aa484cd15c1acfe26d8b4636b074a0136d0b6e6a..c28b92fe0d3113ff32f03f06258af3bb3b104216 100644 (file)
@@ -22,6 +22,7 @@
                                 <label value="Jelszó"/>
                                 <hlayout>
                                     <textbox hflex="true" instant="true" type="password"
+                                             disabled="@load(vm.formDocument.remotelyAuthenticated)"
                                              value="@bind(vm.formDocument.password) @validator(vm)"
                                              forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
                                     <button iconSclass="z-icon-eye"/>
index 2acf7a44f8c26dc7e1c0398da2f12789b13541ea..9482f5b2e72fcdcc8d97b700aa86ebe6803ca034 100644 (file)
@@ -1,7 +1,11 @@
+<?init class="hu.user.lis.ui.auth.Guard"?>
 <?link rel="stylesheet" type="text/css" href="~./static/css/skeleton.css" ?>
 <?link rel="stylesheet" type="text/css" href="~./static/css/webclient.css" ?>
 <zk>
     <style>
+        <!--        .z-caption-content {-->
+        <!--        width: 100%;-->
+        <!--        }-->
         .z-window-header {
         font-size: 18px;
         font-weight: bolder;
     </script>
     <window vflex="true" viewModel="@id('vm') @init('hu.user.lis.ui.view.IndexViewModel')">
         <caption>
-            <hlayout valign="middle">
-                <image width="24px" height="24px" src="~./static/images/logo.png"/>
-                <label value="SLY-CRM"/>
-                <separator orient="vertical"/>
-                <label style="font-size: 0.8em" value="@load(vm.buildProperties.version)"/>
-            </hlayout>
+            <div style="display: block">
+                <div style="display: inline; float: left">
+                    <hlayout valign="middle">
+                        <image width="24px" height="24px" src="~./static/images/logo.png"/>
+                        <label value="SLY-CRM"/>
+                        <separator orient="vertical"/>
+                        <label style="font-size: 0.8em" value="@load(vm.buildProperties.version)"/>
+                    </hlayout>
+                </div>
+                <div style="display: inline; float: right">
+                    <hlayout valign="middle">
+                        <menubar autodrop="true" hflex="true">
+                            <menu iconSclass="z-icon-user" label="@load(vm.currentProfile.associate.name)">
+                                <menupopup>
+                                    <menuitem iconSclass="z-icon-user" label="Profil">
+                                        <attribute name="onClick"><![CDATA[
+                                            Messagebox.show("Coming soon!", "Information", Messagebox.OK, Messagebox.INFORMATION);
+                                        ]]></attribute>
+                                    </menuitem>
+                                    <menuseparator/>
+                                    <menuitem label="Kijelentkezés">
+                                        <attribute name="onClick"><![CDATA[
+                                            Executions.sendRedirect("/logout");
+                                        ]]></attribute>
+                                    </menuitem>
+                                </menupopup>
+                            </menu>
+                        </menubar>
+                        <!--                        <button iconSclass="z-icon-user"-->
+                        <!--                                label="@load(vm.currentProfile.associate.name)"/>-->
+                    </hlayout>
+                </div>
+
+            </div>
         </caption>
+
         <borderlayout>
             <north border="none" hflex="true">
-                <hlayout valign="middle">
-                    <menubar autodrop="true" hflex="true">
-                        <menuitem iconSclass="z-icon-group" label="Partnerek"
-                                  onClick="@command(vm.selectPage('~./partners.zul'))"/>
-                        <menuitem iconSclass="z-icon-tasks" label="Projektek"
-                                  onClick="@command(vm.selectPage('~./projects.zul'))"/>
-                        <menuitem iconSclass="z-icon-th" label="Munkalapok"
-                                  onClick="@command(vm.selectPage('~./service-records.zul'))"/>
-                        <menuseparator/>
-                        <menuitem iconSclass="z-icon-user" label="Munkatársak"
-                                  onClick="@command(vm.selectPage('~./associates.zul'))"/>
-                        <menuseparator/>
-                        <menuitem iconSclass="z-icon-cogs" label="Beállítások"
-                                  onClick="@command(vm.selectPage('~./settings.zul'))"/>
-                    </menubar>
-                    <hbox hflex="min" pack="right">
-                        <textbox value="@bind(vm.searchPhrase)" onOK="@command('search')" disabled="true"></textbox>
-                        <button iconSclass="z-icon-search"/>
-                    </hbox>
-                </hlayout>
+                <vlayout>
+                    <hlayout valign="middle">
+                        <menubar autodrop="true" hflex="true">
+                            <menuitem iconSclass="z-icon-group" label="Partnerek"
+                                      onClick="@command(vm.selectPage('~./partners.zul'))"/>
+                            <menuitem iconSclass="z-icon-tasks" label="Projektek"
+                                      onClick="@command(vm.selectPage('~./projects.zul'))"/>
+                            <menuitem iconSclass="z-icon-th" label="Munkalapok"
+                                      onClick="@command(vm.selectPage('~./service-records.zul'))"/>
+                            <menuseparator/>
+                            <menuitem iconSclass="z-icon-user" label="Munkatársak"
+                                      onClick="@command(vm.selectPage('~./associates.zul'))"/>
+                            <menuseparator/>
+                            <menuitem iconSclass="z-icon-cogs" label="Beállítások"
+                                      onClick="@command(vm.selectPage('~./settings.zul'))"/>
+                        </menubar>
+                        <hbox hflex="min" pack="right">
+                            <textbox value="@bind(vm.searchPhrase)" onOK="@command('search')" disabled="true"></textbox>
+                            <button iconSclass="z-icon-search"/>
+                        </hbox>
+                    </hlayout>
+                </vlayout>
             </north>
             <center border="none" hflex="true">
                 <include src="@load(vm.page)" hflex="true" vflex="true"/>
-
-                <!--                <tabbox id="mainContent" vflex="true" hflex="true" orient="top" selectedIndex="@bind(vm.selectedPage)">-->
-                <!--                    <tabs visible="true">-->
-                <!--                        <tab id="tab0" label="Partnerek"/>-->
-                <!--                        <tab id="tab1" label="Projektek"/>-->
-                <!--                        <tab id="tab2" label="Szerkesztő"/>-->
-                <!--                    </tabs>-->
-                <!--                    <tabpanels>-->
-                <!--                        <tabpanel id="partnersTab">-->
-                <!--                            <partners/>-->
-                <!--                        </tabpanel>-->
-                <!--                        <tabpanel id="projectsTab"-->
-                <!--                                  fulfill="self.linkedTab.onSelect, projectsMenuItem.onClick, onFulFillProjectsTab">-->
-                <!--                            <projects/>-->
-                <!--                        </tabpanel>-->
-                <!--                        <tabpanel id="editorTab">-->
-                <!--                            <include src="@load(vm.editor)" hflex="true" vflex="true"/>-->
-                <!--                        </tabpanel>-->
-                <!--                    </tabpanels>-->
-                <!--                </tabbox>-->
             </center>
         </borderlayout>
     </window>
index e7556c5c03fcf7f9f2c477f85cc2a0f9dac68f06..2173d92080d222d898ac134f08d178c5650738df 100644 (file)
@@ -1,33 +1,46 @@
-<!--<zk>-->
-<!--    <window title="login">-->
-<!--        <label value="AAAAAAAAA"/>-->
-
-<!--    </window>-->
-
-<!--</zk>-->
 <zk xmlns:n="native">
+    <n:style>
+        body, html {
+        width: 100%;
+        height: 100%;
+        margin: 0;
+        padding: 0;
+        display:table;
+        }
+        body {
+        display:table-cell;
+        vertical-align:middle;
+        }
+        form {
+        display:table;
+        margin:auto;
+        }
+    </n:style>
     <n:form action="/login" method="POST">
-        <grid width="450px">
+        <grid style="margin-top: 200px">
             <columns>
-                <column width="160px"/>
+                <column width="100px"/>
                 <column width="280px"/>
             </columns>
             <rows>
                 <row spans="2" align="center">
-                    <label value="LOGIN"/>
+                    <hlayout valign="middle">
+                        <!--                        <image width="24px" height="24px" src="~./static/images/logo.png"/>-->
+                        <label value="SLY-CRM bejelentkezés"/>
+                    </hlayout>
                 </row>
                 <row>
-                    <label value="User :"/>
+                    <label value="User"/>
                     <textbox name="username" value="user"/>
                 </row>
                 <row>
-                    <label value="Password :"/>
+                    <label value="Password"/>
                     <textbox type="password" name="password" value="password"/>
                 </row>
                 <row spans="2" align="right">
                     <hlayout>
-                        <button type="reset" label="Reset"/>
-                        <button type="submit" label="Login"/>
+                        <button type="reset" label="Mégsem"/>
+                        <button type="submit" label="Belépés"/>
                     </hlayout>
                 </row>
             </rows>
index 851acab9880f6097b1cd326d70dd9a4ff226eb9d..ba035a3a9b76d4b7fb7ba1f650f0ec464f8dc81f 100644 (file)
@@ -31,7 +31,7 @@
                                 <textbox inplace="true" instant="true" width="100%" value="@bind(each.name)"/>
                             </listcell>
                             <listcell>
-                                <checkbox checked="@bind(each.active)"/>
+                                <checkbox checked="@bind(each.active)" onCheck="@command('onActiveChecked')"/>
                             </listcell>
                         </listitem>
                     </template>