From 643a0eefa113277e8a3e9d3ee2f66123a0fc1086 Mon Sep 17 00:00:00 2001
From: RIHTARSIC Joze <joze.rihtarsic@ext.ec.europa.eu>
Date: Thu, 19 Sep 2024 07:46:00 +0200
Subject: [PATCH] [EDELIVERY-13793] Fix filter list to return only domains and
 resourceDef for which user has rights.

---
 .../DBDomainToDomainPublicROConverter.java    | 57 +++++++++++++++++++
 .../ec/edelivery/smp/data/dao/DomainDao.java  | 50 +++++++++++-----
 .../ec/edelivery/smp/data/dao/QueryNames.java |  4 ++
 .../smp/data/dao/ResourceDefDao.java          | 36 +++++++++++-
 .../ec/edelivery/smp/data/model/DBDomain.java | 24 +++++++-
 .../smp/data/model/ext/DBResourceDef.java     | 24 ++++++++
 .../edelivery/smp/data/ui/DomainPublicRO.java |  2 +-
 .../smp/services/ui/UIDomainEditService.java  | 38 ++++++++++++-
 .../services/ui/UIResourceSearchService.java  | 42 +++++++-------
 .../edelivery/smp/data/dao/TestUtilsDao.java  |  2 +
 .../smp/ui/external/DomainController.java     | 16 ++----
 .../smp/ui/external/DomainResourceIT.java     |  4 +-
 12 files changed, 245 insertions(+), 54 deletions(-)
 create mode 100644 smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/DBDomainToDomainPublicROConverter.java

diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/DBDomainToDomainPublicROConverter.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/DBDomainToDomainPublicROConverter.java
new file mode 100644
index 000000000..39300e666
--- /dev/null
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/DBDomainToDomainPublicROConverter.java
@@ -0,0 +1,57 @@
+/*-
+ * #START_LICENSE#
+ * smp-server-library
+ * %%
+ * Copyright (C) 2017 - 2024 European Commission | eDelivery | DomiSMP
+ * %%
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent
+ * versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * [PROJECT_HOME]\license\eupl-1.2\license.txt or https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence is
+ * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ * #END_LICENSE#
+ */
+package eu.europa.ec.edelivery.smp.conversion;
+
+import eu.europa.ec.edelivery.smp.data.model.DBDomain;
+import eu.europa.ec.edelivery.smp.data.ui.DomainPublicRO;
+import eu.europa.ec.edelivery.smp.logging.SMPLogger;
+import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
+import org.apache.commons.beanutils.BeanUtils;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.InvocationTargetException;
+
+
+/**
+ * Converter for domain DAO entity {@link DBDomain} to enriched webservice object {@link eu.europa.ec.edelivery.smp.data.ui.DomainPublicRO}.
+ *
+ * @author Joze Rihtarsic
+ * @since 5.1
+ */
+@Component
+public class DBDomainToDomainPublicROConverter implements Converter<DBDomain, DomainPublicRO> {
+    private static final SMPLogger LOG = SMPLoggerFactory.getLogger(DBDomainToDomainPublicROConverter.class);
+
+    @Override
+    public DomainPublicRO convert(DBDomain source) {
+
+        if (source == null) {
+            return null;
+        }
+        DomainPublicRO target = new DomainPublicRO();
+        try {
+            BeanUtils.copyProperties(target, source);
+        } catch (IllegalAccessException | InvocationTargetException e) {
+            LOG.error("Error occurred while converting DBDomain", e);
+            return null;
+        }
+        return target;
+    }
+}
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DomainDao.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DomainDao.java
index c312c1b63..972d001d9 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DomainDao.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DomainDao.java
@@ -20,7 +20,9 @@
 package eu.europa.ec.edelivery.smp.data.dao;
 
 import eu.europa.ec.edelivery.smp.data.enums.MembershipRoleType;
+import eu.europa.ec.edelivery.smp.data.enums.VisibilityType;
 import eu.europa.ec.edelivery.smp.data.model.DBDomain;
+import eu.europa.ec.edelivery.smp.data.model.user.DBUser;
 import eu.europa.ec.edelivery.smp.exceptions.ErrorCode;
 import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
 import org.apache.commons.lang3.StringUtils;
@@ -78,17 +80,6 @@ public class DomainDao extends BaseDao<DBDomain> {
         return query.getResultList();
     }
 
-    /**
-     * Returns domain code records from smp_domain table.
-     *
-     * @return the list of domain codes from smp_domain table
-     */
-    public List<String> getAllDomainCodes() {
-        TypedQuery<String> query = memEManager.createNamedQuery(QUERY_DOMAIN_ALL_CODES, String.class);
-        return query.getResultList();
-    }
-
-
     public Optional<DBDomain> getFirstDomain() {
         TypedQuery<DBDomain> query = memEManager.createNamedQuery(QUERY_DOMAIN_ALL, DBDomain.class);
         query.setMaxResults(1);
@@ -197,8 +188,9 @@ public class DomainDao extends BaseDao<DBDomain> {
      * Check if domain for domain code exists. If not SMPRuntimeException with DOMAIN_NOT_EXISTS is thrown.
      * If code is null or blank - then null is returned.
      *
-     * @param domainCode
-     * @return
+     * @param domainCode  - domain code to be validated
+     * @return DBDomain - domain if exists
+     * @throws SMPRuntimeException if domain does not exist
      */
     public DBDomain validateDomainCode(String domainCode) {
         DBDomain domain = null;
@@ -228,4 +220,36 @@ public class DomainDao extends BaseDao<DBDomain> {
         }
         return false;
     }
+
+    /**
+     * Method returns all public domains with all domains where user is direct or indirect member.
+     * and have some resources assigned. See the EDELIVERY-13793
+     * If user is null then only public domains are returned.
+     *
+     * @param user - user to search for
+     *             if null only public domains are returned
+     * @return list of domains
+     * @Param page - page number
+     * @Param pageSize - page size
+     */
+    public List<DBDomain> getAllDomainsForUser(DBUser user, int page, int pageSize) {
+        TypedQuery<DBDomain> query = createAllDomainsForUserQuery(DBDomain.class, user);
+        setPaginationParametersToQuery(query, page, pageSize);
+        return query.getResultList();
+    }
+
+    public long getAllDomainsForUserCount(DBUser user) {
+        TypedQuery<Long> query = createAllDomainsForUserQuery(Long.class, user);
+        return query.getSingleResult();
+    }
+
+    private <T> TypedQuery<T> createAllDomainsForUserQuery(Class<T> resultClass, DBUser user) {
+        String queryName = resultClass == Long.class ? QUERY_DOMAIN_FOR_USER_COUNT :
+                QUERY_DOMAIN_FOR_USER;
+        LOG.debug("Create search query [{}] for all users domain", queryName);
+        TypedQuery<T> query = memEManager.createNamedQuery(queryName, resultClass);
+        query.setParameter(PARAM_USER_ID, user != null ? user.getId() : null);
+        query.setParameter(PARAM_DOMAIN_VISIBILITY, VisibilityType.PUBLIC);
+        return query;
+    }
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/QueryNames.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/QueryNames.java
index 77e690af2..f89a188ab 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/QueryNames.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/QueryNames.java
@@ -39,6 +39,8 @@ public class QueryNames {
 
     public static final String QUERY_DOMAIN_BY_USER_ROLES_COUNT = "DBDomain.getByUserAndRolesCount";
     public static final String QUERY_DOMAIN_BY_USER_ROLES = "DBDomain.getByUserAndRoles";
+    public static final String QUERY_DOMAIN_FOR_USER = "DBDomain.getAllDomainsForUser";
+    public static final String QUERY_DOMAIN_FOR_USER_COUNT = "DBDomain.getAllDomainsForUserCount";
 
     public static final String QUERY_DOMAIN_BY_USER_GROUP_ROLES_COUNT = "DBDomain.getByUserAndGroupRolesCount";
     public static final String QUERY_DOMAIN_BY_USER_GROUP_ROLES = "DBDomain.getByUserAndGroupRoles";
@@ -119,6 +121,8 @@ public class QueryNames {
     public static final String QUERY_RESOURCE_DEF_URL_SEGMENT = "DBResourceDef.getResourceDefByURLSegment";
     public static final String QUERY_RESOURCE_DEF_BY_IDENTIFIER = "DBResourceDef.getResourceDefByIdentifier";
     public static final String QUERY_RESOURCE_DEF_BY_IDENTIFIER_EXTENSION = "DBExtResourceDef.getByIdentifierExtension";
+    public static final String QUERY_RESOURCE_DEF_FOR_USER = "DBResourceDef.getAllForUser";
+    public static final String QUERY_RESOURCE_DEF_FOR_USER_COUNT = "DBResourceDef.getAllForUserCount";
 
     public static final String QUERY_DOCUMENT_FOR_RESOURCE = "DBDocument.getForResource";
     public static final String QUERY_SEARCH_DOCUMENT_REFERENCES = "DBDocument.getDocumentReferences";
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDefDao.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDefDao.java
index 79f14e037..f31898f58 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDefDao.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDefDao.java
@@ -19,10 +19,13 @@
 
 package eu.europa.ec.edelivery.smp.data.dao;
 
+import eu.europa.ec.edelivery.smp.data.enums.VisibilityType;
 import eu.europa.ec.edelivery.smp.data.model.DBDomain;
 import eu.europa.ec.edelivery.smp.data.model.ext.DBExtension;
 import eu.europa.ec.edelivery.smp.data.model.ext.DBResourceDef;
+import eu.europa.ec.edelivery.smp.data.model.user.DBUser;
 import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
+import org.slf4j.Logger;
 import org.springframework.stereotype.Repository;
 
 import javax.persistence.NoResultException;
@@ -41,7 +44,7 @@ import static eu.europa.ec.edelivery.smp.exceptions.ErrorCode.INTERNAL_ERROR;
  */
 @Repository
 public class ResourceDefDao extends BaseDao<DBResourceDef> {
-
+    private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(ResourceDefDao.class);
 
     /**
      * Returns DBResourceDef records from the database.
@@ -133,4 +136,35 @@ public class ResourceDefDao extends BaseDao<DBResourceDef> {
             throw new SMPRuntimeException(CONFIGURATION_ERROR, "More than one resource type is registered for the name!");
         }
     }
+
+    /**
+     * Method returns all public domains with all domains where user is direct or indirect member.
+     * If user is null then only public domains are returned.
+     *
+     * @param user - user to search for
+     *             if null only public domains are returned
+     * @return list of domains
+     * @Param page - page number
+     * @Param pageSize - page size
+     */
+    public List<DBResourceDef> getAllResourceDefsForUser(DBUser user, int page, int pageSize) {
+        TypedQuery<DBResourceDef> query = createAllResourceDefForUserQuery(DBResourceDef.class, user);
+        setPaginationParametersToQuery(query, page, pageSize);
+        return query.getResultList();
+    }
+
+    public long getAllResourceDefsForUserCount(DBUser user) {
+        TypedQuery<Long> query = createAllResourceDefForUserQuery(Long.class, user);
+        return query.getSingleResult();
+    }
+
+    private <T> TypedQuery<T> createAllResourceDefForUserQuery(Class<T> resultClass, DBUser user) {
+        String queryName = resultClass == Long.class ? QUERY_RESOURCE_DEF_FOR_USER_COUNT :
+                QUERY_RESOURCE_DEF_FOR_USER;
+        LOG.debug("Create search query [{}] for user [{}]", queryName, user);
+        TypedQuery<T> query = memEManager.createNamedQuery(queryName, resultClass);
+        query.setParameter(PARAM_USER_ID, user != null ? user.getId() : null);
+        query.setParameter(PARAM_DOMAIN_VISIBILITY, VisibilityType.PUBLIC);
+        return query;
+    }
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java
index 5bce6d7f3..674a3721b 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java
@@ -72,15 +72,33 @@ import static eu.europa.ec.edelivery.smp.data.dao.QueryNames.*;
         " JOIN DBResource r ON  g.id = r.group.id " +
         " JOIN DBResourceMember rm ON r.id = rm.resource.id " +
         " WHERE rm.role in (:membership_roles) and rm.user.id= :user_id")
-
-
 @NamedQuery(name = QUERY_DOMAIN_BY_USER_RESOURCE_ROLES, query = "SELECT distinct d FROM DBDomain d " +
         " JOIN DBGroup g ON d.id = g.domain.id " +
         " JOIN DBResource r ON  g.id = r.group.id " +
         " JOIN DBResourceMember rm ON r.id = rm.resource.id " +
         " WHERE rm.role in (:membership_roles) and rm.user.id= :user_id")
 
-@org.hibernate.annotations.Table(appliesTo = "SMP_DOMAIN", comment = "SMP can handle multiple domains. This table contains domain specific data")
+@NamedQuery(name = QUERY_DOMAIN_FOR_USER, query = "SELECT distinct d FROM DBDomain d " +
+        " JOIN DBGroup g ON d.id = g.domain.id " +
+        " JOIN DBResource r ON  g.id = r.group.id " +
+        " WHERE d.visibility = :domain_visibility " +
+        "   or (:user_id IS NOT NULL " +
+        "         AND  (" +
+        "               (select count(dm.id) FROM  DBDomainMember dm where dm.user.id = :user_id and dm.domain.id = d.id) > 0 " +
+        "            OR (select count(gm.id) FROM  DBGroupMember gm where gm.user.id = :user_id and gm.group.id = g.id) > 0 " +
+        "            OR (select count(rm.id) from DBResourceMember rm where rm.user.id = :user_id and rm.resource.id = r.id) > 0) " +
+        "   ) " )
+@NamedQuery(name = QUERY_DOMAIN_FOR_USER_COUNT, query = "SELECT distinct COUNT( distinct d.id) FROM DBDomain d " +
+        " JOIN DBGroup g ON d.id = g.domain.id " +
+        " JOIN DBResource r ON  g.id = r.group.id " +
+        " WHERE d.visibility = :domain_visibility " +
+        "   or (:user_id IS NOT NULL " +
+        "         AND  (" +
+        "               (select count(dm.id) FROM  DBDomainMember dm where dm.user.id = :user_id and dm.domain.id = d.id) > 0 " +
+        "            OR (select count(gm.id) FROM  DBGroupMember gm where gm.user.id = :user_id and gm.group.id = g.id) > 0 " +
+        "            OR (select count(rm.id) from DBResourceMember rm where rm.user.id = :user_id and rm.resource.id = r.id) > 0) " +
+        "   ) " )
+        @org.hibernate.annotations.Table(appliesTo = "SMP_DOMAIN", comment = "SMP can handle multiple domains. This table contains domain specific data")
 public class DBDomain extends BaseEntity {
 
     private static final long serialVersionUID = 1008583888835630004L;
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/ext/DBResourceDef.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/ext/DBResourceDef.java
index 74fa363fb..f2721d48c 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/ext/DBResourceDef.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/ext/DBResourceDef.java
@@ -51,6 +51,30 @@ import static eu.europa.ec.edelivery.smp.data.dao.QueryNames.*;
 @NamedQuery(name = QUERY_RESOURCE_DEF_BY_DOMAIN, query = "SELECT d FROM DBResourceDef d JOIN d.domainResourceDefs dr where dr.domain.id = :domain_id order by d.id asc")
 @NamedQuery(name = QUERY_RESOURCE_DEF_URL_SEGMENT, query = "SELECT d FROM DBResourceDef d WHERE d.urlSegment = :url_segment")
 @NamedQuery(name = QUERY_RESOURCE_DEF_BY_IDENTIFIER, query = "SELECT d FROM DBResourceDef d WHERE d.identifier = :identifier")
+@NamedQuery(name = QUERY_RESOURCE_DEF_FOR_USER, query = "SELECT distinct rd FROM DBResourceDef rd " +
+        " JOIN DBDomainResourceDef drd ON drd.resourceDef.id = rd.id " +
+        " JOIN DBDomain d ON d.id = drd.domain.id " +
+        " JOIN DBGroup g ON d.id = g.domain.id " +
+        " JOIN DBResource r ON  g.id = r.group.id " +
+        " WHERE d.visibility = :domain_visibility " +
+        "   or (:user_id IS NOT NULL " +
+        "         AND  (" +
+        "               (select count(dm.id) FROM  DBDomainMember dm where dm.user.id = :user_id and dm.domain.id = d.id) > 0 " +
+        "            OR (select count(gm.id) FROM  DBGroupMember gm where gm.user.id = :user_id and gm.group.id = g.id) > 0 " +
+        "            OR (select count(rm.id) from DBResourceMember rm where rm.user.id = :user_id and rm.resource.id = r.id) > 0) " +
+        "   ) " )
+@NamedQuery(name = QUERY_RESOURCE_DEF_FOR_USER_COUNT, query = "SELECT count(distinct rd.id) FROM DBResourceDef rd " +
+        " JOIN DBDomainResourceDef drd ON drd.resourceDef.id = rd.id " +
+        " JOIN DBDomain d ON d.id = drd.domain.id " +
+        " JOIN DBGroup g ON d.id = g.domain.id " +
+        " JOIN DBResource r ON  g.id = r.group.id " +
+        " WHERE d.visibility = :domain_visibility " +
+        "   or (:user_id IS NOT NULL " +
+        "         AND  (" +
+        "               (select count(dm.id) FROM  DBDomainMember dm where dm.user.id = :user_id and dm.domain.id = d.id) > 0 " +
+        "            OR (select count(gm.id) FROM  DBGroupMember gm where gm.user.id = :user_id and gm.group.id = g.id) > 0 " +
+        "            OR (select count(rm.id) from DBResourceMember rm where rm.user.id = :user_id and rm.resource.id = r.id) > 0) " +
+        "   ) " )
 public class DBResourceDef extends BaseEntity {
     private static final long serialVersionUID = 1008583888835630001L;
 
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/DomainPublicRO.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/DomainPublicRO.java
index 73cb52ccc..6ee12b9a0 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/DomainPublicRO.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/DomainPublicRO.java
@@ -20,7 +20,7 @@ package eu.europa.ec.edelivery.smp.data.ui;
 
 
 /**
- * Domain resource object containing only public data
+ * Domain resource object containing only public data. Mainly used for search filtering.
  *
  * @author Joze Rihtarsic
  * @since 5.0
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIDomainEditService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIDomainEditService.java
index d2bfbec09..48de159a1 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIDomainEditService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIDomainEditService.java
@@ -18,6 +18,7 @@
  */
 package eu.europa.ec.edelivery.smp.services.ui;
 
+import eu.europa.ec.edelivery.smp.auth.SMPUserDetails;
 import eu.europa.ec.edelivery.smp.data.dao.*;
 import eu.europa.ec.edelivery.smp.data.enums.MembershipRoleType;
 import eu.europa.ec.edelivery.smp.data.model.DBDomain;
@@ -32,6 +33,7 @@ import eu.europa.ec.edelivery.smp.exceptions.ErrorCode;
 import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
+import eu.europa.ec.edelivery.smp.utils.SessionSecurityUtils;
 import org.springframework.core.convert.ConversionService;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -51,6 +53,7 @@ import java.util.stream.Collectors;
 public class UIDomainEditService extends UIServiceBase<DBDomain, DomainPublicRO> {
 
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(UIDomainEditService.class);
+    public static final String DOMAIN_DOES_NOT_EXIST_IN_DATABASE = "Domain does not exist in database!";
     private final DomainDao domainDao;
     private final DomainConfigurationDao domainConfigurationDao;
     private final DomainMemberDao domainMemberDao;
@@ -91,6 +94,35 @@ public class UIDomainEditService extends UIServiceBase<DBDomain, DomainPublicRO>
         return super.getTableList(page, pageSize, sortField, sortOrder, filter);
     }
 
+
+    /**
+     * Method returns only domains  current users have access to.
+     *
+     * @param page      - page number
+     * @param pageSize  - page size
+     * @return ServiceResult<DomainPublicRO> - list of domain resource objects
+     */
+    public ServiceResult<DomainPublicRO> getUserPermittedDomains(int page, int pageSize) {
+        LOG.debug("Query for public domain data: page: [{}], page size [{}].", page, pageSize);
+        SMPUserDetails userDetails = SessionSecurityUtils.getSessionUserDetails();
+        DBUser user = userDetails!=null?userDetails.getUser():null;
+
+        ServiceResult<DomainPublicRO> result = new ServiceResult<>();
+        result.setPage(page);
+        result.setPageSize(pageSize);
+        Long count = domainDao.getAllDomainsForUserCount(user);
+        if (count < 1) {
+            result.setCount(0L);
+            return result;
+        }
+        result.setCount(count);
+        List<DomainPublicRO> refList = domainDao.getAllDomainsForUser(user, page, pageSize).stream()
+                .map(doc -> conversionService.convert(doc, DomainPublicRO.class))
+                .collect(Collectors.toList());
+        result.getServiceEntities().addAll(refList);
+        return result;
+    }
+
     @Transactional
     public List<DomainRO> getAllDomainsForDomainAdminUser(Long userId) {
         List<DBDomain> domains = domainDao.getDomainsByUserIdAndDomainRoles(userId, MembershipRoleType.ADMIN);
@@ -171,7 +203,7 @@ public class UIDomainEditService extends UIServiceBase<DBDomain, DomainPublicRO>
         DBDomain domain = domainDao.find(domainId);
         if (domain == null) {
             LOG.warn("Can not get domain for ID [{}], because it does not exists!", domainId);
-            throw new BadRequestException(ErrorBusinessCode.NOT_FOUND, "Domain does not exist in database!");
+            throw new BadRequestException(ErrorBusinessCode.NOT_FOUND, DOMAIN_DOES_NOT_EXIST_IN_DATABASE);
         }
 
         //filter and validate resources to be removed
@@ -189,7 +221,7 @@ public class UIDomainEditService extends UIServiceBase<DBDomain, DomainPublicRO>
     public List<DomainPropertyRO> getDomainEditProperties(Long domainId) {
         DBDomain domain = domainDao.find(domainId);
         if (domain == null) {
-            throw new BadRequestException(ErrorBusinessCode.NOT_FOUND, "Domain does not exist in database!");
+            throw new BadRequestException(ErrorBusinessCode.NOT_FOUND, DOMAIN_DOES_NOT_EXIST_IN_DATABASE);
         }
         return domainConfigurationDao.getDomainPropertiesForRole(domain, SMPRole.USER).stream()
                 .map(property -> conversionService.convert(property, DomainPropertyRO.class))
@@ -207,7 +239,7 @@ public class UIDomainEditService extends UIServiceBase<DBDomain, DomainPublicRO>
     public List<DomainPropertyRO> updateDomainEditProperties(Long domainId, List<DomainPropertyRO> domainProperties) {
         DBDomain domain = domainDao.find(domainId);
         if (domain == null) {
-            throw new BadRequestException(ErrorBusinessCode.NOT_FOUND, "Domain does not exist in database!");
+            throw new BadRequestException(ErrorBusinessCode.NOT_FOUND, DOMAIN_DOES_NOT_EXIST_IN_DATABASE);
         }
         return domainConfigurationDao.updateDomainPropertiesForRole(domain, domainProperties, SMPRole.USER).stream()
                 .map(property -> conversionService.convert(property, DomainPropertyRO.class))
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIResourceSearchService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIResourceSearchService.java
index 44be22aa3..b38234ae0 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIResourceSearchService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIResourceSearchService.java
@@ -8,9 +8,9 @@
  * versions of the EUPL (the "Licence");
  * You may not use this work except in compliance with the Licence.
  * You may obtain a copy of the Licence at:
- * 
+ *
  * [PROJECT_HOME]\license\eupl-1.2\license.txt or https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software distributed under the Licence is
  * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the Licence for the specific language governing permissions and limitations under the Licence.
@@ -18,7 +18,12 @@
  */
 package eu.europa.ec.edelivery.smp.services.ui;
 
-import eu.europa.ec.edelivery.smp.data.dao.*;
+import eu.europa.ec.edelivery.smp.auth.SMPUserDetails;
+import eu.europa.ec.edelivery.smp.data.dao.BaseDao;
+import eu.europa.ec.edelivery.smp.data.dao.DomainDao;
+import eu.europa.ec.edelivery.smp.data.dao.ResourceDao;
+import eu.europa.ec.edelivery.smp.data.dao.ResourceDefDao;
+import eu.europa.ec.edelivery.smp.data.model.DBDomain;
 import eu.europa.ec.edelivery.smp.data.model.doc.DBResource;
 import eu.europa.ec.edelivery.smp.data.model.ext.DBResourceDef;
 import eu.europa.ec.edelivery.smp.data.model.user.DBUser;
@@ -30,7 +35,6 @@ import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
 import eu.europa.ec.edelivery.smp.services.ui.filters.ResourceFilter;
 import eu.europa.ec.edelivery.smp.utils.SessionSecurityUtils;
-import org.springframework.core.convert.ConversionService;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -46,18 +50,12 @@ public class UIResourceSearchService extends UIServiceBase<DBResource, ServiceGr
 
     private final ResourceDao resourceDao;
 
-    private final UserDao userDao;
-
     private final ResourceDefDao resourceDefDao;
 
-    private final ConversionService conversionService;
-
-    public UIResourceSearchService(DomainDao domainDao, ResourceDao resourceDao, UserDao userDao, ResourceDefDao resourceDefDao, ConversionService conversionService) {
+    public UIResourceSearchService(DomainDao domainDao, ResourceDao resourceDao, ResourceDefDao resourceDefDao) {
         this.domainDao = domainDao;
         this.resourceDao = resourceDao;
-        this.userDao = userDao;
         this.resourceDefDao = resourceDefDao;
-        this.conversionService = conversionService;
     }
 
 
@@ -77,16 +75,16 @@ public class UIResourceSearchService extends UIServiceBase<DBResource, ServiceGr
      * @return
      */
     @Transactional
-    public ServiceResult<ServiceGroupSearchRO> getTableList(int page, int pageSize,
-                                                            String sortField,
-                                                            String sortOrder, ResourceFilter filter) {
-
+    public ServiceResult<ServiceGroupSearchRO> getTableList(int page, int pageSize, String sortField, String sortOrder, ResourceFilter filter) {
+        LOG.debug("Get table list for page: [{}], page size: [{}], sort field: [{}], sort order: [{}], filter: [{}]", page, pageSize, sortField, sortOrder, filter);
         ServiceResult<ServiceGroupSearchRO> sg = new ServiceResult<>();
         sg.setPage(page < 0 ? 0 : page);
         sg.setPageSize(pageSize);
-        DBUser user = SessionSecurityUtils.getSessionUserDetails() != null ? SessionSecurityUtils.getSessionUserDetails().getUser() : null;
+        DBUser user = SessionSecurityUtils.getSessionUserDetails() != null ?
+                SessionSecurityUtils.getSessionUserDetails().getUser() : null;
 
-        long iCnt = resourceDao.getPublicResourcesSearchCount(user, filter.getIdentifierSchemeLike(), filter.getIdentifierValueLike(), filter.getDomainCode(), filter.getDocumentType());
+        long iCnt = resourceDao.getPublicResourcesSearchCount(user, filter.getIdentifierSchemeLike(),
+                filter.getIdentifierValueLike(), filter.getDomainCode(), filter.getDocumentType());
         sg.setCount(iCnt);
 
         if (iCnt > 0) {
@@ -111,7 +109,7 @@ public class UIResourceSearchService extends UIServiceBase<DBResource, ServiceGr
     /**
      * Convert Database object to Rest object for UI
      *
-     * @param resource     - database entity wrapper
+     * @param resource - database entity wrapper
      * @return ServiceGroupRO
      */
     private ServiceGroupSearchRO convert(ResourceDao.DBResourceWrapper resource) {
@@ -136,8 +134,12 @@ public class UIResourceSearchService extends UIServiceBase<DBResource, ServiceGr
     }
 
     public ResourceFilterOptionsResult getResourceMetadata() {
-        List<String> domainCodes = domainDao.getAllDomainCodes();
-        List<String> documentTypes = resourceDefDao.getAllResourceDef().stream().map(DBResourceDef::getName).collect(Collectors.toList());
+        SMPUserDetails userDetails = SessionSecurityUtils.getSessionUserDetails();
+        DBUser user = userDetails != null ? userDetails.getUser() : null;
+        List<String> domainCodes = domainDao.getAllDomainsForUser(user, -1, -1)
+                .stream().map(DBDomain::getDomainCode).collect(Collectors.toList());
+        List<String> documentTypes = resourceDefDao.getAllResourceDefsForUser(user, -1, -1)
+                .stream().map(DBResourceDef::getName).collect(Collectors.toList());
         return new ResourceFilterOptionsResult(domainCodes, documentTypes);
     }
 }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/TestUtilsDao.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/TestUtilsDao.java
index 2d3899d5e..995bd1c0a 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/TestUtilsDao.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/TestUtilsDao.java
@@ -376,8 +376,10 @@ public class TestUtilsDao {
         DBDomain publicDomain = createDomain("publicDomain", VisibilityType.PUBLIC);
         DBDomain privateDomain = createDomain("privateDomain", VisibilityType.PRIVATE);
 
+
         DBDomainResourceDef publicDomainResourceDef = registerDomainResourceDefinition(publicDomain, resourceDefSmp);
         DBDomainResourceDef privateDomainResourceDef= registerDomainResourceDefinition(privateDomain, resourceDefSmp);
+        DBDomainResourceDef privateDomainResourceDef2= registerDomainResourceDefinition(privateDomain, resourceDefCpp);
         // membership of the domain
         createDomainMembership(MembershipRoleType.VIEWER, user3, privateDomain);
 
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/DomainController.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/DomainController.java
index 1d8a428fc..6572bfce5 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/DomainController.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/DomainController.java
@@ -8,9 +8,9 @@
  * versions of the EUPL (the "Licence");
  * You may not use this work except in compliance with the Licence.
  * You may obtain a copy of the Licence at:
- * 
+ *
  * [PROJECT_HOME]\license\eupl-1.2\license.txt or https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software distributed under the Licence is
  * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the Licence for the specific language governing permissions and limitations under the Licence.
@@ -24,7 +24,6 @@ import eu.europa.ec.edelivery.smp.data.ui.ServiceResult;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
 import eu.europa.ec.edelivery.smp.services.ui.UIDomainEditService;
-import eu.europa.ec.edelivery.smp.utils.SessionSecurityUtils;
 import org.springframework.util.MimeTypeUtils;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -34,7 +33,7 @@ import org.springframework.web.bind.annotation.RestController;
 import static eu.europa.ec.edelivery.smp.ui.ResourceConstants.*;
 
 /**
- * Purpose of the DomainResource is to provide public methoda to retrieve configured domains in SMP.
+ * Purpose of the DomainResource is to provide public method to retrieve configured domains in SMP.
  *
  * @author Joze Rihtarsic
  * @since 4.1
@@ -57,15 +56,8 @@ public class DomainController {
     public ServiceResult<DomainPublicRO> getDomainList(
             @RequestParam(value = PARAM_PAGINATION_PAGE, defaultValue = "0") int page,
             @RequestParam(value = PARAM_PAGINATION_PAGE_SIZE, defaultValue = "10") int pageSize,
-            @RequestParam(value = PARAM_PAGINATION_ORDER_BY, required = false) String orderBy,
-            @RequestParam(value = PARAM_PAGINATION_ORDER_TYPE, defaultValue = "asc", required = false) String orderType,
             @RequestParam(value = PARAM_QUERY_USER, required = false) String user) {
-
         LOG.info("Search for page: {}, page size: {}, user: {}", page, pageSize, user);
-        return uiDomainService.getTableList(page, pageSize, orderBy, orderType, null);
-    }
-
-    protected void logAdminAccess(String action) {
-        LOG.info(SMPLogger.SECURITY_MARKER, "Admin Domain action [{}] by user [{}], ", action, SessionSecurityUtils.getSessionUserDetails());
+        return uiDomainService.getUserPermittedDomains(page, pageSize);
     }
 }
diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/DomainResourceIT.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/DomainResourceIT.java
index c71840dd6..c52770714 100644
--- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/DomainResourceIT.java
+++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/DomainResourceIT.java
@@ -90,7 +90,9 @@ class DomainResourceIT {
 
 
         assertNotNull(res);
-        assertEquals(2, res.getServiceEntities().size());
+        // there are two  public domains in the database but only one has resources
+        // see EDELIVERY-13793
+        assertEquals(1, res.getServiceEntities().size());
         res.getServiceEntities().forEach(sgMap -> {
             DomainRO sgro = mapper.convertValue(sgMap, DomainRO.class);
             assertNotNull(sgro.getDomainCode());
-- 
GitLab